diff --git a/.babelrc b/.babelrc deleted file mode 100644 index df4ad4d9..00000000 --- a/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": ["env"], - "plugins": [ - "add-module-exports", - "transform-es2015-modules-umd" - ] -} diff --git a/.bithoundrc b/.bithoundrc deleted file mode 100644 index 46722b1d..00000000 --- a/.bithoundrc +++ /dev/null @@ -1,19 +0,0 @@ -{ - "ignore": [ - "**/.vscode/**", - "**/node_modules/**", - "**/dist/**", - "**/examples/**" - ], - "test": [ - "**/test/**" - ], - "critics": { - "lint": { - "engine": "eslint" - }, - "wc": { - "limit": 1000 - } - } -} diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index ac117e1a..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "env": { - "browser": true, - "commonjs": true, - "es6": true, - "node": true - }, - "globals": { - "expect": true, - "it": true, - "describe": true, - "beforeEach": true, - "afterEach": true, - "document": false, - "navigator": false, - "window": false - }, - "parser": "babel-eslint", - "extends": "airbnb-base", - "rules": { - "class-methods-use-this": 0, - "no-plusplus": 0, - "arrow-parens": 0, - "no-console": 0, - "import/prefer-default-export": 0, - "comma-dangle": 0, - "no-underscore-dangle": 0, - "no-param-reassign": 0, - "no-return-assign": 0, - "no-restricted-globals": 0, - "no-multi-assign": 0, - "prefer-destructuring": ["error", {"object": true, "array": false}], - "padded-blocks": 0, - "no-sparse-arrays": 0, - "array-bracket-spacing": 0, - "import/no-named-as-default": 0, - "implicit-arrow-linebreak": 0 - } -} diff --git a/.firebaserc b/.firebaserc deleted file mode 100644 index d33152ab..00000000 --- a/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "javascript-ds-algorithms-book" - } -} diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index cdaaeff1..00000000 --- a/.gitattributes +++ /dev/null @@ -1,40 +0,0 @@ -# Handle line endings automatically for files detected as text -# and leave all files detected as binary untouched. -* text=auto - -# -# The above will handle all files NOT found below -# -# These files are text and should be normalized (Convert crlf => lf) -*.css eol=lf -*.df eol=lf -*.htm eol=lf -*.html eol=lf -*.java eol=lf -*.js eol=lf -*.json eol=lf -*.jsp eol=lf -*.jspf eol=lf -*.jspx eol=lf -*.properties eol=lf -*.sh eol=lf -*.tld eol=lf -*.txt eol=lf -*.tag eol=lf -*.tagx eol=lf -*.xml eol=lf -*.yml eol=lf - -# These files are binary and should be left untouched -# (binary is a macro for -text -diff) -*.class binary -*.dll binary -*.ear binary -*.gif binary -*.ico binary -*.jar binary -*.jpg binary -*.jpeg binary -*.png binary -*.so binary -*.war binary diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index af297e37..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,27 +0,0 @@ -# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs - -name: Node.js CI - -on: - push: - branches: [ "fourth-edition" ] - pull_request: - branches: [ "fourth-edition" ] - -jobs: - build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [20.x, 22.x] - steps: - - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm test diff --git a/.gitignore b/.gitignore index 0c2aa12a..642271f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,2 @@ -.idea/* -*.log -node_modules -coverage -.nyc_output -coverage.lcov -mochawesome-report/* -dist/js/* -dist-/* -dist/ts/* -snippet.js +node_modules/ +coverage/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7def9b91..00000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: node_js -node_js: - - node -before_script: - - npm install -g --silent firebase-tools -install: - - npm install -script: - - npm run go -after_success: - - npm run coverage - - test $TRAVIS_BRANCH = "master" && test $TRAVIS_PULL_REQUEST = "false" && firebase deploy --token $FIREBASE_TOKEN --non-interactive -notifications: - email: - on_failure: change - on_success: change diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 85c3207b..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "chrome", - "request": "launch", - "name": "Chrome", - "url": "http://127.0.0.1:8080/examples", - "webRoot": "${workspaceRoot}" - }, - { - "type": "node", - "request": "launch", - "name": "Mocha JS", - "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", - "args": [ - "-u", - "tdd", - "--timeout", - "999999", - "--compilers", - "js:babel-core/register", - "--colors", - "${workspaceRoot}/test/js/**/*.spec.js" - ], - "internalConsoleOptions": "openOnSessionStart" - }, - { - "type": "node", - "request": "launch", - "name": "Mocha TS", - "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", - "args": [ - "-u", - "tdd", - "--timeout", - "999999", - "-r", - "ts-node/register", - "--colors", - "${workspaceRoot}/test/ts/**/**/*.spec.ts" - ], - "protocol": "auto", - "internalConsoleOptions": "openOnSessionStart" - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 55712c19..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "typescript.tsdk": "node_modules/typescript/lib" -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 9b4e4d2c..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "go", - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "type": "npm", - "script": "dev", - "group": { - "kind": "test", - "isDefault": true - } - } - ] -} diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index ade741a9..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# Change Log -All notable changes to the "javascript-datastructures-algorithms" third edition source code bundle will be documented in this file. - -Based on [Keep a Changelog](http://keepachangelog.com/). - -## [Unreleased] -- Initial release diff --git a/README.md b/README.md index e5657bcd..ad176a72 100644 --- a/README.md +++ b/README.md @@ -1,108 +1,89 @@ Learning JavaScript Data Structures and Algorithms -==================================== +=================================================== -[![Build Status](https://travis-ci.org/loiane/javascript-datastructures-algorithms.svg?branch=master)](https://travis-ci.org/loiane/javascript-datastructures-algorithms) -[![codecov](https://codecov.io/gh/loiane/javascript-datastructures-algorithms/branch/master/graph/badge.svg)](https://codecov.io/gh/loiane/javascript-datastructures-algorithms) -[![devDependencies Status](https://david-dm.org/loiane/javascript-datastructures-algorithms/dev-status.svg)](https://david-dm.org/loiane/javascript-datastructures-algorithms?type=dev) -[![dependencies Status](https://david-dm.org/loiane/javascript-datastructures-algorithms/status.svg)](https://david-dm.org/loiane/javascript-datastructures-algorithms) -[![Greenkeeper badge](https://badges.greenkeeper.io/loiane/javascript-datastructures-algorithms.svg)](https://greenkeeper.io/) +Source code of **Learning JavaScript Data Structures and Algorithms** (4th edition) book. +# Chapters -Source code of **Learning JavaScript Data Structures and Algorithms** book, third edition. +## Part 1: Introduction -## List of available chapters: +* 01: Introducing Data Structures and Algorithms in JavaScript +* 02: Understanding Big O Notation -* 01: [JavaScript: a quick overview](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter01_02) -* 02: [ECMAScript and TypeScript Introduction](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter01_02) -* 03: [Arrays](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter03) -* 04: [Stacks](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter04) -* 05: [Queues and Deques](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter05) -* 06: [LinkedLists](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter06) -* 07: [Sets](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter07) -* 08: [Dictionaries and Hashes](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter08) -* 09: [Recursion](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter09) -* 10: [Trees](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter10) -* 11: [Heap](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter11) -* 12: [Graphs](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter12) -* 13: [Sorting and Searching Algorithms](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter13) -* 14: [Algorithm Design and Techniques](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter14) -* 15: [Algorithm Complexity](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter15) +## Part 2: Data Structures -### Third Edition Updates +* 03: Arrays + * _Hackerrank_ exercises: + * Arrays DS + * Array Left Rotation +* 04: Stacks + * Stack data structure (array-based) + * Stack data structure (object-based) + * Decimal to binary algorithm + * Decimal to bases 2-32 algorithm + * Decimal to bases 2-32 or 64 algorithm + * Tower of Hanoi algorithm + * _LeetCode_ exercises: + * Valid Parantheses + * MinStack + * Simplify Path +* 05: Queues and Deques +* 06: Linked Lists +* 07: Sets +* 08: Dictionaries and Hashes +* 09: Recursion +* 10: Trees +* 11: Binary Heap and Heap Sort +* 12: Tries +* 13: Graphs -* Algorithms using ES2015+ (ES6+) -* New data structures and algorithms -* All chapters rewritten and reviewed -* Three (3) new chapters -* Creation of a Data Structures and Algorithms library that can be used in the browser or with Node.js -* Algorithms tested with Mocha + Chai (test code available in `test` directory) -* **TypeScript** version of the source code included (library and tests) +## Part 3: Algorithms -## Project Structure +* 14: Sorting Algorithms +* 15: Searching and Shuffling Algorithms +* 16: String Algorithms +* 17: Math Algorithms +* 18: Algorithm Designs and Techniques -`src/js/index.js` file contains all the data structures and algorithms listed by chapter. +# Project Structure -``` -|_examples (how to use each data structure and algorithm, organized by chapter) -|_src -|___js (source code: JavaScript version) -|_____data-structures -|_______models (classes used by DS: Node, ValuePair, ...) -|_____others (other algorithms such as palindome checker, hanoi tower) -|___ts (source code: TypeScript version) -|_____data-structures -|_______models -|_____others -|_test (unit tests with Mocha and Chai for src) -|___js (tests for JavaScript code) -|___ts (tests for TypeScript code) -``` - -## Installing and running the book examples With Node +You can find the source code organized by chapter under the `src` folder. -* Install [Node](https://nodejs.org) -* Open terminal/cmd and change directory to this project folder: `cd /Users/.../javascript-datastructures-algorithms` (Linux/Max) or `cd C:/.../javascript-datastructures-algorithms` -* run `npm install` to install all dependencies -* To see the examples, run `http-server html` or `npm run serve`. Open your browser `http:\\localhost:8080` to see the book examples -* Or `cd html/chapter01` and run each javascript file with node: `node 02-Variables` +*Each file has the `.js` and the `.ts` extension, so you get both the JavaScript and the Typescript versions of the source code.* -## Running the examples in the browser +*Each data structure and algorithm from parts 2 and 3 also have a `_test_`* folder where you can find the respective `Jest` test cases. -* Right click on the html file you would like to see the examples, right click and 'Open with Chrome (or any other browser)' +## How to use this repository -* Or open the `examples/index.html` file to easily navigate through all examples: +**Install all dependencies** -* Demo: [https://javascript-ds-algorithms-book.firebaseapp.com](https://javascript-ds-algorithms-book.firebaseapp.com) +``` +npm install +``` - +**Run all tests** -Happy Coding! +``` +npm test +``` -## Other editions +**Run a particular example** -| 1st edition | 2nd edition | 3rd edition | -| ------------- |:-------------:|:-------------:| -| ![1st edition](https://images-na.ssl-images-amazon.com/images/I/51xXGv7QlBL._SX403_BO1,204,203,200_.jpg) | ![2nd edition](https://images-na.ssl-images-amazon.com/images/I/51PWJ%2BoKc2L._SX403_BO1,204,203,200_.jpg) | ![3rd edition](https://images-na.ssl-images-amazon.com/images/I/41oSXp3VztL._SX404_BO1,204,203,200_.jpg) | -| [Book link](http://amzn.to/1Y1OWPx)| [Book link](http://amzn.to/1TSkcA1)| [Book link](http://a.co/cbMlYmJ)| +``` +cd src/01-intro +node 01-hello-variables.js +``` -Book link - first edition: - - [Packt](https://www.packtpub.com/application-development/learning-javascript-data-structures-and-algorithms) - - [Amazon](http://amzn.to/1Y1OWPx) - - [Chinese version](http://www.ituring.com.cn/book/1613) - - [Korean version](http://www.acornpub.co.kr/book/javascript-data-structure) +or: -Book link - second edition: - - [Packt](https://www.packtpub.com/web-development/learning-javascript-data-structures-and-algorithms-second-edition) - - [Amazon](http://amzn.to/1TSkcA1) - - [Chinese version](http://www.ituring.com.cn/book/2029) - - [Brazilian Portuguese version](https://novatec.com.br/livros/estruturas-de-dados-algoritmos-em-javascript/) +``` +node src/01-intro/01-hello-variables.js +``` - Book link - third edition: - - [Packt](https://www.packtpub.com/en-us/product/learning-javascript-data-structures-and-algorithms-9781788624947) - - [Amazon](http://a.co/cbMlYmJ) - - [Chinese version](http://www.ituring.com.cn/book/2653) - - [Brazilian Portuguese version](https://novatec.com.br/livros/estruturas-de-dados-algoritmos-em-javascript-2ed/) +## 💻 Tecnologies -### Found an issue or have a question? +* JavaScript +* TypeScript +* Jest (tests) -Please create an [Issue](https://github.com/loiane/javascript-datastructures-algorithms/issues) or [Pull Request](https://github.com/loiane/javascript-datastructures-algorithms/pulls) +Happy Coding! \ No newline at end of file diff --git a/examples/PacktDataStructuresAlgorithms.min.js b/examples/PacktDataStructuresAlgorithms.min.js deleted file mode 100644 index b7d4c0c6..00000000 --- a/examples/PacktDataStructuresAlgorithms.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("PacktDataStructuresAlgorithms",[],t):"object"==typeof exports?exports.PacktDataStructuresAlgorithms=t():e.PacktDataStructuresAlgorithms=t()}(window,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=66)}([function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.lesserEquals=function(e,n,r){var i=r(e,n);return i===t.LESS_THAN||i===t.EQUALS},e.biggerEquals=function(e,n,r){var i=r(e,n);return i===t.BIGGER_THAN||i===t.EQUALS},e.defaultCompare=function(e,n){return e===n?t.EQUALS:e0&&void 0!==arguments[0]?arguments[0]:n.defaultEquals;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.equalsFn=t,this.count=0,this.head=void 0}return i(e,[{key:"push",value:function(e){var t=new r.Node(e),n=void 0;if(null==this.head)this.head=t;else{for(n=this.head;null!=n.next;)n=n.next;n.next=t}this.count++}},{key:"getElementAt",value:function(e){if(e>=0&&e<=this.count){for(var t=this.head,n=0;n=0&&t<=this.count){var n=new r.Node(e);if(0===t){var i=this.head;n.next=i,this.head=n}else{var o=this.getElementAt(t-1);n.next=o.next,o.next=n}return this.count++,!0}return!1}},{key:"removeAt",value:function(e){if(e>=0&&e1&&(u=function(e,n,r,i){for(var o=e[Math.floor((r+n)/2)],u=n,a=r;u<=a;){for(;i(e[u],o)===t.Compare.LESS_THAN;)u++;for(;i(e[a],o)===t.Compare.BIGGER_THAN;)a--;u<=a&&((0,t.swap)(e,u,a),u++,a--)}return u}(e,r,i,o),r1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare;return n(e,0,e.length-1,r)}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(0)],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.findMaxValue=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare;if(e&&e.length>0){for(var r=e[0],i=1;i1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare;if(e&&e.length>0){for(var r=e[0],i=1;i1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare,r=e.length,i=void 0,o=1;o0&&n(e[u-1],i)===t.Compare.BIGGER_THAN;)e[u]=e[u-1],u--;e[u]=i}return e}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var t=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:n.defaultCompare;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.compareFn=t,this.root=void 0}return i(e,[{key:"insert",value:function(e){null==this.root?this.root=new r.Node(e):this.insertNode(this.root,e)}},{key:"insertNode",value:function(e,t){this.compareFn(t,e.key)===n.Compare.LESS_THAN?null==e.left?e.left=new r.Node(t):this.insertNode(e.left,t):null==e.right?e.right=new r.Node(t):this.insertNode(e.right,t)}},{key:"getRoot",value:function(){return this.root}},{key:"search",value:function(e){return this.searchNode(this.root,e)}},{key:"searchNode",value:function(e,t){return null!=e&&(this.compareFn(t,e.key)===n.Compare.LESS_THAN?this.searchNode(e.left,t):this.compareFn(t,e.key)!==n.Compare.BIGGER_THAN||this.searchNode(e.right,t))}},{key:"inOrderTraverse",value:function(e){this.inOrderTraverseNode(this.root,e)}},{key:"inOrderTraverseNode",value:function(e,t){null!=e&&(this.inOrderTraverseNode(e.left,t),t(e.key),this.inOrderTraverseNode(e.right,t))}},{key:"preOrderTraverse",value:function(e){this.preOrderTraverseNode(this.root,e)}},{key:"preOrderTraverseNode",value:function(e,t){null!=e&&(t(e.key),this.preOrderTraverseNode(e.left,t),this.preOrderTraverseNode(e.right,t))}},{key:"postOrderTraverse",value:function(e){this.postOrderTraverseNode(this.root,e)}},{key:"postOrderTraverseNode",value:function(e,t){null!=e&&(this.postOrderTraverseNode(e.left,t),this.postOrderTraverseNode(e.right,t),t(e.key))}},{key:"min",value:function(){return this.minNode(this.root)}},{key:"minNode",value:function(e){for(var t=e;null!=t&&null!=t.left;)t=t.left;return t}},{key:"max",value:function(){return this.maxNode(this.root)}},{key:"maxNode",value:function(e){for(var t=e;null!=t&&null!=t.right;)t=t.right;return t}},{key:"remove",value:function(e){this.root=this.removeNode(this.root,e)}},{key:"removeNode",value:function(e,t){if(null!=e){if(this.compareFn(t,e.key)===n.Compare.LESS_THAN)return e.left=this.removeNode(e.left,t),e;if(this.compareFn(t,e.key)===n.Compare.BIGGER_THAN)return e.right=this.removeNode(e.right,t),e;if(null==e.left&&null==e.right)return e=void 0;if(null==e.left)return e=e.right;if(null==e.right)return e=e.left;var r=this.minNode(e.right);return e.key=r.key,e.right=this.removeNode(e.right,r.key),e}}}]),e}();t.default=o,e.exports=t.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[e,t,n(0),n(1)],void 0===(o="function"==typeof(r=function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:n.defaultToString;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.toStrFn=t,this.table={}}return i(e,[{key:"set",value:function(e,t){if(null!=e&&null!=t){var n=this.toStrFn(e);return this.table[n]=new r.ValuePair(e,t),!0}return!1}},{key:"get",value:function(e){var t=this.table[this.toStrFn(e)];return null==t?void 0:t.value}},{key:"hasKey",value:function(e){return null!=this.table[this.toStrFn(e)]}},{key:"remove",value:function(e){return!!this.hasKey(e)&&(delete this.table[this.toStrFn(e)],!0)}},{key:"values",value:function(){return this.keyValues().map(function(e){return e.value})}},{key:"keys",value:function(){return this.keyValues().map(function(e){return e.key})}},{key:"keyValues",value:function(){return Object.values(this.table)}},{key:"forEach",value:function(e){for(var t=this.keyValues(),n=0;n0&&void 0!==arguments[0]?arguments[0]:n.defaultEquals;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var r=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return r.tail=void 0,r}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),a(t,[{key:"push",value:function(e){var t=new i.DoublyNode(e);null==this.head?(this.head=t,this.tail=t):(this.tail.next=t,t.prev=this.tail,this.tail=t),this.count++}},{key:"insert",value:function(e,t){if(t>=0&&t<=this.count){var n=new i.DoublyNode(e),r=this.head;if(0===t)null==this.head?(this.head=n,this.tail=n):(n.next=this.head,this.head.prev=n,this.head=n);else if(t===this.count)(r=this.tail).next=n,n.prev=r,this.tail=n;else{var o=this.getElementAt(t-1);r=o.next,n.next=r,o.next=n,r.prev=n,n.prev=o}return this.count++,!0}return!1}},{key:"removeAt",value:function(e){if(e>=0&&e0)this.lowestCount--,this.items[this.lowestCount]=e;else{for(var t=this.count;t>0;t--)this.items[t]=this.items[t-1];this.count++,this.items[0]=e}}},{key:"addBack",value:function(e){this.items[this.count]=e,this.count++}},{key:"removeFront",value:function(){if(!this.isEmpty()){var e=this.items[this.lowestCount];return delete this.items[this.lowestCount],this.lowestCount++,e}}},{key:"removeBack",value:function(){if(!this.isEmpty()){this.count--;var e=this.items[this.count];return delete this.items[this.count],e}}},{key:"peekFront",value:function(){if(!this.isEmpty())return this.items[this.lowestCount]}},{key:"peekBack",value:function(){if(!this.isEmpty())return this.items[this.count-1]}},{key:"isEmpty",value:function(){return 0===this.size()}},{key:"clear",value:function(){this.items={},this.count=0,this.lowestCount=0}},{key:"size",value:function(){return this.count-this.lowestCount}},{key:"toString",value:function(){if(this.isEmpty())return"";for(var e=""+this.items[this.lowestCount],t=this.lowestCount+1;t=0&&n>=0&&t1&&void 0!==arguments[1]?arguments[1]:1,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.length-1;if(n===r)return 0;for(var i=Number.MAX_SAFE_INTEGER,o=n;o2&&void 0!==arguments[2]?arguments[2]:t.length,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:n.length;if(0===r||0===i)return 0;if(t[r-1]===n[i-1])return 1+e(t,n,r-1,i-1);var o=e(t,n,r,i-1),u=e(t,n,r-1,i);return o>u?o:u}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.lcs=function(e,t){for(var n=e.length,r=t.length,i=[],o=[],u=0;u<=n;u++){i[u]=[],o[u]=[];for(var a=0;a<=r;a++)i[u][a]=0,o[u][a]="0"}for(var f=0;f<=n;f++)for(var l=0;l<=r;l++)if(0===f||0===l)i[f][l]=0;else if(e[f-1]===t[l-1])i[f][l]=i[f-1][l-1]+1,o[f][l]="diagonal";else{var s=i[f-1][l],c=i[f][l-1];i[f][l]=s>c?s:c,o[f][l]=i[f][l]===i[f-1][l]?"top":"left"}return function(e,t,n,r){for(var i=n,o=r,u=e[i][o],a="";"0"!==u;)"diagonal"===e[i][o]?(a=t[i-1]+a,i--,o--):"left"===e[i][o]?o--:"top"===e[i][o]&&i--,u=e[i][o];return a}(o,e,n,r)}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.lcs=function(e,t){for(var n=e.length,r=t.length,i=[],o=0;o<=n;o++){i[o]=[];for(var u=0;u<=r;u++)i[o][u]=0}for(var a=0;a<=n;a++)for(var f=0;f<=r;f++)if(0===a||0===f)i[a][f]=0;else if(e[a-1]===t[f-1])i[a][f]=i[a-1][f-1]+1;else{var l=i[a-1][f],s=i[a][f-1];i[a][f]=l>s?l:s}return i[n][r]}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.knapSack=function(e,t,n){for(var r=n.length,i=0,o=0,u=0;ut)return e(t,n,r,i-1);var o=r[i-1]+e(t-n[i-1],n,r,i-1),u=e(t,n,r,i-1);return o>u?o:u}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.knapSack=function(e,t,n,r){for(var i=[],o=0;o<=r;o++)i[o]=[];for(var u=0;u<=r;u++)for(var a=0;a<=e;a++)if(0===u||0===a)i[u][a]=0;else if(t[u-1]<=a){var f=n[u-1]+i[u-1][a-t[u-1]],l=i[u-1][a];i[u][a]=f>l?f:l}else i[u][a]=i[u-1][a];return function(e,t,n){for(var r=e,i=t;r>0&&i>0;)n[r][i]!==n[r-1][i]?i-=n[--r][i]:r--}(r,e,i),i[r][e]}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.minCoinChange=function(e,t){for(var n=[],r=0,i=e.length;i>=0;i--)for(var o=e[i];r+o<=t;)n.push(o),r+=o;return n}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.minCoinChange=function(e,t){var n=[];return function t(r){if(!r)return[];if(n[r])return n[r];for(var i=[],o=void 0,u=void 0,a=0;a=0&&(o=t(u)),u>=0&&(o.length2&&void 0!==arguments[2]?arguments[2]:t.defaultCompare,o=(0,n.quickSort)(e).length-1;return function e(n,r,i,o){var u=arguments.length>4&&void 0!==arguments[4]?arguments[4]:t.defaultCompare;if(i<=o){var a=Math.floor((i+o)/2),f=n[a];return u(f,r)===t.Compare.LESS_THAN?e(n,r,a+1,o,u):u(f,r)===t.Compare.BIGGER_THAN?e(n,r,i,a-1,u):a}return t.DOES_NOT_EXIST}(e,r,0,o,i)}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(0)],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.sequentialSearch=function(e,n){for(var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.defaultEquals,i=0;i2&&void 0!==arguments[2]?arguments[2]:t.defaultCompare,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:t.defaultEquals,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:t.defaultDiff,u=0,a=e.length-1,f=-1,l=-1;u<=a&&(0,t.biggerEquals)(n,e[u],r)&&(0,t.lesserEquals)(n,e[a],r);){if(l=o(n,e[u])/o(e[a],e[u]),f=u+Math.floor((a-u)*l),i(e[f],n))return f;r(e[f],n)===t.Compare.LESS_THAN?u=f+1:a=f-1}return t.DOES_NOT_EXIST}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(0),n(4)],void 0===(o="function"==typeof(r=function(e,t,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.binarySearch=function(e,r){for(var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.defaultCompare,o=(0,n.quickSort)(e),u=0,a=o.length-1;u<=a;){var f=Math.floor((u+a)/2),l=o[f];if(i(l,r)===t.Compare.LESS_THAN)u=f+1;else{if(i(l,r)!==t.Compare.BIGGER_THAN)return f;a=f-1}}return t.DOES_NOT_EXIST}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(0)],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.shellSort=function(e){for(var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare,r=e.length/2;r>0;){for(var i=r;i=r&&n(e[o-r],u)===t.Compare.BIGGER_THAN;)e[o]=e[o-r],o-=r;e[o]=u}r=2===r?1:Math.floor(5*r/11)}return e}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(0)],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.selectionSort=void 0,e.selectionSort=function(e){for(var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare,r=e.length,i=void 0,o=0;o1&&void 0!==arguments[1]?arguments[1]:10;if(e.length<2)return e;for(var i=(0,t.findMinValue)(e),o=(0,t.findMaxValue)(e),u=1;(o-i)/u>=1;)e=r(e,n,u,i),u*=n;return e};var n=function(e,t,n,r){return Math.floor((e-t)/n%r)},r=function(e,t,r,i){for(var o=void 0,u=[],a=[],f=0;f=0;c--)o=n(e[c],i,r,t),a[--u[o]]=e[c];for(var h=0;h1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare;if(n.length>1){var i=n,o=i.length,u=Math.floor(o/2),a=e(n.slice(0,u),r),f=e(n.slice(u,o),r);n=function(e,n,r){for(var i=0,o=0,u=[];i0;)e[r++]=n,t--}),e}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(8)],void 0===(o="function"==typeof(r=function(e,t){"use strict";function n(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1&&void 0!==arguments[1]?arguments[1]:5;return e.length<2?e:function(e){for(var r=[],i=0;ir&&(r=e[i]);for(var o=Math.floor((r-n)/t)+1,u=[],a=0;a1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare,r=e.length,i=0;i1&&void 0!==arguments[1]?arguments[1]:t.defaultCompare,r=e.length,i=0;i0&&void 0!==arguments[0]&&arguments[0];!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.isDirected=t,this.vertices=[],this.adjList=new i.default}return o(e,[{key:"addVertex",value:function(e){this.vertices.includes(e)||(this.vertices.push(e),this.adjList.set(e,[]))}},{key:"addEdge",value:function(e,t){this.adjList.get(e)||this.addVertex(e),this.adjList.get(t)||this.addVertex(t),this.adjList.get(e).push(t),!0!==this.isDirected&&this.adjList.get(t).push(e)}},{key:"getVertices",value:function(){return this.vertices}},{key:"getAdjList",value:function(){return this.adjList}},{key:"toString",value:function(){for(var e="",t=0;t ";for(var n=this.adjList.get(this.vertices[t]),r=0;r0&&(u=a),f0&&(u=f),u!==t&&((0,n.swap)(e,t,u),r(e,u,i,o))}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n.defaultCompare,i=e.length;for(!function(e,t){for(var n=Math.floor(e.length/2);n>=0;n-=1)r(e,n,e.length,t)}(e,t);i>1;)(0,n.swap)(e,0,--i),r(e,0,i,t);return e},e.exports=t.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(0)],void 0===(o="function"==typeof(r=function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0}),e.MaxHeap=e.MinHeap=void 0;var r=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:t.defaultCompare;n(this,e),this.compareFn=r,this.heap=[]}return r(e,[{key:"getLeftIndex",value:function(e){return 2*e+1}},{key:"getRightIndex",value:function(e){return 2*e+2}},{key:"getParentIndex",value:function(e){if(0!==e)return Math.floor((e-1)/2)}},{key:"size",value:function(){return this.heap.length}},{key:"isEmpty",value:function(){return this.size()<=0}},{key:"clear",value:function(){this.heap=[]}},{key:"findMinimum",value:function(){return this.isEmpty()?void 0:this.heap[0]}},{key:"insert",value:function(e){if(null!=e){var t=this.heap.length;return this.heap.push(e),this.siftUp(t),!0}return!1}},{key:"siftDown",value:function(e){var n=e,r=this.getLeftIndex(e),i=this.getRightIndex(e),o=this.size();r0&&this.compareFn(this.heap[n],this.heap[e])===t.Compare.BIGGER_THAN;)(0,t.swap)(this.heap,n,e),e=n,n=this.getParentIndex(e)}},{key:"extract",value:function(){if(!this.isEmpty()){if(1===this.size())return this.heap.shift();var e=this.heap[0];return this.heap[0]=this.heap.pop(),this.siftDown(0),e}}},{key:"heapify",value:function(e){e&&(this.heap=e);for(var t=Math.floor(this.size()/2)-1,n=0;n<=t;n++)this.siftDown(n);return this.heap}},{key:"getAsArray",value:function(){return this.heap}}]),e}();e.MaxHeap=function(e){function r(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:t.defaultCompare;n(this,r);var i=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(r.__proto__||Object.getPrototypeOf(r)).call(this,e));return i.compareFn=e,i.compareFn=(0,t.reverseCompare)(e),i}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(r,e),r}(i)})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[e,t,n(0),n(10),n(9)],void 0===(o="function"==typeof(r=function(e,t,n,r,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,u=(o=r)&&o.__esModule?o:{default:o},a=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:n.defaultCompare;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var r=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return r.compareFn=e,r.root=null,r}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),a(t,[{key:"getNodeHeight",value:function(e){return null==e?-1:Math.max(this.getNodeHeight(e.left),this.getNodeHeight(e.right))+1}},{key:"rotationLL",value:function(e){var t=e.left;return e.left=t.right,t.right=e,t}},{key:"rotationRR",value:function(e){var t=e.right;return e.right=t.left,t.left=e,t}},{key:"rotationLR",value:function(e){return e.left=this.rotationRR(e.left),this.rotationLL(e)}},{key:"rotationRL",value:function(e){return e.right=this.rotationLL(e.right),this.rotationRR(e)}},{key:"getBalanceFactor",value:function(e){var t=this.getNodeHeight(e.left)-this.getNodeHeight(e.right);switch(t){case-2:return f.UNBALANCED_RIGHT;case-1:return f.SLIGHTLY_UNBALANCED_RIGHT;case 1:return f.SLIGHTLY_UNBALANCED_LEFT;case 2:return f.UNBALANCED_LEFT;default:return f.BALANCED}}},{key:"insert",value:function(e){this.root=this.insertNode(this.root,e)}},{key:"insertNode",value:function(e,t){if(null==e)return new i.Node(t);if(this.compareFn(t,e.key)===n.Compare.LESS_THAN)e.left=this.insertNode(e.left,t);else{if(this.compareFn(t,e.key)!==n.Compare.BIGGER_THAN)return e;e.right=this.insertNode(e.right,t)}var r=this.getBalanceFactor(e);if(r===f.UNBALANCED_LEFT){if(this.compareFn(t,e.left.key)!==n.Compare.LESS_THAN)return this.rotationLR(e);e=this.rotationLL(e)}if(r===f.UNBALANCED_RIGHT){if(this.compareFn(t,e.right.key)!==n.Compare.BIGGER_THAN)return this.rotationRL(e);e=this.rotationRR(e)}return e}},{key:"removeNode",value:function(e,n){if(null==(e=function e(t,n,r){null===t&&(t=Function.prototype);var i=Object.getOwnPropertyDescriptor(t,n);if(void 0===i){var o=Object.getPrototypeOf(t);return null===o?void 0:e(o,n,r)}if("value"in i)return i.value;var u=i.get;return void 0!==u?u.call(r):void 0}(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"removeNode",this).call(this,e,n)))return e;var r=this.getBalanceFactor(e);if(r===f.UNBALANCED_LEFT){if(this.getBalanceFactor(e.left)===f.BALANCED||this.getBalanceFactor(e.left)===f.SLIGHTLY_UNBALANCED_LEFT)return this.rotationLL(e);if(this.getBalanceFactor(e.left)===f.SLIGHTLY_UNBALANCED_RIGHT)return this.rotationLR(e.left)}if(r===f.UNBALANCED_RIGHT){if(this.getBalanceFactor(e.right)===f.BALANCED||this.getBalanceFactor(e.right)===f.SLIGHTLY_UNBALANCED_RIGHT)return this.rotationRR(e);if(this.getBalanceFactor(e.right)===f.SLIGHTLY_UNBALANCED_LEFT)return this.rotationRL(e.right)}return e}}]),t}(u.default);t.default=l,e.exports=t.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.fibonacci=function e(t){return t<1?0:t<=2?1:e(t-1)+e(t-2)},e.fibonacciIterative=function(e){if(e<1)return 0;for(var t=0,n=1,r=e,i=2;i<=e;i++)r=n+t,t=n,n=r;return r},e.fibonacciMemoization=function(e){if(e<1)return 0;var t=[0,1];return function e(n){return null!=t[n]?t[n]:t[n]=e(n-1)+e(n-2)}(e)}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t],void 0===(o="function"==typeof(r=function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.factorialIterative=function(e){if(!(e<0)){for(var t=1,n=e;n>1;n--)t*=n;return t}},e.factorial=function e(t){if(!(t<0))return 1===t||0===t?1:t*e(t-1)}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(1)],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ValuePairLazy=void 0,e.ValuePairLazy=function(e){function t(e,n){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var i=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));return i.key=e,i.value=n,i.isDeleted=r,i}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t}(t.ValuePair)})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[e,t,n(0),n(51)],void 0===(o="function"==typeof(r=function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:n.defaultToString;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.toStrFn=t,this.table={}}return i(e,[{key:"loseloseHashCode",value:function(e){if("number"==typeof e)return e;for(var t=this.toStrFn(e),n=0,r=0;r "+this.table[e[0]].toString()+"}",n=1;n "+this.table[e[n]].toString()+"}";return t}}]),e}();t.default=o,e.exports=t.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[e,t,n(0),n(1)],void 0===(o="function"==typeof(r=function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:n.defaultToString;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.toStrFn=t,this.table={}}return i(e,[{key:"loseloseHashCode",value:function(e){if("number"==typeof e)return e;for(var t=this.toStrFn(e),n=0,r=0;r "+this.table[e[0]].toString()+"}",n=1;n "+this.table[e[n]].toString()+"}";return t}}]),e}();t.default=o,e.exports=t.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[e,t,n(0),n(2),n(1)],void 0===(o="function"==typeof(r=function(e,t,n,r,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,u=(o=r)&&o.__esModule?o:{default:o},a=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:n.defaultToString;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.toStrFn=t,this.table={}}return a(e,[{key:"loseloseHashCode",value:function(e){if("number"==typeof e)return e;for(var t=this.toStrFn(e),n=0,r=0;r "+this.table[e[0]].toString()+"}",n=1;n "+this.table[e[n]].toString()+"}";return t}}]),e}();t.default=f,e.exports=t.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[e,t,n(0),n(1)],void 0===(o="function"==typeof(r=function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:n.defaultToString;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.toStrFn=t,this.table={}}return i(e,[{key:"loseloseHashCode",value:function(e){if("number"==typeof e)return e;for(var t=this.toStrFn(e),n=0,r=0;r "+this.table[e[0]].toString()+"}",n=1;n "+this.table[e[n]].toString()+"}";return t}}]),e}();t.default=o,e.exports=t.default})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[e,t],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var n=0;n0&&(o=i,u=r),u.forEach(function(e){o.includes(e)&&n.add(e)}),n}},{key:"difference",value:function(t){var n=new e;return this.values().forEach(function(e){t.has(e)||n.add(e)}),n}},{key:"isSubsetOf",value:function(e){if(this.size()>e.size())return!1;var t=!0;return this.values().every(function(n){return!!e.has(n)||(t=!1,!1)}),t}},{key:"isEmpty",value:function(){return 0===this.size()}},{key:"size",value:function(){return Object.keys(this.items).length}},{key:"clear",value:function(){this.items={}}},{key:"toString",value:function(){if(this.isEmpty())return"";for(var e=this.values(),t=""+e[0],n=1;n0&&void 0!==arguments[0]?arguments[0]:n.defaultEquals,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n.defaultCompare;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var i=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return i.equalsFn=e,i.compareFn=r,i}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),u(t,[{key:"push",value:function(e){if(this.isEmpty())a(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"push",this).call(this,e);else{var n=this.getIndexNextSortedElement(e);a(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"insert",this).call(this,e,n)}}},{key:"insert",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;if(this.isEmpty())return a(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"insert",this).call(this,e,0===n?n:0);var r=this.getIndexNextSortedElement(e);return a(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"insert",this).call(this,e,r)}},{key:"getIndexNextSortedElement",value:function(e){for(var t=this.head,r=0;r0&&void 0!==arguments[0]?arguments[0]:n.defaultEquals;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),a(t,[{key:"push",value:function(e){var t=new i.Node(e);null==this.head?this.head=t:this.getElementAt(this.size()-1).next=t,t.next=this.head,this.count++}},{key:"insert",value:function(e,t){if(t>=0&&t<=this.count){var n=new i.Node(e),r=this.head;if(0===t)null==this.head?(this.head=n,n.next=this.head):(n.next=r,r=this.getElementAt(this.size()),this.head=n,r.next=this.head);else{var o=this.getElementAt(t-1);n.next=o.next,o.next=n}return this.count++,!0}return!1}},{key:"removeAt",value:function(e){if(e>=0&&e1;)if(i=t.removeFront(),o=t.removeBack(),i!==o)return!1;return!0};var n,r=(n=t)&&n.__esModule?n:{default:n}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(7)],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.hotPotato=function(e,t){for(var n=new r.default,i=[],o=0;o1;){for(var u=0;u=0?t.push(o):t.isEmpty()?n=!1:(u=t.pop(),"([{".indexOf(u)!==")]}".indexOf(o)&&(n=!1)),i++;return n&&t.isEmpty()};var n,r=(n=t)&&n.__esModule?n:{default:n}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(3)],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.decimalToBinary=function(e){for(var t=new r.default,n=e,i=void 0,o="";n>0;)i=Math.floor(n%2),t.push(i),n=Math.floor(n/2);for(;!t.isEmpty();)o+=t.pop().toString();return o},e.baseConverter=function(e,t){var n=new r.default,i=e,o=void 0,u="";if(!(t>=2&&t<=36))return"";for(;i>0;)o=Math.floor(i%t),n.push(o),i=Math.floor(i/t);for(;!n.isEmpty();)u+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n.pop()];return u};var n,r=(n=t)&&n.__esModule?n:{default:n}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[t,n(3)],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.hanoiStack=function(e){for(var t=new r.default,n=new r.default,i=new r.default,o=e;o>0;o--)t.push(o);return function e(t,n,r,i,o,u,a){var f=arguments.length>7&&void 0!==arguments[7]?arguments[7]:[];if(t<=0)return f;if(1===t){i.push(n.pop());var l={};l[o]=n.toString(),l[u]=r.toString(),l[a]=i.toString(),f.push(l)}else{e(t-1,n,i,r,o,a,u,f),i.push(n.pop());var s={};s[o]=n.toString(),s[u]=r.toString(),s[a]=i.toString(),f.push(s),e(t-1,r,n,i,u,o,a,f)}return f}(e,t,i,n,"source","helper","dest")},e.hanoi=function e(t,n,r,i){var o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[];return t<=0?o:(1===t?o.push([n,i]):(e(t-1,n,i,r,o),o.push([n,i]),e(t-1,r,n,i,o)),o)};var n,r=(n=t)&&n.__esModule?n:{default:n}})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){var r,i,o;i=[e,t],void 0===(o="function"==typeof(r=function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var n=0;n compareFn(b, a);\n}\n\nexport function defaultDiff(a, b) {\n return Number(a) - Number(b);\n}\n","export class ValuePair {\n constructor(key, value) {\n this.key = key;\n this.value = value;\n }\n toString() {\n return `[#${this.key}: ${this.value}]`;\n }\n}\n","import { defaultEquals } from '../util';\nimport { Node } from './models/linked-list-models';\n\nexport default class LinkedList {\n constructor(equalsFn = defaultEquals) {\n this.equalsFn = equalsFn;\n this.count = 0;\n this.head = undefined;\n }\n push(element) {\n const node = new Node(element);\n let current;\n if (this.head == null) {\n // catches null && undefined\n this.head = node;\n } else {\n current = this.head;\n while (current.next != null) {\n current = current.next;\n }\n current.next = node;\n }\n this.count++;\n }\n getElementAt(index) {\n if (index >= 0 && index <= this.count) {\n let node = this.head;\n for (let i = 0; i < index && node != null; i++) {\n node = node.next;\n }\n return node;\n }\n return undefined;\n }\n insert(element, index) {\n if (index >= 0 && index <= this.count) {\n const node = new Node(element);\n if (index === 0) {\n const current = this.head;\n node.next = current;\n this.head = node;\n } else {\n const previous = this.getElementAt(index - 1);\n node.next = previous.next;\n previous.next = node;\n }\n this.count++;\n return true;\n }\n return false;\n }\n removeAt(index) {\n if (index >= 0 && index < this.count) {\n let current = this.head;\n if (index === 0) {\n this.head = current.next;\n } else {\n const previous = this.getElementAt(index - 1);\n current = previous.next;\n previous.next = current.next;\n }\n this.count--;\n return current.element;\n }\n return undefined;\n }\n remove(element) {\n const index = this.indexOf(element);\n return this.removeAt(index);\n }\n indexOf(element) {\n let current = this.head;\n for (let i = 0; i < this.size() && current != null; i++) {\n if (this.equalsFn(element, current.element)) {\n return i;\n }\n current = current.next;\n }\n return -1;\n }\n isEmpty() {\n return this.size() === 0;\n }\n size() {\n return this.count;\n }\n getHead() {\n return this.head;\n }\n clear() {\n this.head = undefined;\n this.count = 0;\n }\n toString() {\n if (this.head == null) {\n return '';\n }\n let objString = `${this.head.element}`;\n let current = this.head.next;\n for (let i = 1; i < this.size() && current != null; i++) {\n objString = `${objString},${current.element}`;\n current = current.next;\n }\n return objString;\n }\n}\n","// @ts-check\n\nexport default class Stack {\n constructor() {\n this.count = 0;\n this.items = {};\n }\n push(element) {\n this.items[this.count] = element;\n this.count++;\n }\n pop() {\n if (this.isEmpty()) {\n return undefined;\n }\n this.count--;\n const result = this.items[this.count];\n delete this.items[this.count];\n return result;\n }\n peek() {\n if (this.isEmpty()) {\n return undefined;\n }\n return this.items[this.count - 1];\n }\n isEmpty() {\n return this.count === 0;\n }\n size() {\n return this.count;\n }\n clear() {\n /* while (!this.isEmpty()) {\n this.pop();\n } */\n this.items = {};\n this.count = 0;\n }\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n let objString = `${this.items[0]}`;\n for (let i = 1; i < this.count; i++) {\n objString = `${objString},${this.items[i]}`;\n }\n return objString;\n }\n}\n","import { Compare, defaultCompare, swap } from '../../util';\n\nfunction partition(array, left, right, compareFn) {\n const pivot = array[Math.floor((right + left) / 2)];\n let i = left;\n let j = right;\n\n while (i <= j) {\n while (compareFn(array[i], pivot) === Compare.LESS_THAN) {\n i++;\n }\n while (compareFn(array[j], pivot) === Compare.BIGGER_THAN) {\n j--;\n }\n if (i <= j) {\n swap(array, i, j);\n i++;\n j--;\n }\n }\n return i;\n}\nfunction quick(array, left, right, compareFn) {\n let index;\n if (array.length > 1) {\n index = partition(array, left, right, compareFn);\n if (left < index - 1) {\n quick(array, left, index - 1, compareFn);\n }\n if (index < right) {\n quick(array, index, right, compareFn);\n }\n }\n return array;\n}\nexport function quickSort(array, compareFn = defaultCompare) {\n return quick(array, 0, array.length - 1, compareFn);\n}\n","import { defaultCompare, Compare } from '../../util';\n\nexport function findMaxValue(array, compareFn = defaultCompare) {\n if (array && array.length > 0) {\n let max = array[0];\n for (let i = 1; i < array.length; i++) {\n if (compareFn(max, array[i]) === Compare.LESS_THAN) {\n max = array[i];\n }\n }\n return max;\n }\n return undefined;\n}\nexport function findMinValue(array, compareFn = defaultCompare) {\n if (array && array.length > 0) {\n let min = array[0];\n for (let i = 1; i < array.length; i++) {\n if (compareFn(min, array[i]) === Compare.BIGGER_THAN) {\n min = array[i];\n }\n }\n return min;\n }\n return undefined;\n}\n","export class Node {\n constructor(element, next) {\n this.element = element;\n this.next = next;\n }\n}\nexport class DoublyNode extends Node {\n constructor(element, next, prev) {\n super(element, next);\n this.prev = prev;\n }\n}\n","// @ts-check\n\nexport default class Queue {\n constructor() {\n this.count = 0;\n this.lowestCount = 0;\n this.items = {};\n }\n\n enqueue(element) {\n this.items[this.count] = element;\n this.count++;\n }\n\n dequeue() {\n if (this.isEmpty()) {\n return undefined;\n }\n const result = this.items[this.lowestCount];\n delete this.items[this.lowestCount];\n this.lowestCount++;\n return result;\n }\n\n peek() {\n if (this.isEmpty()) {\n return undefined;\n }\n return this.items[this.lowestCount];\n }\n\n isEmpty() {\n return this.size() === 0;\n }\n\n clear() {\n this.items = {};\n this.count = 0;\n this.lowestCount = 0;\n }\n\n size() {\n return this.count - this.lowestCount;\n }\n\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n let objString = `${this.items[this.lowestCount]}`;\n for (let i = this.lowestCount + 1; i < this.count; i++) {\n objString = `${objString},${this.items[i]}`;\n }\n return objString;\n }\n}\n","import { Compare, defaultCompare } from '../../util';\n\nexport const insertionSort = (array, compareFn = defaultCompare) => {\n const { length } = array;\n let temp;\n for (let i = 1; i < length; i++) {\n let j = i;\n temp = array[i];\n // console.log('to be inserted ' + temp);\n while (j > 0 && compareFn(array[j - 1], temp) === Compare.BIGGER_THAN) {\n // console.log('shift ' + array[j - 1]);\n array[j] = array[j - 1];\n j--;\n }\n // console.log('insert ' + temp);\n array[j] = temp;\n }\n return array;\n};\n","export class Node {\n constructor(key) {\n this.key = key;\n this.left = undefined;\n this.right = undefined;\n }\n toString() {\n return `${this.key}`;\n }\n}\n","import { Compare, defaultCompare } from '../util';\nimport { Node } from './models/node';\n\nexport default class BinarySearchTree {\n constructor(compareFn = defaultCompare) {\n this.compareFn = compareFn;\n this.root = undefined;\n }\n insert(key) {\n // special case: first key\n if (this.root == null) {\n this.root = new Node(key);\n } else {\n this.insertNode(this.root, key);\n }\n }\n insertNode(node, key) {\n if (this.compareFn(key, node.key) === Compare.LESS_THAN) {\n if (node.left == null) {\n node.left = new Node(key);\n } else {\n this.insertNode(node.left, key);\n }\n } else if (node.right == null) {\n node.right = new Node(key);\n } else {\n this.insertNode(node.right, key);\n }\n }\n getRoot() {\n return this.root;\n }\n search(key) {\n return this.searchNode(this.root, key);\n }\n searchNode(node, key) {\n if (node == null) {\n return false;\n }\n if (this.compareFn(key, node.key) === Compare.LESS_THAN) {\n return this.searchNode(node.left, key);\n } else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {\n return this.searchNode(node.right, key);\n }\n return true;\n }\n inOrderTraverse(callback) {\n this.inOrderTraverseNode(this.root, callback);\n }\n inOrderTraverseNode(node, callback) {\n if (node != null) {\n this.inOrderTraverseNode(node.left, callback);\n callback(node.key);\n this.inOrderTraverseNode(node.right, callback);\n }\n }\n preOrderTraverse(callback) {\n this.preOrderTraverseNode(this.root, callback);\n }\n preOrderTraverseNode(node, callback) {\n if (node != null) {\n callback(node.key);\n this.preOrderTraverseNode(node.left, callback);\n this.preOrderTraverseNode(node.right, callback);\n }\n }\n postOrderTraverse(callback) {\n this.postOrderTraverseNode(this.root, callback);\n }\n postOrderTraverseNode(node, callback) {\n if (node != null) {\n this.postOrderTraverseNode(node.left, callback);\n this.postOrderTraverseNode(node.right, callback);\n callback(node.key);\n }\n }\n min() {\n return this.minNode(this.root);\n }\n minNode(node) {\n let current = node;\n while (current != null && current.left != null) {\n current = current.left;\n }\n return current;\n }\n max() {\n return this.maxNode(this.root);\n }\n maxNode(node) {\n let current = node;\n while (current != null && current.right != null) {\n current = current.right;\n }\n return current;\n }\n remove(key) {\n this.root = this.removeNode(this.root, key);\n }\n removeNode(node, key) {\n if (node == null) {\n return undefined;\n }\n if (this.compareFn(key, node.key) === Compare.LESS_THAN) {\n node.left = this.removeNode(node.left, key);\n return node;\n } else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {\n node.right = this.removeNode(node.right, key);\n return node;\n }\n // key is equal to node.item\n // handle 3 special conditions\n // 1 - a leaf node\n // 2 - a node with only 1 child\n // 3 - a node with 2 children\n // case 1\n if (node.left == null && node.right == null) {\n node = undefined;\n return node;\n }\n // case 2\n if (node.left == null) {\n node = node.right;\n return node;\n } else if (node.right == null) {\n node = node.left;\n return node;\n }\n // case 3\n const aux = this.minNode(node.right);\n node.key = aux.key;\n node.right = this.removeNode(node.right, aux.key);\n return node;\n }\n}\n","import { defaultToString } from '../util';\nimport { ValuePair } from './models/value-pair';\n\nexport default class Dictionary {\n constructor(toStrFn = defaultToString) {\n this.toStrFn = toStrFn;\n this.table = {};\n }\n set(key, value) {\n if (key != null && value != null) {\n const tableKey = this.toStrFn(key);\n this.table[tableKey] = new ValuePair(key, value);\n return true;\n }\n return false;\n }\n get(key) {\n const valuePair = this.table[this.toStrFn(key)];\n return valuePair == null ? undefined : valuePair.value;\n }\n hasKey(key) {\n return this.table[this.toStrFn(key)] != null;\n }\n remove(key) {\n if (this.hasKey(key)) {\n delete this.table[this.toStrFn(key)];\n return true;\n }\n return false;\n }\n values() {\n return this.keyValues().map(valuePair => valuePair.value);\n }\n keys() {\n return this.keyValues().map(valuePair => valuePair.key);\n }\n keyValues() {\n return Object.values(this.table);\n }\n forEach(callbackFn) {\n const valuePairs = this.keyValues();\n for (let i = 0; i < valuePairs.length; i++) {\n const result = callbackFn(valuePairs[i].key, valuePairs[i].value);\n if (result === false) {\n break;\n }\n }\n }\n isEmpty() {\n return this.size() === 0;\n }\n size() {\n return Object.keys(this.table).length;\n }\n clear() {\n this.table = {};\n }\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n const valuePairs = this.keyValues();\n let objString = `${valuePairs[0].toString()}`;\n for (let i = 1; i < valuePairs.length; i++) {\n objString = `${objString},${valuePairs[i].toString()}`;\n }\n return objString;\n }\n}\n","import { defaultEquals } from '../util';\nimport LinkedList from './linked-list';\nimport { DoublyNode } from './models/linked-list-models';\n\nexport default class DoublyLinkedList extends LinkedList {\n constructor(equalsFn = defaultEquals) {\n super(equalsFn);\n this.tail = undefined;\n }\n push(element) {\n const node = new DoublyNode(element);\n if (this.head == null) {\n this.head = node;\n this.tail = node; // NEW\n } else {\n // attach to the tail node // NEW\n this.tail.next = node;\n node.prev = this.tail;\n this.tail = node;\n }\n this.count++;\n }\n insert(element, index) {\n if (index >= 0 && index <= this.count) {\n const node = new DoublyNode(element);\n let current = this.head;\n if (index === 0) {\n if (this.head == null) { // NEW\n this.head = node;\n this.tail = node; // NEW\n } else {\n node.next = this.head;\n this.head.prev = node; // NEW\n this.head = node;\n }\n } else if (index === this.count) { // last item NEW\n current = this.tail;\n current.next = node;\n node.prev = current;\n this.tail = node;\n } else {\n const previous = this.getElementAt(index - 1);\n current = previous.next;\n node.next = current;\n previous.next = node;\n current.prev = node; // NEW\n node.prev = previous; // NEW\n }\n this.count++;\n return true;\n }\n return false;\n }\n removeAt(index) {\n if (index >= 0 && index < this.count) {\n let current = this.head;\n if (index === 0) {\n this.head = this.head.next;\n // if there is only one item, then we update tail as well //NEW\n if (this.count === 1) {\n // {2}\n this.tail = undefined;\n } else {\n this.head.prev = undefined;\n }\n } else if (index === this.count - 1) {\n // last item //NEW\n current = this.tail;\n this.tail = current.prev;\n this.tail.next = undefined;\n } else {\n current = this.getElementAt(index);\n const previous = current.prev;\n // link previous with current's next - skip it to remove\n previous.next = current.next;\n current.next.prev = previous; // NEW\n }\n this.count--;\n return current.element;\n }\n return undefined;\n }\n indexOf(element) {\n let current = this.head;\n let index = 0;\n while (current != null) {\n if (this.equalsFn(element, current.element)) {\n return index;\n }\n index++;\n current = current.next;\n }\n return -1;\n }\n getHead() {\n return this.head;\n }\n getTail() {\n return this.tail;\n }\n clear() {\n super.clear();\n this.tail = undefined;\n }\n toString() {\n if (this.head == null) {\n return '';\n }\n let objString = `${this.head.element}`;\n let current = this.head.next;\n while (current != null) {\n objString = `${objString},${current.element}`;\n current = current.next;\n }\n return objString;\n }\n inverseToString() {\n if (this.tail == null) {\n return '';\n }\n let objString = `${this.tail.element}`;\n let previous = this.tail.prev;\n while (previous != null) {\n objString = `${objString},${previous.element}`;\n previous = previous.prev;\n }\n return objString;\n }\n}\n","// @ts-check\n\nexport default class Deque {\n constructor() {\n this.count = 0;\n this.lowestCount = 0;\n this.items = {};\n }\n\n addFront(element) {\n if (this.isEmpty()) {\n this.addBack(element);\n } else if (this.lowestCount > 0) {\n this.lowestCount--;\n this.items[this.lowestCount] = element;\n } else {\n for (let i = this.count; i > 0; i--) {\n this.items[i] = this.items[i - 1];\n }\n this.count++;\n this.items[0] = element;\n }\n }\n\n addBack(element) {\n this.items[this.count] = element;\n this.count++;\n }\n\n removeFront() {\n if (this.isEmpty()) {\n return undefined;\n }\n const result = this.items[this.lowestCount];\n delete this.items[this.lowestCount];\n this.lowestCount++;\n return result;\n }\n\n removeBack() {\n if (this.isEmpty()) {\n return undefined;\n }\n this.count--;\n const result = this.items[this.count];\n delete this.items[this.count];\n return result;\n }\n\n peekFront() {\n if (this.isEmpty()) {\n return undefined;\n }\n return this.items[this.lowestCount];\n }\n\n peekBack() {\n if (this.isEmpty()) {\n return undefined;\n }\n return this.items[this.count - 1];\n }\n\n isEmpty() {\n return this.size() === 0;\n }\n\n clear() {\n this.items = {};\n this.count = 0;\n this.lowestCount = 0;\n }\n\n size() {\n return this.count - this.lowestCount;\n }\n\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n let objString = `${this.items[this.lowestCount]}`;\n for (let i = this.lowestCount + 1; i < this.count; i++) {\n objString = `${objString},${this.items[i]}`;\n }\n return objString;\n }\n}\n","export const floydWarshall = graph => {\n const dist = [];\n const { length } = graph;\n for (let i = 0; i < length; i++) {\n dist[i] = [];\n for (let j = 0; j < length; j++) {\n if (i === j) {\n dist[i][j] = 0;\n } else if (!isFinite(graph[i][j])) {\n dist[i][j] = Infinity;\n } else {\n dist[i][j] = graph[i][j];\n }\n }\n }\n for (let k = 0; k < length; k++) {\n for (let i = 0; i < length; i++) {\n for (let j = 0; j < length; j++) {\n if (dist[i][k] + dist[k][j] < dist[i][j]) {\n dist[i][j] = dist[i][k] + dist[k][j];\n }\n }\n }\n }\n return dist;\n};\n","const UNASSIGNED = 0;\n\nfunction usedInRow(matrix, row, num) {\n for (let col = 0; col < matrix.length; col++) {\n if (matrix[row][col] === num) {\n return true;\n }\n }\n return false;\n}\n\nfunction usedInCol(matrix, col, num) {\n for (let row = 0; row < matrix.length; row++) {\n if (matrix[row][col] === num) {\n return true;\n }\n }\n return false;\n}\n\nfunction usedInBox(matrix, boxStartRow, boxStartCol, num) {\n for (let row = 0; row < 3; row++) {\n for (let col = 0; col < 3; col++) {\n if (matrix[row + boxStartRow][col + boxStartCol] === num) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction isSafe(matrix, row, col, num) {\n return (\n !usedInRow(matrix, row, num) &&\n !usedInCol(matrix, col, num) &&\n !usedInBox(matrix, row - (row % 3), col - (col % 3), num)\n );\n}\nfunction solveSudoku(matrix) {\n let row = 0;\n let col = 0;\n let checkBlankSpaces = false;\n\n for (row = 0; row < matrix.length; row++) {\n for (col = 0; col < matrix[row].length; col++) {\n if (matrix[row][col] === UNASSIGNED) {\n checkBlankSpaces = true;\n break;\n }\n }\n if (checkBlankSpaces === true) {\n break;\n }\n }\n if (checkBlankSpaces === false) {\n return true;\n }\n\n for (let num = 1; num <= 9; num++) {\n if (isSafe(matrix, row, col, num)) {\n matrix[row][col] = num;\n if (solveSudoku(matrix)) {\n return true;\n }\n matrix[row][col] = UNASSIGNED;\n }\n }\n return false;\n}\n\nexport function sudokuSolver(matrix) {\n if (solveSudoku(matrix) === true) {\n return matrix;\n }\n return 'NO SOLUTION EXISTS!';\n}\n","function isSafe(maze, x, y) {\n const n = maze.length;\n if (x >= 0 && y >= 0 && x < n && y < n && maze[x][y] !== 0) {\n return true;\n }\n return false;\n}\n\nfunction findPath(maze, x, y, solution) {\n const n = maze.length;\n if (x === n - 1 && y === n - 1) {\n solution[x][y] = 1;\n return true;\n }\n if (isSafe(maze, x, y) === true) {\n solution[x][y] = 1;\n if (findPath(maze, x + 1, y, solution)) {\n return true;\n }\n if (findPath(maze, x, y + 1, solution)) {\n return true;\n }\n solution[x][y] = 0;\n return false;\n }\n return false;\n}\n\nexport function ratInAMaze(maze) {\n const solution = [];\n for (let i = 0; i < maze.length; i++) {\n solution[i] = [];\n for (let j = 0; j < maze[i].length; j++) {\n solution[i][j] = 0;\n }\n }\n if (findPath(maze, 0, 0, solution) === true) {\n return solution;\n }\n return 'NO PATH FOUND';\n}\n","export function matrixChainOrder(p, i = 1, j = p.length - 1) {\n if (i === j) {\n return 0;\n }\n let min = Number.MAX_SAFE_INTEGER;\n for (let k = i; k < j; k++) {\n const count =\n matrixChainOrder(p, i, k) + matrixChainOrder(p, k + 1, j) + ((p[i - 1] * p[k]) * p[j]);\n if (count < min) {\n min = count;\n }\n }\n return min;\n}\n","function printOptimalParenthesis(s, i, j) {\n if (i === j) {\n // console.log('A[' + i + ']');\n } else {\n // console.log('(');\n printOptimalParenthesis(s, i, s[i][j]);\n printOptimalParenthesis(s, s[i][j] + 1, j);\n // console.log(')');\n }\n}\n\nexport function matrixChainOrder(p) {\n const n = p.length;\n const m = [];\n const s = [];\n for (let i = 1; i <= n; i++) {\n m[i] = [];\n m[i][i] = 0;\n }\n for (let i = 0; i <= n; i++) {\n // to help printing the optimal solution\n s[i] = []; // auxiliary\n for (let j = 0; j <= n; j++) {\n s[i][j] = 0;\n }\n }\n for (let l = 2; l < n; l++) {\n for (let i = 1; i <= (n - l) + 1; i++) {\n const j = (i + l) - 1;\n m[i][j] = Number.MAX_SAFE_INTEGER;\n for (let k = i; k <= j - 1; k++) {\n // q = cost/scalar multiplications\n const q = m[i][k] + m[k + 1][j] + ((p[i - 1] * p[k]) * p[j]);\n if (q < m[i][j]) {\n m[i][j] = q;\n s[i][j] = k; // s[i,j] = Second auxiliary table that stores k\n }\n }\n }\n }\n // console.log(m);\n // console.log(s);\n printOptimalParenthesis(s, 1, n - 1);\n return m[1][n - 1];\n}\n\n","export function lcs(wordX, wordY, m = wordX.length, n = wordY.length) {\n if (m === 0 || n === 0) {\n return 0;\n }\n if (wordX[m - 1] === wordY[n - 1]) {\n return 1 + lcs(wordX, wordY, m - 1, n - 1);\n }\n const a = lcs(wordX, wordY, m, n - 1);\n const b = lcs(wordX, wordY, m - 1, n);\n return a > b ? a : b;\n}\n","function printSolution(solution, wordX, m, n) {\n let a = m;\n let b = n;\n let x = solution[a][b];\n let answer = '';\n while (x !== '0') {\n if (solution[a][b] === 'diagonal') {\n answer = wordX[a - 1] + answer;\n a--;\n b--;\n } else if (solution[a][b] === 'left') {\n b--;\n } else if (solution[a][b] === 'top') {\n a--;\n }\n x = solution[a][b];\n }\n return answer;\n}\nexport function lcs(wordX, wordY) {\n const m = wordX.length;\n const n = wordY.length;\n const l = [];\n const solution = [];\n for (let i = 0; i <= m; i++) {\n l[i] = [];\n solution[i] = [];\n for (let j = 0; j <= n; j++) {\n l[i][j] = 0;\n solution[i][j] = '0';\n }\n }\n for (let i = 0; i <= m; i++) {\n for (let j = 0; j <= n; j++) {\n if (i === 0 || j === 0) {\n l[i][j] = 0;\n } else if (wordX[i - 1] === wordY[j - 1]) {\n l[i][j] = l[i - 1][j - 1] + 1;\n solution[i][j] = 'diagonal';\n } else {\n const a = l[i - 1][j];\n const b = l[i][j - 1];\n l[i][j] = a > b ? a : b; // max(a,b)\n solution[i][j] = l[i][j] === l[i - 1][j] ? 'top' : 'left';\n }\n }\n // console.log(l[i].join());\n // console.log(solution[i].join());\n }\n return printSolution(solution, wordX, m, n);\n}\n","export function lcs(wordX, wordY) {\n const m = wordX.length;\n const n = wordY.length;\n const l = [];\n for (let i = 0; i <= m; i++) {\n l[i] = [];\n for (let j = 0; j <= n; j++) {\n l[i][j] = 0;\n }\n }\n for (let i = 0; i <= m; i++) {\n for (let j = 0; j <= n; j++) {\n if (i === 0 || j === 0) {\n l[i][j] = 0;\n } else if (wordX[i - 1] === wordY[j - 1]) {\n l[i][j] = l[i - 1][j - 1] + 1;\n } else {\n const a = l[i - 1][j];\n const b = l[i][j - 1];\n l[i][j] = a > b ? a : b; // max(a,b)\n }\n }\n // console.log(l[i].join());\n }\n return l[m][n];\n}\n","export function knapSack(capacity, weights, values) {\n const n = values.length;\n let load = 0;\n let val = 0;\n for (let i = 0; i < n && load < capacity; i++) {\n if (weights[i] <= capacity - load) {\n val += values[i];\n load += weights[i];\n // console.log('using item ' + (i + 1) + ' for the solution');\n } else {\n const r = (capacity - load) / weights[i];\n val += r * values[i];\n load += weights[i];\n // console.log('using ratio of ' + r + ' for item ' + (i + 1) + ' for the solution');\n }\n }\n return val;\n}\n","export function knapSack(capacity, weights, values, n) {\n if (n === 0 || capacity === 0) {\n return 0;\n }\n if (weights[n - 1] > capacity) {\n return knapSack(capacity, weights, values, n - 1);\n }\n const a = values[n - 1] + knapSack(capacity - weights[n - 1], weights, values, n - 1);\n const b = knapSack(capacity, weights, values, n - 1);\n return a > b ? a : b;\n}\n","function findValues(n, capacity, kS) {\n let i = n;\n let k = capacity;\n // console.log('Items that are part of the solution:');\n while (i > 0 && k > 0) {\n if (kS[i][k] !== kS[i - 1][k]) {\n // console.log(\n // item ' + i + ' can be part of solution w,v: ' + weights[i - 1] + ',' + values[i - 1]\n // );\n i--;\n k -= kS[i][k];\n } else {\n i--;\n }\n }\n}\n\nexport function knapSack(capacity, weights, values, n) {\n const kS = [];\n for (let i = 0; i <= n; i++) {\n kS[i] = [];\n }\n for (let i = 0; i <= n; i++) {\n for (let w = 0; w <= capacity; w++) {\n if (i === 0 || w === 0) {\n kS[i][w] = 0;\n } else if (weights[i - 1] <= w) {\n const a = values[i - 1] + kS[i - 1][w - weights[i - 1]];\n const b = kS[i - 1][w];\n kS[i][w] = a > b ? a : b; // max(a,b)\n // console.log(a + ' can be part of the solution');\n } else {\n kS[i][w] = kS[i - 1][w];\n }\n }\n // console.log(kS[i].join());\n }\n // extra algorithm to find the items that are part of the solution\n findValues(n, capacity, kS);\n return kS[n][capacity];\n}\n","export function minCoinChange(coins, amount) {\n const change = [];\n let total = 0;\n for (let i = coins.length; i >= 0; i--) {\n const coin = coins[i];\n while (total + coin <= amount) {\n change.push(coin);\n total += coin;\n }\n }\n return change;\n}\n","export function minCoinChange(coins, amount) {\n const cache = [];\n\n const makeChange = (value) => {\n if (!value) {\n return [];\n }\n if (cache[value]) {\n return cache[value];\n }\n let min = [];\n let newMin;\n let newAmount;\n for (let i = 0; i < coins.length; i++) {\n const coin = coins[i];\n newAmount = value - coin;\n if (newAmount >= 0) {\n newMin = makeChange(newAmount);\n }\n if (\n newAmount >= 0 &&\n (newMin.length < min.length - 1 || !min.length) &&\n (newMin.length || !newAmount)\n ) {\n min = [coin].concat(newMin);\n // console.log('new Min ' + min + ' for ' + amount);\n }\n }\n return (cache[value] = min);\n };\n return makeChange(amount);\n}\n","import { Compare, defaultCompare, DOES_NOT_EXIST } from '../../util';\nimport { quickSort } from '../sorting/quicksort';\n\nfunction binarySearchRecursive(array, value, low, high, compareFn = defaultCompare) {\n if (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const element = array[mid];\n if (compareFn(element, value) === Compare.LESS_THAN) {\n return binarySearchRecursive(array, value, mid + 1, high, compareFn);\n }\n if (compareFn(element, value) === Compare.BIGGER_THAN) {\n return binarySearchRecursive(array, value, low, mid - 1, compareFn);\n }\n return mid;\n }\n return DOES_NOT_EXIST;\n}\n\nexport function binarySearch(array, value, compareFn = defaultCompare) {\n const sortedArray = quickSort(array);\n const low = 0;\n const high = sortedArray.length - 1;\n return binarySearchRecursive(array, value, low, high, compareFn);\n}\n","import { defaultEquals, DOES_NOT_EXIST } from '../../util';\n\nexport function sequentialSearch(array, value, equalsFn = defaultEquals) {\n for (let i = 0; i < array.length; i++) {\n if (equalsFn(value, array[i])) {\n return i;\n }\n }\n return DOES_NOT_EXIST;\n}\n","import {\n biggerEquals,\n Compare,\n defaultCompare,\n defaultEquals,\n defaultDiff,\n DOES_NOT_EXIST,\n lesserEquals\n} from '../../util';\n\nexport function interpolationSearch(\n array,\n value,\n compareFn = defaultCompare,\n equalsFn = defaultEquals,\n diffFn = defaultDiff\n) {\n const { length } = array;\n let low = 0;\n let high = length - 1;\n let position = -1;\n let delta = -1;\n while (\n low <= high &&\n biggerEquals(value, array[low], compareFn) &&\n lesserEquals(value, array[high], compareFn)\n ) {\n delta = diffFn(value, array[low]) / diffFn(array[high], array[low]);\n position = low + Math.floor((high - low) * delta);\n if (equalsFn(array[position], value)) {\n return position;\n }\n if (compareFn(array[position], value) === Compare.LESS_THAN) {\n low = position + 1;\n } else {\n high = position - 1;\n }\n }\n return DOES_NOT_EXIST;\n}\n","import { Compare, defaultCompare, DOES_NOT_EXIST } from '../../util';\nimport { quickSort } from '../sorting/quicksort';\n\nexport function binarySearch(array, value, compareFn = defaultCompare) {\n const sortedArray = quickSort(array);\n let low = 0;\n let high = sortedArray.length - 1;\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const element = sortedArray[mid];\n // console.log('mid element is ' + element);\n if (compareFn(element, value) === Compare.LESS_THAN) {\n low = mid + 1;\n // console.log('low is ' + low);\n } else if (compareFn(element, value) === Compare.BIGGER_THAN) {\n high = mid - 1;\n // console.log('high is ' + high);\n } else {\n // console.log('found it');\n return mid;\n }\n }\n return DOES_NOT_EXIST;\n}\n","import { Compare, defaultCompare } from '../../util';\n\nexport function shellSort(array, compareFn = defaultCompare) {\n let increment = array.length / 2;\n while (increment > 0) {\n for (let i = increment; i < array.length; i++) {\n let j = i;\n const temp = array[i];\n while (j >= increment && compareFn(array[j - increment], temp) === Compare.BIGGER_THAN) {\n array[j] = array[j - increment];\n j -= increment;\n }\n array[j] = temp;\n }\n if (increment === 2) {\n increment = 1;\n } else {\n increment = Math.floor((increment * 5) / 11);\n }\n }\n return array;\n}\n","import { Compare, defaultCompare, swap } from '../../util';\n\nexport const selectionSort = (array, compareFn = defaultCompare) => {\n const { length } = array;\n let indexMin;\n for (let i = 0; i < length - 1; i++) {\n indexMin = i;\n // console.log('index ' + array[i]);\n for (let j = i; j < length; j++) {\n if (compareFn(array[indexMin], array[j]) === Compare.BIGGER_THAN) {\n // console.log('new index min ' + array[j]);\n indexMin = j;\n }\n }\n if (i !== indexMin) {\n // console.log('swap ' + array[i] + ' with ' + array[indexMin]);\n swap(array, i, indexMin);\n }\n }\n return array;\n};\n","import { findMaxValue, findMinValue } from '../search/min-max-search';\n\nconst getBucketIndex = (value, minValue, significantDigit, radixBase) =>\n Math.floor(((value - minValue) / significantDigit) % radixBase);\n\nconst countingSortForRadix = (array, radixBase, significantDigit, minValue) => {\n let bucketsIndex;\n const buckets = [];\n const aux = [];\n for (let i = 0; i < radixBase; i++) {\n buckets[i] = 0;\n }\n for (let i = 0; i < array.length; i++) {\n bucketsIndex = getBucketIndex(array[i], minValue, significantDigit, radixBase);\n buckets[bucketsIndex]++;\n }\n for (let i = 1; i < radixBase; i++) {\n buckets[i] += buckets[i - 1];\n }\n for (let i = array.length - 1; i >= 0; i--) {\n bucketsIndex = getBucketIndex(array[i], minValue, significantDigit, radixBase);\n aux[--buckets[bucketsIndex]] = array[i];\n }\n for (let i = 0; i < array.length; i++) {\n array[i] = aux[i];\n }\n return array;\n};\nexport function radixSort(array, radixBase = 10) {\n if (array.length < 2) {\n return array;\n }\n const minValue = findMinValue(array);\n const maxValue = findMaxValue(array);\n // Perform counting sort for each significant digit, starting at 1\n let significantDigit = 1;\n while ((maxValue - minValue) / significantDigit >= 1) {\n // console.log('radix sort for digit ' + significantDigit);\n array = countingSortForRadix(array, radixBase, significantDigit, minValue);\n // console.log(array.join());\n significantDigit *= radixBase;\n }\n return array;\n}\n","import { Compare, defaultCompare } from '../../util';\n\nfunction merge(left, right, compareFn) {\n let i = 0;\n let j = 0;\n const result = [];\n while (i < left.length && j < right.length) {\n result.push(compareFn(left[i], right[j]) === Compare.LESS_THAN ? left[i++] : right[j++]);\n }\n return result.concat(i < left.length ? left.slice(i) : right.slice(j));\n}\nexport function mergeSort(array, compareFn = defaultCompare) {\n if (array.length > 1) {\n const { length } = array;\n const middle = Math.floor(length / 2);\n const left = mergeSort(array.slice(0, middle), compareFn);\n const right = mergeSort(array.slice(middle, length), compareFn);\n array = merge(left, right, compareFn);\n }\n return array;\n}\n","import { findMaxValue } from '../search/min-max-search';\n\nexport function countingSort(array) {\n if (array.length < 2) {\n return array;\n }\n const maxValue = findMaxValue(array);\n let sortedIndex = 0;\n const counts = new Array(maxValue + 1);\n array.forEach(element => {\n if (!counts[element]) {\n counts[element] = 0;\n }\n counts[element]++;\n });\n // console.log('Frequencies: ' + counts.join());\n counts.forEach((element, i) => {\n while (element > 0) {\n array[sortedIndex++] = i;\n element--;\n }\n });\n return array;\n}\n","import { insertionSort } from './insertion-sort';\n\nfunction createBuckets(array, bucketSize) {\n let minValue = array[0];\n let maxValue = array[0];\n for (let i = 1; i < array.length; i++) {\n if (array[i] < minValue) {\n minValue = array[i];\n } else if (array[i] > maxValue) {\n maxValue = array[i];\n }\n }\n const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;\n const buckets = [];\n for (let i = 0; i < bucketCount; i++) {\n buckets[i] = [];\n }\n for (let i = 0; i < array.length; i++) {\n buckets[Math.floor((array[i] - minValue) / bucketSize)].push(array[i]);\n }\n return buckets;\n}\nfunction sortBuckets(buckets) {\n const sortedArray = [];\n for (let i = 0; i < buckets.length; i++) {\n if (buckets[i] != null) {\n insertionSort(buckets[i]);\n sortedArray.push(...buckets[i]);\n }\n }\n return sortedArray;\n}\nexport function bucketSort(array, bucketSize = 5) {\n if (array.length < 2) {\n return array;\n }\n const buckets = createBuckets(array, bucketSize);\n return sortBuckets(buckets);\n}\n","import { Compare, defaultCompare, swap } from '../../util';\n\nexport function modifiedBubbleSort(array, compareFn = defaultCompare) {\n const { length } = array;\n for (let i = 0; i < length; i++) {\n // console.log('--- ');\n for (let j = 0; j < length - 1 - i; j++) {\n // console.log('compare ' + array[j] + ' with ' + array[j + 1]);\n if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) {\n // console.log('swap ' + array[j] + ' with ' + array[j + 1]);\n swap(array, j, j + 1);\n }\n }\n }\n return array;\n}\n","import { Compare, defaultCompare, swap } from '../../util';\n\nexport function bubbleSort(array, compareFn = defaultCompare) {\n const { length } = array;\n for (let i = 0; i < length; i++) {\n // console.log('--- ');\n for (let j = 0; j < length - 1; j++) {\n // console.log('compare ' + array[j] + ' with ' + array[j + 1]);\n if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) {\n // console.log('swap ' + array[j] + ' with ' + array[j + 1]);\n swap(array, j, j + 1);\n }\n }\n }\n return array;\n}\n","import { swap } from '../../util';\n\nexport function shuffle(array) {\n let currentIndex = array.length;\n while (currentIndex !== 0) {\n const randomIndex = Math.floor(Math.random() * currentIndex);\n currentIndex--;\n swap(array, currentIndex, randomIndex);\n }\n return array;\n}\n","const INF = Number.MAX_SAFE_INTEGER;\nconst find = (i, parent) => {\n while (parent[i]) {\n i = parent[i]; // eslint-disable-line prefer-destructuring\n }\n return i;\n};\nconst union = (i, j, parent) => {\n if (i !== j) {\n parent[j] = i;\n return true;\n }\n return false;\n};\nconst initializeCost = graph => {\n const cost = [];\n const { length } = graph;\n for (let i = 0; i < length; i++) {\n cost[i] = [];\n for (let j = 0; j < length; j++) {\n if (graph[i][j] === 0) {\n cost[i][j] = INF;\n } else {\n cost[i][j] = graph[i][j];\n }\n }\n }\n return cost;\n};\nexport const kruskal = graph => {\n const { length } = graph;\n const parent = [];\n let ne = 0;\n let a;\n let b;\n let u;\n let v;\n const cost = initializeCost(graph);\n while (ne < length - 1) {\n for (let i = 0, min = INF; i < length; i++) {\n for (let j = 0; j < length; j++) {\n if (cost[i][j] < min) {\n min = cost[i][j];\n a = u = i;\n b = v = j;\n }\n }\n }\n u = find(u, parent);\n v = find(v, parent);\n if (union(u, v, parent)) {\n ne++;\n }\n cost[a][b] = cost[b][a] = INF;\n }\n return parent;\n};\n","const INF = Number.MAX_SAFE_INTEGER;\nconst minKey = (graph, key, visited) => {\n // Initialize min value\n let min = INF;\n let minIndex = 0;\n for (let v = 0; v < graph.length; v++) {\n if (visited[v] === false && key[v] < min) {\n min = key[v];\n minIndex = v;\n }\n }\n return minIndex;\n};\nexport const prim = graph => {\n const parent = [];\n const key = [];\n const visited = [];\n const { length } = graph;\n for (let i = 0; i < length; i++) {\n key[i] = INF;\n visited[i] = false;\n }\n key[0] = 0;\n parent[0] = -1;\n for (let i = 0; i < length - 1; i++) {\n const u = minKey(graph, key, visited);\n visited[u] = true;\n for (let v = 0; v < length; v++) {\n if (graph[u][v] && !visited[v] && graph[u][v] < key[v]) {\n parent[v] = u;\n key[v] = graph[u][v];\n }\n }\n }\n return parent;\n};\n","const INF = Number.MAX_SAFE_INTEGER;\nconst minDistance = (dist, visited) => {\n let min = INF;\n let minIndex = -1;\n for (let v = 0; v < dist.length; v++) {\n if (visited[v] === false && dist[v] <= min) {\n min = dist[v];\n minIndex = v;\n }\n }\n return minIndex;\n};\nexport const dijkstra = (graph, src) => {\n const dist = [];\n const visited = [];\n const { length } = graph;\n for (let i = 0; i < length; i++) {\n dist[i] = INF;\n visited[i] = false;\n }\n dist[src] = 0;\n for (let i = 0; i < length - 1; i++) {\n const u = minDistance(dist, visited);\n visited[u] = true;\n for (let v = 0; v < length; v++) {\n if (!visited[v] && graph[u][v] !== 0 && dist[u] !== INF && dist[u] + graph[u][v] < dist[v]) {\n dist[v] = dist[u] + graph[u][v];\n }\n }\n }\n return dist;\n};\n","// import Graph from '../../data-structures/graph';\n\nconst Colors = {\n WHITE: 0,\n GREY: 1,\n BLACK: 2\n};\n\nconst initializeColor = vertices => {\n const color = {};\n for (let i = 0; i < vertices.length; i++) {\n color[vertices[i]] = Colors.WHITE;\n }\n return color;\n};\n\nconst depthFirstSearchVisit = (u, color, adjList, callback) => {\n color[u] = Colors.GREY;\n if (callback) {\n callback(u);\n }\n // console.log('Discovered ' + u);\n const neighbors = adjList.get(u);\n for (let i = 0; i < neighbors.length; i++) {\n const w = neighbors[i];\n if (color[w] === Colors.WHITE) {\n depthFirstSearchVisit(w, color, adjList, callback);\n }\n }\n color[u] = Colors.BLACK;\n // console.log('explored ' + u);\n};\n\nexport const depthFirstSearch = (graph, callback) => {\n const vertices = graph.getVertices();\n const adjList = graph.getAdjList();\n const color = initializeColor(vertices);\n\n for (let i = 0; i < vertices.length; i++) {\n if (color[vertices[i]] === Colors.WHITE) {\n depthFirstSearchVisit(vertices[i], color, adjList, callback);\n }\n }\n};\n\nconst DFSVisit = (u, color, d, f, p, time, adjList) => {\n // console.log('discovered ' + u);\n color[u] = Colors.GREY;\n d[u] = ++time.count;\n const neighbors = adjList.get(u);\n for (let i = 0; i < neighbors.length; i++) {\n const w = neighbors[i];\n if (color[w] === Colors.WHITE) {\n p[w] = u;\n DFSVisit(w, color, d, f, p, time, adjList);\n }\n }\n color[u] = Colors.BLACK;\n f[u] = ++time.count;\n // console.log('explored ' + u);\n};\n\nexport const DFS = graph => {\n const vertices = graph.getVertices();\n const adjList = graph.getAdjList();\n const color = initializeColor(vertices);\n const d = {};\n const f = {};\n const p = {};\n const time = { count: 0 };\n for (let i = 0; i < vertices.length; i++) {\n f[vertices[i]] = 0;\n d[vertices[i]] = 0;\n p[vertices[i]] = null;\n }\n for (let i = 0; i < vertices.length; i++) {\n if (color[vertices[i]] === Colors.WHITE) {\n DFSVisit(vertices[i], color, d, f, p, time, adjList);\n }\n }\n return {\n discovery: d,\n finished: f,\n predecessors: p\n };\n};\n","import Queue from '../../data-structures/queue';\n\nconst Colors = {\n WHITE: 0,\n GREY: 1,\n BLACK: 2\n};\n\nconst initializeColor = vertices => {\n const color = {};\n for (let i = 0; i < vertices.length; i++) {\n color[vertices[i]] = Colors.WHITE;\n }\n return color;\n};\n\nexport const breadthFirstSearch = (graph, startVertex, callback) => {\n const vertices = graph.getVertices();\n const adjList = graph.getAdjList();\n const color = initializeColor(vertices);\n const queue = new Queue();\n\n queue.enqueue(startVertex);\n\n while (!queue.isEmpty()) {\n const u = queue.dequeue();\n const neighbors = adjList.get(u);\n color[u] = Colors.GREY;\n for (let i = 0; i < neighbors.length; i++) {\n const w = neighbors[i];\n if (color[w] === Colors.WHITE) {\n color[w] = Colors.GREY;\n queue.enqueue(w);\n }\n }\n color[u] = Colors.BLACK;\n if (callback) {\n callback(u);\n }\n }\n};\n\nexport const BFS = (graph, startVertex) => {\n const vertices = graph.getVertices();\n const adjList = graph.getAdjList();\n const color = initializeColor(vertices);\n const queue = new Queue();\n const distances = {};\n const predecessors = {};\n queue.enqueue(startVertex);\n for (let i = 0; i < vertices.length; i++) {\n distances[vertices[i]] = 0;\n predecessors[vertices[i]] = null;\n }\n while (!queue.isEmpty()) {\n const u = queue.dequeue();\n const neighbors = adjList.get(u);\n color[u] = Colors.GREY;\n for (let i = 0; i < neighbors.length; i++) {\n const w = neighbors[i];\n if (color[w] === Colors.WHITE) {\n color[w] = Colors.GREY;\n distances[w] = distances[u] + 1;\n predecessors[w] = u;\n queue.enqueue(w);\n }\n }\n color[u] = Colors.BLACK;\n }\n return {\n distances,\n predecessors\n };\n};\n","import Dictionary from './dictionary';\n\nexport default class Graph {\n constructor(isDirected = false) {\n this.isDirected = isDirected;\n this.vertices = [];\n this.adjList = new Dictionary();\n }\n addVertex(v) {\n if (!this.vertices.includes(v)) {\n this.vertices.push(v);\n this.adjList.set(v, []); // initialize adjacency list with array as well;\n }\n }\n addEdge(a, b) {\n if (!this.adjList.get(a)) {\n this.addVertex(a);\n }\n if (!this.adjList.get(b)) {\n this.addVertex(b);\n }\n this.adjList.get(a).push(b);\n if (this.isDirected !== true) {\n this.adjList.get(b).push(a);\n }\n }\n getVertices() {\n return this.vertices;\n }\n getAdjList() {\n return this.adjList;\n }\n toString() {\n let s = '';\n for (let i = 0; i < this.vertices.length; i++) {\n s += `${this.vertices[i]} -> `;\n const neighbors = this.adjList.get(this.vertices[i]);\n for (let j = 0; j < neighbors.length; j++) {\n s += `${neighbors[j]} `;\n }\n s += '\\n';\n }\n return s;\n }\n}\n","import { defaultCompare, swap } from '../../util';\n\nfunction heapify(array, index, heapSize, compareFn) {\n let largest = index;\n const left = (2 * index) + 1;\n const right = (2 * index) + 2;\n if (left < heapSize && compareFn(array[left], array[index]) > 0) {\n largest = left;\n }\n if (right < heapSize && compareFn(array[right], array[largest]) > 0) {\n largest = right;\n }\n if (largest !== index) {\n swap(array, index, largest);\n heapify(array, largest, heapSize, compareFn);\n }\n}\n\nfunction buildMaxHeap(array, compareFn) {\n for (let i = Math.floor(array.length / 2); i >= 0; i -= 1) {\n heapify(array, i, array.length, compareFn);\n }\n return array;\n}\n\nexport default function heapSort(array, compareFn = defaultCompare) {\n let heapSize = array.length;\n buildMaxHeap(array, compareFn);\n while (heapSize > 1) {\n swap(array, 0, --heapSize);\n heapify(array, 0, heapSize, compareFn);\n }\n return array;\n}\n","import { Compare, defaultCompare, reverseCompare, swap } from '../util';\n\nexport class MinHeap {\n constructor(compareFn = defaultCompare) {\n this.compareFn = compareFn;\n this.heap = [];\n }\n getLeftIndex(index) {\n return (2 * index) + 1;\n }\n getRightIndex(index) {\n return (2 * index) + 2;\n }\n getParentIndex(index) {\n if (index === 0) {\n return undefined;\n }\n return Math.floor((index - 1) / 2);\n }\n size() {\n return this.heap.length;\n }\n isEmpty() {\n return this.size() <= 0;\n }\n clear() {\n this.heap = [];\n }\n findMinimum() {\n return this.isEmpty() ? undefined : this.heap[0];\n }\n insert(value) {\n if (value != null) {\n const index = this.heap.length;\n this.heap.push(value);\n this.siftUp(index);\n return true;\n }\n return false;\n }\n siftDown(index) {\n let element = index;\n const left = this.getLeftIndex(index);\n const right = this.getRightIndex(index);\n const size = this.size();\n if (\n left < size &&\n this.compareFn(this.heap[element], this.heap[left]) === Compare.BIGGER_THAN\n ) {\n element = left;\n }\n if (\n right < size &&\n this.compareFn(this.heap[element], this.heap[right]) === Compare.BIGGER_THAN\n ) {\n element = right;\n }\n if (index !== element) {\n swap(this.heap, index, element);\n this.siftDown(element);\n }\n }\n siftUp(index) {\n let parent = this.getParentIndex(index);\n while (\n index > 0 &&\n this.compareFn(this.heap[parent], this.heap[index]) === Compare.BIGGER_THAN\n ) {\n swap(this.heap, parent, index);\n index = parent;\n parent = this.getParentIndex(index);\n }\n }\n extract() {\n if (this.isEmpty()) {\n return undefined;\n }\n if (this.size() === 1) {\n return this.heap.shift();\n }\n const removedValue = this.heap[0];\n this.heap[0] = this.heap.pop();\n this.siftDown(0);\n return removedValue;\n }\n heapify(array) {\n if (array) {\n this.heap = array;\n }\n const maxIndex = Math.floor(this.size() / 2) - 1;\n for (let i = 0; i <= maxIndex; i++) {\n this.siftDown(i);\n }\n return this.heap;\n }\n getAsArray() {\n return this.heap;\n }\n}\nexport class MaxHeap extends MinHeap {\n constructor(compareFn = defaultCompare) {\n super(compareFn);\n this.compareFn = compareFn;\n this.compareFn = reverseCompare(compareFn);\n }\n}\n","import { Compare, defaultCompare } from '../util';\nimport BinarySearchTree from './binary-search-tree';\nimport { Node } from './models/node';\n\nconst BalanceFactor = {\n UNBALANCED_RIGHT: 1,\n SLIGHTLY_UNBALANCED_RIGHT: 2,\n BALANCED: 3,\n SLIGHTLY_UNBALANCED_LEFT: 4,\n UNBALANCED_LEFT: 5\n};\n\nexport default class AVLTree extends BinarySearchTree {\n constructor(compareFn = defaultCompare) {\n super(compareFn);\n this.compareFn = compareFn;\n this.root = null;\n }\n getNodeHeight(node) {\n if (node == null) {\n return -1;\n }\n return Math.max(this.getNodeHeight(node.left), this.getNodeHeight(node.right)) + 1;\n }\n /**\n * Left left case: rotate right\n *\n * b a\n * / \\ / \\\n * a e -> rotationLL(b) -> c b\n * / \\ / \\\n * c d d e\n *\n * @param node Node\n */\n rotationLL(node) {\n const tmp = node.left;\n node.left = tmp.right;\n tmp.right = node;\n return tmp;\n }\n /**\n * Right right case: rotate left\n *\n * a b\n * / \\ / \\\n * c b -> rotationRR(a) -> a e\n * / \\ / \\\n * d e c d\n *\n * @param node Node\n */\n rotationRR(node) {\n const tmp = node.right;\n node.right = tmp.left;\n tmp.left = node;\n return tmp;\n }\n /**\n * Left right case: rotate left then right\n * @param node Node\n */\n rotationLR(node) {\n node.left = this.rotationRR(node.left);\n return this.rotationLL(node);\n }\n /**\n * Right left case: rotate right then left\n * @param node Node\n */\n rotationRL(node) {\n node.right = this.rotationLL(node.right);\n return this.rotationRR(node);\n }\n getBalanceFactor(node) {\n const heightDifference = this.getNodeHeight(node.left) - this.getNodeHeight(node.right);\n switch (heightDifference) {\n case -2:\n return BalanceFactor.UNBALANCED_RIGHT;\n case -1:\n return BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT;\n case 1:\n return BalanceFactor.SLIGHTLY_UNBALANCED_LEFT;\n case 2:\n return BalanceFactor.UNBALANCED_LEFT;\n default:\n return BalanceFactor.BALANCED;\n }\n }\n insert(key) {\n this.root = this.insertNode(this.root, key);\n }\n insertNode(node, key) {\n if (node == null) {\n return new Node(key);\n } else if (this.compareFn(key, node.key) === Compare.LESS_THAN) {\n node.left = this.insertNode(node.left, key);\n } else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {\n node.right = this.insertNode(node.right, key);\n } else {\n return node; // duplicated key\n }\n // verify if tree is balanced\n const balanceFactor = this.getBalanceFactor(node);\n if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) {\n if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) {\n // Left left case\n node = this.rotationLL(node);\n } else {\n // Left right case\n return this.rotationLR(node);\n }\n }\n if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) {\n if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) {\n // Right right case\n node = this.rotationRR(node);\n } else {\n // Right left case\n return this.rotationRL(node);\n }\n }\n return node;\n }\n removeNode(node, key) {\n node = super.removeNode(node, key); // {1}\n if (node == null) {\n return node;\n }\n // verify if tree is balanced\n const balanceFactor = this.getBalanceFactor(node);\n if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) {\n // Left left case\n if (\n this.getBalanceFactor(node.left) === BalanceFactor.BALANCED ||\n this.getBalanceFactor(node.left) === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT\n ) {\n return this.rotationLL(node);\n }\n // Left right case\n if (this.getBalanceFactor(node.left) === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT) {\n return this.rotationLR(node.left);\n }\n }\n if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) {\n // Right right case\n if (\n this.getBalanceFactor(node.right) === BalanceFactor.BALANCED ||\n this.getBalanceFactor(node.right) === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT\n ) {\n return this.rotationRR(node);\n }\n // Right left case\n if (this.getBalanceFactor(node.right) === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT) {\n return this.rotationRL(node.right);\n }\n }\n return node;\n }\n}\n","export function fibonacci(n) {\n if (n < 1) {\n return 0;\n }\n if (n <= 2) {\n return 1;\n }\n return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\nexport function fibonacciIterative(n) {\n if (n < 1) { return 0; }\n let fibNMinus2 = 0;\n let fibNMinus1 = 1;\n let fibN = n;\n for (let i = 2; i <= n; i++) {\n fibN = fibNMinus1 + fibNMinus2;\n fibNMinus2 = fibNMinus1;\n fibNMinus1 = fibN;\n }\n return fibN;\n}\n\nexport function fibonacciMemoization(n) {\n if (n < 1) { return 0; }\n const memo = [0, 1];\n const fibonacciMem = num => {\n if (memo[num] != null) { return memo[num]; }\n return (memo[num] = fibonacciMem(num - 1) + fibonacciMem(num - 2));\n };\n return fibonacciMem(n);\n}\n","export function factorialIterative(number) {\n if (number < 0) {\n return undefined;\n }\n let total = 1;\n for (let n = number; n > 1; n--) {\n total *= n;\n }\n return total;\n}\n\nexport function factorial(n) {\n if (n < 0) {\n return undefined;\n }\n if (n === 1 || n === 0) {\n return 1;\n }\n return n * factorial(n - 1);\n}\n","import { ValuePair } from './value-pair';\n\nexport class ValuePairLazy extends ValuePair {\n constructor(key, value, isDeleted = false) {\n super(key, value);\n this.key = key;\n this.value = value;\n this.isDeleted = isDeleted;\n }\n}\n","import { defaultToString } from '../util';\nimport { ValuePairLazy } from './models/value-pair-lazy';\n\nexport default class HashTableLinearProbingLazy {\n constructor(toStrFn = defaultToString) {\n this.toStrFn = toStrFn;\n this.table = {};\n }\n loseloseHashCode(key) {\n if (typeof key === 'number') {\n return key;\n }\n const tableKey = this.toStrFn(key);\n let hash = 0;\n for (let i = 0; i < tableKey.length; i++) {\n hash += tableKey.charCodeAt(i);\n }\n return hash % 37;\n }\n hashCode(key) {\n return this.loseloseHashCode(key);\n }\n put(key, value) {\n if (key != null && value != null) {\n const position = this.hashCode(key);\n if (\n this.table[position] == null ||\n (this.table[position] != null && this.table[position].isDeleted)\n ) {\n this.table[position] = new ValuePairLazy(key, value);\n } else {\n let index = position + 1;\n while (this.table[index] != null && !this.table[position].isDeleted) {\n index++;\n }\n this.table[index] = new ValuePairLazy(key, value);\n }\n return true;\n }\n return false;\n }\n get(key) {\n const position = this.hashCode(key);\n if (this.table[position] != null) {\n if (this.table[position].key === key && !this.table[position].isDeleted) {\n return this.table[position].value;\n }\n let index = position + 1;\n while (\n this.table[index] != null &&\n (this.table[index].key !== key || this.table[index].isDeleted)\n ) {\n if (this.table[index].key === key && this.table[index].isDeleted) {\n return undefined;\n }\n index++;\n }\n if (\n this.table[index] != null &&\n this.table[index].key === key &&\n !this.table[index].isDeleted\n ) {\n return this.table[position].value;\n }\n }\n return undefined;\n }\n remove(key) {\n const position = this.hashCode(key);\n if (this.table[position] != null) {\n if (this.table[position].key === key && !this.table[position].isDeleted) {\n this.table[position].isDeleted = true;\n return true;\n }\n let index = position + 1;\n while (\n this.table[index] != null &&\n (this.table[index].key !== key || this.table[index].isDeleted)\n ) {\n index++;\n }\n if (\n this.table[index] != null &&\n this.table[index].key === key &&\n !this.table[index].isDeleted\n ) {\n this.table[index].isDeleted = true;\n return true;\n }\n }\n return false;\n }\n isEmpty() {\n return this.size() === 0;\n }\n size() {\n let count = 0;\n Object.values(this.table).forEach(valuePair => {\n count += valuePair.isDeleted === true ? 0 : 1;\n });\n return count;\n }\n clear() {\n this.table = {};\n }\n getTable() {\n return this.table;\n }\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n const keys = Object.keys(this.table);\n let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`;\n for (let i = 1; i < keys.length; i++) {\n objString = `${objString},{${keys[i]} => ${this.table[\n keys[i]\n ].toString()}}`;\n }\n return objString;\n }\n}\n","import { defaultToString } from '../util';\nimport { ValuePair } from './models/value-pair';\n\nexport default class HashTableLinearProbing {\n constructor(toStrFn = defaultToString) {\n this.toStrFn = toStrFn;\n this.table = {};\n }\n loseloseHashCode(key) {\n if (typeof key === 'number') {\n return key;\n }\n const tableKey = this.toStrFn(key);\n let hash = 0;\n for (let i = 0; i < tableKey.length; i++) {\n hash += tableKey.charCodeAt(i);\n }\n return hash % 37;\n }\n hashCode(key) {\n return this.loseloseHashCode(key);\n }\n put(key, value) {\n if (key != null && value != null) {\n const position = this.hashCode(key);\n if (this.table[position] == null) {\n this.table[position] = new ValuePair(key, value);\n } else {\n let index = position + 1;\n while (this.table[index] != null) {\n index++;\n }\n this.table[index] = new ValuePair(key, value);\n }\n return true;\n }\n return false;\n }\n get(key) {\n const position = this.hashCode(key);\n if (this.table[position] != null) {\n if (this.table[position].key === key) {\n return this.table[position].value;\n }\n let index = position + 1;\n while (this.table[index] != null && this.table[index].key !== key) {\n index++;\n }\n if (this.table[index] != null && this.table[index].key === key) {\n return this.table[position].value;\n }\n }\n return undefined;\n }\n remove(key) {\n const position = this.hashCode(key);\n if (this.table[position] != null) {\n if (this.table[position].key === key) {\n delete this.table[position];\n this.verifyRemoveSideEffect(key, position);\n return true;\n }\n let index = position + 1;\n while (this.table[index] != null && this.table[index].key !== key) {\n index++;\n }\n if (this.table[index] != null && this.table[index].key === key) {\n delete this.table[index];\n this.verifyRemoveSideEffect(key, index);\n return true;\n }\n }\n return false;\n }\n verifyRemoveSideEffect(key, removedPosition) {\n const hash = this.hashCode(key);\n let index = removedPosition + 1;\n while (this.table[index] != null) {\n const posHash = this.hashCode(this.table[index].key);\n if (posHash <= hash || posHash <= removedPosition) {\n this.table[removedPosition] = this.table[index];\n delete this.table[index];\n removedPosition = index;\n }\n index++;\n }\n }\n isEmpty() {\n return this.size() === 0;\n }\n size() {\n return Object.keys(this.table).length;\n }\n clear() {\n this.table = {};\n }\n getTable() {\n return this.table;\n }\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n const keys = Object.keys(this.table);\n let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`;\n for (let i = 1; i < keys.length; i++) {\n objString = `${objString},{${keys[i]} => ${this.table[\n keys[i]\n ].toString()}}`;\n }\n return objString;\n }\n}\n","import { defaultToString } from '../util';\nimport LinkedList from './linked-list';\nimport { ValuePair } from './models/value-pair';\n\nexport default class HashTableSeparateChaining {\n constructor(toStrFn = defaultToString) {\n this.toStrFn = toStrFn;\n this.table = {};\n }\n loseloseHashCode(key) {\n if (typeof key === 'number') {\n return key;\n }\n const tableKey = this.toStrFn(key);\n let hash = 0;\n for (let i = 0; i < tableKey.length; i++) {\n hash += tableKey.charCodeAt(i);\n }\n return hash % 37;\n }\n hashCode(key) {\n return this.loseloseHashCode(key);\n }\n put(key, value) {\n if (key != null && value != null) {\n const position = this.hashCode(key);\n if (this.table[position] == null) {\n this.table[position] = new LinkedList();\n }\n this.table[position].push(new ValuePair(key, value));\n return true;\n }\n return false;\n }\n get(key) {\n const position = this.hashCode(key);\n const linkedList = this.table[position];\n if (linkedList != null && !linkedList.isEmpty()) {\n let current = linkedList.getHead();\n while (current != null) {\n if (current.element.key === key) {\n return current.element.value;\n }\n current = current.next;\n }\n }\n return undefined;\n }\n remove(key) {\n const position = this.hashCode(key);\n const linkedList = this.table[position];\n if (linkedList != null && !linkedList.isEmpty()) {\n let current = linkedList.getHead();\n while (current != null) {\n if (current.element.key === key) {\n linkedList.remove(current.element);\n if (linkedList.isEmpty()) {\n delete this.table[position];\n }\n return true;\n }\n current = current.next;\n }\n }\n return false;\n }\n isEmpty() {\n return this.size() === 0;\n }\n size() {\n let count = 0;\n Object.values(this.table).forEach(linkedList => {\n count += linkedList.size();\n });\n return count;\n }\n clear() {\n this.table = {};\n }\n getTable() {\n return this.table;\n }\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n const keys = Object.keys(this.table);\n let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`;\n for (let i = 1; i < keys.length; i++) {\n objString = `${objString},{${keys[i]} => ${this.table[\n keys[i]\n ].toString()}}`;\n }\n return objString;\n }\n}\n","import { defaultToString } from '../util';\nimport { ValuePair } from './models/value-pair';\n\nexport default class HashTable {\n constructor(toStrFn = defaultToString) {\n this.toStrFn = toStrFn;\n this.table = {};\n }\n loseloseHashCode(key) {\n if (typeof key === 'number') {\n return key;\n }\n const tableKey = this.toStrFn(key);\n let hash = 0;\n for (let i = 0; i < tableKey.length; i++) {\n hash += tableKey.charCodeAt(i);\n }\n return hash % 37;\n }\n /* djb2HashCode(key) {\n const tableKey = this.toStrFn(key);\n let hash = 5381;\n for (let i = 0; i < tableKey.length; i++) {\n hash = (hash * 33) + tableKey.charCodeAt(i);\n }\n return hash % 1013;\n } */\n hashCode(key) {\n return this.loseloseHashCode(key);\n }\n put(key, value) {\n if (key != null && value != null) {\n const position = this.hashCode(key);\n this.table[position] = new ValuePair(key, value);\n return true;\n }\n return false;\n }\n get(key) {\n const valuePair = this.table[this.hashCode(key)];\n return valuePair == null ? undefined : valuePair.value;\n }\n remove(key) {\n const hash = this.hashCode(key);\n const valuePair = this.table[hash];\n if (valuePair != null) {\n delete this.table[hash];\n return true;\n }\n return false;\n }\n getTable() {\n return this.table;\n }\n isEmpty() {\n return this.size() === 0;\n }\n size() {\n return Object.keys(this.table).length;\n }\n clear() {\n this.table = {};\n }\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n const keys = Object.keys(this.table);\n let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`;\n for (let i = 1; i < keys.length; i++) {\n objString = `${objString},{${keys[i]} => ${this.table[keys[i]].toString()}}`;\n }\n return objString;\n }\n}\n","export default class Set {\n constructor() {\n this.items = {};\n }\n add(element) {\n if (!this.has(element)) {\n this.items[element] = element;\n return true;\n }\n return false;\n }\n delete(element) {\n if (this.has(element)) {\n delete this.items[element];\n return true;\n }\n return false;\n }\n has(element) {\n return Object.prototype.hasOwnProperty.call(this.items, element);\n }\n values() {\n return Object.values(this.items);\n }\n union(otherSet) {\n const unionSet = new Set();\n this.values().forEach(value => unionSet.add(value));\n otherSet.values().forEach(value => unionSet.add(value));\n return unionSet;\n }\n intersection(otherSet) {\n const intersectionSet = new Set();\n const values = this.values();\n const otherValues = otherSet.values();\n let biggerSet = values;\n let smallerSet = otherValues;\n if (otherValues.length - values.length > 0) {\n biggerSet = otherValues;\n smallerSet = values;\n }\n smallerSet.forEach(value => {\n if (biggerSet.includes(value)) {\n intersectionSet.add(value);\n }\n });\n return intersectionSet;\n }\n difference(otherSet) {\n const differenceSet = new Set();\n this.values().forEach(value => {\n if (!otherSet.has(value)) {\n differenceSet.add(value);\n }\n });\n return differenceSet;\n }\n isSubsetOf(otherSet) {\n if (this.size() > otherSet.size()) {\n return false;\n }\n let isSubset = true;\n this.values().every(value => {\n if (!otherSet.has(value)) {\n isSubset = false;\n return false;\n }\n return true;\n });\n return isSubset;\n }\n isEmpty() {\n return this.size() === 0;\n }\n size() {\n return Object.keys(this.items).length;\n }\n clear() {\n this.items = {};\n }\n toString() {\n if (this.isEmpty()) {\n return '';\n }\n const values = this.values();\n let objString = `${values[0]}`;\n for (let i = 1; i < values.length; i++) {\n objString = `${objString},${values[i].toString()}`;\n }\n return objString;\n }\n}\n","import DoublyLinkedList from './doubly-linked-list';\n\nexport default class StackLinkedList {\n constructor() {\n this.items = new DoublyLinkedList();\n }\n push(element) {\n this.items.push(element);\n }\n pop() {\n if (this.isEmpty()) {\n return undefined;\n }\n const result = this.items.removeAt(this.size() - 1);\n return result;\n }\n peek() {\n if (this.isEmpty()) {\n return undefined;\n }\n return this.items.getElementAt(this.size() - 1).element;\n }\n isEmpty() {\n return this.items.isEmpty();\n }\n size() {\n return this.items.size();\n }\n clear() {\n this.items.clear();\n }\n toString() {\n return this.items.toString();\n }\n}\n","import { Compare, defaultCompare, defaultEquals } from '../util';\nimport LinkedList from './linked-list';\n\nexport default class SortedLinkedList extends LinkedList {\n constructor(equalsFn = defaultEquals, compareFn = defaultCompare) {\n super(equalsFn);\n this.equalsFn = equalsFn;\n this.compareFn = compareFn;\n }\n push(element) {\n if (this.isEmpty()) {\n super.push(element);\n } else {\n const index = this.getIndexNextSortedElement(element);\n super.insert(element, index);\n }\n }\n insert(element, index = 0) {\n if (this.isEmpty()) {\n return super.insert(element, index === 0 ? index : 0);\n }\n const pos = this.getIndexNextSortedElement(element);\n return super.insert(element, pos);\n }\n getIndexNextSortedElement(element) {\n let current = this.head;\n let i = 0;\n for (; i < this.size() && current; i++) {\n const comp = this.compareFn(element, current.element);\n if (comp === Compare.LESS_THAN) {\n return i;\n }\n current = current.next;\n }\n return i;\n }\n}\n","import { defaultEquals } from '../util';\nimport LinkedList from './linked-list';\nimport { Node } from './models/linked-list-models';\n\nexport default class CircularLinkedList extends LinkedList {\n constructor(equalsFn = defaultEquals) {\n super(equalsFn);\n }\n push(element) {\n const node = new Node(element);\n let current;\n if (this.head == null) {\n this.head = node;\n } else {\n current = this.getElementAt(this.size() - 1);\n current.next = node;\n }\n // set node.next to head - to have circular list\n node.next = this.head;\n this.count++;\n }\n insert(element, index) {\n if (index >= 0 && index <= this.count) {\n const node = new Node(element);\n let current = this.head;\n if (index === 0) {\n if (this.head == null) {\n // if no node in list\n this.head = node;\n node.next = this.head;\n } else {\n node.next = current;\n current = this.getElementAt(this.size());\n // update last element\n this.head = node;\n current.next = this.head;\n }\n } else {\n const previous = this.getElementAt(index - 1);\n node.next = previous.next;\n previous.next = node;\n }\n this.count++;\n return true;\n }\n return false;\n }\n removeAt(index) {\n if (index >= 0 && index < this.count) {\n let current = this.head;\n if (index === 0) {\n if (this.size() === 1) {\n this.head = undefined;\n } else {\n const removed = this.head;\n current = this.getElementAt(this.size() - 1);\n this.head = this.head.next;\n current.next = this.head;\n current = removed;\n }\n } else {\n // no need to update last element for circular list\n const previous = this.getElementAt(index - 1);\n current = previous.next;\n previous.next = current.next;\n }\n this.count--;\n return current.element;\n }\n return undefined;\n }\n}\n","import Deque from '../data-structures/deque';\n\nexport function palindromeChecker(aString) {\n if (\n aString === undefined ||\n aString === null ||\n (aString !== null && aString.length === 0)\n ) {\n return false;\n }\n const deque = new Deque();\n const lowerString = aString.toLocaleLowerCase().split(' ').join('');\n let firstChar;\n let lastChar;\n\n for (let i = 0; i < lowerString.length; i++) {\n deque.addBack(lowerString.charAt(i));\n }\n\n while (deque.size() > 1) {\n firstChar = deque.removeFront();\n lastChar = deque.removeBack();\n if (firstChar !== lastChar) {\n return false;\n }\n }\n\n return true;\n}\n","import Queue from '../data-structures/queue';\n\nexport function hotPotato(elementsList, num) {\n const queue = new Queue();\n const elimitatedList = [];\n\n for (let i = 0; i < elementsList.length; i++) {\n queue.enqueue(elementsList[i]);\n }\n\n while (queue.size() > 1) {\n for (let i = 0; i < num; i++) {\n queue.enqueue(queue.dequeue());\n }\n elimitatedList.push(queue.dequeue());\n }\n\n return {\n eliminated: elimitatedList,\n winner: queue.dequeue()\n };\n}\n","// @ts-check\nimport Stack from '../data-structures/stack';\n\nexport function parenthesesChecker(symbols) {\n const stack = new Stack();\n const opens = '([{';\n const closers = ')]}';\n let balanced = true;\n let index = 0;\n let symbol;\n let top;\n\n while (index < symbols.length && balanced) {\n symbol = symbols[index];\n if (opens.indexOf(symbol) >= 0) {\n stack.push(symbol);\n } else if (stack.isEmpty()) {\n balanced = false;\n } else {\n top = stack.pop();\n if (!(opens.indexOf(top) === closers.indexOf(symbol))) {\n balanced = false;\n }\n }\n index++;\n }\n return balanced && stack.isEmpty();\n}\n","// @ts-check\nimport Stack from '../data-structures/stack';\n\nexport function decimalToBinary(decNumber) {\n const remStack = new Stack();\n let number = decNumber;\n let rem;\n let binaryString = '';\n\n while (number > 0) {\n rem = Math.floor(number % 2);\n remStack.push(rem);\n number = Math.floor(number / 2);\n }\n\n while (!remStack.isEmpty()) {\n binaryString += remStack.pop().toString();\n }\n\n return binaryString;\n}\n\nexport function baseConverter(decNumber, base) {\n const remStack = new Stack();\n const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n let number = decNumber;\n let rem;\n let baseString = '';\n\n if (!(base >= 2 && base <= 36)) {\n return '';\n }\n\n while (number > 0) {\n rem = Math.floor(number % base);\n remStack.push(rem);\n number = Math.floor(number / base);\n }\n\n while (!remStack.isEmpty()) {\n baseString += digits[remStack.pop()];\n }\n\n return baseString;\n}\n","// @ts-check\nimport Stack from '../data-structures/stack';\n\nfunction towerOfHanoi(plates, source, helper, dest, sourceName, helperName, destName, moves = []) {\n if (plates <= 0) {\n return moves;\n }\n if (plates === 1) {\n dest.push(source.pop());\n const move = {};\n move[sourceName] = source.toString();\n move[helperName] = helper.toString();\n move[destName] = dest.toString();\n moves.push(move);\n } else {\n towerOfHanoi(plates - 1, source, dest, helper, sourceName, destName, helperName, moves);\n dest.push(source.pop());\n const move = {};\n move[sourceName] = source.toString();\n move[helperName] = helper.toString();\n move[destName] = dest.toString();\n moves.push(move);\n towerOfHanoi(plates - 1, helper, source, dest, helperName, sourceName, destName, moves);\n }\n return moves;\n}\n\nexport function hanoiStack(plates) {\n const source = new Stack();\n const dest = new Stack();\n const helper = new Stack();\n\n for (let i = plates; i > 0; i--) {\n source.push(i);\n }\n\n return towerOfHanoi(plates, source, helper, dest, 'source', 'helper', 'dest');\n}\n\nexport function hanoi(plates, source, helper, dest, moves = []) {\n if (plates <= 0) {\n return moves;\n }\n if (plates === 1) {\n moves.push([source, dest]);\n } else {\n hanoi(plates - 1, source, dest, helper, moves);\n moves.push([source, dest]);\n hanoi(plates - 1, helper, source, dest, moves);\n }\n return moves;\n}\n","// @ts-check\n\nexport default class StackArray {\n constructor() {\n this.items = [];\n }\n push(element) {\n this.items.push(element);\n }\n\n pop() {\n return this.items.pop();\n }\n\n peek() {\n return this.items[this.items.length - 1];\n }\n\n isEmpty() {\n return this.items.length === 0;\n }\n\n size() {\n return this.items.length;\n }\n\n clear() {\n this.items = [];\n }\n\n toArray() {\n return this.items;\n }\n\n toString() {\n return this.items.toString();\n }\n}\n","import * as _util from './util';\n\n// chapters 05 and 07\nexport const util = _util;\n\n// chapter 03\nexport { default as StackArray } from './data-structures/stack-array';\nexport { default as Stack } from './data-structures/stack';\nexport { hanoi } from './others/hanoi';\nexport { hanoiStack } from './others/hanoi';\nexport { baseConverter } from './others/base-converter';\nexport { decimalToBinary } from './others/base-converter';\nexport { parenthesesChecker } from './others/balanced-symbols';\n\n// chapter 04\nexport { default as Queue } from './data-structures/queue';\nexport { default as Deque } from './data-structures/deque';\nexport { hotPotato } from './others/hot-potato';\nexport { palindromeChecker } from './others/palindrome-checker';\n\n// chapter 05\nexport { default as LinkedList } from './data-structures/linked-list';\nexport { default as DoublyLinkedList } from './data-structures/doubly-linked-list';\nexport { default as CircularLinkedList } from './data-structures/circular-linked-list';\nexport { default as SortedLinkedList } from './data-structures/sorted-linked-list';\nexport { default as StackLinkedList } from './data-structures/stack-linked-list';\n\n// chapter 06\nexport { default as Set } from './data-structures/set';\n\n// chapter 07\nexport { default as Dictionary } from './data-structures/dictionary';\nexport { default as HashTable } from './data-structures/hash-table';\nexport { default as HashTableSeparateChaining } from './data-structures/hash-table-separate-chaining';\nexport { default as HashTableLinearProbing } from './data-structures/hash-table-linear-probing';\nexport { default as HashTableLinearProbingLazy } from './data-structures/hash-table-linear-probing-lazy';\n\n// chapter 08\nexport { default as factorialIterative } from './others/factorial';\nexport { default as factorial } from './others/factorial';\nexport { default as fibonacci } from './others/fibonacci';\nexport { default as fibonacciIterative } from './others/fibonacci';\nexport { default as fibonacciMemoization } from './others/fibonacci';\n\n// chapter 09\nexport { default as BinarySearchTree } from './data-structures/binary-search-tree';\nexport { default as AVLTree } from './data-structures/avl-tree';\n\n// chapter 10\nexport { MinHeap } from './data-structures/heap';\nexport { MaxHeap } from './data-structures/heap';\nexport { default as heapSort } from './algorithms/sorting/heap-sort';\n\n// chapter 11\nexport { default as Graph } from './data-structures/graph';\nexport { breadthFirstSearch } from './algorithms/graph/breadth-first-search';\nexport { BFS } from './algorithms/graph/breadth-first-search';\nexport { depthFirstSearch } from './algorithms/graph/depth-first-search';\nexport { DFS } from './algorithms/graph/depth-first-search';\nexport { dijkstra } from './algorithms/graph/dijkstra';\nexport { floydWarshall } from './algorithms/graph/floyd-warshall';\nexport { prim } from './algorithms/graph/prim';\nexport { kruskal } from './algorithms/graph/kruskal';\n\n// chapter 12\nexport { shuffle } from './algorithms/shuffle/fisher–yates';\n\nexport { bubbleSort } from './algorithms/sorting/bubble-sort';\nexport { modifiedBubbleSort } from './algorithms/sorting/bubble-sort-improved';\nexport { bucketSort } from './algorithms/sorting/bucket-sort';\nexport { countingSort } from './algorithms/sorting/counting-sort';\nexport { insertionSort } from './algorithms/sorting/insertion-sort';\nexport { mergeSort } from './algorithms/sorting/merge-sort';\nexport { quickSort } from './algorithms/sorting/quicksort';\nexport { radixSort } from './algorithms/sorting/radix-sort';\nexport { selectionSort } from './algorithms/sorting/selection-sort';\nexport { shellSort } from './algorithms/sorting/shell-sort';\n\nexport { binarySearch } from './algorithms/search/binary-search';\nexport { interpolationSearch } from './algorithms/search/interpolation-search';\nexport { sequentialSearch } from './algorithms/search/sequential-search';\nexport { findMaxValue } from './algorithms/search/min-max-search';\nexport { findMinValue } from './algorithms/search/min-max-search';\n\n// chapter 14\nexport { binarySearch as binarySearchRecursive } from './algorithms/search/binary-search-recursive';\nexport { minCoinChange } from './algorithms/dynamic-programing/min-coin-change';\nexport { minCoinChange as minCoinChangeGreedy } from './algorithms/greedy/min-coin-change';\nexport { knapSack } from './algorithms/dynamic-programing/knapsack';\nexport { knapSack as knapSackRecursive } from './algorithms/dynamic-programing/knapsack-recursive';\nexport { knapSack as knapSackGreedy } from './algorithms/greedy/knapsack';\nexport { lcs } from './algorithms/dynamic-programing/longest-common-subsequence';\nexport { lcs as lcsPrint } from './algorithms/dynamic-programing/longest-common-subsequence-print';\nexport { lcs as lcsRecursive } from './algorithms/greedy/longest-common-subsequence';\nexport { matrixChainOrder } from './algorithms/dynamic-programing/matrix-chain-multiplication';\nexport { matrixChainOrder as matrixChainOrderGreedy } from './algorithms/greedy/matrix-chain-multiplication';\nexport { ratInAMaze } from './algorithms/backtracking/rat-in-maze';\nexport { sudokuSolver } from './algorithms/backtracking/sudoku-solver';\n"],"sourceRoot":""} \ No newline at end of file diff --git a/examples/chapter01_02/01-HelloWorld.html b/examples/chapter01_02/01-HelloWorld.html deleted file mode 100755 index f7eca1bf..00000000 --- a/examples/chapter01_02/01-HelloWorld.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter01_02/01-HelloWorld.js b/examples/chapter01_02/01-HelloWorld.js deleted file mode 100644 index b67b0e2c..00000000 --- a/examples/chapter01_02/01-HelloWorld.js +++ /dev/null @@ -1,10 +0,0 @@ -// @ts-check -/* eslint-disable */ - -function output(t) { - document.write('

' + t + '

'); -} - -alert('Hello, World!'); -console.log('Hello, World!'); -output('Hello, World!'); diff --git a/examples/chapter01_02/02-Variables.html b/examples/chapter01_02/02-Variables.html deleted file mode 100755 index f093a684..00000000 --- a/examples/chapter01_02/02-Variables.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter01_02/02-Variables.js b/examples/chapter01_02/02-Variables.js deleted file mode 100644 index 4d1cf7d5..00000000 --- a/examples/chapter01_02/02-Variables.js +++ /dev/null @@ -1,40 +0,0 @@ -// @ts-check -/* eslint-disable */ - -var num = 1; // {1} -num = 3; // {2} - -var price = 1.5; // {3} -var myName = 'Packt'; // {4} -var trueValue = true; // {5} -var nullVar = null; // {6} -var und; // {7} - -console.log('num: ' + num); -console.log('myName: ' + myName); -console.log('trueValue: ' + trueValue); -console.log('price: ' + price); -console.log('nullVar: ' + nullVar); -console.log('und: ' + und); - -// ******* Variable Scope - -var myVariable = 'global'; -myOtherVariable = 'global'; - -function myFunction() { - var myVariable = 'local'; - return myVariable; -} - -function myOtherFunction() { - myOtherVariable = 'local'; - return myOtherVariable; -} - -console.log(myVariable); //{1} -console.log(myFunction()); //{2} - -console.log(myOtherVariable); //{3} -console.log(myOtherFunction()); //{4} -console.log(myOtherVariable); //{5} diff --git a/examples/chapter01_02/03-Operators.html b/examples/chapter01_02/03-Operators.html deleted file mode 100755 index 2502aa78..00000000 --- a/examples/chapter01_02/03-Operators.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter01_02/03-Operators.js b/examples/chapter01_02/03-Operators.js deleted file mode 100755 index 7895b17b..00000000 --- a/examples/chapter01_02/03-Operators.js +++ /dev/null @@ -1,65 +0,0 @@ -// @ts-check -/* eslint-disable */ - -/* Arithmetic operators */ -var num = 0; // {1} -console.log('num value is ' + num); - -num = num + 2; -console.log('New num value is ' + num); - -num = num * 3; -console.log('New num value is ' + num); - -num = num / 2; -console.log('New num value is ' + num); - -num++; -num--; - -console.log('New num value is ' + num); - -console.log('num mod 2 value is ' + num % 2); - -/* Assignment operators */ -num += 1; -num -= 2; -num *= 3; -num /= 2; -num %= 3; - -console.log('New num value is ' + num); - -/* Assignment operators */ -console.log('num == 1 : ' + (num == 1)); -console.log('num === 1 : ' + (num === 1)); -console.log('num != 1 : ' + (num != 1)); -console.log('num > 1 : ' + (num > 1)); -console.log('num < 1 : ' + (num < 1)); -console.log('num >= 1 : ' + (num >= 1)); -console.log('num <= 1 : ' + (num <= 1)); - -/* Logical operators */ -console.log('true && false : ' + (true && false)); -console.log('true || false : ' + (true || false)); -console.log('!true : ' + !true); - -/* Bitwise operators */ -console.log('5 & 1:', 5 & 1); // same as 0101 & 0001 (result 0001 / 1) -console.log('5 | 1:', 5 | 1); // same as 0101 | 0001 (result 0101 / 5) -console.log('~ 5:', ~5); // same as ~0101 (result 1010 / 10) -console.log('5 ^ 1:', 5 ^ 1); // same as 0101 ^ 0001 (result 0100 / 4) -console.log('5 << 1:', 5 << 1); // same as 0101 << 1 (result 1010 / 10) -console.log('5 >> 1:', 5 >> 1); // same as 0101 >> 1 (result 0010 / 2) - -/* typeOf */ -console.log('typeof num:', typeof num); -console.log('typeof Packt:', typeof 'Packt'); -console.log('typeof true:', typeof true); -console.log('typeof [1,2,3]:', typeof [1, 2, 3]); -console.log('typeof {name:John}:', typeof { name: 'John' }); - -/* delete */ -var myObj = { name: 'John', age: 21 }; -delete myObj.age; -console.log(myObj); // Object {name: "John"} diff --git a/examples/chapter01_02/04-TruthyFalsy.html b/examples/chapter01_02/04-TruthyFalsy.html deleted file mode 100755 index 9b20f161..00000000 --- a/examples/chapter01_02/04-TruthyFalsy.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter01_02/04-TruthyFalsy.js b/examples/chapter01_02/04-TruthyFalsy.js deleted file mode 100644 index 0090ee74..00000000 --- a/examples/chapter01_02/04-TruthyFalsy.js +++ /dev/null @@ -1,27 +0,0 @@ -// @ts-check -/* eslint-disable */ - -function testTruthy(val) { - return val ? console.log('truthy') : console.log('falsy'); -} - -testTruthy(true); // true -testTruthy(false); // false -testTruthy(new Boolean(false)); // true (object is always true) - -testTruthy(''); // false -testTruthy('a'); // true -testTruthy('Packt'); // true -testTruthy(new String('')); // true (object is always true) - -testTruthy(1); // true -testTruthy(-1); // true -testTruthy(NaN); // false -testTruthy(new Number(NaN)); // true (object is always true) - -testTruthy({}); // true (object is always true) - -var obj = { name: 'John' }; -testTruthy(obj); // true -testTruthy(obj.name); // true -testTruthy(obj.age); // false (property age does not exist) diff --git a/examples/chapter01_02/05-EqualsOperators.html b/examples/chapter01_02/05-EqualsOperators.html deleted file mode 100755 index bf26fbf3..00000000 --- a/examples/chapter01_02/05-EqualsOperators.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter01_02/05-EqualsOperators.js b/examples/chapter01_02/05-EqualsOperators.js deleted file mode 100644 index d5b43ecc..00000000 --- a/examples/chapter01_02/05-EqualsOperators.js +++ /dev/null @@ -1,39 +0,0 @@ -// @ts-check -/* eslint-disable */ - -// Packt == true - -console.log('packt' ? true : false); -// outputs true - -console.log('packt' == true); -// 1 - converts Boolean using toNumber -// 'packt' == 1 -// 2 - converts String using toNumber -// NaN == 1 -// outputs false - -console.log('packt' == false); -// 1 - converts Boolean using toNumber -// 'packt' == 0 -// 2 - converts String using toNumber -// NaN == 0 -// outputs false - -console.log([0] == true); -// 1 - converts Boolean using toNumber -// [0] == 1 -// 2 - converts Object using toPrimitive -// 2.1 - [0].valueOf() is not primitive -// 2.2 - [0].toString is 0 -// 0 == 1 -// outputs false - -//* ****************************** === -console.log('packt' === true); // false - -console.log('packt' === 'packt'); // true - -var person1 = { name: 'John' }; -var person2 = { name: 'John' }; -console.log(person1 === person2); // false, different objects diff --git a/examples/chapter01_02/06-ConditionalStatements.html b/examples/chapter01_02/06-ConditionalStatements.html deleted file mode 100755 index 885a409b..00000000 --- a/examples/chapter01_02/06-ConditionalStatements.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter01_02/06-ConditionalStatements.js b/examples/chapter01_02/06-ConditionalStatements.js deleted file mode 100644 index c939967c..00000000 --- a/examples/chapter01_02/06-ConditionalStatements.js +++ /dev/null @@ -1,54 +0,0 @@ -// @ts-check -/* eslint-disable */ - -/* Example 01 - if */ -var num = 1; -if (num === 1) { - console.log('num is equal to 1'); -} - -/* Example 02 - if-else */ -var num = 0; -if (num === 1) { - console.log('num is equal to 1'); -} else { - console.log('num is not equal to 1, the value of num is ' + num); -} - -/* Example 03 - if-else-if-else... */ -var month = 5; -if (month === 1) { - console.log('January'); -} else if (month === 2) { - console.log('February'); -} else if (month === 3) { - console.log('March'); -} else { - console.log('Month is not January, February or March'); -} - -/* Example 04 - switch */ -var month = 5; -switch (month) { - case 1: - console.log('January'); - break; - case 2: - console.log('February'); - break; - case 3: - console.log('March'); - break; - default: - console.log('Month is not January, February or March'); -} - -/* Example 05 - ternary operator - if..else */ -if (num === 1) { - num--; -} else { - num++; -} - -// is the same as -num === 1 ? num-- : num++; diff --git a/examples/chapter01_02/07-Loops.html b/examples/chapter01_02/07-Loops.html deleted file mode 100755 index e87a478f..00000000 --- a/examples/chapter01_02/07-Loops.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter01_02/07-Loops.js b/examples/chapter01_02/07-Loops.js deleted file mode 100755 index 9d12b19e..00000000 --- a/examples/chapter01_02/07-Loops.js +++ /dev/null @@ -1,24 +0,0 @@ -// @ts-check -/* eslint-disable */ - -console.log('**** for example ****'); -/* for - example */ -for (var i = 0; i < 10; i++) { - console.log(i); -} - -console.log('**** while example ****'); -/* while - example */ -var i = 0; -while (i < 10) { - console.log(i); - i++; -} - -console.log('**** do-while example ****'); -/* do-while - example */ -var i = 0; -do { - console.log(i); - i++; -} while (i < 10); diff --git a/examples/chapter01_02/08-Functions.html b/examples/chapter01_02/08-Functions.html deleted file mode 100755 index cde89bcf..00000000 --- a/examples/chapter01_02/08-Functions.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter01_02/08-Functions.js b/examples/chapter01_02/08-Functions.js deleted file mode 100644 index 52d5f9c8..00000000 --- a/examples/chapter01_02/08-Functions.js +++ /dev/null @@ -1,27 +0,0 @@ -// @ts-check -/* eslint-disable */ - -function sayHello() { - console.log('Hello!'); -} - -sayHello(); - -/* function with parameter */ -function output(text) { - console.log(text); -} - -output('Hello!'); - -output('Hello!', 'Other text'); - -output(); - -/* function using the return statement */ -function sum(num1, num2) { - return num1 + num2; -} - -var result = sum(1, 2); -output(result); diff --git a/examples/chapter01_02/09-ObjectOrientedJS.html b/examples/chapter01_02/09-ObjectOrientedJS.html deleted file mode 100644 index cfbe1a04..00000000 --- a/examples/chapter01_02/09-ObjectOrientedJS.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter01_02/09-ObjectOrientedJS.js b/examples/chapter01_02/09-ObjectOrientedJS.js deleted file mode 100644 index 28c15a1c..00000000 --- a/examples/chapter01_02/09-ObjectOrientedJS.js +++ /dev/null @@ -1,42 +0,0 @@ -// @ts-check -/* eslint-disable */ - -/* Object example 1 */ -var obj = new Object(); - -/* Object example 2 */ -var obj = {}; - -obj = { - name: { - first: 'Gandalf', - last: 'the Grey' - }, - address: 'Middle Earth' -}; - -/* Object example 3 */ -function Book(title, pages, isbn) { - this.title = title; - this.pages = pages; - this.isbn = isbn; - this.printIsbn = function() { - console.log(this.isbn); - }; -} - -var book = new Book('title', 'pag', 'isbn'); - -console.log(book.title); // outputs the book title - -book.title = 'new title'; // update the value of the book title - -console.log(book.title); // outputs the updated value - -Book.prototype.printTitle = function() { - console.log(this.title); -}; - -book.printTitle(); - -book.printIsbn(); diff --git a/examples/chapter01_02/10-ES2015-ES6-letconst.html b/examples/chapter01_02/10-ES2015-ES6-letconst.html deleted file mode 100644 index ba8c81d0..00000000 --- a/examples/chapter01_02/10-ES2015-ES6-letconst.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter01_02/10-ES2015-ES6-letconst.js b/examples/chapter01_02/10-ES2015-ES6-letconst.js deleted file mode 100644 index 0295e187..00000000 --- a/examples/chapter01_02/10-ES2015-ES6-letconst.js +++ /dev/null @@ -1,31 +0,0 @@ -// @ts-check -/* eslint-disable */ - -//* ****** EcmaScript 2015 (ES6): let and const keywords - -//* ****** EcmaScript 2015 (ES6): let is the new var (https://goo.gl/he0udZ) -var framework = 'Angular'; -var framework = 'React'; -console.log(framework); - -let language = 'JavaScript!'; // {1} -// let language = 'Ruby!'; // {2} - throws error -console.log(language); - - -//* ****** EcmaScript 2015 (ES6): const (https://goo.gl/YUQj3r) -const PI = 3.141593; -// PI = 3.0; //throws error -console.log(PI); - -const jsFramework = { - name: 'Angular' -}; -jsFramework.name = 'React'; - -// error, cannot reassign object reference -/* -jsFramework = { - name: 'Vue' -}; -*/ diff --git a/examples/chapter01_02/11-ES2015-ES6-variableScope.html b/examples/chapter01_02/11-ES2015-ES6-variableScope.html deleted file mode 100644 index b4d3476f..00000000 --- a/examples/chapter01_02/11-ES2015-ES6-variableScope.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter01_02/11-ES2015-ES6-variableScope.html.js b/examples/chapter01_02/11-ES2015-ES6-variableScope.html.js deleted file mode 100644 index 3f5f022a..00000000 --- a/examples/chapter01_02/11-ES2015-ES6-variableScope.html.js +++ /dev/null @@ -1,46 +0,0 @@ -// @ts-check -/* eslint-disable */ - -//* ****** EcmaScript 2015 (ES6): variables scope (https://goo.gl/NbsVvg) -let movie = 'Lord of the Rings'; // {1} -// var movie = 'Batman v Superman'; //throws error, variable movie already declared - -function starWarsFan() { - const movie = 'Star Wars'; // {2} - return movie; -} - -function marvelFan() { - movie = 'The Avengers'; // {3} - return movie; -} - -function blizzardFan() { - const isFan = true; - let phrase = 'Warcraft'; // {4} - console.log('Before if: ' + phrase); - if (isFan) { - let phrase = 'initial text'; // {5} - phrase = 'For the Horde!'; // {6} - console.log('Inside if: ' + phrase); - } - phrase = 'For the Alliance!'; // {7} - console.log('After if: ' + phrase); -} - -console.log(movie); // {8} -console.log(starWarsFan()); // {9} -console.log(marvelFan()); // {10} -console.log(movie); // {11} -blizzardFan(); // {12} - -// output -// Lord of the Rings -// Star Wars -// The Avengers -// The Avengers -// Before if: Warcraft -// Inside if: For the Horde! -// After if: For the Alliance! - - diff --git a/examples/chapter01_02/12-ES2015-ES6-StringTemplates.html b/examples/chapter01_02/12-ES2015-ES6-StringTemplates.html deleted file mode 100644 index c7eb7ef3..00000000 --- a/examples/chapter01_02/12-ES2015-ES6-StringTemplates.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter01_02/12-ES2015-ES6-StringTemplates.js b/examples/chapter01_02/12-ES2015-ES6-StringTemplates.js deleted file mode 100644 index b1a65b40..00000000 --- a/examples/chapter01_02/12-ES2015-ES6-StringTemplates.js +++ /dev/null @@ -1,14 +0,0 @@ -// @ts-check -/* eslint-disable */ - -//* ****** EcmaScript 2015 (ES6): Template literals (https://goo.gl/4N36CS) -const book = { - name: 'Learning JavaScript DataStructures and Algorithms' -}; - -console.log('You are reading ' + book.name + '.,\n and this is a new line\n and so is this.'); - -console.log(`You are reading ${book.name}., - and this is a new line - and so is this.`); - diff --git a/examples/chapter01_02/13-ES2015-ES6-ArrowFunctions.html b/examples/chapter01_02/13-ES2015-ES6-ArrowFunctions.html deleted file mode 100644 index 0a922d1c..00000000 --- a/examples/chapter01_02/13-ES2015-ES6-ArrowFunctions.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter01_02/13-ES2015-ES6-ArrowFunctions.js b/examples/chapter01_02/13-ES2015-ES6-ArrowFunctions.js deleted file mode 100644 index 8f4775f3..00000000 --- a/examples/chapter01_02/13-ES2015-ES6-ArrowFunctions.js +++ /dev/null @@ -1,23 +0,0 @@ -// @ts-check -/* eslint-disable */ - -//* ****** EcmaScript 2015 (ES6): arrow functions (https://goo.gl/nM414v) -var circleAreaES5 = function circleArea(r) { - var PI = 3.14; - var area = PI * r * r; - return area; -}; -console.log(circleAreaES5(2)); - -const circleArea = r => { // {1} - const PI = 3.14; - const area = PI * r * r; - return area; -}; -console.log(circleArea(2)); - -const circleArea2 = r => 3.14 * r * r; -console.log(circleArea2(2)); - -const hello = () => console.log('hello!'); -hello(); diff --git a/examples/chapter01_02/14-ES2015-ES6-ParameterHandling.html b/examples/chapter01_02/14-ES2015-ES6-ParameterHandling.html deleted file mode 100644 index 703cf2c9..00000000 --- a/examples/chapter01_02/14-ES2015-ES6-ParameterHandling.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter01_02/14-ES2015-ES6-ParameterHandling.js b/examples/chapter01_02/14-ES2015-ES6-ParameterHandling.js deleted file mode 100644 index 66a6e089..00000000 --- a/examples/chapter01_02/14-ES2015-ES6-ParameterHandling.js +++ /dev/null @@ -1,48 +0,0 @@ -// @ts-check -/* eslint-disable */ - -//* ****** EcmaScript 2015 (ES6): Default Parameter Values (https://goo.gl/AP5EYb) -function sum(x = 1, y = 2, z = 3) { - return x + y + z; -} -console.log(sum(4, 2)); // outputs 9 - -// function above is the same as -function sum2(x, y, z) { - if (x === undefined) x = 1; - if (y === undefined) y = 2; - if (z === undefined) z = 3; - return x + y + z; -} -console.log(sum2(4, 2)); // outputs 9 - -// or -function sum3() { - var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; - var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3; - - return x + y + z; -} -console.log(sum3(4, 2)); // outputs 9 - -//* ****** EcmaScript 6: spread operator ('...') (https://goo.gl/8equk5) -let params = [3, 4, 5]; -console.log(sum(...params)); // ES2015 -console.log(sum.apply(undefined, params)); // ES5 - -let numbers = [1, 2, ...params]; // pushing values into array -console.log(numbers); - -//* ****** EcmaScript 6: rest parameter ('...') (https://goo.gl/LaJZqU) -function restParamaterFunction(x, y, ...a) { - return (x + y) * a.length; -} -console.log(restParamaterFunction(1, 2, 'hello', true, 7)); // outputs 9; - -// code above is the same as ES5: -function restParamaterFunction2(x, y) { - var a = Array.prototype.slice.call(arguments, 2); - return (x + y) * a.length; -} -console.log(restParamaterFunction2(1, 2, 'hello', true, 7)); diff --git a/examples/chapter01_02/15-ES2015-ES6-EnhancedObjectProperties.html b/examples/chapter01_02/15-ES2015-ES6-EnhancedObjectProperties.html deleted file mode 100644 index c915b7d8..00000000 --- a/examples/chapter01_02/15-ES2015-ES6-EnhancedObjectProperties.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter01_02/15-ES2015-ES6-EnhancedObjectProperties.js b/examples/chapter01_02/15-ES2015-ES6-EnhancedObjectProperties.js deleted file mode 100644 index 00ec03ad..00000000 --- a/examples/chapter01_02/15-ES2015-ES6-EnhancedObjectProperties.js +++ /dev/null @@ -1,37 +0,0 @@ -// @ts-check -/* eslint-disable */ - -//* ****** EcmaScript 2015 (ES6): Destructuring Assignment + Property Shorthand (https://goo.gl/VsLecp ) -let [x, y] = ['a', 'b']; -let obj = { x, y }; -console.log(obj); // { x: "a", y: "b" } - -// swap (https://goo.gl/EyFAII) -[x, y] = [y, x]; -var temp = x; -x = y; -y = temp; - -// code above is the same as -var x2 = 'a'; -var y2 = 'b'; -var obj2 = { x2: x2, y2: y2 }; -console.log(obj2); // { x: "a", y: "b" } - -// Method Properties (https://goo.gl/DKU2PN) -const hello = { - name: 'abcdef', - printHello() { - console.log('Hello'); - } -}; -console.log(hello.printHello()); - -// code above is the same as: -var hello2 = { - name: 'abcdef', - printHello: function printHello() { - console.log('Hello'); - } -}; -console.log(hello2.printHello()); diff --git a/examples/chapter01_02/16-ES2015-ES6-Classes.html b/examples/chapter01_02/16-ES2015-ES6-Classes.html deleted file mode 100644 index 95f0d6d5..00000000 --- a/examples/chapter01_02/16-ES2015-ES6-Classes.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter01_02/16-ES2015-ES6-Classes.js b/examples/chapter01_02/16-ES2015-ES6-Classes.js deleted file mode 100644 index c088b6bb..00000000 --- a/examples/chapter01_02/16-ES2015-ES6-Classes.js +++ /dev/null @@ -1,89 +0,0 @@ -// @ts-check -/* eslint-disable */ - -//* ****** EcmaScript 2015 (ES6): classes (https://goo.gl/UhK1n4) -class Book { - constructor(title, pages, isbn) { - this.title = title; - this.pages = pages; - this.isbn = isbn; - } - printIsbn() { - console.log(this.isbn); - } -} - -let book = new Book('title', 'pag', 'isbn'); - -console.log(book.title); // outputs the book title - -book.title = 'new title'; // update the value of the book title - -console.log(book.title); // outputs the book title - -// inheritance (https://goo.gl/hgQvo9) -class ITBook extends Book { // {1} - constructor(title, pages, isbn, technology) { - super(title, pages, isbn); // {2} - this.technology = technology; - } - - printTechnology() { - console.log(this.technology); - } -} - -let jsBook = new ITBook( - 'Learning JS Algorithms', - '200', - '1234567890', - 'JavaScript' -); - -console.log(jsBook.title); -console.log(jsBook.printTechnology()); - -// getter and setters (https://goo.gl/SMRYsv) -class Person { - constructor(name) { - this._name = name; // {1} - } - - get name() { // {2} - return this._name; - } - - set name(value) { // {3} - this._name = value; - } -} - -let lotrChar = new Person('Frodo'); -console.log(lotrChar.name); // {4} -lotrChar.name = 'Gandalf'; // {5} -console.log(lotrChar.name); -lotrChar._name = 'Sam'; // {6} -console.log(lotrChar.name); - -// using symbols for private atributes -var _name = Symbol(); -class Person2 { - constructor(name) { - this[_name] = name; - } - - get name() { - return this[_name]; - } - - set name(value) { - this[_name] = value; - } -} - -let lotrChar2 = new Person2('Frodo'); -console.log(lotrChar2.name); -lotrChar2.name = 'Gandalf'; -console.log(lotrChar2.name); - -console.log(Object.getOwnPropertySymbols(lotrChar2)); diff --git a/examples/chapter01_02/17-Book.js b/examples/chapter01_02/17-Book.js deleted file mode 100644 index 8b8b4f48..00000000 --- a/examples/chapter01_02/17-Book.js +++ /dev/null @@ -1,11 +0,0 @@ -// @ts-check -/* eslint-disable */ - -export default class Book { - constructor(title) { - this.title = title; - } - printTitle() { - console.log(this.title); - } -} diff --git a/examples/chapter01_02/17-CalcArea.js b/examples/chapter01_02/17-CalcArea.js deleted file mode 100644 index 085e9ef0..00000000 --- a/examples/chapter01_02/17-CalcArea.js +++ /dev/null @@ -1,9 +0,0 @@ -// @ts-check -/* eslint-disable */ - -export const circleArea = r => 3.14 * (r ** 2); - -export const squareArea = s => s * s; - -// export { circleArea, squareArea }; // {1} -export { circleArea as circle, squareArea as square }; diff --git a/examples/chapter01_02/17-ES2015-ES6-Modules-node.js b/examples/chapter01_02/17-ES2015-ES6-Modules-node.js deleted file mode 100644 index 7512f4ca..00000000 --- a/examples/chapter01_02/17-ES2015-ES6-Modules-node.js +++ /dev/null @@ -1,11 +0,0 @@ -// @ts-check -/* eslint-disable */ - -const area = require('./lib/17-CalcArea'); -const Book = require('./lib/17-Book'); - -console.log(area.circle(2)); -console.log(area.square(2)); - -const myBook = new Book('some title'); -myBook.printTitle(); diff --git a/examples/chapter01_02/17-ES2015-ES6-Modules.html b/examples/chapter01_02/17-ES2015-ES6-Modules.html deleted file mode 100644 index fb2709ae..00000000 --- a/examples/chapter01_02/17-ES2015-ES6-Modules.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter01_02/17-ES2015-ES6-Modules.js b/examples/chapter01_02/17-ES2015-ES6-Modules.js deleted file mode 100644 index da26b541..00000000 --- a/examples/chapter01_02/17-ES2015-ES6-Modules.js +++ /dev/null @@ -1,20 +0,0 @@ -// @ts-check -/* eslint-disable */ -// import { circleArea, squareArea } from './17-CalcArea'; // {2} -// import { circleArea as circle } from './17-CalcArea'; - -// console.log(circleArea(2)); -// console.log(squareArea(2)); - -/* Different way of importing the module */ -// import * as area from './17-CalcArea'; -// import Book from './17-Book'; - -import * as area from './17-CalcArea.js'; // we need the .js to run this code in the browser -import Book from './17-Book.js'; - -console.log(area.circle(2)); -console.log(area.square(2)); - -const myBook = new Book('some title'); -myBook.printTitle(); diff --git a/examples/chapter01_02/17-ES2015-Modules-node/17-Book.mjs b/examples/chapter01_02/17-ES2015-Modules-node/17-Book.mjs deleted file mode 100644 index 076f2bb0..00000000 --- a/examples/chapter01_02/17-ES2015-Modules-node/17-Book.mjs +++ /dev/null @@ -1,8 +0,0 @@ -export default class Book { - constructor(title) { - this.title = title; - } - printTitle() { - console.log(this.title); - } -} diff --git a/examples/chapter01_02/17-ES2015-Modules-node/17-CalcArea.mjs b/examples/chapter01_02/17-ES2015-Modules-node/17-CalcArea.mjs deleted file mode 100644 index ca4454a5..00000000 --- a/examples/chapter01_02/17-ES2015-Modules-node/17-CalcArea.mjs +++ /dev/null @@ -1,6 +0,0 @@ -export const circleArea = r => 3.14 * (r ** 2); - -export const squareArea = s => s * s; - -// export { circleArea, squareArea }; // {1} -export { circleArea as circle, squareArea as square }; diff --git a/examples/chapter01_02/17-ES2015-Modules-node/17-ES2015-ES6-Modules.mjs b/examples/chapter01_02/17-ES2015-Modules-node/17-ES2015-ES6-Modules.mjs deleted file mode 100644 index 53817060..00000000 --- a/examples/chapter01_02/17-ES2015-Modules-node/17-ES2015-ES6-Modules.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import * as area from './17-CalcArea.mjs'; -import Book from './17-Book.mjs'; - -console.log(area.circle(2)); -console.log(area.square(2)); - -const myBook = new Book('some title'); -myBook.printTitle(); diff --git a/examples/chapter01_02/18-ES2016-ES7-ExponentiationOperator.html b/examples/chapter01_02/18-ES2016-ES7-ExponentiationOperator.html deleted file mode 100644 index 129d0193..00000000 --- a/examples/chapter01_02/18-ES2016-ES7-ExponentiationOperator.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter01_02/18-ES2016-ES7-ExponentiationOperator.js b/examples/chapter01_02/18-ES2016-ES7-ExponentiationOperator.js deleted file mode 100644 index 705933de..00000000 --- a/examples/chapter01_02/18-ES2016-ES7-ExponentiationOperator.js +++ /dev/null @@ -1,12 +0,0 @@ -// @ts-check -/* eslint-disable */ - -//* ****** EcmaScript 2016 (ES7): Exponentiation operator (https://goo.gl/Z6dCFB) -let r = 2; -const area = 3.14 * r * r; -const area2 = 3.14 * Math.pow(r, 2); -const area3 = 3.14 * r ** 2; - -console.log(area); -console.log(area2); -console.log(area3); diff --git a/examples/chapter01_02/lib/17-Book.js b/examples/chapter01_02/lib/17-Book.js deleted file mode 100644 index 802d4191..00000000 --- a/examples/chapter01_02/lib/17-Book.js +++ /dev/null @@ -1,63 +0,0 @@ -(function (global, factory) { - if (typeof define === "function" && define.amd) { - define(["module", "exports"], factory); - } else if (typeof exports !== "undefined") { - factory(module, exports); - } else { - var mod = { - exports: {} - }; - factory(mod, mod.exports); - global.Book = mod.exports; - } -})(this, function (module, exports) { - "use strict"; - - Object.defineProperty(exports, "__esModule", { - value: true - }); - - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } - - var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - }(); - - var Book = function () { - function Book(title) { - _classCallCheck(this, Book); - - this.title = title; - } - - _createClass(Book, [{ - key: "printTitle", - value: function printTitle() { - console.log(this.title); - } - }]); - - return Book; - }(); - - exports.default = Book; - module.exports = exports["default"]; -}); \ No newline at end of file diff --git a/examples/chapter01_02/lib/17-CalcArea.js b/examples/chapter01_02/lib/17-CalcArea.js deleted file mode 100644 index 63335f1d..00000000 --- a/examples/chapter01_02/lib/17-CalcArea.js +++ /dev/null @@ -1,30 +0,0 @@ -(function (global, factory) { - if (typeof define === "function" && define.amd) { - define(["exports"], factory); - } else if (typeof exports !== "undefined") { - factory(exports); - } else { - var mod = { - exports: {} - }; - factory(mod.exports); - global.CalcArea = mod.exports; - } -})(this, function (exports) { - "use strict"; - - Object.defineProperty(exports, "__esModule", { - value: true - }); - var circleArea = exports.circleArea = function circleArea(r) { - return 3.14 * Math.pow(r, 2); - }; - - var squareArea = exports.squareArea = function squareArea(s) { - return s * s; - }; - - // export { circleArea, squareArea }; // {1} - exports.circle = circleArea; - exports.square = squareArea; -}); \ No newline at end of file diff --git a/examples/chapter01_02/lib/17-ES2015-ES6-Modules-bundle.js b/examples/chapter01_02/lib/17-ES2015-ES6-Modules-bundle.js deleted file mode 100644 index bc101140..00000000 --- a/examples/chapter01_02/lib/17-ES2015-ES6-Modules-bundle.js +++ /dev/null @@ -1,158 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o b.age ? 1 : -1; - }; - return MyObject; -}()); -function compareTwoObjects(a, b) { - console.log(a.compareTo(b)); - console.log(b.compareTo(a)); -} diff --git a/examples/chapter03/01-Introduction.html b/examples/chapter03/01-Introduction.html deleted file mode 100755 index 86731b13..00000000 --- a/examples/chapter03/01-Introduction.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter03/01-Introduction.js b/examples/chapter03/01-Introduction.js deleted file mode 100755 index 59311202..00000000 --- a/examples/chapter03/01-Introduction.js +++ /dev/null @@ -1,26 +0,0 @@ -// @ts-check - -const averageTempJan = 31.9; -const averageTempFeb = 35.3; -const averageTempMar = 42.4; -const averageTempApr = 52; -const averageTempMay = 60.8; - -const averageTemp = []; -averageTemp[0] = 31.9; -averageTemp[1] = 35.3; -averageTemp[2] = 42.4; -averageTemp[3] = 52; -averageTemp[4] = 60.8; - -console.log('averageTempJan', averageTempJan); -console.log('averageTempFeb', averageTempFeb); -console.log('averageTempMar', averageTempMar); -console.log('averageTempApr', averageTempApr); -console.log('averageTempMay', averageTempMay); - -console.log('averageTemp[0]', averageTemp[0]); -console.log('averageTemp[1]', averageTemp[1]); -console.log('averageTemp[2]', averageTemp[2]); -console.log('averageTemp[3]', averageTemp[3]); -console.log('averageTemp[4]', averageTemp[4]); diff --git a/examples/chapter03/02-CreatingAndInitialingArrays.html b/examples/chapter03/02-CreatingAndInitialingArrays.html deleted file mode 100755 index 7a51f1c9..00000000 --- a/examples/chapter03/02-CreatingAndInitialingArrays.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter03/02-CreatingAndInitialingArrays.js b/examples/chapter03/02-CreatingAndInitialingArrays.js deleted file mode 100755 index b07aaed3..00000000 --- a/examples/chapter03/02-CreatingAndInitialingArrays.js +++ /dev/null @@ -1,36 +0,0 @@ -// @ts-check -/* eslint-disable */ - -let daysOfWeek = new Array(); // {1} - -daysOfWeek = new Array(7); // {2} - -daysOfWeek = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); // {3} - -// preferred -daysOfWeek = []; - -daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; // {3} - -console.log('daysOfWeek.length', daysOfWeek.length); - -for (let i = 0; i < daysOfWeek.length; i++) { - console.log(`daysOfWeek[${i}]`, daysOfWeek[i]); -} - -// fibonacci numbers -// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... -const fibonacci = []; // {1} -fibonacci[1] = 1; // {2} -fibonacci[2] = 1; // {3} - -for (let i = 3; i < 20; i++) { - fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]; // //{4} -} - -for (let i = 1; i < fibonacci.length; i++) { // {5} - console.log(`fibonacci[${i}]`, fibonacci[i]); // {6} -} - -// instead of {5} and {6} we can simply use -console.log('fibonacci', fibonacci); diff --git a/examples/chapter03/03-AddingRemovingElements.html b/examples/chapter03/03-AddingRemovingElements.html deleted file mode 100755 index 639a368e..00000000 --- a/examples/chapter03/03-AddingRemovingElements.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter03/03-AddingRemovingElements.js b/examples/chapter03/03-AddingRemovingElements.js deleted file mode 100755 index 9a12e833..00000000 --- a/examples/chapter03/03-AddingRemovingElements.js +++ /dev/null @@ -1,105 +0,0 @@ -// @ts-check -/* eslint-disable */ - -function logArray(message = '', array) { - const output = `${message} => (${array.length}) [${array.join(', ')}]`; - document.writeln(`

${output}

`); - console.log(message, array); -} - -let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; - -console.log('Original array', numbers); - -function printArray(myArray) { - for (let i = 0; i < myArray.length; i++) { - console.log(myArray[i]); - } -} - -/****************************** Inserting an element in the end of the Array */ - -// add a new element to the numbers array -numbers[numbers.length] = 10; -console.log('Add 10 to the end', numbers); - -numbers.push(11); -console.log('Add 11 with push', numbers); - -numbers.push(12, 13); -console.log('Add 12 and 13 with push', numbers); - - -// insert first position manually -Array.prototype.insertFirstPosition = function(value) { - for (let i = this.length; i >= 0; i--) { - this[i] = this[i - 1]; - } - this[0] = value; -}; - -numbers.insertFirstPosition(-1); -console.log('Add -1 with insertFirstPosition', numbers); -// printArray(numbers); - -// using method unshift -numbers.unshift(-2); -console.log('Add -2 with unshift', numbers); -//printArray(numbers); - -numbers.unshift(-4, -3); -console.log('Add -4 and -3 with unshift', numbers); -// printArray(numbers); - -// ************** Removing elements - -numbers.pop(); -console.log('Removed last value with pop', numbers); - -for (let i = 0; i < numbers.length; i++) { - numbers[i] = numbers[i + 1]; -} - -console.log('Removed first value manually', numbers); -console.log('Lenght after value removed manually', numbers.length); - -//reset array -numbers = [-4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; - -Array.prototype.reIndex = function(myArray) { - const newArray = []; - for(let i = 0; i < myArray.length; i++ ) { - if (myArray[i] !== undefined) { - // console.log(myArray[i]); - newArray.push(myArray[i]); - } - } - return newArray; -} - -// remove first position manually and reIndex -Array.prototype.removeFirstPosition = function() { - for (let i = 0; i < this.length; i++) { - this[i] = this[i + 1]; - } - return this.reIndex(this); -}; - -numbers = numbers.removeFirstPosition(); -console.log('Removed first with removeFirstPosition + reIndex', numbers); - -// using method shift -numbers.shift(); -console.log('Removed first with shift', numbers); -console.log('Lenght after removed first with shift', numbers.length); - -//* *** Removing and Adding elements from the middle of the array or specific position -// splice method - parameter (index, howManyPositionsToBeRemoved, item1...itemX) -numbers.splice(5, 3); -console.log('Removing 3 elements (3, 4, 5) starting index 5', numbers); - -numbers.splice(5, 0, 2, 3, 4); -console.log('Adding 3 elements (2, 3, 4) starting index 5', numbers); - -numbers.splice(5, 3, 2, 3, 4); -console.log('Removing 3 elements starting index 5 and adding (2, 3, 4)', numbers); diff --git a/examples/chapter03/04-TwoDimensionalMultiDimensional.html b/examples/chapter03/04-TwoDimensionalMultiDimensional.html deleted file mode 100755 index 3e158027..00000000 --- a/examples/chapter03/04-TwoDimensionalMultiDimensional.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter03/04-TwoDimensionalMultiDimensional.js b/examples/chapter03/04-TwoDimensionalMultiDimensional.js deleted file mode 100755 index 97dfb941..00000000 --- a/examples/chapter03/04-TwoDimensionalMultiDimensional.js +++ /dev/null @@ -1,78 +0,0 @@ -// @ts-check -/* eslint-disable */ - -let averageTempDay1 = [72, 75, 79, 79, 81, 81]; -let averageTempDay2 = [81, 79, 75, 75, 73, 72]; - -let averageTemp = []; - -// same as -averageTemp[0] = [72, 75, 79, 79, 81, 81]; -averageTemp[1] = [81, 79, 75, 75, 73, 73]; - -function printMatrix(myMatrix) { - for (let i = 0; i < myMatrix.length; i++) { - for (let j = 0; j < myMatrix[i].length; j++) { - console.log(myMatrix[i][j]); - } - } -} - -// printMatrix(averageTemp); -console.log('averageTemp two-dimensional array:'); - -// same as - -// day 1 -averageTemp[0] = []; -averageTemp[0][0] = 72; -averageTemp[0][1] = 75; -averageTemp[0][2] = 79; -averageTemp[0][3] = 79; -averageTemp[0][4] = 81; -averageTemp[0][5] = 81; -// day 2 -averageTemp[1] = []; -averageTemp[1][0] = 81; -averageTemp[1][1] = 79; -averageTemp[1][2] = 75; -averageTemp[1][3] = 75; -averageTemp[1][4] = 73; -averageTemp[1][5] = 73; - -// printMatrix(averageTemp); -console.table(averageTemp); - -//* * Multidimensional Matrix - -// Matrix 3x3x3 - Cube - -const matrix3x3x3 = []; -for (let i = 0; i < 3; i++) { - matrix3x3x3[i] = []; - for (let j = 0; j < 3; j++) { - matrix3x3x3[i][j] = []; - for (let z = 0; z < 3; z++) { - matrix3x3x3[i][j][z] = i + j + z; - } - } -} - -for (let i = 0; i < matrix3x3x3.length; i++) { - for (let j = 0; j < matrix3x3x3[i].length; j++) { - for (let z = 0; z < matrix3x3x3[i][j].length; z++) { - console.log(matrix3x3x3[i][j][z]); - } - } -} - -// user-friendly-output -const matrix3x3x3Output = []; -for (let i = 0; i < 3; i++) { - matrix3x3x3Output[i] = []; - for (let j = 0; j < 3; j++) { - matrix3x3x3Output[i][j] = `[${matrix3x3x3[i][j].join(', ')}]`; - } -} -console.log('matrix3x3x3 three-dimensional array:'); -console.table(matrix3x3x3Output); diff --git a/examples/chapter03/05-ArrayMethods.html b/examples/chapter03/05-ArrayMethods.html deleted file mode 100755 index a4109697..00000000 --- a/examples/chapter03/05-ArrayMethods.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/chapter03/05-ArrayMethods.js b/examples/chapter03/05-ArrayMethods.js deleted file mode 100755 index 67d97602..00000000 --- a/examples/chapter03/05-ArrayMethods.js +++ /dev/null @@ -1,47 +0,0 @@ -// @ts-check - -//* ************** Joining multiple arrays -const zero = 0; -const positiveNumbers = [1, 2, 3]; -const negativeNumbers = [-3, -2, -1]; -let numbers = negativeNumbers.concat(zero, positiveNumbers); - -console.log('zero', zero); -console.log('positiveNumbers', positiveNumbers); -console.log('negativeNumbers', negativeNumbers); -console.log('negativeNumbers.concat(zero, positiveNumbers)', numbers); - -/* function isEven(x) { - // returns true if x is a multiple of 2. - console.log(x); - return x % 2 === 0 ? true : false; -} */ // ES5 syntax -const isEven = x => x % 2 === 0; - -numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; -console.log('numbers', numbers); - -// it is going to execute the function only once -console.log('numbers.every(isEven)', numbers.every(isEven)); - -// is going to execute the function twice -console.log('numbers.some(isEven)', numbers.some(isEven)); - -/* numbers.forEach(function(x) { - console.log(x % 2 == 0); -}); */ // ES5 sintax for function below - -numbers.forEach(x => console.log(`numbers.forEach: ${x} % 2 === 0`, x % 2 === 0)); - - -console.log('numbers.map(isEven)', numbers.map(isEven)); - -console.log('numbers.filter(isEven)', numbers.filter(isEven)); - -/* console.log('numbers.reduce', - numbers.reduce(function(previous, current, index) { - return previous + current; - }) -); */ // ES5 sintax for function below - -console.log('numbers.reduce', numbers.reduce((previous, current) => previous + current)); diff --git a/examples/chapter03/06-ES2015Methods.html b/examples/chapter03/06-ES2015Methods.html deleted file mode 100755 index cd7abd9c..00000000 --- a/examples/chapter03/06-ES2015Methods.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter03/06-ES2015Methods.js b/examples/chapter03/06-ES2015Methods.js deleted file mode 100755 index 6513e2d3..00000000 --- a/examples/chapter03/06-ES2015Methods.js +++ /dev/null @@ -1,117 +0,0 @@ -// @ts-check - -const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; - -//* ********* using for..of loop -for (const n of numbers) { - console.log(`for..of loop: ${n} % 2 === 0`, n % 2 === 0 ? 'even' : 'odd'); -} - -//* ********* Using the new ES6 iterator (@@iterator) -console.log('Using the new ES6 iterator (@@iterator)'); - -let iterator = numbers[Symbol.iterator](); -console.log('iterator.next().value', iterator.next().value); // 1 -console.log('iterator.next().value', iterator.next().value); // 2 -console.log('iterator.next().value', iterator.next().value); // 3 -console.log('iterator.next().value', iterator.next().value); // 4 -console.log('iterator.next().value', iterator.next().value); // 5 - -// or use code below -iterator = numbers[Symbol.iterator](); -for (const n of iterator) { - console.log(`${n} of iterator`, n); -} - -//* ********* Array entries, keys and values -console.log('Array entries, keys and values'); - -console.log('Array.entries'); -let aEntries = numbers.entries(); // retrieve iterator of key/value -console.log('aEntries.next().value', aEntries.next().value); // [0, 1] - position 0, value 1 -console.log('aEntries.next().value', aEntries.next().value); // [1, 2] - position 1, value 2 -console.log('aEntries.next().value', aEntries.next().value); // [2, 3] - position 2, value 3 - -// or use code below -aEntries = numbers.entries(); -for (const n of aEntries) { - console.log(`entry of ${n}`, n); -} - -console.log('Array.keys'); -const aKeys = numbers.keys(); // retrieve iterator of keys -console.log('aKeys.next()', aKeys.next()); // {value: 0, done: false } done false means iterator has more values -console.log('aKeys.next()', aKeys.next()); // {value: 1, done: false } -console.log('aKeys.next()', aKeys.next()); // {value: 2, done: false } - -console.log('Array.values - Only Edge and Safari - Oct 2017'); -// const aValues = numbers.values(); -// console.log(aValues.next()); // {value: 1, done: false } done false means iterator has more values -// console.log(aValues.next()); // {value: 2, done: false } -// console.log(aValues.next()); // {value: 3, done: false } - -//* ********* Using the from method -console.log('Using the from method'); - -const evens = Array.from(numbers, x => x % 2 === 0); -console.log('Array.from(numbers, x => x % 2 === 0)', evens); - -const numbers2 = Array.from(numbers); -console.log('Array.from(numbers)', numbers2); - -//* ********* Using Array.of -console.log('Using Array.of'); - -const numbers3 = Array.of(1); -const numbers4 = Array.of(1, 2, 3, 4, 5, 6); -const numbersCopy = Array.of(...numbers4); -console.log('Array.of(1)', numbers3); -console.log('Array.of(1, 2, 3, 4, 5, 6)', numbers4); -console.log('Array.of(...numbers4)', numbersCopy); - -//* ********* Using the fill method -console.log('Using the fill method'); - -numbersCopy.fill(0); -console.log('numbersCopy.fill(0)', numbersCopy); - -numbersCopy.fill(2, 1); -console.log('numbersCopy.fill(2, 1)', numbersCopy); - -numbersCopy.fill(1, 3, 5); -console.log('numbersCopy.fill(1, 3, 5)', numbersCopy); - -const ones = Array(6).fill(1); -console.log('Array(6).fill(1)', ones); - -//* ********* Using the copyWithin method -console.log('Using the copyWithin method'); - -let copyArray = [1, 2, 3, 4, 5, 6]; -console.log('copyArray', copyArray); - -copyArray = copyArray.copyWithin(0, 3); // pos 3 value is copied to pos 0 -console.log('copyArray.copyWithin(0, 3)', copyArray); - -copyArray = [1, 2, 3, 4, 5, 6]; -copyArray = copyArray.copyWithin(1, 3, 5); // pos 3-4 values are copied to pos 1-2 -console.log('copyArray.copyWithin(1, 3, 5)', copyArray); - -//* ********* methods find and findIndex -console.log('methods find and findIndex'); - -function multipleOf13(element) { - return element % 13 === 0; -} - -console.log('numbers.find(multipleOf13)', numbers.find(multipleOf13)); -console.log('numbers.findIndex(multipleOf13)', numbers.findIndex(multipleOf13)); - -//* ********* EcmaScript 2016 (ES7): using the method includes -console.log('EcmaScript 2016 (ES7): using the method includes'); - -console.log('numbers.includes(15)', numbers.includes(15)); -console.log('numbers.includes(20)', numbers.includes(20)); - -const numbers5 = [7, 6, 5, 4, 3, 2, 1]; -console.log('numbers5.includes(4, 5)', numbers5.includes(4, 5)); diff --git a/examples/chapter03/07-Sorting.html b/examples/chapter03/07-Sorting.html deleted file mode 100644 index 0e32a5b2..00000000 --- a/examples/chapter03/07-Sorting.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter03/07-Sorting.js b/examples/chapter03/07-Sorting.js deleted file mode 100644 index f9efe1df..00000000 --- a/examples/chapter03/07-Sorting.js +++ /dev/null @@ -1,71 +0,0 @@ -// @ts-check - -let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; -console.log('numbers', numbers); - - -numbers = numbers.reverse(); -console.log('numbers.reverse()', numbers); - -console.log('numbers.sort()', numbers.sort()); - -/* console.log( - numbers.sort(function(a, b) { - return a - b; - }) -); */ // ES5 syntax - -console.log('numbers.sort((a, b) => a - b)', numbers.sort((a, b) => a - b)); - -function compare(a, b) { - if (a < b) { - return -1; - } - if (a > b) { - return 1; - } - // a must be equal to b - return 0; -} - -console.log('numbers.sort(compare)', numbers.sort(compare)); - -// Sorting objects -const friends = [ - { name: 'John', age: 30 }, - { name: 'Ana', age: 20 }, - { name: 'Chris', age: 25 }, // trailing comma ES2017 -]; - -function comparePerson(a, b) { - if (a.age < b.age) { - return -1; - } - if (a.age > b.age) { - return 1; - } - return 0; -} - -console.log('friends.sort(comparePerson)', friends.sort(comparePerson)); - -let names = ['Ana', 'ana', 'john', 'John']; -console.log('names', names); -console.log('names.sort()', names.sort()); - -names = ['Ana', 'ana', 'john', 'John']; // reset to array original state -console.log('names.sort(compareFunction)', names.sort((a, b) => { - if (a.toLowerCase() < b.toLowerCase()) { - return -1; - } - if (a.toLowerCase() > b.toLowerCase()) { - return 1; - } - return 0; -})); -names = ['Ana', 'ana', 'john', 'John']; // reset to array original state -console.log('names.sort((a, b) => a.localeCompare(b))', names.sort((a, b) => a.localeCompare(b))); - -const names2 = ['Maève', 'Maeve']; -console.log('names2', names); -console.log('names2.sort((a, b) => a.localeCompare(b))', names2.sort((a, b) => a.localeCompare(b))); diff --git a/examples/chapter03/08-Searching.html b/examples/chapter03/08-Searching.html deleted file mode 100644 index 6dd9aac1..00000000 --- a/examples/chapter03/08-Searching.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter03/08-Searching.js b/examples/chapter03/08-Searching.js deleted file mode 100644 index 1388a873..00000000 --- a/examples/chapter03/08-Searching.js +++ /dev/null @@ -1,17 +0,0 @@ -// @ts-check - -const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; -console.log('numbers', numbers); - -//* ** toString -console.log('numbers.toString()', numbers.toString()); - -console.log('numbers.indexOf(10)', numbers.indexOf(10)); -console.log('numbers.indexOf(100)', numbers.indexOf(100)); - -numbers.push(10); -console.log('push 10: numbers.lastIndexOf(10)', numbers.lastIndexOf(10)); -console.log('push 10: numbers.lastIndexOf(100)', numbers.lastIndexOf(100)); - -const numbersString = numbers.join('-'); -console.log('numbers.join("-")', numbersString); diff --git a/examples/chapter03/09-TypedArrays.html b/examples/chapter03/09-TypedArrays.html deleted file mode 100755 index 9257fe4a..00000000 --- a/examples/chapter03/09-TypedArrays.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter03/09-TypedArrays.js b/examples/chapter03/09-TypedArrays.js deleted file mode 100755 index be92f508..00000000 --- a/examples/chapter03/09-TypedArrays.js +++ /dev/null @@ -1,24 +0,0 @@ -const length = 5; -const int16 = new Int16Array(length); - -const array16 = []; -array16.length = length; - -for (let i = 0; i < length; i++) { - int16[i] = i + 1; -} - -console.log(int16); - -// Int8Array(); -// Uint8Array(); -// Uint8ClampedArray(); -// Int16Array(); -// Uint16Array(); -// Int32Array(); -// Uint32Array(); -// Float32Array(); -// Float64Array(); - -// http://www.html5rocks.com/en/tutorials/webgl/typed_arrays/ -// http://www.i-programmer.info/programming/javascript/6135-javascript-data-structures-typed-arrays.html diff --git a/examples/chapter03/10-ArraysAndTypeScript.ts b/examples/chapter03/10-ArraysAndTypeScript.ts deleted file mode 100644 index 63e97f2e..00000000 --- a/examples/chapter03/10-ArraysAndTypeScript.ts +++ /dev/null @@ -1,32 +0,0 @@ -// const numbers: number[]; -const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; -console.log('numbers', numbers); - -// let names: string[]; -let names = ['Ana', 'ana', 'john', 'John']; -console.log('names', names); -console.log('names.sort()', names.sort()); - -interface Person { - name: string; - age: number; -} - -// const friends: {name: string, age: number}[]; -const friends = [ - { name: 'John', age: 30 }, - { name: 'Ana', age: 20 }, - { name: 'Chris', age: 25 }, // trailing comma ES2017 -]; - -function comparePerson(a: Person, b: Person) { - if (a.age < b.age) { - return -1; - } - if (a.age > b.age) { - return 1; - } - return 0; -} - -console.log('friends.sort(comparePerson)', friends.sort(comparePerson)); diff --git a/examples/chapter04/01-Stack.html b/examples/chapter04/01-Stack.html deleted file mode 100755 index 3025a012..00000000 --- a/examples/chapter04/01-Stack.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - diff --git a/examples/chapter04/01-Stack.js b/examples/chapter04/01-Stack.js deleted file mode 100755 index d3994b08..00000000 --- a/examples/chapter04/01-Stack.js +++ /dev/null @@ -1,33 +0,0 @@ -// import Stack from './../../src/js/data-structures/stack.js'; // ES2015 modules -// import StackArray from './../../src/js/data-structures/stack-array.js'; // ES2015 modules -// const Stack = require('../../dist/js/data-structures/stack'); // for node -// const Stack = stack; // older browsers - remove from html script import: type="module" -const { Stack } = PacktDataStructuresAlgorithms; - -const stack = new Stack(); // new StackArray(); - -// using WeakMap to store Stack items we ensure true privacy -// console.log(Object.getOwnPropertyNames(stack)); -// console.log(Object.keys(stack)); -// console.log(stack.items); - -console.log('stack.isEmpty() => ', stack.isEmpty()); // outputs true - -stack.push(5); -stack.push(8); - -console.log('stack after push 5 and 8 => ', stack.toString()); - -console.log('stack.peek() => ', stack.peek()); // outputs 8 - -stack.push(11); - -console.log('stack.size() after push 11 => ', stack.size()); // outputs 3 -console.log('stack.isEmpty() => ', stack.isEmpty()); // outputs false - -stack.push(15); - -stack.pop(); -stack.pop(); - -console.log('stack.size() after push 15 and pop twice => ', stack.size()); // outputs 2 diff --git a/examples/chapter04/01-StackSymbol.js b/examples/chapter04/01-StackSymbol.js deleted file mode 100755 index c525f359..00000000 --- a/examples/chapter04/01-StackSymbol.js +++ /dev/null @@ -1,47 +0,0 @@ -const _items = Symbol('stackItems'); - -class Stack { - constructor() { - this[_items] = []; - } - - push(element) { - this[_items].push(element); - } - - pop() { - return this[_items].pop(); - } - - peek() { - return this[_items][this[_items].length - 1]; - } - - isEmpty() { - return this[_items].length === 0; - } - - size() { - return this[_items].length; - } - - clear() { - this[_items] = []; - } - - print() { - console.log(this.toString()); - } - - toString() { - return this[_items].toString(); - } -} - -const stack = new Stack(); -const objectSymbols = Object.getOwnPropertySymbols(stack); -console.log(objectSymbols.length); // 1 -console.log(objectSymbols); // [Symbol()] -console.log(objectSymbols[0]); // Symbol() -stack[objectSymbols[0]].push(1); -stack.print(); // 5, 8, 1 diff --git a/examples/chapter04/01-StackWeakMap.js b/examples/chapter04/01-StackWeakMap.js deleted file mode 100644 index 7471b8d1..00000000 --- a/examples/chapter04/01-StackWeakMap.js +++ /dev/null @@ -1,70 +0,0 @@ -// @ts-check - - -const _items = new WeakMap(); -const _count = new WeakMap(); - -class Stack { - constructor() { - _count.set(this, 0); - _items.set(this, {}); - } - - push(element) { - const items = _items.get(this); - const count = _count.get(this); - items[count] = element; - _count.set(this, count + 1); - } - - pop() { - if (this.isEmpty()) { - return undefined; - } - const items = _items.get(this); - let count = _count.get(this); - count--; - _count.set(this, count); - const result = items[count]; - delete items[count]; - return result; - } - - peek() { - if (this.isEmpty()) { - return undefined; - } - const items = _items.get(this); - const count = _count.get(this); - return items[count - 1]; - } - - isEmpty() { - return _count.get(this) === 0; - } - - size() { - return _count.get(this); - } - - clear() { - /* while (!this.isEmpty()) { - this.pop(); - } */ - _count.set(this, 0); - _items.set(this, {}); - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const items = _items.get(this); - const count = _count.get(this); - let objString = `${items[0]}`; - for (let i = 1; i < count; i++) { - objString = `${objString},${items[i]}`; - } - return objString; - } -} diff --git a/examples/chapter04/02-BalancedSymbols.html b/examples/chapter04/02-BalancedSymbols.html deleted file mode 100755 index f2aea40d..00000000 --- a/examples/chapter04/02-BalancedSymbols.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/examples/chapter04/02-BalancedSymbols.js b/examples/chapter04/02-BalancedSymbols.js deleted file mode 100755 index 614f44e7..00000000 --- a/examples/chapter04/02-BalancedSymbols.js +++ /dev/null @@ -1,5 +0,0 @@ -const { parenthesesChecker } = PacktDataStructuresAlgorithms; - -console.log('{([])}', parenthesesChecker('{([])}')); // true -console.log('{{([][])}()}', parenthesesChecker('{{([][])}()}')); // true -console.log('[{()]', parenthesesChecker('[{()]')); // false diff --git a/examples/chapter04/03-DecimalToBinary.html b/examples/chapter04/03-DecimalToBinary.html deleted file mode 100755 index 88b6c362..00000000 --- a/examples/chapter04/03-DecimalToBinary.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter04/03-DecimalToBinary.js b/examples/chapter04/03-DecimalToBinary.js deleted file mode 100755 index f39fcb1d..00000000 --- a/examples/chapter04/03-DecimalToBinary.js +++ /dev/null @@ -1,13 +0,0 @@ -const { decimalToBinary } = PacktDataStructuresAlgorithms; -const { baseConverter } = PacktDataStructuresAlgorithms; - -// 233 == 11101001 -// 2x(10x10) + 3x(10) + 3x(1) -console.log(decimalToBinary(233)); // 11101001 -console.log(decimalToBinary(10)); // 1010 -console.log(decimalToBinary(1000)); // 1111101000 - -console.log(baseConverter(100345, 2)); // 11000011111111001 -console.log(baseConverter(100345, 8)); // 303771 -console.log(baseConverter(100345, 16)); // 187F9 -console.log(baseConverter(100345, 35)); // 2BW0 diff --git a/examples/chapter04/04-TowerOfHanoi.html b/examples/chapter04/04-TowerOfHanoi.html deleted file mode 100755 index f6d0cb52..00000000 --- a/examples/chapter04/04-TowerOfHanoi.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter04/04-TowerOfHanoi.js b/examples/chapter04/04-TowerOfHanoi.js deleted file mode 100755 index f5d85cf7..00000000 --- a/examples/chapter04/04-TowerOfHanoi.js +++ /dev/null @@ -1,6 +0,0 @@ -const { hanoiStack } = PacktDataStructuresAlgorithms; -const { hanoi } = PacktDataStructuresAlgorithms; - -console.log(hanoiStack(3)); - -console.log(hanoi(3, 'source', 'helper', 'dest')); diff --git a/examples/chapter05/01-Queue.html b/examples/chapter05/01-Queue.html deleted file mode 100755 index 2e67f7f4..00000000 --- a/examples/chapter05/01-Queue.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter05/01-Queue.js b/examples/chapter05/01-Queue.js deleted file mode 100755 index 852a1b4d..00000000 --- a/examples/chapter05/01-Queue.js +++ /dev/null @@ -1,14 +0,0 @@ -const { Queue } = PacktDataStructuresAlgorithms; - -const queue = new Queue(); -console.log(queue.isEmpty()); // outputs true -queue.enqueue('John'); -queue.enqueue('Jack'); -console.log(queue.toString()); // John,Jack -queue.enqueue('Camila'); -console.log(queue.toString()); // John,Jack,Camila -console.log(queue.size()); // outputs 3 -console.log(queue.isEmpty()); // outputs false -queue.dequeue(); // remove John -queue.dequeue(); // remove Jack -console.log(queue.toString()); // Camila diff --git a/examples/chapter05/02-Deque.html b/examples/chapter05/02-Deque.html deleted file mode 100755 index 99b838af..00000000 --- a/examples/chapter05/02-Deque.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter05/02-Deque.js b/examples/chapter05/02-Deque.js deleted file mode 100755 index 4c84b6de..00000000 --- a/examples/chapter05/02-Deque.js +++ /dev/null @@ -1,17 +0,0 @@ -const { Deque } = PacktDataStructuresAlgorithms; - -const deque = new Deque(); -console.log(deque.isEmpty()); // outputs true -deque.addBack('John'); -deque.addBack('Jack'); -console.log(deque.toString()); // John,Jack -deque.addBack('Camila'); -console.log(deque.toString()); // John,Jack,Camila -console.log(deque.size()); // outputs 3 -console.log(deque.isEmpty()); // outputs false -deque.removeFront(); // remove John -console.log(deque.toString()); // Jack,Camila -deque.removeBack(); // Camila decides to leave -console.log(deque.toString()); // Jack -deque.addFront('John'); // John comes back for information -console.log(deque.toString()); // John,Jack diff --git a/examples/chapter05/03-HotPotato.html b/examples/chapter05/03-HotPotato.html deleted file mode 100755 index 85d45104..00000000 --- a/examples/chapter05/03-HotPotato.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter05/03-HotPotato.js b/examples/chapter05/03-HotPotato.js deleted file mode 100755 index 686f6791..00000000 --- a/examples/chapter05/03-HotPotato.js +++ /dev/null @@ -1,16 +0,0 @@ -const { hotPotato } = PacktDataStructuresAlgorithms; - -const names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl']; -const result = hotPotato(names, 7); - -result.eliminated.forEach(name => { - console.log(`${name} was eliminated from the Hot Potato game.`); -}); - -console.log(`The winner is: ${result.winner}`); - -// Camila was eliminated from the Hot Potato game. -// Jack was eliminated from the Hot Potato game. -// Carl was eliminated from the Hot Potato game. -// Ingrid was eliminated from the Hot Potato game. -// The winner is: John diff --git a/examples/chapter05/04-PalindromeChecker.html b/examples/chapter05/04-PalindromeChecker.html deleted file mode 100755 index 785e0482..00000000 --- a/examples/chapter05/04-PalindromeChecker.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter05/04-PalindromeChecker.js b/examples/chapter05/04-PalindromeChecker.js deleted file mode 100755 index 99c29cf9..00000000 --- a/examples/chapter05/04-PalindromeChecker.js +++ /dev/null @@ -1,8 +0,0 @@ -const { palindromeChecker } = PacktDataStructuresAlgorithms; - -console.log('a', palindromeChecker('a')); -console.log('aa', palindromeChecker('aa')); -console.log('kayak', palindromeChecker('kayak')); -console.log('level', palindromeChecker('level')); -console.log('Was it a car or a cat I saw', palindromeChecker('Was it a car or a cat I saw')); -console.log('Step on no pets', palindromeChecker('Step on no pets')); diff --git a/examples/chapter06/01-LinkedList.html b/examples/chapter06/01-LinkedList.html deleted file mode 100644 index df7c5591..00000000 --- a/examples/chapter06/01-LinkedList.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter06/01-LinkedList.js b/examples/chapter06/01-LinkedList.js deleted file mode 100644 index 8d7c6e49..00000000 --- a/examples/chapter06/01-LinkedList.js +++ /dev/null @@ -1,48 +0,0 @@ -const { LinkedList } = PacktDataStructuresAlgorithms; - -const list = new LinkedList(); - -console.log('push element 15'); -list.push(15); - -console.log('list.indexOf(15) => ', list.indexOf(15)); - -console.log('push element 10'); -list.push(10); - -console.log('list.toString() => ', list.toString()); -console.log('list.indexOf(10) => ', list.indexOf(10)); - -console.log('push element 13'); -list.push(13); - -console.log('list.toString() => ', list.toString()); -console.log('list.indexOf(13) => ', list.indexOf(13)); -console.log('list.indexOf(10) => ', list.indexOf(10)); - -console.log('push elements 11 and 12'); -list.push(11); -list.push(12); - -console.log('list.toString() => ', list.toString()); -console.log('list.removeAt(1) => ', list.removeAt(1)); -console.log('list.toString() => ', list.toString()); -console.log('list.removeAt(3) => ', list.removeAt(3)); -console.log('list.toString() => ', list.toString()); - -console.log('push element 14'); -list.push(14); - -console.log('list.toString() => ', list.toString()); -console.log('insert element 16 pos 0 => ', list.insert(16, 0)); -console.log('list.toString() => ', list.toString()); -console.log('insert element 17 pos 1 => ', list.insert(17, 1)); -console.log('list.toString() => ', list.toString()); -console.log('insert element 18 pos list.size() => ', list.insert(18, list.size())); -console.log('list.toString() => ', list.toString()); -console.log('remove element 16 => ', list.remove(16)); -console.log('list.toString() => ', list.toString()); -console.log('remove element 11 => ', list.remove(11)); -console.log('list.toString() => ', list.toString()); -console.log('remove element 18 => ', list.remove(18)); -console.log('list.toString() => ', list.toString()); diff --git a/examples/chapter06/02-DoublyLinkedList.html b/examples/chapter06/02-DoublyLinkedList.html deleted file mode 100644 index 1aea7c24..00000000 --- a/examples/chapter06/02-DoublyLinkedList.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter06/02-DoublyLinkedList.js b/examples/chapter06/02-DoublyLinkedList.js deleted file mode 100644 index 333f701c..00000000 --- a/examples/chapter06/02-DoublyLinkedList.js +++ /dev/null @@ -1,54 +0,0 @@ -const { DoublyLinkedList } = PacktDataStructuresAlgorithms; - -const list = new DoublyLinkedList(); - -console.log('push element 15'); -list.push(15); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('push element 16'); -list.push(16); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('push element 17'); -list.push(17); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('insert element 13 pos 0 => ', list.insert(13, 0)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('insert element 18 pos 4 => ', list.insert(18, 4)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('insert element 14 pos 1 => ', list.insert(14, 1)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('list.removeAt(0) => ', list.removeAt(0)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('list.removeAt(list.size() - 1) => ', list.removeAt(list.size() - 1)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('list.removeAt(1) => ', list.removeAt(1)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('remove element 16 => ', list.remove(16)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('remove element 14 => ', list.remove(14)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); - -console.log('remove element 17 => ', list.remove(17)); -console.log('list.toString() => ', list.toString()); -console.log('list.inverseToString() => ', list.inverseToString()); diff --git a/examples/chapter06/03-CircularLinkedList.html b/examples/chapter06/03-CircularLinkedList.html deleted file mode 100644 index 10fbd6b6..00000000 --- a/examples/chapter06/03-CircularLinkedList.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter06/03-CircularLinkedList.js b/examples/chapter06/03-CircularLinkedList.js deleted file mode 100644 index 05178956..00000000 --- a/examples/chapter06/03-CircularLinkedList.js +++ /dev/null @@ -1,32 +0,0 @@ -const { CircularLinkedList } = PacktDataStructuresAlgorithms; - -const list = new CircularLinkedList(); - -console.log('push element 15'); -list.push(15); -console.log('list.toString() => ', list.toString()); - -console.log('push element 16'); -list.push(16); -console.log('list.toString() => ', list.toString()); - -console.log('insert element 14 pos 0 => ', list.insert(14, 0)); -console.log('list.toString() => ', list.toString()); - -console.log('insert element 14.5 pos 1 => ', list.insert(14.5, 1)); -console.log('list.toString() => ', list.toString()); - -console.log('insert element 17 pos 4 => ', list.insert(17, 4)); -console.log('list.toString() => ', list.toString()); - -console.log('list.removeAt(0) => ', list.removeAt(0)); -console.log('list.toString() => ', list.toString()); - -console.log('list.removeAt(1) => ', list.removeAt(1)); -console.log('list.toString() => ', list.toString()); - -console.log('list.removeAt(2) => ', list.removeAt(2)); -console.log('list.toString() => ', list.toString()); - -console.log('list.indexOf(14.5) => ', list.indexOf(14.5)); -console.log('list.indexOf(16) => ', list.indexOf(16)); diff --git a/examples/chapter06/04-SortedLinkedList.html b/examples/chapter06/04-SortedLinkedList.html deleted file mode 100644 index 9feb1a70..00000000 --- a/examples/chapter06/04-SortedLinkedList.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter06/04-SortedLinkedList.js b/examples/chapter06/04-SortedLinkedList.js deleted file mode 100644 index c6351f8f..00000000 --- a/examples/chapter06/04-SortedLinkedList.js +++ /dev/null @@ -1,53 +0,0 @@ -const { SortedLinkedList } = PacktDataStructuresAlgorithms; -const { util } = PacktDataStructuresAlgorithms; - -const list = new SortedLinkedList(); - -console.log(''); -for (let i = 5; i > 0; i--) { - list.push(i); -} - -console.log('list after pushing 5, 4, 3, 2, and 1 => ', list.toString()); - -console.log('list.removeAt(1) => ', list.removeAt(1)); - -console.log('remove element 16 => ', list.remove(5)); - -console.log('list.toString() => ', list.toString()); - -// ------- Example 02 - -class MyObj { - constructor(el1, el2) { - this.el1 = el1; - this.el2 = el2; - } - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } -} - -function myObjCompare(a, b) { - return a.toString().localeCompare(b.toString()); -} - -const ds = new SortedLinkedList(util.defaultEquals, myObjCompare); - -console.log('*** SortedLinkedList with custom sorting function'); - -ds.push(new MyObj(3, 4)); -console.log('push MyObj(3, 4)'); -console.log('list.toString() => ', ds.toString()); - -ds.push(new MyObj(1, 2)); -console.log('push MyObj(1, 2)'); -console.log('list.toString() => ', ds.toString()); - -ds.push(new MyObj(5, 6)); -console.log('push MyObj(5, 6)'); -console.log('list.toString() => ', ds.toString()); - -ds.insert(new MyObj(0, 0), 4); -console.log('insert MyObj(0, 0) pos 4 (pos ignored)'); -console.log('list.toString() => ', ds.toString()); diff --git a/examples/chapter06/05-StackLinkedList.html b/examples/chapter06/05-StackLinkedList.html deleted file mode 100644 index c511e977..00000000 --- a/examples/chapter06/05-StackLinkedList.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter06/05-StackLinkedList.js b/examples/chapter06/05-StackLinkedList.js deleted file mode 100644 index 866e7f91..00000000 --- a/examples/chapter06/05-StackLinkedList.js +++ /dev/null @@ -1,24 +0,0 @@ -const { StackLinkedList } = PacktDataStructuresAlgorithms; - -const stack = new StackLinkedList(); - -console.log('stack.isEmpty() => ', stack.isEmpty()); // outputs true - -stack.push(5); -stack.push(8); - -console.log('stack after push 5 and 8 => ', stack.toString()); - -console.log('stack.peek() => ', stack.peek()); // outputs 8 - -stack.push(11); - -console.log('stack.size() after push 11 => ', stack.size()); // outputs 3 -console.log('stack.isEmpty() => ', stack.isEmpty()); // outputs false - -stack.push(15); - -stack.pop(); -stack.pop(); - -console.log('stack.size() after push 15 and pop twice => ', stack.size()); // outputs 2 diff --git a/examples/chapter07/01-Set.html b/examples/chapter07/01-Set.html deleted file mode 100755 index cf2f575b..00000000 --- a/examples/chapter07/01-Set.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter07/01-Set.js b/examples/chapter07/01-Set.js deleted file mode 100755 index e893c2c8..00000000 --- a/examples/chapter07/01-Set.js +++ /dev/null @@ -1,19 +0,0 @@ -const { Set } = PacktDataStructuresAlgorithms; - -const set = new Set(); - -set.add(1); -console.log(set.values()); // outputs [1] -console.log(set.has(1)); // outputs true -console.log(set.size()); // outputs 1 - -set.add(2); -console.log(set.values()); // outputs [1, 2] -console.log(set.has(2)); // true -console.log(set.size()); // 2 - -set.delete(1); -console.log(set.values()); // outputs [2] - -set.delete(2); -console.log(set.values()); // outputs [] diff --git a/examples/chapter07/02-SetOperations.html b/examples/chapter07/02-SetOperations.html deleted file mode 100755 index b55d7e0d..00000000 --- a/examples/chapter07/02-SetOperations.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter07/02-SetOperations.js b/examples/chapter07/02-SetOperations.js deleted file mode 100755 index 2608c7ef..00000000 --- a/examples/chapter07/02-SetOperations.js +++ /dev/null @@ -1,66 +0,0 @@ -const { Set } = PacktDataStructuresAlgorithms; - -// --------- Union ---------- - -let setA = new Set(); -setA.add(1); -setA.add(2); -setA.add(3); - -let setB = new Set(); -setB.add(3); -setB.add(4); -setB.add(5); -setB.add(6); - -const unionAB = setA.union(setB); -console.log(unionAB.values()); // [1, 2, 3, 4, 5, 6] - -// --------- Intersection ---------- - -setA = new Set(); -setA.add(1); -setA.add(2); -setA.add(3); - -setB = new Set(); -setB.add(2); -setB.add(3); -setB.add(4); - -const intersectionAB = setA.intersection(setB); -console.log(intersectionAB.values()); // [2, 3] - -// --------- Difference ---------- - -setA = new Set(); -setA.add(1); -setA.add(2); -setA.add(3); - -setB = new Set(); -setB.add(2); -setB.add(3); -setB.add(4); - -const differenceAB = setA.difference(setB); -console.log(differenceAB.values()); // [1] - -// --------- Subset ---------- - -setA = new Set(); -setA.add(1); -setA.add(2); - -setB = new Set(); -setB.add(1); -setB.add(2); -setB.add(3); - -const setC = new Set(); -setC.add(2); -setC.add(3); -setC.add(4); - -console.log(setA.isSubsetOf(setB)); // true -console.log(setA.isSubsetOf(setC)); // false diff --git a/examples/chapter07/03-ES2015Set.html b/examples/chapter07/03-ES2015Set.html deleted file mode 100755 index 7fe40e1b..00000000 --- a/examples/chapter07/03-ES2015Set.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter07/03-ES2015Set.js b/examples/chapter07/03-ES2015Set.js deleted file mode 100755 index 721ea4d1..00000000 --- a/examples/chapter07/03-ES2015Set.js +++ /dev/null @@ -1,72 +0,0 @@ -const set = new Set(); - -set.add(1); -console.log(set.values()); // outputs @Iterator -console.log(set.has(1)); // outputs true -console.log(set.size); // outputs 1 - -set.add(2); -console.log(set.values()); // outputs [1, 2] -console.log(set.has(2)); // true -console.log(set.size); // 2 - -set.delete(1); -console.log(set.values()); // outputs [2] - -set.delete(2); -console.log(set.values()); // outputs [] - -const setA = new Set(); -setA.add(1); -setA.add(2); -setA.add(3); - -const setB = new Set(); -setB.add(2); -setB.add(3); -setB.add(4); - -// --------- Union ---------- -const union = (set1, set2) => { - const unionAb = new Set(); - set1.forEach(value => unionAb.add(value)); - set2.forEach(value => unionAb.add(value)); - return unionAb; -}; -console.log(union(setA, setB)); - -console.log(new Set([...setA, ...setB])); - -// --------- Intersection ---------- -const intersection = (set1, set2) => { - const intersectionSet = new Set(); - set1.forEach(value => { - if (set2.has(value)) { - intersectionSet.add(value); - } - }); - return intersectionSet; -}; -console.log(intersection(setA, setB)); - -console.log(new Set([...setA].filter(x => setB.has(x)))); - -// alternative - works on FF only -// console.log(new Set([x for (x of setA) if (setB.has(x))])); - -// --------- Difference ---------- -const difference = (set1, set2) => { - const differenceSet = new Set(); - set1.forEach(value => { - if (!set2.has(value)) { - differenceSet.add(value); - } - }); - return differenceSet; -}; -console.log(difference(setA, setB)); - -console.log(new Set([...setA].filter(x => !setB.has(x)))); - -// alternative - works on FF only -// console.log(new Set([x for (x of setA) if (!setB.has(x))])); diff --git a/examples/chapter08/01-Dictionaries.html b/examples/chapter08/01-Dictionaries.html deleted file mode 100755 index d972458c..00000000 --- a/examples/chapter08/01-Dictionaries.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter08/01-Dictionaries.js b/examples/chapter08/01-Dictionaries.js deleted file mode 100755 index 53433cc0..00000000 --- a/examples/chapter08/01-Dictionaries.js +++ /dev/null @@ -1,28 +0,0 @@ -const { Dictionary } = PacktDataStructuresAlgorithms; - -const dictionary = new Dictionary(); - -dictionary.set('Gandalf', 'gandalf@email.com'); -dictionary.set('John', 'johnsnow@email.com'); -dictionary.set('Tyrion', 'tyrion@email.com'); - -console.log(dictionary.hasKey('Gandalf')); // true -console.log(dictionary.size()); // 3 - -console.log(dictionary.keys()); // ["Gandalf", "John", "Tyrion"] -console.log(dictionary.values()); // ["gandalf@email.com", "johnsnow@email.com", "tyrion@email.com"] -console.log(dictionary.get('Tyrion')); // tyrion@email.com - -dictionary.remove('John'); - -console.log(dictionary.keys()); // ["Gandalf", "Tyrion"] -console.log(dictionary.values()); // ["gandalf@email.com", "tyrion@email.com"] - -console.log(dictionary.keyValues()); // [{key: "Gandalf", value: "gandalf@email.com"}, {key: "Tyrion", value: "tyrion@email.com"}] -console.log(dictionary.toString()); // [#Gandalf: gandalf@email.com],[#Tyrion: tyrion@email.com] - -dictionary.forEach((k, v) => { - console.log('forEach: ', `key: ${k}, value: ${v}`); -}); -// forEach: key: Gandalf, value: gandalf@email.com -// forEach: key: Tyrion, value: tyrion@email.com diff --git a/examples/chapter08/02-HashTable.html b/examples/chapter08/02-HashTable.html deleted file mode 100755 index 67ad128c..00000000 --- a/examples/chapter08/02-HashTable.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter08/02-HashTable.js b/examples/chapter08/02-HashTable.js deleted file mode 100755 index fbee2022..00000000 --- a/examples/chapter08/02-HashTable.js +++ /dev/null @@ -1,51 +0,0 @@ -const { HashTable } = PacktDataStructuresAlgorithms; - -const hash = new HashTable(); - -console.log(hash.hashCode('Gandalf') + ' - Gandalf'); -console.log(hash.hashCode('John') + ' - John'); -console.log(hash.hashCode('Tyrion') + ' - Tyrion'); - -console.log(' '); - -console.log(hash.hashCode('Ygritte') + ' - Ygritte'); -console.log(hash.hashCode('Jonathan') + ' - Jonathan'); -console.log(hash.hashCode('Jamie') + ' - Jamie'); -console.log(hash.hashCode('Jack') + ' - Jack'); -console.log(hash.hashCode('Jasmine') + ' - Jasmine'); -console.log(hash.hashCode('Jake') + ' - Jake'); -console.log(hash.hashCode('Nathan') + ' - Nathan'); -console.log(hash.hashCode('Athelstan') + ' - Athelstan'); -console.log(hash.hashCode('Sue') + ' - Sue'); -console.log(hash.hashCode('Aethelwulf') + ' - Aethelwulf'); -console.log(hash.hashCode('Sargeras') + ' - Sargeras'); - -hash.put('Ygritte', 'ygritte@email.com'); -hash.put('Jonathan', 'jonathan@email.com'); -hash.put('Jamie', 'jamie@email.com'); -hash.put('Jack', 'jack@email.com'); -hash.put('Jasmine', 'jasmine@email.com'); -hash.put('Jake', 'jake@email.com'); -hash.put('Nathan', 'nathan@email.com'); -hash.put('Athelstan', 'athelstan@email.com'); -hash.put('Sue', 'sue@email.com'); -hash.put('Aethelwulf', 'aethelwulf@email.com'); -hash.put('Sargeras', 'sargeras@email.com'); - -console.log('**** Printing Hash **** '); - -console.log(hash.toString()); -// {4 => [#Ygritte: ygritte@email.com]},{5 => [#Aethelwulf: aethelwulf@email.com]},{7 => [#Athelstan: athelstan@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Sargeras: sargeras@email.com]} - -console.log('**** Get **** '); - -console.log(hash.get('Ygritte')); // ygritte@email.com -console.log(hash.get('Loiane')); // jasmine@email.com - -console.log('**** Remove **** '); - -hash.remove('Ygritte'); -console.log(hash.get('Ygritte')); // undefined - -console.log(hash.toString()); -// {5 => [#Aethelwulf: aethelwulf@email.com]},{7 => [#Athelstan: athelstan@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Sargeras: sargeras@email.com]} diff --git a/examples/chapter08/03-HashCollisionSeparateChaining.html b/examples/chapter08/03-HashCollisionSeparateChaining.html deleted file mode 100755 index cddcc3db..00000000 --- a/examples/chapter08/03-HashCollisionSeparateChaining.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter08/03-HashCollisionSeparateChaining.js b/examples/chapter08/03-HashCollisionSeparateChaining.js deleted file mode 100755 index f791ba89..00000000 --- a/examples/chapter08/03-HashCollisionSeparateChaining.js +++ /dev/null @@ -1,46 +0,0 @@ -const { HashTableSeparateChaining } = PacktDataStructuresAlgorithms; - -const hashTable = new HashTableSeparateChaining(); - -hashTable.put('Ygritte', 'ygritte@email.com'); -hashTable.put('Jonathan', 'jonathan@email.com'); -hashTable.put('Jamie', 'jamie@email.com'); -hashTable.put('Jack', 'jack@email.com'); -hashTable.put('Jasmine', 'jasmine@email.com'); -hashTable.put('Jake', 'jake@email.com'); -hashTable.put('Nathan', 'nathan@email.com'); -hashTable.put('Athelstan', 'athelstan@email.com'); -hashTable.put('Sue', 'sue@email.com'); -hashTable.put('Aethelwulf', 'aethelwulf@email.com'); -hashTable.put('Sargeras', 'sargeras@email.com'); - -console.log('**** Printing Hash **** '); - -console.log(hashTable.toString()); -// {4 => [#Ygritte: ygritte@email.com]},{5 => [#Jonathan: jonathan@email.com],[#Jamie: jamie@email.com],[#Sue: sue@email.com],[#Aethelwulf: aethelwulf@email.com]},{7 => [#Jack: jack@email.com],[#Athelstan: athelstan@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com],[#Sargeras: sargeras@email.com]} - -console.log('**** Get **** '); - -console.log(hashTable.get('Jamie')); // jamie@email.com -console.log(hashTable.get('Sue')); // sue@email.com -console.log(hashTable.get('Jonathan')); // jonathan@email.com -console.log(hashTable.get('Loiane')); // undefined - -console.log('**** Remove **** '); - -console.log(hashTable.remove('Ygritte')); // true -console.log(hashTable.get('Ygritte')); // undefined -console.log(hashTable.toString()); -// {5 => [#Jonathan: jonathan@email.com],[#Jamie: jamie@email.com],[#Sue: sue@email.com],[#Aethelwulf: aethelwulf@email.com]},{7 => [#Jack: jack@email.com],[#Athelstan: athelstan@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com],[#Sargeras: sargeras@email.com]} - -console.log(hashTable.remove('Sue')); // true -console.log(hashTable.toString()); -// {5 => [#Jonathan: jonathan@email.com],[#Jamie: jamie@email.com],[#Aethelwulf: aethelwulf@email.com]},{7 => [#Jack: jack@email.com],[#Athelstan: athelstan@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com],[#Sargeras: sargeras@email.com]} - -console.log(hashTable.remove('Jamie')); // true -console.log(hashTable.toString()); -// {5 => [#Jonathan: jonathan@email.com],[#Aethelwulf: aethelwulf@email.com]},{7 => [#Jack: jack@email.com],[#Athelstan: athelstan@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com],[#Sargeras: sargeras@email.com]} - -console.log(hashTable.remove('Aethelwulf')); // true -console.log(hashTable.toString()); -// {5 => [#Jonathan: jonathan@email.com]},{7 => [#Jack: jack@email.com],[#Athelstan: athelstan@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com],[#Sargeras: sargeras@email.com]} diff --git a/examples/chapter08/04-HashCollisionLinearProbing.html b/examples/chapter08/04-HashCollisionLinearProbing.html deleted file mode 100755 index 6f8bbe52..00000000 --- a/examples/chapter08/04-HashCollisionLinearProbing.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter08/04-HashCollisionLinearProbing.js b/examples/chapter08/04-HashCollisionLinearProbing.js deleted file mode 100755 index b75cd98d..00000000 --- a/examples/chapter08/04-HashCollisionLinearProbing.js +++ /dev/null @@ -1,42 +0,0 @@ -const { HashTableLinearProbing } = PacktDataStructuresAlgorithms; - -const hashTable = new HashTableLinearProbing(); - -hashTable.put('Ygritte', 'ygritte@email.com'); -hashTable.put('Jonathan', 'jonathan@email.com'); -hashTable.put('Jamie', 'jamie@email.com'); -hashTable.put('Jack', 'jack@email.com'); -hashTable.put('Jasmine', 'jasmine@email.com'); -hashTable.put('Jake', 'jake@email.com'); -hashTable.put('Nathan', 'nathan@email.com'); -hashTable.put('Athelstan', 'athelstan@email.com'); -hashTable.put('Sue', 'sue@email.com'); -hashTable.put('Aethelwulf', 'aethelwulf@email.com'); -hashTable.put('Sargeras', 'sargeras@email.com'); - -console.log('**** Printing Hash **** '); - -console.log(hashTable.toString()); -// {4 => [#Ygritte: ygritte@email.com]},{5 => [#Jonathan: jonathan@email.com]},{6 => [#Jamie: jamie@email.com]},{7 => [#Jack: jack@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com]},{11 => [#Athelstan: athelstan@email.com]},{12 => [#Sue: sue@email.com]},{13 => [#Aethelwulf: aethelwulf@email.com]},{14 => [#Sargeras: sargeras@email.com]} -console.log('**** Get **** '); - -console.log(hashTable.get('Nathan')); // nathan@email.com -console.log(hashTable.get('Loiane')); // undefined - -console.log('**** Remove **** '); - -hashTable.remove('Ygritte'); -console.log(hashTable.get('Ygritte')); // undefined -console.log(hashTable.toString()); -// {5 => [#Jonathan: jonathan@email.com]},{6 => [#Jamie: jamie@email.com]},{7 => [#Jack: jack@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com]},{11 => [#Athelstan: athelstan@email.com]},{12 => [#Sue: sue@email.com]},{13 => [#Aethelwulf: aethelwulf@email.com]},{14 => [#Sargeras: sargeras@email.com]} - -console.log('**** Remove Test 2 **** '); -console.log('Removing Jonathan', hashTable.remove('Jonathan')); // true -console.log('**** Print **** '); -console.log(hashTable.toString()); -// {5 => [#Jamie: jamie@email.com]},{6 => [#Sue: sue@email.com]},{7 => [#Jack: jack@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com]},{11 => [#Athelstan: athelstan@email.com]},{12 => [#Aethelwulf: aethelwulf@email.com]},{13 => [#Sargeras: sargeras@email.com]} - -console.log(hashTable.get('Jamie')); // jamie@email.com -console.log('**** Print **** '); -console.log(hashTable.toString()); -// {5 => [#Jamie: jamie@email.com]},{6 => [#Sue: sue@email.com]},{7 => [#Jack: jack@email.com]},{8 => [#Jasmine: jasmine@email.com]},{9 => [#Jake: jake@email.com]},{10 => [#Nathan: nathan@email.com]},{11 => [#Athelstan: athelstan@email.com]},{12 => [#Aethelwulf: aethelwulf@email.com]},{13 => [#Sargeras: sargeras@email.com]} diff --git a/examples/chapter08/05-ES2015Map.html b/examples/chapter08/05-ES2015Map.html deleted file mode 100755 index 8a2ade05..00000000 --- a/examples/chapter08/05-ES2015Map.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter08/05-ES2015Map.js b/examples/chapter08/05-ES2015Map.js deleted file mode 100755 index e944f988..00000000 --- a/examples/chapter08/05-ES2015Map.js +++ /dev/null @@ -1,17 +0,0 @@ -const map = new Map(); - -map.set('Gandalf', 'gandalf@email.com'); -map.set('John', 'johnsnow@email.com'); -map.set('Tyrion', 'tyrion@email.com'); - -console.log(map.has('Gandalf')); // true -console.log(map.size); // 3 - -console.log(map.keys()); // MapIterator {"Gandalf", "John", "Tyrion"} -console.log(map.values()); // MapIterator {"gandalf@email.com", "johnsnow@email.com", "tyrion@email.com"} -console.log(map.get('Tyrion')); // tyrion@email.com - -map.delete('John'); - -console.log(map.keys()); // MapIterator {"Gandalf", "Tyrion"} -console.log(map.values()); // MapIterator {"gandalf@email.com", "tyrion@email.com"} diff --git a/examples/chapter08/06-ES2015WeakMap.html b/examples/chapter08/06-ES2015WeakMap.html deleted file mode 100755 index 15daf46d..00000000 --- a/examples/chapter08/06-ES2015WeakMap.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter08/06-ES2015WeakMap.js b/examples/chapter08/06-ES2015WeakMap.js deleted file mode 100755 index 1f2d01bc..00000000 --- a/examples/chapter08/06-ES2015WeakMap.js +++ /dev/null @@ -1,18 +0,0 @@ -const map = new WeakMap(); - -const ob1 = { name: 'Gandalf' }; -const ob2 = { name: 'John' }; -const ob3 = { name: 'Tyrion' }; - -map.set(ob1, 'gandalf@email.com'); -map.set(ob2, 'johnsnow@email.com'); -map.set(ob3, 'tyrion@email.com'); - -console.log(map.has(ob1)); // true -console.log(map.has(ob2)); // true -console.log(map.has(ob3)); // true - -console.log(map.get(ob3)); // tyrion@email.com - -map.delete(ob2); -console.log(map.has(ob2)); // false diff --git a/examples/chapter08/07-ES2015WeakSet.html b/examples/chapter08/07-ES2015WeakSet.html deleted file mode 100755 index 7a4f82f4..00000000 --- a/examples/chapter08/07-ES2015WeakSet.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter08/07-ES2015WeakSet.js b/examples/chapter08/07-ES2015WeakSet.js deleted file mode 100755 index 0e849f1a..00000000 --- a/examples/chapter08/07-ES2015WeakSet.js +++ /dev/null @@ -1,16 +0,0 @@ -var set = new WeakSet(); - -const ob1 = { name: 'Gandalf' }; -const ob2 = { name: 'John' }; -const ob3 = { name: 'Tyrion' }; - -set.add(ob1); -set.add(ob2); -set.add(ob3); - -console.log(set.has(ob1)); // true -console.log(set.has(ob2)); // true -console.log(set.has(ob3)); // true - -set.delete(ob2); -console.log(set.has(ob2)); // false diff --git a/examples/chapter09/01-IntroRecursion.html b/examples/chapter09/01-IntroRecursion.html deleted file mode 100644 index ae42e54f..00000000 --- a/examples/chapter09/01-IntroRecursion.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter09/01-IntroRecursion.js b/examples/chapter09/01-IntroRecursion.js deleted file mode 100644 index d2843215..00000000 --- a/examples/chapter09/01-IntroRecursion.js +++ /dev/null @@ -1,26 +0,0 @@ - -// functions commented below - inifite loop - -/* -function recursiveFunction(someParam) { - recursiveFunction(someParam); -} - -function recursiveFunction1(someParam) { - recursiveFunction2(someParam); -} - -function recursiveFunction2(someParam) { - recursiveFunction1(someParam); -} -*/ - -function understandRecursion(doIunderstandRecursion) { - const recursionAnswer = confirm('Do you understand recursion?'); // function logic - if (recursionAnswer === true) { // base case or stop point - return true; - } - understandRecursion(recursionAnswer); // recursive call -} - -understandRecursion(false); diff --git a/examples/chapter09/02-Factorial.html b/examples/chapter09/02-Factorial.html deleted file mode 100755 index 94c6c103..00000000 --- a/examples/chapter09/02-Factorial.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter09/02-Factorial.js b/examples/chapter09/02-Factorial.js deleted file mode 100644 index 774006f9..00000000 --- a/examples/chapter09/02-Factorial.js +++ /dev/null @@ -1,26 +0,0 @@ -// @ts-check - -function factorialIterative(number) { - if (number < 0) { - return undefined; - } - let total = 1; - for (let n = number; n > 1; n--) { - total = total * n; - } - return total; -} - -console.log('factorialIterative(5): ', factorialIterative(5)); -console.log('factorialIterative(3): ', factorialIterative(3)); - -function factorial(n) { - // console.trace(); - if (n === 1 || n === 0) { - return 1; - } - return n * factorial(n - 1); -} - -console.log('factorial(5): ', factorial(5)); -console.log('factorial(3): ', factorial(3)); diff --git a/examples/chapter09/03-JSCallStack.html b/examples/chapter09/03-JSCallStack.html deleted file mode 100644 index 0f88040d..00000000 --- a/examples/chapter09/03-JSCallStack.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter09/03-JSCallStack.js b/examples/chapter09/03-JSCallStack.js deleted file mode 100644 index fcfd6ef8..00000000 --- a/examples/chapter09/03-JSCallStack.js +++ /dev/null @@ -1,11 +0,0 @@ -let i = 0; -function recursiveFn() { - i++; - recursiveFn(); -} - -try { - recursiveFn(); -} catch (ex) { - console.log('i = ' + i + ' error: ' + ex); -} diff --git a/examples/chapter09/04-Fibonacci.html b/examples/chapter09/04-Fibonacci.html deleted file mode 100755 index 8413c457..00000000 --- a/examples/chapter09/04-Fibonacci.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter09/04-Fibonacci.js b/examples/chapter09/04-Fibonacci.js deleted file mode 100644 index 67eae205..00000000 --- a/examples/chapter09/04-Fibonacci.js +++ /dev/null @@ -1,43 +0,0 @@ -function fibonacci(n){ - if (n < 1) return 0; // {1} - if (n <= 2) return 1; // {2} - return fibonacci(n - 1) + fibonacci(n - 2); // {3} -} - -console.log('fibonacci(2)', fibonacci(2)); -console.log('fibonacci(3)', fibonacci(3)); -console.log('fibonacci(4)', fibonacci(4)); -console.log('fibonacci(5)', fibonacci(5)); - -function fibonacciIterative(n){ - let fibNMinus2 = 0; - let fibNMinus1 = 1; - let fibN = n; - for (let i = 2; i <= n; i++) { // n >= 2 - fibN = fibNMinus1 + fibNMinus2; // f(n-1) + f(n-2) - fibNMinus2 = fibNMinus1; - fibNMinus1 = fibN; - } - return fibN; -} - -console.log('fibonacciIterative(2)', fibonacciIterative(2)); -console.log('fibonacciIterative(3)', fibonacciIterative(3)); -console.log('fibonacciIterative(4)', fibonacciIterative(4)); -console.log('fibonacciIterative(5)', fibonacciIterative(5)); - -function fibonacciMemoization(n) { - const memo = [0, 1]; - const fibonacci = (n) => { - if (memo[n] != null) return memo[n]; - return memo[n] = fibonacci(n - 1) + fibonacci(n - 2); - }; - return fibonacci(n); -} - -console.log('fibonacciMemoization(2)', fibonacciMemoization(2)); -console.log('fibonacciMemoization(3)', fibonacciMemoization(3)); -console.log('fibonacciMemoization(4)', fibonacciMemoization(4)); -console.log('fibonacciMemoization(5)', fibonacciMemoization(5)); - -// https://jsperf.com/fibonacci-comparison-jsbook diff --git a/examples/chapter10/01-UsingMinHeap.html b/examples/chapter10/01-UsingMinHeap.html deleted file mode 100644 index 83814ba1..00000000 --- a/examples/chapter10/01-UsingMinHeap.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter10/01-UsingMinHeap.js b/examples/chapter10/01-UsingMinHeap.js deleted file mode 100644 index 59b7753b..00000000 --- a/examples/chapter10/01-UsingMinHeap.js +++ /dev/null @@ -1,27 +0,0 @@ -const { MinHeap } = PacktDataStructuresAlgorithms; - -let heap = new MinHeap(); - -heap.insert(2); -heap.insert(3); -heap.insert(4); -heap.insert(5); - -heap.insert(2); - -console.log(heap.getAsArray()); - -console.log('Heap size: ', heap.size()); // 5 -console.log('Heap is empty: ', heap.isEmpty()); // false -console.log('Heap min value: ', heap.findMinimum()); // 1 - -heap = new MinHeap(); -for (let i = 1; i < 10; i++) { - heap.insert(i); -} - -console.log(heap.getAsArray()); - -console.log('Extract minimum: ', heap.extract()); // 1 -console.log(heap.getAsArray()); // [2, 4, 3, 8, 5, 6, 7, 9] - diff --git a/examples/chapter10/02-UsingMaxHeap.html b/examples/chapter10/02-UsingMaxHeap.html deleted file mode 100644 index 9d573bda..00000000 --- a/examples/chapter10/02-UsingMaxHeap.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter10/02-UsingMaxHeap.js b/examples/chapter10/02-UsingMaxHeap.js deleted file mode 100644 index f1a5b97d..00000000 --- a/examples/chapter10/02-UsingMaxHeap.js +++ /dev/null @@ -1,27 +0,0 @@ -const { MaxHeap } = PacktDataStructuresAlgorithms; - -const maxHeap = new MaxHeap(); - -maxHeap.insert(2); -maxHeap.insert(3); -maxHeap.insert(4); -maxHeap.insert(5); - -maxHeap.insert(1); - -console.log(maxHeap.getAsArray()); - -console.log('Heap size: ', maxHeap.size()); // 5 -console.log('Heap is empty: ', maxHeap.isEmpty()); // false -console.log('Heap min value: ', maxHeap.findMinimum()); // 5 - -maxHeap.insert(6); -maxHeap.insert(9); -maxHeap.insert(10); -maxHeap.insert(14); - -console.log(maxHeap.getAsArray()); - -console.log('Extract minimum: ', maxHeap.extract()); -console.log(maxHeap.getAsArray()); - diff --git a/examples/chapter10/03-HeapSort.html b/examples/chapter10/03-HeapSort.html deleted file mode 100644 index e52c43f4..00000000 --- a/examples/chapter10/03-HeapSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter10/03-HeapSort.js b/examples/chapter10/03-HeapSort.js deleted file mode 100644 index 9d9b1ac0..00000000 --- a/examples/chapter10/03-HeapSort.js +++ /dev/null @@ -1,7 +0,0 @@ -const { heapSort } = PacktDataStructuresAlgorithms; - -console.log('********** Heap Sort **********'); -const array = [7, 6, 3, 5, 4, 1, 2]; - -console.log('Before sorting: ', array); -console.log('After sorting: ', heapSort(array)); diff --git a/examples/chapter11/01-UsingMinHeap.html b/examples/chapter11/01-UsingMinHeap.html deleted file mode 100644 index 83814ba1..00000000 --- a/examples/chapter11/01-UsingMinHeap.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter11/01-UsingMinHeap.js b/examples/chapter11/01-UsingMinHeap.js deleted file mode 100644 index 59b7753b..00000000 --- a/examples/chapter11/01-UsingMinHeap.js +++ /dev/null @@ -1,27 +0,0 @@ -const { MinHeap } = PacktDataStructuresAlgorithms; - -let heap = new MinHeap(); - -heap.insert(2); -heap.insert(3); -heap.insert(4); -heap.insert(5); - -heap.insert(2); - -console.log(heap.getAsArray()); - -console.log('Heap size: ', heap.size()); // 5 -console.log('Heap is empty: ', heap.isEmpty()); // false -console.log('Heap min value: ', heap.findMinimum()); // 1 - -heap = new MinHeap(); -for (let i = 1; i < 10; i++) { - heap.insert(i); -} - -console.log(heap.getAsArray()); - -console.log('Extract minimum: ', heap.extract()); // 1 -console.log(heap.getAsArray()); // [2, 4, 3, 8, 5, 6, 7, 9] - diff --git a/examples/chapter11/02-UsingMaxHeap.html b/examples/chapter11/02-UsingMaxHeap.html deleted file mode 100644 index 9d573bda..00000000 --- a/examples/chapter11/02-UsingMaxHeap.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter11/02-UsingMaxHeap.js b/examples/chapter11/02-UsingMaxHeap.js deleted file mode 100644 index f1a5b97d..00000000 --- a/examples/chapter11/02-UsingMaxHeap.js +++ /dev/null @@ -1,27 +0,0 @@ -const { MaxHeap } = PacktDataStructuresAlgorithms; - -const maxHeap = new MaxHeap(); - -maxHeap.insert(2); -maxHeap.insert(3); -maxHeap.insert(4); -maxHeap.insert(5); - -maxHeap.insert(1); - -console.log(maxHeap.getAsArray()); - -console.log('Heap size: ', maxHeap.size()); // 5 -console.log('Heap is empty: ', maxHeap.isEmpty()); // false -console.log('Heap min value: ', maxHeap.findMinimum()); // 5 - -maxHeap.insert(6); -maxHeap.insert(9); -maxHeap.insert(10); -maxHeap.insert(14); - -console.log(maxHeap.getAsArray()); - -console.log('Extract minimum: ', maxHeap.extract()); -console.log(maxHeap.getAsArray()); - diff --git a/examples/chapter11/03-HeapSort.html b/examples/chapter11/03-HeapSort.html deleted file mode 100644 index e52c43f4..00000000 --- a/examples/chapter11/03-HeapSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter11/03-HeapSort.js b/examples/chapter11/03-HeapSort.js deleted file mode 100644 index 9d9b1ac0..00000000 --- a/examples/chapter11/03-HeapSort.js +++ /dev/null @@ -1,7 +0,0 @@ -const { heapSort } = PacktDataStructuresAlgorithms; - -console.log('********** Heap Sort **********'); -const array = [7, 6, 3, 5, 4, 1, 2]; - -console.log('Before sorting: ', array); -console.log('After sorting: ', heapSort(array)); diff --git a/examples/chapter12/01-UsingGraphs.html b/examples/chapter12/01-UsingGraphs.html deleted file mode 100644 index 49eb9bff..00000000 --- a/examples/chapter12/01-UsingGraphs.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter12/01-UsingGraphs.js b/examples/chapter12/01-UsingGraphs.js deleted file mode 100644 index dde70c0d..00000000 --- a/examples/chapter12/01-UsingGraphs.js +++ /dev/null @@ -1,23 +0,0 @@ -const { Graph } = PacktDataStructuresAlgorithms; - -const graph = new Graph(); - -const myVertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; - -for (let i = 0; i < myVertices.length; i++) { - graph.addVertex(myVertices[i]); -} -graph.addEdge('A', 'B'); -graph.addEdge('A', 'C'); -graph.addEdge('A', 'D'); -graph.addEdge('C', 'D'); -graph.addEdge('C', 'G'); -graph.addEdge('D', 'G'); -graph.addEdge('D', 'H'); -graph.addEdge('B', 'E'); -graph.addEdge('B', 'F'); -graph.addEdge('E', 'I'); - -console.log('********* printing graph ***********'); - -console.log(graph.toString()); diff --git a/examples/chapter12/02-BFS.html b/examples/chapter12/02-BFS.html deleted file mode 100644 index 044da5d6..00000000 --- a/examples/chapter12/02-BFS.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter12/02-BFS.js b/examples/chapter12/02-BFS.js deleted file mode 100644 index d65c8b66..00000000 --- a/examples/chapter12/02-BFS.js +++ /dev/null @@ -1,54 +0,0 @@ -const { Graph } = PacktDataStructuresAlgorithms; -const { Stack } = PacktDataStructuresAlgorithms; -const { BFS } = PacktDataStructuresAlgorithms; -const { breadthFirstSearch } = PacktDataStructuresAlgorithms; - -const graph = new Graph(); - -const myVertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; - -for (let i = 0; i < myVertices.length; i++) { - graph.addVertex(myVertices[i]); -} -graph.addEdge('A', 'B'); -graph.addEdge('A', 'C'); -graph.addEdge('A', 'D'); -graph.addEdge('C', 'D'); -graph.addEdge('C', 'G'); -graph.addEdge('D', 'G'); -graph.addEdge('D', 'H'); -graph.addEdge('B', 'E'); -graph.addEdge('B', 'F'); -graph.addEdge('E', 'I'); - -console.log('********* printing graph ***********'); - -console.log(graph.toString()); - -console.log('********* bfs with callback ***********'); - -const printVertex = (value) => console.log('Visited vertex: ' + value); - -breadthFirstSearch(graph, myVertices[0], printVertex); - -console.log('********* sorthest path - BFS ***********'); -const shortestPathA = BFS(graph, myVertices[0]); -console.log(shortestPathA.distances); -console.log(shortestPathA.predecessors); - -//from A to all other vertices -const fromVertex = myVertices[0]; - -for (let i = 1; i < myVertices.length; i++) { - const toVertex = myVertices[i]; - const path = new Stack(); - for (let v = toVertex; v !== fromVertex; v = shortestPathA.predecessors[v]) { - path.push(v); - } - path.push(fromVertex); - let s = path.pop(); - while (!path.isEmpty()) { - s += ' - ' + path.pop(); - } - console.log(s); -} diff --git a/examples/chapter12/03-DFS.html b/examples/chapter12/03-DFS.html deleted file mode 100644 index 1a5bd4f3..00000000 --- a/examples/chapter12/03-DFS.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter12/03-DFS.js b/examples/chapter12/03-DFS.js deleted file mode 100644 index 5c440a74..00000000 --- a/examples/chapter12/03-DFS.js +++ /dev/null @@ -1,67 +0,0 @@ -const { Graph } = PacktDataStructuresAlgorithms; -const { depthFirstSearch } = PacktDataStructuresAlgorithms; -const { DFS } = PacktDataStructuresAlgorithms; - -let graph = new Graph(true); - -let myVertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; - -for (let i = 0; i < myVertices.length; i++) { - graph.addVertex(myVertices[i]); -} -graph.addEdge('A', 'B'); -graph.addEdge('A', 'C'); -graph.addEdge('A', 'D'); -graph.addEdge('C', 'D'); -graph.addEdge('C', 'G'); -graph.addEdge('D', 'G'); -graph.addEdge('D', 'H'); -graph.addEdge('B', 'E'); -graph.addEdge('B', 'F'); -graph.addEdge('E', 'I'); - -console.log('********* printing graph ***********'); - -console.log(graph.toString()); - -console.log('********* dfs with callback ***********'); - -const printVertex = value => console.log('Visited vertex: ' + value); - -depthFirstSearch(graph, printVertex); - -console.log('********* topological sort - DFS ***********'); - -graph = new Graph(true); // directed graph - -myVertices = ['A', 'B', 'C', 'D', 'E', 'F']; -for (i = 0; i < myVertices.length; i++) { - graph.addVertex(myVertices[i]); -} -graph.addEdge('A', 'C'); -graph.addEdge('A', 'D'); -graph.addEdge('B', 'D'); -graph.addEdge('B', 'E'); -graph.addEdge('C', 'F'); -graph.addEdge('F', 'E'); - -const result = DFS(graph); -console.log('discovery', result.discovery); -console.log('finished', result.finished); -console.log('predecessors', result.predecessors); - -const fTimes = result.finished; -s = ''; -for (let count = 0; count < myVertices.length; count++) { - let max = 0; - let maxName = null; - for (i = 0; i < myVertices.length; i++) { - if (fTimes[myVertices[i]] > max) { - max = fTimes[myVertices[i]]; - maxName = myVertices[i]; - } - } - s += ' - ' + maxName; - delete fTimes[maxName]; -} -console.log(s); diff --git a/examples/chapter12/04-Dijkstra.html b/examples/chapter12/04-Dijkstra.html deleted file mode 100644 index 8b9e0f74..00000000 --- a/examples/chapter12/04-Dijkstra.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter12/04-Dijkstra.js b/examples/chapter12/04-Dijkstra.js deleted file mode 100644 index dfa58854..00000000 --- a/examples/chapter12/04-Dijkstra.js +++ /dev/null @@ -1,18 +0,0 @@ -const { dijkstra } = PacktDataStructuresAlgorithms; - -const graph = [ - [0, 2, 4, 0, 0, 0], - [0, 0, 2, 4, 2, 0], - [0, 0, 0, 0, 3, 0], - [0, 0, 0, 0, 0, 2], - [0, 0, 0, 3, 0, 2], - [0, 0, 0, 0, 0, 0] -]; - -console.log("********* Dijkstra's Algorithm - Shortest Path ***********"); - -const dist = dijkstra(graph, 0); - -for (i = 0; i < dist.length; i++){ - console.log(i + '\t\t' + dist[i]); -} diff --git a/examples/chapter12/05-Floyd-Warshall.html b/examples/chapter12/05-Floyd-Warshall.html deleted file mode 100644 index be411625..00000000 --- a/examples/chapter12/05-Floyd-Warshall.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter12/05-Floyd-Warshall.js b/examples/chapter12/05-Floyd-Warshall.js deleted file mode 100644 index 18c2dee6..00000000 --- a/examples/chapter12/05-Floyd-Warshall.js +++ /dev/null @@ -1,25 +0,0 @@ -const { floydWarshall } = PacktDataStructuresAlgorithms; - -const INF = Infinity; -const graph = [ - [INF, 2, 4, INF, INF, INF], - [INF, INF, 2, 4, 2, INF], - [INF, INF, INF, INF, 3, INF], - [INF, INF, INF, INF, INF, 2], - [INF, INF, INF, 3, INF, 2], - [INF, INF, INF, INF, INF, INF] -]; - -console.log('********* Floyd-Warshall Algorithm - All-Pairs Shortest Path ***********'); - -dist = floydWarshall(graph); - -let s = ''; -for (let i = 0; i < dist.length; ++i) { - s = ''; - for (var j = 0; j < dist.length; ++j) { - if (dist[i][j] === INF) s += 'INF '; - else s += dist[i][j] + ' '; - } - console.log(s); -} diff --git a/examples/chapter12/06-Prim.html b/examples/chapter12/06-Prim.html deleted file mode 100644 index 7cbb2537..00000000 --- a/examples/chapter12/06-Prim.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter12/06-Prim.js b/examples/chapter12/06-Prim.js deleted file mode 100644 index cb971a4e..00000000 --- a/examples/chapter12/06-Prim.js +++ /dev/null @@ -1,19 +0,0 @@ -const { prim } = PacktDataStructuresAlgorithms; - -const graph = [ - [0, 2, 4, 0, 0, 0], - [2, 0, 2, 4, 2, 0], - [4, 2, 0, 0, 3, 0], - [0, 4, 0, 0, 3, 2], - [0, 2, 3, 3, 0, 2], - [0, 0, 0, 2, 2, 0] -]; - -console.log("********* Prim's Algorithm - Minimum Spanning Tree ***********"); - -const parent = prim(graph); - -console.log('Edge Weight'); -for (let i = 1; i < graph.length; i++) { - console.log(parent[i] + ' - ' + i + ' ' + graph[i][parent[i]]); -} diff --git a/examples/chapter12/07-Kruskal.html b/examples/chapter12/07-Kruskal.html deleted file mode 100644 index 89e214fb..00000000 --- a/examples/chapter12/07-Kruskal.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter12/07-Kruskal.js b/examples/chapter12/07-Kruskal.js deleted file mode 100644 index 460fbd83..00000000 --- a/examples/chapter12/07-Kruskal.js +++ /dev/null @@ -1,19 +0,0 @@ -const { kruskal } = PacktDataStructuresAlgorithms; - -const graph = [ - [0, 2, 4, 0, 0, 0], - [2, 0, 2, 4, 2, 0], - [4, 2, 0, 0, 3, 0], - [0, 4, 0, 0, 3, 2], - [0, 2, 3, 3, 0, 2], - [0, 0, 0, 2, 2, 0] -]; - -console.log('********* Kruskal Algorithm - Minimum Spanning Tree ***********'); - -const parent = kruskal(graph); - -console.log('Edge Weight'); -for (i = 1; i < graph.length; i++) { - console.log(parent[i] + ' - ' + i + ' ' + graph[i][parent[i]]); -} diff --git a/examples/chapter13/01-BubbleSort.html b/examples/chapter13/01-BubbleSort.html deleted file mode 100644 index 88d9a1da..00000000 --- a/examples/chapter13/01-BubbleSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter13/01-BubbleSort.js b/examples/chapter13/01-BubbleSort.js deleted file mode 100644 index fff8970e..00000000 --- a/examples/chapter13/01-BubbleSort.js +++ /dev/null @@ -1,12 +0,0 @@ -const { bubbleSort } = PacktDataStructuresAlgorithms; - -function createNonSortedArray(){ - var array = []; - for (let i = 5; i > 0; i--){ - array.push(i); - } - return array; -} - -const array = bubbleSort(createNonSortedArray()); -console.log(array); diff --git a/examples/chapter13/01-BucketSort.html b/examples/chapter13/01-BucketSort.html deleted file mode 100644 index 88d9a1da..00000000 --- a/examples/chapter13/01-BucketSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter13/01-BucketSort.js b/examples/chapter13/01-BucketSort.js deleted file mode 100644 index fff8970e..00000000 --- a/examples/chapter13/01-BucketSort.js +++ /dev/null @@ -1,12 +0,0 @@ -const { bubbleSort } = PacktDataStructuresAlgorithms; - -function createNonSortedArray(){ - var array = []; - for (let i = 5; i > 0; i--){ - array.push(i); - } - return array; -} - -const array = bubbleSort(createNonSortedArray()); -console.log(array); diff --git a/examples/chapter13/01-CountingSort.html b/examples/chapter13/01-CountingSort.html deleted file mode 100644 index 88d9a1da..00000000 --- a/examples/chapter13/01-CountingSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter13/01-CountingSort.js b/examples/chapter13/01-CountingSort.js deleted file mode 100644 index fff8970e..00000000 --- a/examples/chapter13/01-CountingSort.js +++ /dev/null @@ -1,12 +0,0 @@ -const { bubbleSort } = PacktDataStructuresAlgorithms; - -function createNonSortedArray(){ - var array = []; - for (let i = 5; i > 0; i--){ - array.push(i); - } - return array; -} - -const array = bubbleSort(createNonSortedArray()); -console.log(array); diff --git a/examples/chapter13/01-InsertionSort.html b/examples/chapter13/01-InsertionSort.html deleted file mode 100644 index 88d9a1da..00000000 --- a/examples/chapter13/01-InsertionSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter13/01-InsertionSort.js b/examples/chapter13/01-InsertionSort.js deleted file mode 100644 index fff8970e..00000000 --- a/examples/chapter13/01-InsertionSort.js +++ /dev/null @@ -1,12 +0,0 @@ -const { bubbleSort } = PacktDataStructuresAlgorithms; - -function createNonSortedArray(){ - var array = []; - for (let i = 5; i > 0; i--){ - array.push(i); - } - return array; -} - -const array = bubbleSort(createNonSortedArray()); -console.log(array); diff --git a/examples/chapter13/01-MergeSort.html b/examples/chapter13/01-MergeSort.html deleted file mode 100644 index 88d9a1da..00000000 --- a/examples/chapter13/01-MergeSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter13/01-MergeSort.js b/examples/chapter13/01-MergeSort.js deleted file mode 100644 index fff8970e..00000000 --- a/examples/chapter13/01-MergeSort.js +++ /dev/null @@ -1,12 +0,0 @@ -const { bubbleSort } = PacktDataStructuresAlgorithms; - -function createNonSortedArray(){ - var array = []; - for (let i = 5; i > 0; i--){ - array.push(i); - } - return array; -} - -const array = bubbleSort(createNonSortedArray()); -console.log(array); diff --git a/examples/chapter13/01-QuickSort.html b/examples/chapter13/01-QuickSort.html deleted file mode 100644 index 88d9a1da..00000000 --- a/examples/chapter13/01-QuickSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter13/01-QuickSort.js b/examples/chapter13/01-QuickSort.js deleted file mode 100644 index fff8970e..00000000 --- a/examples/chapter13/01-QuickSort.js +++ /dev/null @@ -1,12 +0,0 @@ -const { bubbleSort } = PacktDataStructuresAlgorithms; - -function createNonSortedArray(){ - var array = []; - for (let i = 5; i > 0; i--){ - array.push(i); - } - return array; -} - -const array = bubbleSort(createNonSortedArray()); -console.log(array); diff --git a/examples/chapter13/01-RadixSort.html b/examples/chapter13/01-RadixSort.html deleted file mode 100644 index 88d9a1da..00000000 --- a/examples/chapter13/01-RadixSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter13/01-RadixSort.js b/examples/chapter13/01-RadixSort.js deleted file mode 100644 index fff8970e..00000000 --- a/examples/chapter13/01-RadixSort.js +++ /dev/null @@ -1,12 +0,0 @@ -const { bubbleSort } = PacktDataStructuresAlgorithms; - -function createNonSortedArray(){ - var array = []; - for (let i = 5; i > 0; i--){ - array.push(i); - } - return array; -} - -const array = bubbleSort(createNonSortedArray()); -console.log(array); diff --git a/examples/chapter13/01-SelectionSort.html b/examples/chapter13/01-SelectionSort.html deleted file mode 100644 index 88d9a1da..00000000 --- a/examples/chapter13/01-SelectionSort.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter13/01-SelectionSort.js b/examples/chapter13/01-SelectionSort.js deleted file mode 100644 index fff8970e..00000000 --- a/examples/chapter13/01-SelectionSort.js +++ /dev/null @@ -1,12 +0,0 @@ -const { bubbleSort } = PacktDataStructuresAlgorithms; - -function createNonSortedArray(){ - var array = []; - for (let i = 5; i > 0; i--){ - array.push(i); - } - return array; -} - -const array = bubbleSort(createNonSortedArray()); -console.log(array); diff --git a/examples/chapter14/01-DC-BinarySearch.html b/examples/chapter14/01-DC-BinarySearch.html deleted file mode 100644 index b110b636..00000000 --- a/examples/chapter14/01-DC-BinarySearch.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/01-DC-BinarySearch.js b/examples/chapter14/01-DC-BinarySearch.js deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/chapter14/02-MinCoinChangeDP.html b/examples/chapter14/02-MinCoinChangeDP.html deleted file mode 100644 index 4c2027b3..00000000 --- a/examples/chapter14/02-MinCoinChangeDP.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/02-MinCoinChangeDP.js b/examples/chapter14/02-MinCoinChangeDP.js deleted file mode 100644 index 51ce7ed3..00000000 --- a/examples/chapter14/02-MinCoinChangeDP.js +++ /dev/null @@ -1,5 +0,0 @@ -const { minCoinChange } = PacktDataStructuresAlgorithms; - -console.log(minCoinChange([1, 5, 10], 15)); // [5, 10] -console.log(minCoinChange([1, 3, 4], 6)); // [3, 3] - diff --git a/examples/chapter14/03-MinCoinChangeGreedy.html b/examples/chapter14/03-MinCoinChangeGreedy.html deleted file mode 100644 index 92b0618f..00000000 --- a/examples/chapter14/03-MinCoinChangeGreedy.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/03-MinCoinChangeGreedy.js b/examples/chapter14/03-MinCoinChangeGreedy.js deleted file mode 100644 index 584603f2..00000000 --- a/examples/chapter14/03-MinCoinChangeGreedy.js +++ /dev/null @@ -1,5 +0,0 @@ -const { minCoinChangeGreedy } = PacktDataStructuresAlgorithms; - -console.log(minCoinChangeGreedy([1, 5, 10], 15)); // [5, 10] -console.log(minCoinChangeGreedy([1, 3, 4], 6)); // [4, 1, 1] - diff --git a/examples/chapter14/04-KnapsackProblemDP.html b/examples/chapter14/04-KnapsackProblemDP.html deleted file mode 100644 index 1f06c983..00000000 --- a/examples/chapter14/04-KnapsackProblemDP.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/04-KnapsackProblemDP.js b/examples/chapter14/04-KnapsackProblemDP.js deleted file mode 100644 index e9ff4369..00000000 --- a/examples/chapter14/04-KnapsackProblemDP.js +++ /dev/null @@ -1,8 +0,0 @@ -const { knapSack } = PacktDataStructuresAlgorithms; - -const values = [3,4,5]; -const weights = [2,3,4]; -const capacity = 5; -const n = values.length; - -console.log(knapSack(capacity, weights, values, n)); diff --git a/examples/chapter14/05-KnapSackProblemRecursive.html b/examples/chapter14/05-KnapSackProblemRecursive.html deleted file mode 100644 index 610d7310..00000000 --- a/examples/chapter14/05-KnapSackProblemRecursive.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/05-KnapSackProblemRecursive.js b/examples/chapter14/05-KnapSackProblemRecursive.js deleted file mode 100644 index ba76971b..00000000 --- a/examples/chapter14/05-KnapSackProblemRecursive.js +++ /dev/null @@ -1,8 +0,0 @@ -const { knapSackRecursive } = PacktDataStructuresAlgorithms; - -const values = [3,4,5]; -const weights = [2,3,4]; -const capacity = 5; -const n = values.length; - -console.log(knapSackRecursive(capacity, weights, values, n)); diff --git a/examples/chapter14/06-KnapSackProblemGreedy.html b/examples/chapter14/06-KnapSackProblemGreedy.html deleted file mode 100644 index 0d2e3c04..00000000 --- a/examples/chapter14/06-KnapSackProblemGreedy.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/06-KnapSackProblemGreedy.js b/examples/chapter14/06-KnapSackProblemGreedy.js deleted file mode 100644 index d9858107..00000000 --- a/examples/chapter14/06-KnapSackProblemGreedy.js +++ /dev/null @@ -1,7 +0,0 @@ -const { knapSackGreedy } = PacktDataStructuresAlgorithms; - -const values = [3,4,5]; -const weights = [2,3,4]; -const capacity = 5; - -console.log(knapSackGreedy(capacity, weights, values)); diff --git a/examples/chapter14/07-LongestCommonSubsequenceDP.html b/examples/chapter14/07-LongestCommonSubsequenceDP.html deleted file mode 100644 index f4b8b8a8..00000000 --- a/examples/chapter14/07-LongestCommonSubsequenceDP.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/07-LongestCommonSubsequenceDP.js b/examples/chapter14/07-LongestCommonSubsequenceDP.js deleted file mode 100644 index 75e86015..00000000 --- a/examples/chapter14/07-LongestCommonSubsequenceDP.js +++ /dev/null @@ -1,8 +0,0 @@ -const { lcs } = PacktDataStructuresAlgorithms; -const { lcsPrint } = PacktDataStructuresAlgorithms; - -const wordX = 'acbaed'; -const wordY = 'abcadf'; - -console.log('lcs', lcs(wordX, wordY)); -console.log('lcsPrint', lcsPrint(wordX, wordY)); diff --git a/examples/chapter14/08-LongestCommonSubsequenceRecursive.html b/examples/chapter14/08-LongestCommonSubsequenceRecursive.html deleted file mode 100644 index 25fa3a3f..00000000 --- a/examples/chapter14/08-LongestCommonSubsequenceRecursive.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/08-LongestCommonSubsequenceRecursive.js b/examples/chapter14/08-LongestCommonSubsequenceRecursive.js deleted file mode 100644 index 63c2daf7..00000000 --- a/examples/chapter14/08-LongestCommonSubsequenceRecursive.js +++ /dev/null @@ -1,6 +0,0 @@ -const { lcsRecursive } = PacktDataStructuresAlgorithms; - -const wordX = 'acbaed'; -const wordY = 'abcadf'; - -console.log('lcsRecursive', lcsRecursive(wordX, wordY)); diff --git a/examples/chapter14/09-MatrixChainMultiplicationDP.html b/examples/chapter14/09-MatrixChainMultiplicationDP.html deleted file mode 100644 index 110165d7..00000000 --- a/examples/chapter14/09-MatrixChainMultiplicationDP.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/09-MatrixChainMultiplicationDP.js b/examples/chapter14/09-MatrixChainMultiplicationDP.js deleted file mode 100644 index 50e92fd5..00000000 --- a/examples/chapter14/09-MatrixChainMultiplicationDP.js +++ /dev/null @@ -1,4 +0,0 @@ -const { matrixChainOrder } = PacktDataStructuresAlgorithms; - -const p = [10, 100, 5, 50, 1]; -console.log(matrixChainOrder(p)); diff --git a/examples/chapter14/10-MatrixChainMultiplicationRecursive.html b/examples/chapter14/10-MatrixChainMultiplicationRecursive.html deleted file mode 100644 index eba9ceaf..00000000 --- a/examples/chapter14/10-MatrixChainMultiplicationRecursive.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/10-MatrixChainMultiplicationRecursive.js b/examples/chapter14/10-MatrixChainMultiplicationRecursive.js deleted file mode 100644 index 97245276..00000000 --- a/examples/chapter14/10-MatrixChainMultiplicationRecursive.js +++ /dev/null @@ -1,4 +0,0 @@ -const { matrixChainOrderGreedy } = PacktDataStructuresAlgorithms; - -const p = [10, 100, 5, 50, 1]; -console.log(matrixChainOrderGreedy(p)); diff --git a/examples/chapter14/11-RatInMaze.html b/examples/chapter14/11-RatInMaze.html deleted file mode 100644 index da73582f..00000000 --- a/examples/chapter14/11-RatInMaze.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/11-RatInMaze.js b/examples/chapter14/11-RatInMaze.js deleted file mode 100644 index 221e7f19..00000000 --- a/examples/chapter14/11-RatInMaze.js +++ /dev/null @@ -1,10 +0,0 @@ -const { ratInAMaze } = PacktDataStructuresAlgorithms; - -const maze = [ - [1, 0, 0, 0], - [1, 1, 1, 1], - [0, 0, 1, 0], - [0, 1, 1, 1] -]; - -console.log(ratInAMaze(maze)); diff --git a/examples/chapter14/12-SudokuSolver.html b/examples/chapter14/12-SudokuSolver.html deleted file mode 100644 index b3126287..00000000 --- a/examples/chapter14/12-SudokuSolver.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/12-SudokuSolver.js b/examples/chapter14/12-SudokuSolver.js deleted file mode 100644 index bf52ddf3..00000000 --- a/examples/chapter14/12-SudokuSolver.js +++ /dev/null @@ -1,15 +0,0 @@ -const { sudokuSolver } = PacktDataStructuresAlgorithms; - -const sudokuGrid = [ - [5, 3, 0, 0, 7, 0, 0, 0, 0], - [6, 0, 0, 1, 9, 5, 0, 0, 0], - [0, 9, 8, 0, 0, 0, 0, 6, 0], - [8, 0, 0, 0, 6, 0, 0, 0, 3], - [4, 0, 0, 8, 0, 3, 0, 0, 1], - [7, 0, 0, 0, 2, 0, 0, 0, 6], - [0, 6, 0, 0, 0, 0, 2, 8, 0], - [0, 0, 0, 4, 1, 9, 0, 0, 5], - [0, 0, 0, 0, 8, 0, 0, 7, 9] -]; - -console.log(sudokuSolver(sudokuGrid)); diff --git a/examples/chapter14/13-IntroFunctionalProgramming.html b/examples/chapter14/13-IntroFunctionalProgramming.html deleted file mode 100644 index 0d7cd0ed..00000000 --- a/examples/chapter14/13-IntroFunctionalProgramming.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/examples/chapter14/13-IntroFunctionalProgramming.js b/examples/chapter14/13-IntroFunctionalProgramming.js deleted file mode 100644 index 692bebd6..00000000 --- a/examples/chapter14/13-IntroFunctionalProgramming.js +++ /dev/null @@ -1,147 +0,0 @@ -console.log('Using imperative JS'); - -var printArray = function(array){ - for (var i=0; i array[i]){ - minValue = array[i]; - } - } - - return minValue; -}; - -console.log(findMinArray([8,6,4,5,9])); - -console.log('Finding the min value in an array - functional ES2015'); -const min_ = function(array){ - return Math.min(...array) -}; - -//simplifying using arrow functions -const min = arr => Math.min(...arr); - -console.log(min_([8,6,4,5,9])); -console.log(min([8,6,4,5,9])); - -//concat + reduce -console.log('merge arrays - imperative'); - -var mergeArrays_ = function(arrays){ - var count = arrays.length, - newArray = [], - k =0; - for (var i=0; i [].concat(...arrays); -console.log(mergeArrays([1, 2, 3], [4, 5], [6])); - -console.log('sum values of arrays - imperative'); -var sumValues = function(array){ - var total = array[0]; - for (var i=1; i arr.reduce((a, b) => a + b); - -console.log(sum([1, 2, 3, 4, 5])); - -//map -var daysOfWeek = [ - {name: 'Monday', value: 1}, - {name: 'Tuesday', value: 2}, - {name: 'Wednesday', value: 7} -]; - -var daysOfWeekValues_ = []; -for (var i = 0; i < daysOfWeek.length; i++) { - daysOfWeekValues_.push(daysOfWeek[i].value); -} - -//to -var daysOfWeekValues = daysOfWeek.map(function(day) { - return day.value; -}); -console.log(daysOfWeekValues); - - -//filter -var positiveNumbers_ = function(array){ - var positive = []; - for (var i = 0; i < array.length; i++) { - if (array[i] >= 0){ - positive.push(array[i]); - } - } - return positive; -} -console.log(positiveNumbers_([-1,1,2,-2])); - -var positiveNumbers = function(array){ - return array.filter(function(num){ - return num >= 0; - }) -}; -console.log(positiveNumbers([-1,1,2,-2])); diff --git a/examples/chapter15/01-BigONotation.html b/examples/chapter15/01-BigONotation.html deleted file mode 100755 index f8f26334..00000000 --- a/examples/chapter15/01-BigONotation.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/examples/chapter15/01-BigONotation.js b/examples/chapter15/01-BigONotation.js deleted file mode 100755 index a48bd6ab..00000000 --- a/examples/chapter15/01-BigONotation.js +++ /dev/null @@ -1,65 +0,0 @@ -//*************** o(1) -function increment(num){ - console.log('cost for increment with input ' + num + ' is 1'); - return ++num; -} - -increment(1); -increment(2); - -//*************** o(n) - -function createNonSortedArray(size){ - var array = []; - - for (var i = size; i> 0; i--){ - array[i] = i; - } - - return array; -} - -function sequentialSearch(array, item){ - var cost = 0; - for (var i=0; i array[j+1]){ - swap(array, j, j+1); - } - } - } - console.log('cost for bubbleSort with input size ' + length + ' is ' + cost); -} - -var array1 = createNonSortedArray(99); -var array2 = createNonSortedArray(999); -var array3 = createNonSortedArray(9999); -bubbleSort(array1); -bubbleSort(array2); -bubbleSort(array3); \ No newline at end of file diff --git a/examples/examples-screenshot.png b/examples/examples-screenshot.png deleted file mode 100644 index a264d142..00000000 Binary files a/examples/examples-screenshot.png and /dev/null differ diff --git a/examples/index.html b/examples/index.html deleted file mode 100644 index 7e3e6629..00000000 --- a/examples/index.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - Data Structures and Algorithms with JavaScript - - - - - - - - - - -
-
-
- - Learning JavaScript Data Structures and Algorithms -
- -
- 01_02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 -
-
-
- Please open the Developer Tools Console to see the output - -
- -
- -
- -
-
- -
-
- -
-
- -
-
- -
-
-
- -
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
- -
-
-
-
-
- - - diff --git a/firebase.json b/firebase.json deleted file mode 100644 index f90fd865..00000000 --- a/firebase.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "hosting": { - "public": "examples", - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ] - } -} diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 00000000..cb9f7f6b --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,199 @@ +/** + * For a detailed explanation regarding each configuration property, visit: + * https://jestjs.io/docs/configuration + */ + +import type {Config} from 'jest'; + +const config: Config = { + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after `n` failures + // bail: 0, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/private/var/folders/0n/pj12f8hx3d93_n_gvxzr7qwc0000gn/T/jest_dx", + + // Automatically clear mock calls, instances, contexts and results before every test + clearMocks: true, + + // Indicates whether the coverage information should be collected while executing the test + collectCoverage: true, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: undefined, + + // The directory where Jest should output its coverage files + coverageDirectory: "coverage", + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // Indicates which provider should be used to instrument code for coverage + coverageProvider: "v8", + + // A list of reporter names that Jest uses when writing coverage reports + // coverageReporters: [ + // "json", + // "text", + // "lcov", + // "clover" + // ], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // The default configuration for fake timers + // fakeTimers: { + // "enableGlobally": false + // }, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // maxWorkers: "50%", + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // "node_modules" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "mjs", + // "cjs", + // "jsx", + // "ts", + // "tsx", + // "json", + // "node" + // ], + + // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module + // moduleNameMapper: {}, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: "failure-change", + + // A preset that is used as a base for Jest's configuration + preset: "ts-jest", + + // Run tests from one or more projects + // projects: undefined, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state before every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: undefined, + + // Automatically restore mock state and implementation before every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // A list of paths to directories that Jest should use to search for files in + // roots: [ + // "" + // ], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: "jest-runner", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + // setupFilesAfterEnv: [], + + // The number of seconds after which a test is considered as slow and reported as such in the results. + // slowTestThreshold: 5, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + testEnvironment: "node", + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + // testMatch: [ + // "**/__tests__/**/*.[jt]s?(x)", + // "**/?(*.)+(spec|test).[tj]s?(x)" + // ], + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // "/node_modules/" + // ], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // This option allows use of a custom test runner + // testRunner: "jest-circus/runner", + + // A map from regular expressions to paths to transformers + // transform: undefined, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/", + // "\\.pnp\\.[^\\/]+$" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: undefined, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, +}; + +export default config; diff --git a/jsconfig.json b/jsconfig.json deleted file mode 100644 index 49805359..00000000 --- a/jsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "target": "ES5", - "module": "commonjs" , - "outDir": "./dist/js", - "removeComments": true, - "strict": true - }, - "exclude": ["node_modules", "dist"], - "include": ["src/js/**/*","html/**"] -} diff --git a/package-lock.json b/package-lock.json index afb891a9..30e3acdb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11558 +1,3733 @@ { "name": "javascript-datastructures-algorithms", - "version": "0.0.1", - "lockfileVersion": 1, + "version": "4.0.0", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" + "packages": { + "": { + "name": "javascript-datastructures-algorithms", + "version": "4.0.0", + "devDependencies": { + "@jest/globals": "^29.7.0", + "jest": "^29.7.0", + "ts-jest": "^29.1.3", + "ts-node": "^10.9.2", + "typescript": "^5.4.5" } }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, - "requires": { - "@babel/types": "^7.22.5" - }, "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - } + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" } }, - "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "node_modules/@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/parser": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.3.tgz", - "integrity": "sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==", - "dev": true - }, - "@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "node_modules/@babel/compat-data": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", + "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - } - }, - "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, - "requires": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "dev": true - }, - "@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" - } - }, - "@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "@babel/types": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz", - "integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==", + "node_modules/@babel/core": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz", + "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - }, "dependencies": { - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - } + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.24.5", + "@babel/helpers": "^7.24.5", + "@babel/parser": "^7.24.5", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.5", + "@babel/types": "^7.24.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "@jridgewell/gen-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", - "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "node_modules/@babel/generator": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", + "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "dependencies": { + "@babel/types": "^7.24.5", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", - "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@types/chai": { - "version": "4.2.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", - "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" + "engines": { + "node": ">=6.9.0" } }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.9.0" + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0" + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "node_modules/@babel/helper-module-imports": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" + "dependencies": { + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz", + "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==", "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.24.3", + "@babel/helper-simple-access": "^7.24.5", + "@babel/helper-split-export-declaration": "^7.24.5", + "@babel/helper-validator-identifier": "^7.24.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz", + "integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==", "dev": true, - "requires": { - "@xtuc/long": "4.2.2" + "engines": { + "node": ">=6.9.0" } }, - "@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@babel/helper-simple-access": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz", + "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==", "dev": true, - "requires": { - "debug": "4" - }, "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } + "@babel/types": "^7.24.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", + "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "dependencies": { + "@babel/types": "^7.24.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "node_modules/@babel/helper-string-parser": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", "dev": true, - "optional": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "engines": { + "node": ">=6.9.0" } }, - "append-transform": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", - "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", + "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", "dev": true, - "requires": { - "default-require-extensions": "^1.0.0" + "engines": { + "node": ">=6.9.0" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + "engines": { + "node": ">=6.9.0" } }, - "argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", - "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", - "dev": true - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "node_modules/@babel/helpers": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.5.tgz", + "integrity": "sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==", "dev": true, - "optional": true, - "requires": { - "arr-flatten": "^1.0.1" + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.5", + "@babel/types": "^7.24.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "node_modules/@babel/highlight": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", + "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "is-string": "^1.0.5" + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true, - "optional": true - }, - "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } + "color-name": "1.1.3" } }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "requires": { - "lodash": "^4.17.14" + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" } }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "optional": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "babel-cli": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", - "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "engines": { + "node": ">=4" } }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "node_modules/@babel/parser": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", + "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "requires": { - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", - "schema-utils": "^2.6.5" + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", + "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-add-module-exports": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz", - "integrity": "sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==", - "dev": true - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true + "node_modules/@babel/traverse": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz", + "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.24.5", + "@babel/parser": "^7.24.5", + "@babel/types": "^7.24.5", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true + "node_modules/@babel/types": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", + "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.1", + "@babel/helper-validator-identifier": "^7.24.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" } }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "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" + }, + "engines": { + "node": ">=8" } }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" } }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "engines": { + "node": ">=6.0.0" } }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=6.0.0" } }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "dependencies": { + "type-detect": "4.0.8" } }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0" + "dependencies": { + "@sinonjs/commons": "^3.0.0" } }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "dependencies": { + "@babel/types": "^7.0.0" } }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "dependencies": { + "@babel/types": "^7.20.7" } }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } + "@types/node": "*" } }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "dependencies": { + "@types/istanbul-lib-coverage": "*" } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } + "node_modules/@types/node": { + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" } }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, - "basic-auth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", - "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=" + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, - "optional": true + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" + "engines": { + "node": ">=0.4.0" } }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=8" } }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "optional": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", - "safe-buffer": "^5.2.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" } }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, - "requires": { - "pako": "~1.0.5" + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" + "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" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" } }, - "call-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", - "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.0" + "dependencies": { + "node-int64": "^0.4.0" } }, - "callsites": { + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001154", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001154.tgz", - "integrity": "sha512-y9DvdSti8NnYB9Be92ddMZQrcOe04kcQtcxtBx4NkB04+qZ+JUWotnXBJTmxlKudhxNTQ3RRknMwNU2YQl/Org==", - "dev": true - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" + "engines": { + "node": ">=6" } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "engines": { + "node": ">=6" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "node_modules/caniuse-lite": { + "version": "1.0.30001621", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001621.tgz", + "integrity": "sha512-+NLXZiviFFKX0fk8Piwv3PfLPGtRqJeq2TiNoUff/qB5KJgwecJTvCXDpmlyP/eCI/GUEmp/h/y5j0yckiiZrA==", "dev": true, - "optional": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, - "requires": { - "restore-cursor": "^2.0.0" + "engines": { + "node": ">=10" } }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" } + ], + "engines": { + "node": ">=8" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", "dev": true }, - "codecov": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.0.tgz", - "integrity": "sha512-7E/S7hmq2CJvCMBMu+aRACO9jxQX1HJug/M3ub8+t84R+5Ai2T5sFMxS3W8P41m2A63+VSAAL4U0aBlqZXkJPw==", - "dev": true, - "requires": { - "argv": "0.0.2", - "ignore-walk": "3.0.3", - "js-yaml": "3.14.0", - "teeny-request": "7.0.1", - "urlgrey": "0.4.4" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, - "requires": { - "color-name": "1.1.3" + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "confusing-browser-globals": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", - "dev": true - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, - "requires": { - "safe-buffer": "~5.1.1" + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "corser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=" - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "requires": { - "type-detect": "^4.0.0" + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "default-require-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", - "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", "dev": true, - "requires": { - "strip-bom": "^2.0.0" + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" }, - "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true } } }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, - "requires": { - "object-keys": "^1.0.12" + "engines": { + "node": ">=0.10.0" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" } }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "engines": { + "node": ">=0.3.1" } }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, - "requires": { - "repeating": "^2.0.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "node_modules/electron-to-chromium": { + "version": "1.4.779", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.779.tgz", + "integrity": "sha512-oaTiIcszNfySXVJzKcjxd2YjPxziAd+GmXyb2HbidCeFo6Z88ygOT7EimlrEQhM2U08VhSrbKhLOXP0kKUCZ6g==", "dev": true }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "engines": { + "node": ">=12" }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "ecstatic": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.2.tgz", - "integrity": "sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==", - "requires": { - "he": "^1.1.1", - "mime": "^1.6.0", - "minimist": "^1.1.0", - "url-join": "^2.0.5" - } - }, - "electron-to-chromium": { - "version": "1.3.585", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.585.tgz", - "integrity": "sha512-xoeqjMQhgHDZM7FiglJAb2aeOxHZWFruUc3MbAGTgE7GB8rr5fTn1Sdh5THGuQtndU3GuXlu91ZKqRivxoCZ/A==", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, - "requires": { - "once": "^1.4.0" + "engines": { + "node": ">=6" } }, - "enhanced-resolve": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", - "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - } + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" } }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "requires": { - "prr": "~1.0.1" + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "requires": { - "is-arrayish": "^0.2.1" + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "engines": { + "node": ">= 0.8.0" } }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "dependencies": { + "bser": "2.1.1" } }, - "eslint-config-airbnb-base": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.2.0.tgz", - "integrity": "sha512-1mg/7eoB4AUeB0X1c/ho4vb2gYkNH8Trr/EgCT/aGmKhhG+F6vF5s8+iRBlWAzFIAphxIdp3YfEKgEl0f9Xg+w==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.5", - "object.assign": "^4.1.0", - "object.entries": "^1.1.0" + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "requires": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "eslint-plugin-import": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", - "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.0", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", - "tsconfig-paths": "^3.9.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "engines": { + "node": ">=6.9.0" } }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "engines": { + "node": ">=8.0.0" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "requires": { - "estraverse": "^5.1.0" + "engines": { + "node": ">=10" }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.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" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "optional": true, - "requires": { - "is-posix-bracket": "^0.1.0" + "engines": { + "node": ">=8" } }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, - "optional": true, - "requires": { - "fill-range": "^2.1.0" + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "expand-tilde": { + "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" + "engines": { + "node": ">=10.17.0" } }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "engines": { + "node": ">=0.8.19" } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "requires": { - "flat-cache": "^2.0.1" + "engines": { + "node": ">=8" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, - "optional": true + "engines": { + "node": ">=6" + } }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "requires": { - "glob": "^7.0.3", - "minimatch": "^3.0.3" + "engines": { + "node": ">=0.12.0" } }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "optional": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "engines": { + "node": ">=8" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/istanbul-lib-instrument": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", "dev": true, - "requires": { - "locate-path": "^3.0.0" + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" } }, - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" + "bin": { + "semver": "bin/semver.js" }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "engines": { + "node": ">=10" } }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" } }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" } }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, - "optional": true, - "requires": { - "for-in": "^1.0.1" + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, - "requires": { - "map-cache": "^0.2.2" + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "fsu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz", - "integrity": "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", - "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, - "optional": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, - "optional": true, - "requires": { - "is-glob": "^2.0.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, - "requires": { - "function-bind": "^1.1.1" + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, - "requires": { - "ansi-regex": "^2.0.0" + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "engines": { + "node": ">=6" }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true } } }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, - "requires": { - "parse-passwd": "^1.0.0" + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "http-server": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.3.tgz", - "integrity": "sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==", - "requires": { - "basic-auth": "^1.0.3", - "colors": "^1.4.0", - "corser": "^2.0.1", - "ecstatic": "^3.3.2", - "http-proxy": "^1.18.0", - "minimist": "^1.2.5", - "opener": "^1.5.1", - "portfinder": "^1.0.25", - "secure-compare": "3.0.1", - "union": "~0.5.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" } }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "requires": { - "minimatch": "^3.0.4" + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "import-fresh": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", - "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "engines": { + "node": ">=6" } }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" + "engines": { + "node": ">=6" } }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "dependencies": { + "yallist": "^3.0.2" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", - "dev": true + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, - "requires": { - "loose-envify": "^1.0.0" + "dependencies": { + "tmpl": "1.0.5" } }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, - "requires": { - "kind-of": "^3.0.2" + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "is-core-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", - "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "requires": { - "has": "^1.0.3" + "engines": { + "node": ">=0.10.0" } }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "requires": { - "kind-of": "^3.0.2" + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "wrappy": "1" } }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "optional": true + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "optional": true, - "requires": { - "is-primitive": "^2.0.0" + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "optional": true - }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-negative-zero": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", - "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", - "dev": true - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" + "engines": { + "node": ">=6" } }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "requires": { - "isobject": "^3.0.1" - }, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "@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" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true, - "optional": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "optional": true + "engines": { + "node": ">=8" + } }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "requires": { - "has-symbols": "^1.0.1" + "engines": { + "node": ">=0.10.0" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "requires": { - "has-symbols": "^1.0.1" + "engines": { + "node": ">=8" } }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "optional": true, - "requires": { - "isarray": "1.0.0" - } - }, - "istanbul": { - "version": "1.1.0-alpha.1", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-1.1.0-alpha.1.tgz", - "integrity": "sha1-eBeVZWAYohdMX2DzZ+5dNhy1e3c=", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "istanbul-api": "^1.1.0-alpha", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - } + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "istanbul-api": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", - "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, - "requires": { - "async": "^2.1.4", - "fileset": "^2.0.2", - "istanbul-lib-coverage": "^1.2.1", - "istanbul-lib-hook": "^1.2.2", - "istanbul-lib-instrument": "^1.10.2", - "istanbul-lib-report": "^1.1.5", - "istanbul-lib-source-maps": "^1.2.6", - "istanbul-reports": "^1.5.1", - "js-yaml": "^3.7.0", - "mkdirp": "^0.5.1", - "once": "^1.4.0" + "engines": { + "node": ">= 6" } }, - "istanbul-lib-coverage": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", - "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", - "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "requires": { - "append-transform": "^0.4.0" + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "istanbul-lib-instrument": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", - "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, - "requires": { - "babel-generator": "^6.18.0", - "babel-template": "^6.16.0", - "babel-traverse": "^6.18.0", - "babel-types": "^6.18.0", - "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.1", - "semver": "^5.3.0" + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "istanbul-lib-report": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", - "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "requires": { - "istanbul-lib-coverage": "^1.2.1", - "mkdirp": "^0.5.1", - "path-parse": "^1.0.5", - "supports-color": "^3.1.2" + "engines": { + "node": ">=10" }, - "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "istanbul-lib-source-maps": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", - "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, - "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^1.2.1", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.1", - "source-map": "^0.5.3" + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" } }, - "istanbul-reports": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", - "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, - "requires": { - "handlebars": "^4.0.3" - } + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "engines": { + "node": ">=0.10.0" } }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "requires": { - "graceful-fs": "^4.1.6" + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "requires": { - "is-buffer": "^1.1.5" + "engines": { + "node": ">=8" } }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, - "requires": { - "invert-kv": "^1.0.0" + "engines": { + "node": ">=10" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "bin": { + "semver": "bin/semver.js" } }, - "load-json-file": { + "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "locate-path": { + "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "engines": { + "node": ">=8" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, - "lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "engines": { + "node": ">=8" } }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "engines": { + "node": ">=0.10.0" } }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, - "requires": { - "p-defer": "^1.0.0" + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, - "requires": { - "object-visit": "^1.0.0" + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "optional": true + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "requires": { - "mimic-fn": "^1.0.0" + "engines": { + "node": ">=8" } }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" + "engines": { + "node": ">=6" } }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "mochawesome": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-3.1.2.tgz", - "integrity": "sha512-w+9QRJNdcOoS4GGj2rJkNl/8KQ34cYyjQfwbFr8tBwjIi2X/jVioAIHUU0gPII5/XpFZd5X24k+IG2DKtdViiQ==", - "dev": true, - "requires": { - "babel-runtime": "^6.20.0", - "chalk": "^2.3.0", - "diff": "^3.4.0", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.3", - "mochawesome-report-generator": "^3.0.1", - "strip-ansi": "^4.0.0", - "uuid": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "mochawesome-report-generator": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-3.1.5.tgz", - "integrity": "sha512-/lFmlpY1cPfLXmV/Qb7kprbQS5VYExEaJGRR86rCLYUdLQM5uivIwvulUEt5VV9mbK/GttN2XPb8al7/5VgtOw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "dateformat": "^3.0.2", - "fs-extra": "^4.0.2", - "fsu": "^1.0.2", - "lodash.isfunction": "^3.0.8", - "opener": "^1.4.2", - "prop-types": "^15.5.8", - "react": "^16.0.0", - "react-dom": "^16.0.0", - "tcomb": "^3.2.17", - "tcomb-validation": "^3.3.0", - "validator": "^9.1.2", - "yargs": "^10.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "yargs": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", - "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.1.0" - } - } - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "optional": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "nyc": { - "version": "11.7.2", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.7.2.tgz", - "integrity": "sha512-gBt7qwsR1vryYfglVjQRx1D+AtMZW5NbUKxb+lZe8SN8KsheGCPGWEsSC9AGQG+r2+te1+10uPHUCahuqm1nGQ==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "arrify": "^1.0.1", - "caching-transform": "^1.0.0", - "convert-source-map": "^1.5.1", - "debug-log": "^1.0.1", - "default-require-extensions": "^1.0.0", - "find-cache-dir": "^0.1.1", - "find-up": "^2.1.0", - "foreground-child": "^1.5.3", - "glob": "^7.0.6", - "istanbul-lib-coverage": "^1.1.2", - "istanbul-lib-hook": "^1.1.0", - "istanbul-lib-instrument": "^1.10.0", - "istanbul-lib-report": "^1.1.3", - "istanbul-lib-source-maps": "^1.2.3", - "istanbul-reports": "^1.4.0", - "md5-hex": "^1.2.0", - "merge-source-map": "^1.1.0", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.0", - "resolve-from": "^2.0.0", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.1", - "spawn-wrap": "^1.4.2", - "test-exclude": "^4.2.0", - "yargs": "11.1.0", - "yargs-parser": "^8.0.0" - }, - "dependencies": { - "align-text": { - "version": "0.1.4", - "bundled": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "amdefine": { - "version": "1.0.1", - "bundled": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "bundled": true, - "dev": true - }, - "append-transform": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "requires": { - "default-require-extensions": "^1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "bundled": true, - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "atob": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-generator": { - "version": "6.26.1", - "bundled": true, - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "bundled": true, - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "base": { - "version": "0.11.2", - "bundled": true, - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "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" - } - }, - "caching-transform": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "md5-hex": "^1.2.0", - "mkdirp": "^0.5.1", - "write-file-atomic": "^1.1.4" - } - }, - "camelcase": { - "version": "1.2.1", - "bundled": true, - "optional": true - }, - "center-align": { - "version": "0.1.3", - "bundled": true, - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "class-utils": { - "version": "0.3.6", - "bundled": true, - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cliui": { - "version": "2.1.0", - "bundled": true, - "optional": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "bundled": true, - "optional": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "commondir": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "bundled": true, - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "core-js": { - "version": "2.5.6", - "bundled": true, - "dev": true - }, - "cross-spawn": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-log": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "bundled": true - }, - "decode-uri-component": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "default-require-extensions": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "strip-bom": "^2.0.0" - } - }, - "define-property": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "detect-indent": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "error-ex": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "esutils": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.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" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "fill-range": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-cache-dir": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "requires": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "for-in": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "foreground-child": { - "version": "1.5.6", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "fragment-cache": { - "version": "0.2.1", - "bundled": true, - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "get-caller-file": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "get-value": { - "version": "2.0.6", - "bundled": true, - "dev": true - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "9.18.0", - "bundled": true, - "dev": true - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "has-value": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "invariant": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "bundled": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "bundled": true, - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-number": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-odd": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "bundled": true, - "dev": true - } - } - }, - "is-plain-object": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "istanbul-lib-coverage": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "istanbul-lib-hook": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "append-transform": "^0.4.0" - } - }, - "istanbul-lib-instrument": { - "version": "1.10.1", - "bundled": true, - "dev": true, - "requires": { - "babel-generator": "^6.18.0", - "babel-template": "^6.16.0", - "babel-traverse": "^6.18.0", - "babel-types": "^6.18.0", - "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.0", - "semver": "^5.3.0" - } - }, - "istanbul-lib-report": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "istanbul-lib-coverage": "^1.1.2", - "mkdirp": "^0.5.1", - "path-parse": "^1.0.5", - "supports-color": "^3.1.2" - }, - "dependencies": { - "supports-color": { - "version": "3.2.3", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "1.2.3", - "bundled": true, - "dev": true, - "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^1.1.2", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.1", - "source-map": "^0.5.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "istanbul-reports": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "handlebars": "^4.0.3" - } - }, - "js-tokens": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "jsesc": { - "version": "1.3.0", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "bundled": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "bundled": true, - "optional": true - }, - "lcid": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - } - } - }, - "longest": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "loose-envify": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "js-tokens": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.3", - "bundled": true, - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "map-cache": { - "version": "0.2.2", - "bundled": true, - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5-hex": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "md5-o-matic": "^0.1.1" - } - }, - "md5-o-matic": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "mem": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "merge-source-map": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "micromatch": { - "version": "3.1.10", - "bundled": true, - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "mixin-deep": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "nanomatch": { - "version": "1.2.9", - "bundled": true, - "dev": true, - "requires": { - "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-odd": "^2.0.0", - "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" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "normalize-package-data": { - "version": "2.4.0", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "bundled": true, - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optimist": { - "version": "0.6.1", - "bundled": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "path-type": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "bundled": true, - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "find-up": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "bundled": true, - "dev": true - }, - "regex-not": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "repeat-element": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "bundled": true - }, - "repeating": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "resolve-from": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "ret": { - "version": "0.1.15", - "bundled": true, - "dev": true - }, - "right-align": { - "version": "0.1.3", - "bundled": true, - "optional": true, - "requires": { - "align-text": "^0.1.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-regex": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "set-value": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "slide": { - "version": "1.1.6", - "bundled": true, - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "bundled": true, - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-map": { - "version": "0.5.7", - "bundled": true - }, - "source-map-resolve": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "atob": "^2.0.0", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "bundled": true, - "dev": true - }, - "spawn-wrap": { - "version": "1.4.2", - "bundled": true, - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - } - }, - "spdx-correct": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "split-string": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "static-extend": { - "version": "0.1.2", - "bundled": true, - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "test-exclude": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "requires": { - "arrify": "^1.0.1", - "micromatch": "^3.1.8", - "object-assign": "^4.1.0", - "read-pkg-up": "^1.0.1", - "require-main-filename": "^1.0.1" - } - }, - "to-fast-properties": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "trim-right": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "uglify-js": { - "version": "2.8.29", - "bundled": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "bundled": true, - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "union-value": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "unset-value": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "bundled": true, - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "bundled": true, - "dev": true - } - } - }, - "urix": { - "version": "0.1.0", - "bundled": true, - "dev": true - }, - "use": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "validate-npm-package-license": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "window-size": { - "version": "0.1.0", - "bundled": true, - "optional": true - }, - "wordwrap": { - "version": "0.0.3", - "bundled": true - }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "write-file-atomic": { - "version": "1.3.4", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } - }, - "y18n": { - "version": "3.2.1", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "yargs": { - "version": "11.1.0", - "bundled": true, - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "cliui": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "yargs-parser": { - "version": "9.0.2", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "8.1.0", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - } - } - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", - "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "has": "^1.0.3" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "optional": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "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" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" - } - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "optional": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true, - "optional": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "optional": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "optional": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "optional": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - } - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "optional": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "optional": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "optional": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "optional": true, - "requires": { - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "optional": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "optional": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "optional": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "optional": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "optional": true, - "requires": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "optional": true - } - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "optional": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true, - "optional": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "resolve": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", - "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", - "dev": true, - "requires": { - "is-core-module": "^2.0.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - }, - "secure-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "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": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", - "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "dev": true, - "requires": { - "stubs": "^3.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", - "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, - "string.prototype.trimstart": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", - "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tcomb": { - "version": "3.2.29", - "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", - "integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==", - "dev": true - }, - "tcomb-validation": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz", - "integrity": "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==", - "dev": true, - "requires": { - "tcomb": "^3.0.0" - } - }, - "teeny-request": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz", - "integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==", - "dev": true, - "requires": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - } - }, - "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "ts-node": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.3.tgz", - "integrity": "sha512-2qayBA4vdtVRuDo11DEFSsD/SFsBXQBRZZhbRGSIkmYmVkWjULn/GGMdG10KVqkaGndljfaTD8dKjWgcejO8YA==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tslint": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.14.0.tgz", - "integrity": "sha512-IUla/ieHVnB8Le7LdQFRGlVJid2T/gaJe5VkjzRVSRR6pA2ODYrnfR1hmxi+5+au9l50jBwpbBL34txgv4NnTQ==", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^3.2.0", - "glob": "^7.1.1", - "js-yaml": "^3.7.0", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "requires": { - "prelude-ls": "~1.1.2" + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" } }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.3333", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3333.tgz", - "integrity": "sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw==", + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "uglify-js": { - "version": "3.11.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.4.tgz", - "integrity": "sha512-FyYnoxVL1D6+jDGQpbK5jW6y/2JlVfRfEeQ67BPCUg5wfCjaKOpr2XeceE4QL+MkhxliLtf5EbrMDZgzpt2CNw==", - "dev": true, - "optional": true - }, - "union": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", - "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", - "requires": { - "qs": "^6.4.0" - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" + "engines": { + "node": ">=4" } }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { - "unique-slug": "^2.0.0" + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "node_modules/ts-jest": { + "version": "29.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.3.tgz", + "integrity": "sha512-6L9qz3ginTd1NKhOxmkP0qU3FyKjj5CPoY+anszfVn6Pmv/RIKzhiMCsH7Yb7UvJR9I2A64rm4zQl531s2F1iw==", "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "babel-jest": { + "optional": true }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "esbuild": { + "optional": true } } }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "optional": true - }, - "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "node_modules/ts-jest/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "requires": { - "punycode": "^2.1.0" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true } } }, - "url-join": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=" - }, - "urlgrey": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", - "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } + "engines": { + "node": ">=4" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "requires": { - "user-home": "^1.1.1" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "validator": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/validator/-/validator-9.4.1.tgz", - "integrity": "sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==", - "dev": true - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, - "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", - "dev": true, - "requires": { - "chokidar": "^3.4.1", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "optional": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true, - "optional": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", - "dev": true, - "optional": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "optional": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "optional": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "optional": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "optional": true - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "optional": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "dev": true, - "optional": true, - "requires": { - "chokidar": "^2.1.8" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "optional": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "optional": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "optional": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "optional": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "optional": true, - "requires": { - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "optional": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "optional": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "optional": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "optional": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "optional": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "optional": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "optional": true, - "requires": { - "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" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "optional": true + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "optional": true + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "webidl-conversions": { + "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "webpack": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", - "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.3.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "webpack-cli": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.0.tgz", - "integrity": "sha512-t1M7G4z5FhHKJ92WRKwZ1rtvi7rHc0NZoZRbSkol0YKl4HvcC8+DsmGDmK7MmZxHSAetHagiOsjOB6MmzC2TUw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "enhanced-resolve": "^4.1.0", - "findup-sync": "^2.0.0", - "global-modules": "^1.0.0", - "import-local": "^2.0.0", - "interpret": "^1.1.0", - "loader-utils": "^1.1.0", - "supports-color": "^5.5.0", - "v8-compile-cache": "^2.0.2", - "yargs": "^12.0.5" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" } }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "dependencies": { + "makeerror": "1.0.12" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, - "requires": { - "mkdirp": "^0.5.1" + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "yargs": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.0.tgz", - "integrity": "sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==", + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "requires": { - "cliui": "^7.0.2", + "dependencies": { + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.2", - "yargs-parser": "^20.2.2" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.3.tgz", - "integrity": "sha512-Gj3QHTkVMPKqwP3f7B4KPkBZRMR9r4rfi5bXFpg1a+Svvj8l7q5CnkBkVQzfxT5DFSsGk2+PascOgL0JYkL2kw==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true - }, - "yargs-parser": { - "version": "20.2.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.3.tgz", - "integrity": "sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww==", - "dev": true - } + "engines": { + "node": ">=12" } }, - "yargs-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "requires": { - "camelcase": "^4.1.0" + "engines": { + "node": ">=12" } }, - "yn": { + "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index db66f5b6..3b607474 100644 --- a/package.json +++ b/package.json @@ -1,86 +1,17 @@ { "name": "javascript-datastructures-algorithms", - "version": "0.0.1", + "version": "4.0.0", "description": "Learning JavaScript Data Structures and Algorithms", - "repository": { - "type": "git", - "url": "git+https://github.com/loiane/javascript-datastructures-algorithms.git" - }, - "keywords": [], - "author": "Loiane Groner", - "license": "MIT", - "bugs": { - "url": "https://github.com/loiane/javascript-datastructures-algorithms/issues" - }, - "homepage": "https://github.com/loiane/javascript-datastructures-algorithms", "scripts": { - "clean": "rm -rf ./dist ./coverage ./.nyc_output ./coverage.lcov ./mochawesome-report", - "build:js": "babel src/js -d dist/js", - "build:ts": "tsc -p ./ --rootDir ./src/ts", - "build": "npm run build:js && npm run build:ts", - "lint:js": "eslint src/js && eslint test/js", - "lint:ts": "tslint -c tslint.json 'src/ts/**/*.ts' && tslint -c tslint.json 'test/ts/**/*.ts'", - "lint": "npm run lint:js && npm run lint:ts", - "eslintFix": "eslint src/js --fix && eslint test/js --fix", - "test:js": "mocha --compilers js:babel-core/register ./test/js --recursive --reporter mochawesome", - "test:ts": "mocha -r ts-node/register ./test/ts/**/*.spec.ts ./test/ts/**/**/*.spec.ts --recursive", - "test": "npm run test:js && npm run test:ts", - "dev": "npm run clean && npm run lint && npm run webpack && npm run generate-report", - "dev2": "npm run clean && npm run lint && npm run webpack && npm run generate-report2", - "coverage": "npm run generate-report && nyc report --reporter=text-lcov > coverage.lcov && codecov", - "generate-report": "nyc --report-dir coverage npm run test && nyc report --reporter=text", - "generate-report2": "nyc --report-dir coverage npm run test", - "go": "npm run clean && npm run lint && npm run build && npm run test", - "webpack": "webpack --env build", - "serve": "http-server -c-1" - }, - "nyc": { - "include": [ - "src/ts/*.ts", - "src/ts/**/*.ts", - "src/js/*.js", - "src/js/**/*.js" - ], - "exclude": [ - "typings" - ], - "extension": [ - ".ts", - ".js" - ], - "reporter": [ - "json", - "html" - ], - "all": true + "build:ts": "tsc -p tsconfig.json", + "test": "jest" }, + "author": "Loiane Groner", "devDependencies": { - "@types/chai": "^4.1.2", - "@types/mocha": "^5.0.0", - "babel-cli": "^6.26.0", - "babel-core": "^6.26.3", - "babel-eslint": "^10.0.1", - "babel-loader": "^8.0.5", - "babel-plugin-add-module-exports": "^1.0.0", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-preset-env": "^1.7.0", - "chai": "^4.1.2", - "codecov": "^3.7.1", - "eslint": "^5.15.1", - "eslint-config-airbnb-base": "^13.1.0", - "eslint-plugin-import": "^2.16.0", - "istanbul": "^v1.1.0-alpha.1", - "mocha": "^5.0.4", - "mochawesome": "^3.0.2", - "nyc": "11.7.2", - "ts-node": "8.0.3", - "tslint": "5.14.0", - "typescript": "3.3.3333", - "webpack": "^4.29.6", - "webpack-cli": "3.3.0", - "yargs": "^16.1.0" - }, - "dependencies": { - "http-server": "^0.12.3" + "@jest/globals": "^29.7.0", + "jest": "^29.7.0", + "ts-jest": "^29.1.3", + "ts-node": "^10.9.2", + "typescript": "^5.4.5" } } diff --git a/src/01-intro/01-hello-variables.js b/src/01-intro/01-hello-variables.js new file mode 100644 index 00000000..9dabae22 --- /dev/null +++ b/src/01-intro/01-hello-variables.js @@ -0,0 +1,55 @@ +// Path: src/01-intro/01-hello-variables.js + +// hello world +console.log('Hello, World!'); + +// variables +var num = 1; +num = 'one' ; + +let myVar = 2; +myVar = 4; + +const price = 1.5; // number +const publisher = 'Packt'; // string +const javaScriptBook = true; // boolean +const nullVar = null; // null +let und; // undefined + +console.log('price: ' + price); +console.log('publisher: ' + publisher); +console.log('javaScriptBook: ' + javaScriptBook); +console.log('nullVar: ' + nullVar); +console.log('und: ' + und); + +console.log('**** Data types ****'); + +console.log('typeof price: ', typeof price); // number +console.log('typeof publisher: ', typeof publisher); // string +console.log('typeof javaScriptBook: ', typeof javaScriptBook); // boolean +console.log('typeof nullVar: ', typeof nullVar); // object +console.log('typeof und: ', typeof und); // undefined + +const book = { + title: 'Data Structures and Algorithms', +} + +console.log('book title: ', book.title); + +book.title = 'Data Structures and Algorithms in JavaScript'; +// book = { anotherTitle: 'Data Structures’ } // this will not work + +// reassignment of objects: +let book2 = { + title: 'Data Structures and Algorithms', +} +book2 = { title: 'Data Structures' }; + +// symbol +const title = Symbol('title'); +const book3 = { + [title]: 'Data Structures and Algorithms' +}; +console.log(book3[title]); // Data Structures and Algorithms + +// to see the output of this file use the command: node src/01-intro/01-hello-variables.js \ No newline at end of file diff --git a/src/01-intro/02-conditionals.js b/src/01-intro/02-conditionals.js new file mode 100644 index 00000000..83dccb3a --- /dev/null +++ b/src/01-intro/02-conditionals.js @@ -0,0 +1,51 @@ +// Path: src/01-intro/02-conditionals.js + +/* Example 01 - if-else */ +let number = 0; +if (number === 1) { + console.log('number is equal to 1'); +} else { + console.log('number is not equal to 1, the value of number is ' + number); +} + +/* Example 02 - ternary operator - if..else */ +if (number === 1) { + number--; +} else { + number++; +} + +// is the same as +number === 1 ? number-- : number++; + +// is the same as +number = number === 1 ? number - 1 : number + 1; + +/* Example 03 - if-else-if-else... */ +let month = 5; +if (month === 1) { + console.log('January'); +} else if (month === 2) { + console.log('February'); +} else if (month === 3) { + console.log('March'); +} else { + console.log('Month is not January, February or March'); +} + +/* Example 05 - switch */ +switch (month) { + case 1: + console.log('January'); + break; + case 2: + console.log('February'); + break; + case 3: + console.log('March'); + break; + default: + console.log('Month is not January, February or March'); +} + +// to see the output of this file use the command: node src/01-intro/02-conditionals.js \ No newline at end of file diff --git a/src/01-intro/03-loops.js b/src/01-intro/03-loops.js new file mode 100644 index 00000000..5ba8ff9e --- /dev/null +++ b/src/01-intro/03-loops.js @@ -0,0 +1,41 @@ +// Path: src/01-intro/03-loops.js + +console.log('**** for example ****'); +/* for - example */ +for (let i = 0; i < 10; i++) { + console.log(i); +} + +console.log('**** while example ****'); +/* while - example */ +let i = 0; +while (i < 10) { + console.log(i); + i++; +} + +console.log('**** do-while example ****'); +/* do-while - example */ +i = 0; +do { + console.log(i); + i++; +} while (i < 10); + +console.log('**** for-in example ****'); +/* for-in - example */ +const obj = { a: 1, b: 2, c: 3 }; +for (const key in obj) { + console.log(key, obj[key]); +} +// output: a 1 b 2 c 3 + +console.log('**** for-of example ****'); +/* for-of - example */ +const arr = [1, 2, 3]; +for (const value of arr) { + console.log(value); +} +// output: 1 2 3 + +// to see the output of this file use the command: node src/01-intro/03-loops.js \ No newline at end of file diff --git a/src/01-intro/04-functions.js b/src/01-intro/04-functions.js new file mode 100644 index 00000000..fbc694c8 --- /dev/null +++ b/src/01-intro/04-functions.js @@ -0,0 +1,24 @@ +// Path: src/01-intro/04-functions.js + +function sayHello(name) { + console.log('Hello! ', name); +} + +sayHello('Packt'); // Hello! Packt + +/* function using the return statement */ +function sum(num1, num2) { + return num1 + num2; +} + +const result = sum(1, 2); +console.log(result); // outputs 3 + +/* function with default parameter */ +function sumDefault(num1, num2 = 2) { // num2 has a default value + return num1 + num2; +} +console.log(sumDefault(1)); // outputs 3 +console.log(sumDefault(1, 3)); // outputs 4 + +// to see the output of this file use the command: node src/01-intro/04-functions.js \ No newline at end of file diff --git a/src/01-intro/05-scope.js b/src/01-intro/05-scope.js new file mode 100644 index 00000000..4be02631 --- /dev/null +++ b/src/01-intro/05-scope.js @@ -0,0 +1,39 @@ +// Path: src/01-intro/05-scope.js + +let movie = 'Lord of the Rings'; + +function starWarsFan() { + const movie = 'Star Wars'; + return movie; +} + +function marvelFan() { + movie = 'The Avengers'; + return movie; +} + +console.log(movie); // Lord of the Rings +console.log(starWarsFan()); // Star Wars +console.log(marvelFan()); // The Avengers +console.log(movie); // The Avengers + +// block scope +function blizzardFan() { + const isFan = true; + let phrase = 'Warcraft'; + console.log('Before if: ' + phrase); + if (isFan) { + let phrase = 'initial text'; + phrase = 'For the Horde!'; + console.log('Inside if: ' + phrase); + } + phrase = 'For the Alliance!'; + console.log('After if: ' + phrase); +} + +blizzardFan(); +// Before if: Warcraft +// Inside if: For the Horde! +// After if: For the Alliance! + +// to see the output of this file use the command: node src/01-intro/05-scope.js diff --git a/src/01-intro/06-objects.js b/src/01-intro/06-objects.js new file mode 100644 index 00000000..511459e4 --- /dev/null +++ b/src/01-intro/06-objects.js @@ -0,0 +1,73 @@ +// Path: src/01-intro/06-objects.js + +/* Object example */ +let obj = new Object(); +obj = {}; +obj = { + name: { + first: 'Gandalf', + last: 'the Grey' + }, + address: 'Middle Earth' +}; + + +/* Class example */ +class Book { + + #percentagePerSale = 0.12; + + constructor(title, pages, isbn) { + this.title = title; + this.pages = pages; + this.isbn = isbn; + } + + get price() { + return this.pages * this.#percentagePerSale; + } + + static copiesSold = 0; + static sellCopy() { + this.copiesSold++; + } + + printIsbn() { + console.log(this.isbn); + } +} + +let myBook = new Book('title', 400, 'isbn'); + +console.log(myBook.title); // outputs the book title +myBook.title = 'new title'; // update the value of the book title +console.log(myBook.title); // outputs the updated value: new title + +console.log(myBook.price); // 48 + +console.log(Book.copiesSold); // 0 +Book.sellCopy(); +console.log(Book.copiesSold); // 1 + +Book.sellCopy(); +console.log(Book.copiesSold); // 2 + +class Ebook extends Book { + constructor(title, pages, isbn, format) { + super(title, pages, isbn); + this.format = format; + } + printIsbn() { + console.log('Ebook ISBN:',this.isbn); + } +} +Ebook.sellCopy(); +console.log(Ebook.copiesSold); // 3 + +const myBook = new Book('title', 400, 'isbn'); +myBook.printIsbn(); // isbn +const myEbook = new Ebook('Data Structures Ebook', 400, 'isbn 123', 'pdf'); +myEbook.printIsbn(); // Ebook ISBN: isbn 123 + + +// to see the output of this file use the command: node src/01-intro/06-objects.js diff --git a/src/01-intro/07-modern.js b/src/01-intro/07-modern.js new file mode 100644 index 00000000..8f6d7165 --- /dev/null +++ b/src/01-intro/07-modern.js @@ -0,0 +1,47 @@ +// @ts-check +// Path: src/01-intro/07-modern.js + +/** + * Arrow function example, calculates the area of a circle + * @param {number} radius + * @returns + */ +const circleAreaFn = function circleArea(radius) { + const PI = 3.14; + const area = PI * radius * radius; + return area; +}; +// circleAreaFn('book'); +console.log(circleAreaFn(2)); // 12.56 + +// refactoring to use arrow function +const circleArea = (radius) => { // {1} + const PI = 3.14; + return PI * radius * radius; +}; + +// simplified version +const circleAreaSimp = radius => 3.14 * radius * radius; +console.log(circleAreaSimp(2)); // 12.56 + +// no parameters +const hello = () => console.log('hello!'); +hello(); // hello! + +/* Spread operator example */ +const sum = (x, y, z) => x + y + z; + +const numbers = [1, 2, 3]; +console.log(sum(...numbers)); // 6 + +/* Rest operator example */ +const restParamaterFunction = (x, y, ...a) => (x + y) * a.length; +console.log(restParamaterFunction(1, 2, 'hello', true, 7)); // 9 + +/* Exponentiation operator example */ +const r = 2; +let area = 3.14 * r * r; +area = 3.14 * Math.pow(r, 2); +area = 3.14 * r ** 2; + +// to see the output of this file use the command: node src/01-intro/07-modern.js \ No newline at end of file diff --git a/src/01-intro/08-typescript.js b/src/01-intro/08-typescript.js new file mode 100644 index 00000000..284054fd --- /dev/null +++ b/src/01-intro/08-typescript.js @@ -0,0 +1,42 @@ +// Path: src/01-intro/08-typescript.ts +let myName = 'Packt'; +// myName = 10; // commented to avoid error +/* Type inference */ +let age = 20; // number +let existsFlag = true; // boolean +let language = 'JavaScript'; // string +let favoriteLanguage; +let langs = ['JavaScript', 'Ruby', 'Python']; +favoriteLanguage = langs[0]; +function printName(person) { + console.log(person.name); +} +const john = { name: 'John', age: 21 }; +const mary = { name: 'Mary', age: 21, phone: '123-45678' }; +printName(john); +printName(mary); +class MyObject { + age; + constructor(age) { + this.age = age; + } + compareTo(b) { + if (this.age === b.age) { + return 0; + } + return this.age > b.age ? 1 : -1; + } +} +/* Enums */ +var Compare; +(function (Compare) { + Compare[Compare["LESS_THAN"] = -1] = "LESS_THAN"; + Compare[Compare["BIGGER_THAN"] = 1] = "BIGGER_THAN"; + Compare[Compare["EQUALS"] = 0] = "EQUALS"; +})(Compare || (Compare = {})); +function compareTo(a, b) { + if (a.age === b.age) { + return Compare.EQUALS; + } + return a.age > b.age ? Compare.BIGGER_THAN : Compare.LESS_THAN; +} diff --git a/examples/chapter01_02/typescript/hello-world.ts b/src/01-intro/08-typescript.ts similarity index 50% rename from examples/chapter01_02/typescript/hello-world.ts rename to src/01-intro/08-typescript.ts index 7cb7ace8..3f4cdee5 100644 --- a/examples/chapter01_02/typescript/hello-world.ts +++ b/src/01-intro/08-typescript.ts @@ -1,6 +1,9 @@ +// Path: src/01-intro/08-typescript.ts + let myName = 'Packt'; -// myName = 10; +// myName = 10; // commented to avoid error +/* Type inference */ let age = 20; // number let existsFlag = true; // boolean let language = 'JavaScript'; // string @@ -9,26 +12,32 @@ let favoriteLanguage: string; let langs = ['JavaScript', 'Ruby', 'Python']; favoriteLanguage = langs[0]; -interface Person { +/* Interfaces as type */ +interface Friend { name: string; age: number; } -function printName(person: Person) { - console.log(person.name); +function printName(person: Friend) { + console.log(person.name); } - + const john = { name: 'John', age: 21 }; const mary = { name: 'Mary', age: 21, phone: '123-45678' }; printName(john); printName(mary); +/* Interfaces as OO */ interface Comparable { compareTo(b: T): number; } class MyObject implements Comparable { age: number; + + constructor(age: number) { + this.age = age; + } compareTo(b: MyObject): number { if (this.age === b.age) { @@ -38,9 +47,23 @@ class MyObject implements Comparable { } } -function compareTwoObjects(a: MyObject, b: MyObject) { - console.log(a.compareTo(b)); - console.log(b.compareTo(a)); +/* Enums */ +enum Compare { + LESS_THAN = -1, + BIGGER_THAN = 1, + EQUALS = 0 } +function compareTo(a: MyObject, b: MyObject): number { + if (a.age === b.age) { + return Compare.EQUALS; + } + return a.age > b.age ? Compare.BIGGER_THAN : Compare.LESS_THAN; +} +/* Type aliases */ +type UserID = string; +type User = { + id: UserID; + name: string; +} \ No newline at end of file diff --git a/src/02-bigOnotation/01-big-o-intro.js b/src/02-bigOnotation/01-big-o-intro.js new file mode 100644 index 00000000..9a740fce --- /dev/null +++ b/src/02-bigOnotation/01-big-o-intro.js @@ -0,0 +1,72 @@ +// Path: src/02-bigOnotation/01-big-o-intro.js + +// O(1) - Constant Time +function secondsInDays(numberOfDays) { + if (numberOfDays <= 0 || !Number.isInteger(numberOfDays)) { + throw new Error('Invalid number of days'); + } + return 60 * 60 * 24 * numberOfDays; +} + +console.log('O(1) - Constant Time'); +console.log('Seconds in 1 day: ', secondsInDays(1)); // 86400 +console.log('Seconds in 10 days: ', secondsInDays(10)); // 864000 +console.log('Seconds in 100 days: ', secondsInDays(100)); // 8640000 + +// O(n) - Linear Time +function calculateTotalExpenses(monthlyExpenses) { + let total = 0; + for (let i = 0; i < monthlyExpenses.length; i++) { + total += monthlyExpenses[i]; + } + return total; +} + +console.log('*******************'); +console.log('O(n) - Linear Time'); +console.log('January: ', calculateTotalExpenses([100, 200, 300])); // 600 +console.log('February: ', calculateTotalExpenses([200, 300, 400])); // 900 +console.log('March: ', calculateTotalExpenses([30, 40, 50, 100, 50])); // 270 + +// O(n^2) - Quadratic Time +function calculateExpensesMatrix(monthlyExpenses) { + let total = 0; + for (let i = 0; i < monthlyExpenses.length; i++) { + for (let j = 0; j < monthlyExpenses[i].length; j++) { + total += monthlyExpenses[i][j]; + } + } + return total; +} + +console.log('************************'); +console.log('O(n^2) - Quadratic Time'); +const monthlyExpenses = [ + [100, 105, 100, 115, 120, 135], + [180, 185, 185, 185, 200, 210], + [30, 30, 30, 30, 30, 30], + [2000, 2000, 2000, 2000, 2000, 2000], + [600, 620, 610, 600, 620, 600], + [150, 100, 130, 200, 150, 100] +]; +console.log('Total expenses: ', calculateExpensesMatrix(monthlyExpenses)); // 18480 + +// calculating the time complexity of the function calculateExpensesMatrix +function multiplicationTable(num, x) { + let s = ''; + let numberOfAsterisks = num * x; + for (let i = 1; i <= numberOfAsterisks; i++) { + s += '*'; + } + console.log(s); + + for (let i = 1; i <= num; i++) { + console.log(`Multiplication table for ${i} with x = ${x}`); + for (let j = 1; j <= x; j++) { + console.log(`${i} * ${j} = `, i * j); + } + } +} + + +// to see the output of this file use the command: node src/02-bigOnotation/01-big-o-intro.js \ No newline at end of file diff --git a/examples/chapter15/bigOChart/index.html b/src/02-bigOnotation/02-bigOChart.html old mode 100755 new mode 100644 similarity index 81% rename from examples/chapter15/bigOChart/index.html rename to src/02-bigOnotation/02-bigOChart.html index 31118263..081815fd --- a/examples/chapter15/bigOChart/index.html +++ b/src/02-bigOnotation/02-bigOChart.html @@ -6,7 +6,7 @@ body { background-color: #DDDDDD; font: 30px sans-serif; } - +
diff --git a/examples/chapter15/bigOChart/chart.js b/src/02-bigOnotation/02-bigOChart.js old mode 100755 new mode 100644 similarity index 72% rename from examples/chapter15/bigOChart/chart.js rename to src/02-bigOnotation/02-bigOChart.js index 765794df..f4aa9492 --- a/examples/chapter15/bigOChart/chart.js +++ b/src/02-bigOnotation/02-bigOChart.js @@ -3,7 +3,7 @@ google.setOnLoadCallback(drawChart); function drawChart() { - var data = new google.visualization.DataTable(); + const data = new google.visualization.DataTable(); data.addColumn('string', 'n'); data.addColumn('number', 'O(1)'); data.addColumn('number', 'O(log n)'); @@ -11,16 +11,18 @@ function drawChart() { data.addColumn('number', 'O(n log n)'); data.addColumn('number', 'O(n^2)'); data.addColumn('number', 'O(2^n)'); + //data.addColumn('number', 'O(n!)'); - for (var i = 0; i <= 30; i++) { + for (let i = 0; i <= 30; i++) { data.addRow([i+'', 1, Math.log(i), i, Math.log(i)*i, Math.pow(i,2), Math.pow(2,i)]); } - var options = {'title':'Big O Notation Complexity Chart', + const options = { 'width':700, 'height':600, 'backgroundColor':{stroke:'#CCC',strokeWidth:1}, 'curveType':'function', + 'legend': { position: 'right'}, 'hAxis':{ title:'Elements (n)', showTextEvery:5 @@ -28,10 +30,10 @@ function drawChart() { 'vAxis':{ title:'Operations', viewWindowMode:'explicit', - viewWindow:{min:0,max:450} + viewWindow:{min:0,max:300} } }; - var chart = new google.visualization.LineChart(document.getElementById('chart_div')); + const chart = new google.visualization.LineChart(document.getElementById('chart_div')); chart.draw(data, options); } \ No newline at end of file diff --git a/src/02-bigOnotation/03-exercises.js b/src/02-bigOnotation/03-exercises.js new file mode 100644 index 00000000..cc09906f --- /dev/null +++ b/src/02-bigOnotation/03-exercises.js @@ -0,0 +1,57 @@ +// Path: src/02-bigOnotation/03-exercises.js + +/* What is the time and space complexities for each of the following functions. + Try them with different inputs to explore how they behave with different inputs */ + +// time complexity: O(1) - Constant Time +// space complexity: O(1) - Constant Space +const oddOrEven = (array) => array.length % 2 === 0 ? 'even' : 'odd'; + +console.log(oddOrEven([1, 2, 3, 4, 5])); // odd +console.log(oddOrEven([1, 2, 3, 4, 5, 6])); // even + +// time complexity: O(n) - Linear Time +// space complexity: O(1) - Constant Space +function calculateAverage(array) { + let sum = 0; + for (let i = 0; i < array.length; i++) { + sum += array[i]; + } + return sum / array.length; +} + +console.log(calculateAverage([1, 2, 3, 4, 5])); // 3 +console.log(calculateAverage([1, 2, 3, 4, 5, 6])); // 3.5 + +// time complexity: O(n^2) - Quadratic Time +// space complexity: O(1) - Constant Space +function hasCommonElements(array1, array2) { + for (let i = 0; i < array1.length; i++) { + for (let j = 0; j < array2.length; j++) { + if (array1[i] === array2[j]) { + return true; + } + } + } + return false; +} + +console.log(hasCommonElements([1, 2, 3, 4, 5], [6, 7, 8, 9, 10])); // false +console.log(hasCommonElements([1, 2, 3, 4, 5], [5, 6, 7, 8, 9])); // true + +// time complexity: O(n) - Linear Time +// space complexity: O(n) - Linear Space +function getOddNumbers(array) { + const result = []; + for (let i = 0; i < array.length; i++) { + if (array[i] % 2 !== 0) { + result.push(array[i]); + } + } + return result; +} + +console.log(getOddNumbers([1, 2, 3, 4, 5])); // [1, 3, 5] +console.log(getOddNumbers([1, 2, 3, 4, 5, 6])); // [1, 3, 5] + +// to see the output of this file use the command: node src/02-bigOnotation/03-exercises.js \ No newline at end of file diff --git a/src/03-array/01-arrays.js b/src/03-array/01-arrays.js new file mode 100644 index 00000000..cd8bb4a7 --- /dev/null +++ b/src/03-array/01-arrays.js @@ -0,0 +1,76 @@ +// Path: src/03-array/01-arrays.js + +/* Arrays Intro */ +const averageTempJan = 12; +const averageTempFeb = 15; +const averageTempMar = 18; +const averageTempApr = 20; +const averageTempMay = 25; + +const averageTemp = [12, 15, 18, 20, 25]; +// or +averageTemp[0] = 12; +averageTemp[1] = 15; +averageTemp[2] = 18; +averageTemp[3] = 20; +averageTemp[4] = 25; + +console.log('averageTempJan', averageTempJan); +console.log('averageTempFeb', averageTempFeb); +console.log('averageTempMar', averageTempMar); +console.log('averageTempApr', averageTempApr); +console.log('averageTempMay', averageTempMay); + +console.log('averageTemp[0]', averageTemp[0]); +console.log('averageTemp[1]', averageTemp[1]); +console.log('averageTemp[2]', averageTemp[2]); +console.log('averageTemp[3]', averageTemp[3]); +console.log('averageTemp[4]', averageTemp[4]); + +/* Creating and initializing arrays */ +// preferred +let daysOfWeek = []; // creates an empty array +daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + +console.log('daysOfWeek.length:', daysOfWeek.length); // daysOfWeek.length: 7 + +// different syntax, avoid: +daysOfWeek = new Array(); // creates an empty array +daysOfWeek = new Array(7); // pre-defined length of 7 +daysOfWeek = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); + +// ---- interating over arrays ---- +for (let i = 0; i < daysOfWeek.length; i++) { + console.log(`daysOfWeek[${i}]`, daysOfWeek[i]); +} + +/* fibonacci numbers */ +// Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... +const fibonacci = []; +fibonacci[0] = 0; +fibonacci[1] = 1; + +// create the fibonacci sequence starting from the 2nd element +for (let i = 2; i < 20; i++) { + fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]; +} + +// display the fibonacci sequence +for (let i = 1; i < fibonacci.length; i++) { + console.log(`fibonacci[${i}]`, fibonacci[i]); +} + +// instead of {5} and {6} we can use +console.log('fibonacci', fibonacci); + +// Using the for..in loop +for (const i in fibonacci) { + console.log(`fibonacci[${i}]`, fibonacci[i]); +} + +// Using the for..of loop +for (const value of fibonacci) { + console.log('value', value); +} + +// to see the output of this file use the command: node src/03-array/01-arrays.js \ No newline at end of file diff --git a/src/03-array/01-arrays.ts b/src/03-array/01-arrays.ts new file mode 100644 index 00000000..f33e8c5f --- /dev/null +++ b/src/03-array/01-arrays.ts @@ -0,0 +1,74 @@ +// Path: src/03-array/01-arrays.ts + +/* Arrays Intro */ +const averageTempJan = 12; +const averageTempFeb = 15; +const averageTempMar = 18; +const averageTempApr = 20; +const averageTempMay = 25; + +const averageTemp = [12, 15, 18, 20, 25]; +// or +averageTemp[0] = 12; +averageTemp[1] = 15; +averageTemp[2] = 18; +averageTemp[3] = 20; +averageTemp[4] = 25; + +console.log('averageTempJan', averageTempJan); +console.log('averageTempFeb', averageTempFeb); +console.log('averageTempMar', averageTempMar); +console.log('averageTempApr', averageTempApr); +console.log('averageTempMay', averageTempMay); + +console.log('averageTemp[0]', averageTemp[0]); +console.log('averageTemp[1]', averageTemp[1]); +console.log('averageTemp[2]', averageTemp[2]); +console.log('averageTemp[3]', averageTemp[3]); +console.log('averageTemp[4]', averageTemp[4]); + +/* Creating and initializing arrays */ +let daysOfWeek = new Array(); // {1} +daysOfWeek = new Array(7); // {2} +daysOfWeek = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); // {3} + +// preferred +daysOfWeek = []; // {4} +daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; // {5} + +console.log('daysOfWeek.length', daysOfWeek.length); // output: 7 + +for (let i = 0; i < daysOfWeek.length; i++) { + console.log(`daysOfWeek[${i}]`, daysOfWeek[i]); +} + +/* fibonacci numbers */ +// Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... +const fibonacci = []; // {1} +fibonacci[1] = 1; // {2} +fibonacci[2] = 1; // {3} + +// create the fibonacci sequence starting from the 3rd element +for (let i = 3; i < 20; i++) { + fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]; // //{4} +} + +// display the fibonacci sequence +for (let i = 1; i < fibonacci.length; i++) { // {5} + console.log(`fibonacci[${i}]`, fibonacci[i]); // {6} +} + +// instead of {5} and {6} we can use +console.log('fibonacci', fibonacci); + +// Using the for..in loop +for (const i in fibonacci) { + console.log(`fibonacci[${i}]`, fibonacci[i]); +} + +// Using the for..of loop +for (const value of fibonacci) { + console.log('value', value); +} + +// to see the output of this file use the command: node src/03-array/01-arrays.ts \ No newline at end of file diff --git a/src/03-array/02-adding-removing-elements.js b/src/03-array/02-adding-removing-elements.js new file mode 100644 index 00000000..fad7f467 --- /dev/null +++ b/src/03-array/02-adding-removing-elements.js @@ -0,0 +1,81 @@ +// Path: src/03-array/02-adding-removing-elements.js + +// @ts-ignore +let raffleTickets = [5, 6, 7, 8, 9]; + +raffleTickets[raffleTickets.length] = 10; + +// using push method +raffleTickets.push(11); +console.log(raffleTickets.push(12, 13)); // 9 + +console.log('raffleTickets: ', raffleTickets); // raffleTickets: [ 5, 6, 7, 8, 9, 10, 11, 12, 13 ] + +// inserting elements at the beginning +const insertAtBeginning = function (array, value) { + for (let i = array.length; i >= 0; i--) { + array[i] = array[i - 1]; + } + array[0] = value; + return array; +}; +raffleTickets = insertAtBeginning(raffleTickets, 4); +console.log('raffleTickets: ', raffleTickets); // raffleTickets: [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ] + +// using unshift method +raffleTickets.unshift(3); +raffleTickets.unshift(0, 1, 2); + +console.log('raffleTickets: ', raffleTickets); // raffleTickets: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ] + +// removing elements from the end +let winningTicket = raffleTickets.pop(); +console.log('The winning ticket is:', winningTicket); // The winning ticket is: 13 + +console.log('raffleTickets: ', raffleTickets); // raffleTickets: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ] +console.log('array length: ', raffleTickets.length); // array length: 13 + +// removing elements from the beginning +for (let i = 0; i < raffleTickets.length; i++) { + // numbers[i] = numbers[i + 1]; +} + +// removing elements from the beginning - educational purposes only +const removeFirstElement = function(array) { + for (let i = 1; i < array.length; i++) { + array[i - 1] = array[i]; + } + array.length--; + return array; +} + +// Apply to our raffleTickets array +raffleTickets = removeFirstElement(raffleTickets); +console.log('Updated raffleTickets:', raffleTickets); // Updated raffleTickets: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ] +console.log('array length: ', raffleTickets.length); // array length: 12 + +// alternative way to remove elements from the beginning using a new array +const removeFirstElementWithNewArray = function(array) { + let newArray = []; + for (let i = 1; i < array.length; i++) { + newArray.push(array[i]); + } + return newArray; +} + +// using shift method +raffleTickets.shift(); +console.log('numbers after shift: ', raffleTickets); // numbers after shift: [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ] +console.log('array length: ', raffleTickets.length); // array length: 11 + +// adding and removing elements from a specific position +// using the splice method to remove elements +const prizeWinners = raffleTickets.splice(5, 3); // removes 3 elements starting from the 5th position +console.log('prizeWinners: ', prizeWinners); // prizeWinners: [ 7, 8, 9 ] +console.log('remaing tickets: ', raffleTickets); // remaing tickets: [ 2, 3, 4, 5, 6, 10, 11, 12 ] + +// adding number 8 and 9 back to the array +raffleTickets.splice(5, 0, 8, 9); // adds 8, 9 back to the array +console.log('raffleTickets: ', raffleTickets); // raffleTickets: [ 2, 3, 4, 5, 6, 8, 9, 10, 11, 12 ] + +// to see the output of this file use the command: node src/03-array/02-adding-removing-elements.js diff --git a/src/03-array/02-adding-removing-elements.ts b/src/03-array/02-adding-removing-elements.ts new file mode 100644 index 00000000..bd9ff917 --- /dev/null +++ b/src/03-array/02-adding-removing-elements.ts @@ -0,0 +1,73 @@ +// Path: src/03-array/02-adding-removing-elements.ts + +// @ts-ignore +let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + +numbers[numbers.length] = 10; + +// using push method +numbers.push(11); +numbers.push(12, 13); + +// inserting elements at the beginning +// @ts-ignore +Array.prototype.insertAtBeginning = function (value) { + for (let i = this.length; i >= 0; i--) { + this[i] = this[i - 1]; + } + this[0] = value; +}; +// @ts-ignore +numbers.insertAtBeginning(-1); + +// using unshift method +numbers.unshift(-2); +numbers.unshift(-4, -3); + +// removing elements from the end +numbers.pop(); // number 13 is removed +// console.log('Removed element: ', numbers.pop()); // Removed element: 13 +console.log('array length: ', numbers.length); // array length: 17 + +// removing elements from the beginning +for (let i = 0; i < numbers.length; i++) { + // numbers[i] = numbers[i + 1]; +} + +// removing elements from the beginning - educational purposes only +// @ts-ignore +Array.prototype.reIndex = function (myArray) { + const newArray = []; + for (let i = 0; i < myArray.length; i++) { + if (myArray[i] !== undefined) { + newArray.push(myArray[i]); + } + } + return newArray; +} +// remove first position manually and reIndex +// @ts-ignore +Array.prototype.removeFromBeginning = function () { + for (let i = 0; i < this.length; i++) { + this[i] = this[i + 1]; + } + // @ts-ignore + return this.reIndex(this); +}; +// @ts-ignore +// numbers = numbers.removeFromBeginning(); + +// using shift method +numbers.shift(); +console.log('numbers after shift: ', numbers); +console.log('array length: ', numbers.length); // array length: 16 + +// adding and removing elements from a specific position +// using the splice method +numbers.splice(5, 3); // removes 3 elements starting from the 5th position +console.log('numbers: ', numbers); // numbers: [ -3, -2, -1, 0, 1, 5, 6, 7, 8, 9, 10, 11, 12 ] + +// adding elements, 2, 3 and 4 at the 5th position +numbers.splice(5, 0, 2, 3, 4); + +// to see the output of this file use the command: node src/03-array/02-adding-removing-elements.ts diff --git a/src/03-array/03-iterator-functions.js b/src/03-array/03-iterator-functions.js new file mode 100644 index 00000000..ea90f93e --- /dev/null +++ b/src/03-array/03-iterator-functions.js @@ -0,0 +1,85 @@ +// Path: src/03-array/03-iterator-functions.js + +// using forEach method +const raffleParticipants = ['poppy@email.com', 'sera@email.com', 'millie@example.com']; +const sendWelcomeEmail = email => { + console.log(`Welcome email sent to ${email}`); +}; + +raffleParticipants.forEach(email => sendWelcomeEmail(email)); + +raffleParticipants.forEach(sendWelcomeEmail); + +const sendConfirmationEmail = (email, raffleNumber) => { + console.log(`Hi ${email}, your raffle number is ${raffleNumber}`); +}; + +const sendSpecialPrizeEmail = (email) => { + console.log(`Congrats ${email}! You've won a special prize!`); +}; + +raffleParticipants.forEach((value, index, array) => { + const raffleNumber = index + 1; // Raffle numbers start from 1 + sendConfirmationEmail(value, raffleNumber); + + if (index === array.length - 1) { // Check if it's the last element + sendSpecialPrizeEmail(value); + } +}); + +// using every method +const formFields = [ + { id: 'username', value: 'poppy' }, + { id: 'email', value: 'poppy@email.com' }, + { id: 'password', value: 'bookClub123!' }]; + + const isFormValid = () => + formFields.every(field => field.value !== '' && field.value !== null); + + +const onFormSubmit = () => { + if (isFormValid()) { + console.log('Form submitted successfully!'); + } else { + console.log('Please fill out all required fields.'); + } +} +onFormSubmit(); // Form submitted successfully! + +// using a for loop +const isFormValidForLoop = () => { + for (let i = 0; i < formFields.length; i++) { + if (formFields[i].value === '' || formFields[i].value === null) { + return false; + } + } + return true; +}; + + +// using some method +const products = [ + { name: 'Laptop', inStock: true }, + { name: 'Smartphone', inStock: false }, + { name: 'Headphones', inStock: true } +]; + +const searchQuery = 'phone'; +const isProductAvailable = products.some(product => { + return product.name.toLowerCase().includes(searchQuery.toLowerCase()) && product.inStock; +}); + +console.log(isProductAvailable ? 'Product Available!' : 'No Products Found.'); // Product Available! + +// using a for loop +const isProductAvailableForLoop = () => { + for (let i = 0; i < products.length; i++) { + if (products[i].name.toLowerCase().includes(searchQuery.toLowerCase()) && products[i].inStock) { + return true; // Found a match, no need to continue checking + } + } + return false; // No match found after checking all products +}; + + +// to see the output of this file use the command: node src/03-array/03-iterator-functions.js \ No newline at end of file diff --git a/src/03-array/03-iterator-functions.ts b/src/03-array/03-iterator-functions.ts new file mode 100644 index 00000000..963288de --- /dev/null +++ b/src/03-array/03-iterator-functions.ts @@ -0,0 +1,45 @@ +// Path: src/03-array/03-iterator-functions.ts + +// @ts-ignore +const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + +// using forEach method +numbers.forEach((value, index) => { + console.log(`numbers[${index}]`, value); +}); + +numbers.forEach(value => console.log(value)); + +// using every method +const isBelowSeven = numbers.every(value => value < 7); +console.log('All values are below 7?:', isBelowSeven); // false + +// rewriting the preceding code using for loop +let isBelowSevenForLoop = true; +for (let i = 0; i < numbers.length; i++) { + if (numbers[i] >= 7) { + isBelowSevenForLoop = false; + break; + } +} +console.log('All values are below 7?:', isBelowSevenForLoop); // false + +// using some method +const isSomeValueBelowSeven = numbers.some(value => value < 7); +console.log('Is any value below 7?:', isSomeValueBelowSeven); // true + +// rewriting the preceding code using for loop +let isSomeValueBelowSevenForLoop = false; +for (let i = 0; i < numbers.length; i++) { + if (numbers[i] < 7) { + isSomeValueBelowSevenForLoop = true; + break; + } +} + +// using filter method +// @ts-ignore +const valuesBelowSeven = numbers.filter(value => value < 7); +console.log('Values below 7:', valuesBelowSeven); // [1, 2, 3, 4, 5, 6] + +// to see the output of this file use the command: node src/03-array/03-iterator-functions.ts \ No newline at end of file diff --git a/src/03-array/04-searching-sorting.js b/src/03-array/04-searching-sorting.js new file mode 100644 index 00000000..918cc72d --- /dev/null +++ b/src/03-array/04-searching-sorting.js @@ -0,0 +1,140 @@ +// Path: src/03-array/04-searching-sorting.js + +// using indexOf method +const shoppingList = ['apples', 'bananas', 'milk', 'eggs', 'bread', 'milk']; + +const itemToFind = 'milk'; +const firstMilkIndex = shoppingList.indexOf(itemToFind); +if (firstMilkIndex !== -1) { + const position = firstMilkIndex + 1; + console.log(`Milk is already on the list at position ${position}`); +} else { + console.log('Milk is not on the list yet.'); +} +// Milk is already on the list at position 3 + +// using lastIndexOf method +const lastMilkIndex = shoppingList.lastIndexOf(itemToFind); +if (lastMilkIndex !== -1 && lastMilkIndex !== firstMilkIndex) { // Check if there's a second occurrence + shoppingList.splice(lastMilkIndex, 1); // Remove the last occurrence + console.log('Removed the duplicate "milk" from the list'); +} +// Removed the duplicate "milk" from the list + +// using includes method +const newItem = 'cheese'; +if (shoppingList.includes(newItem)) { + console.log('Cheese is already on the list!'); +} else { + shoppingList.push(newItem); + console.log('Cheese added to the list!'); +} +// Cheese added to the list! + +// using find, findIndex and findLastIndex methods + +// simple example +const availableToPurchase = [1, 13, 14, 15, 16, 17, 18]; +const desiredTicket = availableToPurchase .find(value => value < 7); +console.log('Desired ticket:', desiredTicket); // 1 + +// findIndex example - find the index and add it to the raflleTickets array +let raffleTickets = [ 2, 3, 4, 5, 6, 8, 9, 10, 11, 12 ]; +const ticketIndex = availableToPurchase.findIndex(value => value < 7); +if (ticketIndex !== -1) { + // Find the correct position to insert the ticket in raffleTickets (maintain numerical order) + const pos = raffleTickets.findIndex(value => value > availableToPurchase[ticketIndex]); + + // If no suitable position is found (all existing tickets are smaller), add to the end + const insertPos = (pos === -1) ? raffleTickets.length : pos; + + // Add the ticket to raffleTickets + raffleTickets.splice(insertPos, 0, availableToPurchase[ticketIndex]); + + // Remove the ticket from availableToPurchase + availableToPurchase.splice(ticketIndex, 1); +} + +// books example +const books = [ + { id: 1, title: 'The Fellowship of the Ring' }, + { id: 2, title: 'Fourth Wing' }, + { id: 3, title: 'A Court of Thorns and Roses' } +]; +console.log('Book with id 2:', books.find(book => book.id === 2)); // { id: 2, title: 'Fourth Wing' } +console.log('The Hobbit:', books.find(book => book.title === 'The Hobbit')); // undefined + +// remove book with id 3 +const bookIndex = books.findIndex(book => book.id === 3); +if (bookIndex !== -1) { + books.splice(bookIndex, 1); +} + +// using the filter method in the numbers array +const ticketsAvailable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +const firstTicket = raffleTickets.find(ticketNumber => ticketNumber < 7); +console.log('First lucky ticket:', firstTicket); // 1 + +const allTickets = raffleTickets.filter(ticketNum => ticketNum < 7); +console.log('All lucky tickets:', allTickets); // [1, 2, 3, 4, 5, 6] + + +// reverse the array +raffleTickets = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +raffleTickets.reverse(); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] +console.log('Reversed numbers:', raffleTickets); + +// sort the array +raffleTickets.sort(); // [1, 10, 2, 3, 4, 5, 6, 7, 8, 9] + +raffleTickets.sort((a, b) => a - b); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +// @ts-ignore +function compareNumbers(a, b) { + if (a < b) return -1; + if (a > b) return 1; + return 0; // a must be equal to b +} + +raffleTickets.sort(compareNumbers); + +console.log('Sorted numbers:', raffleTickets); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +// custom sorting +// @ts-ignore +const friends = [ + { name: 'Frodo', age: 30 }, + { name: 'Violet', age: 18 }, + { name: 'Aelin', age: 20 } +]; +// @ts-ignore +const compareFriends = (friendA, friendB) => friendA.age - friendB.age; +friends.sort(compareFriends); +console.log('Sorted friends:', friends); // [ { name: 'Violet', age: 18 }, { name: 'Aelin', age: 20 }, { name: 'Frodo', age: 30 } ] + +// sorting strings +// @ts-ignore +let playerNames = ['Ana', 'ana', 'john', 'John']; +console.log(playerNames.sort()); // ['Ana', 'John', 'ana', 'john'] + +playerNames = ['Ana', 'ana', 'john', 'John']; // Reset the array +playerNames.sort((a, b) => { + const nameA = a.toLowerCase(); + const nameB = b.toLowerCase(); + if (nameA < nameB) return -1; + if (nameA > nameB) return 1; + return 0; +}); +console.log(playerNames); // ["Ana", "ana", "john", "John"] + +playerNames.sort((a, b) => a.localeCompare(b)); +console.log(playerNames); // ['ana', 'Ana', 'john', 'John'] + +let namesWithAccents = ['Maève', 'Maeve']; +console.log(namesWithAccents.sort((a, b) => a.localeCompare(b))); // ['Maeve', 'Maève'] + +// without localeCompare +namesWithAccents = ['Maève', 'Maeve']; +console.log(namesWithAccents.sort()); // ['Maeve', 'Maève'] + +// to see the output of this file use the command: node src/03-array/04-searching-sorting.js \ No newline at end of file diff --git a/src/03-array/04-searching-sorting.ts b/src/03-array/04-searching-sorting.ts new file mode 100644 index 00000000..8dd73db7 --- /dev/null +++ b/src/03-array/04-searching-sorting.ts @@ -0,0 +1,105 @@ +// Path: src/03-array/04-searching-sorting.ts + +// @ts-ignore +const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + +// using indexOf method +console.log('Index of 5:', numbers.indexOf(5)); // 4 +console.log('Index of 11:', numbers.indexOf(11)); // -1 + +// using lastIndexOf method +console.log('Last index of 5:', numbers.lastIndexOf(5)); // 4 +console.log('Last index of 11:', numbers.lastIndexOf(11)); // -1 + +// using includes method +console.log('Is 5 included?:', numbers.includes(5)); // true +console.log('Is 11 included?:', numbers.includes(11)); // false + +// using find, findIndex and findLastIndex methods +const firstValueBelowSeven = numbers.find(value => value < 7); +console.log('First value below 7:', firstValueBelowSeven); // 1 +console.log('Index of first value below 7:', numbers.findIndex(value => value < 7)); // 0 +console.log('Index of last value below 7:', numbers.findLastIndex(value => value < 7)); // 5 + +const books = [ + { id: 1, title: 'The Fellowship of the Ring' }, + { id: 2, title: 'Fourth Wing' }, + { id: 3, title: 'A Court of Thorns and Roses' } +]; +console.log('Book with id 2:', books.find(book => book.id === 2)); // { id: 2, title: 'Fourth Wing' } +console.log('The Hobbit:', books.find(book => book.title === 'The Hobbit')); // undefined + +// remove book with id 3 +const bookIndex = books.findIndex(book => book.id === 3); +if (bookIndex !== -1) { + books.splice(bookIndex, 1); +} + +// using the filter method in the numbers array +// @ts-ignore +const valuesBelowSeven = numbers.filter(value => value < 7); +console.log('Values below 7:', valuesBelowSeven); // [1, 2, 3, 4, 5, 6] + +// reverse the array +numbers.reverse(); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] +console.log('Reversed numbers:', numbers); + +// sort the array +numbers.sort(); // [1, 10, 2, 3, 4, 5, 6, 7, 8, 9] + +numbers.sort((a, b) => a - b); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +// @ts-ignore +function compareNumbers(a, b) { + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + // a must be equal to b + return 0; + } + numbers.sort(compareNumbers); + +console.log('Sorted numbers:', numbers); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +// custom sorting +// @ts-ignore +const friends = [ + { name: 'Frodo', age: 30 }, + { name: 'Violet', age: 18 }, + { name: 'Aelin', age: 20 } +]; +// @ts-ignore +const compareFriends = (friendA, friendB) => friendA.age - friendB.age; +friends.sort(compareFriends); +console.log('Sorted friends:', friends); // [ { name: 'Violet', age: 18 }, { name: 'Aelin', age: 20 }, { name: 'Frodo', age: 30 } ] + +// sorting strings +// @ts-ignore +let names = ['Ana', 'ana', 'john', 'John']; +console.log(names.sort()); // ['Ana', 'John', 'ana', 'john'] + +names = ['Ana', 'ana', 'john', 'John']; // reset the array to its original state +names.sort((a, b) => { + const nameA = a.toLowerCase(); + const nameB = b.toLowerCase(); + if (nameA < nameB) { + return -1; + } + if (nameA > nameB) { + return 1; + } + return 0; +}); +console.log(names); // ['Ana', 'ana', 'John', 'john'] + +names.sort((a, b) => a.localeCompare(b)); +console.log(names); // ['ana', 'Ana', 'john', 'John'] + +const names2 = ['Maève', 'Maeve']; +console.log(names2.sort((a, b) => a.localeCompare(b))); // ['Maeve', 'Maève'] + + +// to see the output of this file use the command: node src/03-array/04-searching-sorting.ts \ No newline at end of file diff --git a/src/03-array/05-transforming-array.js b/src/03-array/05-transforming-array.js new file mode 100644 index 00000000..fa0ac6a0 --- /dev/null +++ b/src/03-array/05-transforming-array.js @@ -0,0 +1,67 @@ +// Path: src/03-array/05-transforming-array.js + +// @ts-ignore +const numbers_ = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + +// using the map method +const celsiusTemperatures = [0, 5, 10, 15, 20, 25, 30]; +const fahrenheitTemperatures = celsiusTemperatures.map(celsius => { + return (celsius * 9/5) + 32; +}); +console.log('Celsius:', celsiusTemperatures); // Celsius: [0, 5, 10, 15, 20, 25, 30] +console.log('Fahrenheit:', fahrenheitTemperatures); // Fahrenheit: 32, 41, 50, 59, 68, 77, 86] + + +// rewriting the above code using a loop +const fahrenheitTemperaturesLoop = []; +for (let i = 0; i < celsiusTemperatures.length; i++) { + fahrenheitTemperaturesLoop.push((celsiusTemperatures[i] * 9/5) + 32); +} + +// using the split method +const namesFromCSV = 'Aelin,Gandalf,Violet,Poppy'; +// @ts-ignore +const names = namesFromCSV.split(','); +console.log('Names:', names); // ['Aelin', 'Gandalf', 'Violet', 'Poppy'] + +// using the join method +const namesCSV = names.join(';'); +console.log('Names CSV:', namesCSV); // 'Aelin;Gandalf;Violet;Poppy' + +// using the reduce method +const cartItems = [ + { name: 'Laptop', price: 1200 }, + { name: 'Smartphone', price: 500 }, + { name: 'Headphones', price: 100 } +]; + +const totalPrice = cartItems.reduce((accumulator, currentItem) => { + return accumulator + currentItem.price; +}, 0); // Start the accumulator at 0 +console.log('Total Price:', totalPrice); // Total Price: 1800 + +// rewriting the above code using a loop +let totalPriceLoop = 0; +for (let i = 0; i < cartItems.length; i++) { + totalPriceLoop += cartItems[i].price; +} + +// using the reduce method to find the maximum value +const scores = [30, 70, 85, 90, 100]; +const highestScore = scores.reduce((max, score) => { + return score > max ? score : max; +}); +console.log('Highest Score:', highestScore); // Highest Score: 100 + +// using with +const leaderboard = [ + { player: 'Poppy', score: 150 }, + { player: 'Violet', score: 120 }, + { player: 'Tory', score: 90 } +]; + +const updated = leaderboard.with(1, { player: 'Violet', score: 135 }); +console.log('Leaderboard:', leaderboard); // [{ player: 'Poppy', score: 150 }, { player: 'Violet', score: 120 }, { player: 'Tory', score: 90 }] +console.log('Updated :', updated); // [{ player: 'Poppy', score: 150 }, { player: 'Violet', score: 135 }, { player: 'Tory', score: 90 }] + +// to see the output of this file use the command: node src/03-array/05-transforming-array.js \ No newline at end of file diff --git a/src/03-array/05-transforming-array.ts b/src/03-array/05-transforming-array.ts new file mode 100644 index 00000000..43f6e528 --- /dev/null +++ b/src/03-array/05-transforming-array.ts @@ -0,0 +1,47 @@ +// Path: src/03-array/05-transforming-array.ts + +// @ts-ignore +const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + +// using the map method +const squaredNumbers = numbers.map(value => value * value); +console.log('Squared numbers:', squaredNumbers); // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] + +// rewriting the above code using a loop +const squaredNumbersLoop = []; +for (let i = 0; i < numbers.length; i++) { + squaredNumbersLoop.push(numbers[i] * numbers[i]); +} + +// using the split method +const namesFromCSV = 'Aelin,Gandalf,Violet,Poppy'; +// @ts-ignore +const names = namesFromCSV.split(','); +console.log('Names:', names); // ['Aelin', 'Gandalf', 'Violet', 'Poppy'] + +// using the join method +const namesCSV = names.join(';'); +console.log('Names CSV:', namesCSV); // 'Aelin;Gandalf;Violet;Poppy' + +// using the reduce method +// @ts-ignore +const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +const sum = numbers.reduce((acc, value) => acc + value, 0); // 55 + +// rewriting the above code using a loop +let sumLoop = 0; +for (let i = 0; i < numbers.length; i++) { + sumLoop += numbers[i]; +} + +// using the reduce method to find the maximum value +const scores = [30, 70, 85, 90, 100]; +const highestScore = scores.reduce((max, score) => score > max ? score : max, scores[0]); // 100 + +// using reduceRight method +const reversedNumbers = numbers.reduceRight((acc, value) => { + acc.push(value); + return acc; +}, []); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] + +// to see the output of this file use the command: node src/03-array/05-transforming-array.ts \ No newline at end of file diff --git a/src/03-array/06-other-methods.js b/src/03-array/06-other-methods.js new file mode 100644 index 00000000..1a2bc0f3 --- /dev/null +++ b/src/03-array/06-other-methods.js @@ -0,0 +1,82 @@ +// Path: src/03-array/06-other-methods.js + +// using Array.isArray() method +console.log(typeof 'Learning Data Structures'); // string +console.log(typeof 123); // number +console.log(typeof { id: 1 }); // object +console.log(typeof [1, 2, 3]); // object + +console.log(Array.isArray([1, 2, 3])); // true +console.log(Array.isArray({ id: 1 })); // false + +// real world example +const jsonStringFromAPI = '[{"id":1,"title":"The Lord of the Rings"},{"id":2,"title":"The Hobbit"}]'; +const dataReceived = JSON.parse(jsonStringFromAPI); + +if (Array.isArray(dataReceived)) { + console.log('Received an array of books!'); + // check if The Hobbit is in the array + const hobbitBook = dataReceived.find(book => book.title === 'The Hobbit'); + if (hobbitBook) { + console.log('Found The Hobbit!'); + } else { + console.log('The Hobbit was not found in the results.'); + } +} else { + console.log('Data received is not an array.'); + // Handle other possible response types (single object, null, etc.) +} +// Received an array of books! + +// using Array.from() method +const originalPixels = [255, 0, 0, 128, 128, 128]; // red, gray +const backupPixels = Array.from(originalPixels); +console.log(backupPixels); // [255, 0, 0, 128, 128, 128] + +// increase each pixel value by 50 +const brightenedPixels = Array.from(originalPixels, pixelValue => pixelValue + 50); +console.log(brightenedPixels); // [305, 50, 50, 178, 178, 178] + + +// Array.from() method creates a new, shallow-copied Array instance from an array-like or iterable object. +let friends = [ + { name: 'Frodo', age: 30 }, + { name: 'Violet', age: 18 } +]; +const friendsCopy = Array.from(friends); +friends[0].name = 'Sam'; // modify the original +console.log(friendsCopy[0].name); // 'Sam' + + +// deep copy +const anotherBackup = [...originalPixels]; +const friendsDeepCopy = structuredClone(friends); +friendsDeepCopy[0].name = 'Frodo'; +console.log(friends[0].name); // 'Sam' - dit not change the original array + + +// using Array.of() method +let suits = Array.of('Hearts', 'Diamonds', 'Clubs', 'Spades'); +console.log(suits); // ['Hearts', 'Diamonds', 'Clubs', 'Spades'] + +// same as: +suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']; + +const originalDeck = [ 1, 2, 3 ]; +const shuffledDeck = Array.of(...originalDeck); + +// using Array.fill() method +const tornamentResults = new Array(5).fill('pending'); + +tornamentResults.fill('win', 1, 3); +console.log(tornamentResults); // ['pending', 'win', 'win', 'pending', 'pending'] + +// joining arrays +const zero = 0; +const positiveNumbers = [1, 2, 3]; +const negativeNumbers = [-3, -2, -1]; +let allNumbers = negativeNumbers.concat(zero, positiveNumbers); + +allNumbers = [...negativeNumbers,zero,...positiveNumbers]; + +// to see the output of this file use the command: node src/03-array/06-other-methods.js \ No newline at end of file diff --git a/src/03-array/06-other-methods.ts b/src/03-array/06-other-methods.ts new file mode 100644 index 00000000..7ec3fcec --- /dev/null +++ b/src/03-array/06-other-methods.ts @@ -0,0 +1,74 @@ +// Path: src/03-array/06-other-methods.ts + +// using Array.isArray() method +console.log(typeof 'Learning Data Structures'); // string +console.log(typeof 123); // number +console.log(typeof { id: 1 }); // object +console.log(typeof [1, 2, 3]); // object + +console.log(Array.isArray([1, 2, 3])); // true + +// real world example +const jsonString = JSON.stringify('[{"id":1,"title":"The Fellowship of the Ring"},{"id":2,"title":"Fourth Wing"}]'); +const dataReceived = JSON.parse(jsonString); + +if (Array.isArray(dataReceived)) { + console.log('It is an array'); + // check if The Fellowship of the Ring is in the array + const fellowship = dataReceived.find((item) => { + return item.title === 'The Fellowship of the Ring'; + }); + if (fellowship) { + console.log('We received the book we were looking for!'); + } else { + console.log('We did not receive the book we were looking for!'); + } +} + +// using Array.from() method +// @ts-ignore +const numbers = [1, 2, 3, 4, 5]; +const numbersCopy = Array.from(numbers); +console.log(numbersCopy); // [1, 2, 3, 4, 5] + +const evens = Array.from(numbers, x => (x % 2 == 0)); +console.log(evens); // [false, true, false, true, false] + +// Array.from() method creates a new, shallow-copied Array instance from an array-like or iterable object. +// @ts-ignore +const friends = [ + { name: 'Frodo', age: 30 }, + { name: 'Violet', age: 18 }, + { name: 'Aelin', age: 20 } +]; +const friendsCopy = Array.from(friends); +console.log(friendsCopy); + +friends[0].name = 'Sam'; +console.log(friendsCopy[0].name); // Sam + +// deep copy +const friendsDeepCopy = JSON.parse(JSON.stringify(friends)); +friends[0].name = 'Frodo'; +console.log(friendsDeepCopy[0].name); // Sam + +// using Array.of() method +const numbersArray = Array.of(1, 2, 3, 4, 5); +console.log(numbersArray); // [1, 2, 3, 4, 5] + +let numbersCopy2 = Array.of(...numbersArray); + +// using Array.fill() method +const tornamentResults = new Array(5).fill('pending'); + +tornamentResults.fill('win', 1, 3); +console.log(tornamentResults); // ['pending', 'win', 'win', 'pending', 'pending'] + +// joining arrays +const zero = 0; +const positiveNumbers = [1, 2, 3]; +const negativeNumbers = [-3, -2, -1]; +let allNumbers = negativeNumbers.concat(zero, positiveNumbers); + + +// to see the output of this file use the command: node src/03-array/06-other-methods.ts \ No newline at end of file diff --git a/src/03-array/07-multidimensional-arrays.js b/src/03-array/07-multidimensional-arrays.js new file mode 100644 index 00000000..93cc2b3b --- /dev/null +++ b/src/03-array/07-multidimensional-arrays.js @@ -0,0 +1,87 @@ +// Path: src/03-array/07-multidimensional-arrays.js + +let averageHourlyTempDay1 = [72, 75, 79, 79, 81, 81]; +let averageHourlyTempDay2 = [81, 79, 75, 75, 73, 72]; + +// multidimensional array representation +let averageTempMultipleDays = []; +averageTempMultipleDays[0] = [72, 75, 79, 79, 81, 81]; +averageTempMultipleDays[1] = [81, 79, 75, 75, 73, 73]; + +// same as above: +averageTempMultipleDays = [ + [72, 75, 79, 79, 81, 81], + [81, 79, 75, 75, 73, 73] +]; + +// day 1 +averageTempMultipleDays[0] = []; +averageTempMultipleDays[0][0] = 72; +averageTempMultipleDays[0][1] = 75; +averageTempMultipleDays[0][2] = 79; +averageTempMultipleDays[0][3] = 79; +averageTempMultipleDays[0][4] = 81; +averageTempMultipleDays[0][5] = 81; +// day 2 +averageTempMultipleDays[1] = []; +averageTempMultipleDays[1][0] = 81; +averageTempMultipleDays[1][1] = 79; +averageTempMultipleDays[1][2] = 75; +averageTempMultipleDays[1][3] = 75; +averageTempMultipleDays[1][4] = 73; +averageTempMultipleDays[1][5] = 73; + +// @ts-ignore +function printMultidimensionalArray(myArray) { + for (let i = 0; i < myArray.length; i++) { + for (let j = 0; j < myArray[i].length; j++) { + console.log(myArray[i][j]); + } + } +} + +printMultidimensionalArray(averageTempMultipleDays); + +console.table(averageTempMultipleDays); + +//* * Multidimensional Matrix +// Dimension 1 (i): each day +// Dimension 2 (j): location +// Dimension 3 (z): temperature +// declare a 3-dimensional Array 3x3x3: +let averageTempMultipleDaysAndLocation = []; + +// day 1 +averageTempMultipleDaysAndLocation[0] = []; +averageTempMultipleDaysAndLocation[0][0] = [19, 20, 21]; // location 1 +averageTempMultipleDaysAndLocation[0][1] = [20, 22, 23]; // location 2 +averageTempMultipleDaysAndLocation[0][2] = [30, 31, 32]; // location 3 + +// day 2 +averageTempMultipleDaysAndLocation[1] = []; +averageTempMultipleDaysAndLocation[1][0] = [21, 22, 23]; // location 1 +averageTempMultipleDaysAndLocation[1][1] = [22, 23, 24]; // location 2 +averageTempMultipleDaysAndLocation[1][2] = [29, 30, 30]; // location 3 + +// day 3 +averageTempMultipleDaysAndLocation[2] = []; +averageTempMultipleDaysAndLocation[2][0] = [22, 23, 24]; // location 1 +averageTempMultipleDaysAndLocation[2][1] = [23, 24, 23]; // location 2 +averageTempMultipleDaysAndLocation[2][2] = [30, 31, 31]; // location 3 + + +function printMultidimensionalArray3D(myArray) { + for (let i = 0; i < myArray.length; i++) { + for (let j = 0; j < myArray[i].length; j++) { + for (let z = 0; z < myArray[i][j].length; z++) { + console.log(myArray[i][j][z]); + } + } + } +} + +printMultidimensionalArray3D(averageTempMultipleDaysAndLocation); + +console.table(averageTempMultipleDaysAndLocation); + +// to see the output of this file use the command: node src/03-array/07-multidimensional-arrays.js \ No newline at end of file diff --git a/src/03-array/07-multidimensional-arrays.ts b/src/03-array/07-multidimensional-arrays.ts new file mode 100644 index 00000000..35879e40 --- /dev/null +++ b/src/03-array/07-multidimensional-arrays.ts @@ -0,0 +1,87 @@ +// Path: src/03-array/07-multidimensional-arrays.ts + +let averageTempDay1 = [72, 75, 79, 79, 81, 81]; +let averageTempDay2 = [81, 79, 75, 75, 73, 72]; + +// multidimensional array representation +let averageTempMultipleDays = []; +averageTempMultipleDays[0] = [72, 75, 79, 79, 81, 81]; +averageTempMultipleDays[1] = [81, 79, 75, 75, 73, 73]; + +// same as above: +averageTempMultipleDays = [ + [72, 75, 79, 79, 81, 81], + [81, 79, 75, 75, 73, 73] +]; + +// day 1 +averageTempMultipleDays[0] = []; +averageTempMultipleDays[0][0] = 72; +averageTempMultipleDays[0][1] = 75; +averageTempMultipleDays[0][2] = 79; +averageTempMultipleDays[0][3] = 79; +averageTempMultipleDays[0][4] = 81; +averageTempMultipleDays[0][5] = 81; +// day 2 +averageTempMultipleDays[1] = []; +averageTempMultipleDays[1][0] = 81; +averageTempMultipleDays[1][1] = 79; +averageTempMultipleDays[1][2] = 75; +averageTempMultipleDays[1][3] = 75; +averageTempMultipleDays[1][4] = 73; +averageTempMultipleDays[1][5] = 73; + +// @ts-ignore +function printMultidimensionalArray(myArray) { + for (let i = 0; i < myArray.length; i++) { + for (let j = 0; j < myArray[i].length; j++) { + console.log(myArray[i][j]); + } + } +} + +printMultidimensionalArray(averageTempMultipleDays); + +console.table(averageTempMultipleDays); + +//* * Multidimensional Matrix +// Dimension 1 (i): each day +// Dimension 2 (j): location +// Dimension 3 (z): temperature +// declare a 3-dimensional Array 3x3x3: +let averageTempMultipleDaysAndLocation = []; + +// day 1 +averageTempMultipleDaysAndLocation[0] = []; +averageTempMultipleDaysAndLocation[0][0] = [19, 20, 21]; // location 1 +averageTempMultipleDaysAndLocation[0][1] = [20, 22, 23]; // location 2 +averageTempMultipleDaysAndLocation[0][2] = [30, 31, 32]; // location 3 + +// day 2 +averageTempMultipleDaysAndLocation[1] = []; +averageTempMultipleDaysAndLocation[1][0] = [21, 22, 23]; // location 1 +averageTempMultipleDaysAndLocation[1][1] = [22, 23, 24]; // location 2 +averageTempMultipleDaysAndLocation[1][2] = [29, 30, 30]; // location 3 + +// day 3 +averageTempMultipleDaysAndLocation[2] = []; +averageTempMultipleDaysAndLocation[2][0] = [22, 23, 24]; // location 1 +averageTempMultipleDaysAndLocation[2][1] = [23, 24, 23]; // location 2 +averageTempMultipleDaysAndLocation[2][2] = [30, 31, 31]; // location 3 + + +function printMultidimensionalArray3D(myArray) { + for (let i = 0; i < myArray.length; i++) { + for (let j = 0; j < myArray[i].length; j++) { + for (let z = 0; z < myArray[i][j].length; z++) { + console.log(myArray[i][j][z]); + } + } + } +} + +printMultidimensionalArray3D(averageTempMultipleDaysAndLocation); + +console.table(averageTempMultipleDaysAndLocation); + +// to see the output of this file use the command: node src/03-array/07-multidimensional-arrays.ts \ No newline at end of file diff --git a/src/03-array/08-TypedArrays.js b/src/03-array/08-TypedArrays.js new file mode 100644 index 00000000..13e29a8a --- /dev/null +++ b/src/03-array/08-TypedArrays.js @@ -0,0 +1,15 @@ +// Path: src/03-array/08-TypedArrays.js + +// TypedArray example +const arrayLength = 5; +const int16 = new Int16Array(arrayLength); + +for (let i = 0; i < arrayLength; i++) { + int16[i] = i + 1; +} + +console.log(int16); + +// check https://js.tensorflow.org for more practical examples + +// to see the output of this file use the command: node src/03-array/08-TypedArrays.js \ No newline at end of file diff --git a/src/03-array/08-TypedArrays.ts b/src/03-array/08-TypedArrays.ts new file mode 100644 index 00000000..41a6cdc6 --- /dev/null +++ b/src/03-array/08-TypedArrays.ts @@ -0,0 +1,15 @@ +// Path: src/03-array/08-TypedArrays.ts + +// TypedArray example +const arrayLength = 5; +const int16 = new Int16Array(arrayLength); + +for (let i = 0; i < arrayLength; i++) { + int16[i] = i + 1; +} + +console.log(int16); + +// check https://js.tensorflow.org for more practical examples + +// to see the output of this file use the command: node src/03-array/08-TypedArrays.ts \ No newline at end of file diff --git a/src/03-array/08-different-data-types.js b/src/03-array/08-different-data-types.js new file mode 100644 index 00000000..0f6bbc3d --- /dev/null +++ b/src/03-array/08-different-data-types.js @@ -0,0 +1,39 @@ +// Path: src/03-array/07-different-data-types.js + +const legacyOrderData = '12345,Cassian,2024-01-21,Laptop:1200|Mouse:50,1250,Shipped'; +const customerOrderArray = legacyOrderData.split(','); +console.log(customerOrderArray); +// [ +// '12345', +// 'Cassian', +// '2024-01-21', +// 'Laptop:1200|Mouse:50', +// '1250', +// 'Shipped' +// ] + +const customerOrder = { + id: Number(customerOrderArray[0]), + name: customerOrderArray[1], + date: new Date(customerOrderArray[2]), + items: customerOrderArray[3].split('|').map(item => { + const [name, price] = item.split(':'); + return { + name, + price: Number(price) + }; + }), + total: Number(customerOrderArray[4]), + status: customerOrderArray[5] +}; +console.log(customerOrder); +// { +// id: 12345, +// name: 'Cassian', +// date: 2024-01-21T00:00:00.000Z, +// items: [ { name: 'Laptop', price: 1200 }, { name: 'Mouse', price: 50 } ], +// total: 1250, +// status: 'Shipped' +// } + +// to see the output of this file use the command: node src/03-array/07-different-data-types.js \ No newline at end of file diff --git a/src/03-array/09-arrays-typescript.js b/src/03-array/09-arrays-typescript.js new file mode 100644 index 00000000..d5229b24 --- /dev/null +++ b/src/03-array/09-arrays-typescript.js @@ -0,0 +1,14 @@ +// Path: src/03-array/09-arrays-typescript.js +// @ts-ignore +const friends = [ + { name: 'Frodo', age: 30 }, + { name: 'Violet', age: 18 }, + { name: 'Aelin', age: 20 } +]; +// @ts-ignore +const compareFriends = (friendA, friendB) => { + return friendA.age - friendB.age; +}; +friends.sort(compareFriends); +console.log('Sorted friends:', friends); // [ { name: 'Violet', age: 18 }, { name: 'Aelin', age: 20 }, { name: 'Frodo', age: 30 } ] +// to see the output of this file use the command: node src/03-array/09-arrays-typescript.js diff --git a/src/03-array/09-arrays-typescript.ts b/src/03-array/09-arrays-typescript.ts new file mode 100644 index 00000000..34cede53 --- /dev/null +++ b/src/03-array/09-arrays-typescript.ts @@ -0,0 +1,23 @@ +// Path: src/03-array/09-arrays-typescript.ts + +interface Friend { + name: string; + age: number; +} + +// @ts-ignore +const friends = [ + { name: 'Frodo', age: 30 }, + { name: 'Violet', age: 18 }, + { name: 'Aelin', age: 20 } +]; + +// @ts-ignore +const compareFriends = (friendA: Friend, friendB: Friend) => { + return friendA.age - friendB.age; +}; +friends.sort(compareFriends); +console.log('Sorted friends:', friends); // [ { name: 'Violet', age: 18 }, { name: 'Aelin', age: 20 }, { name: 'Frodo', age: 30 } ] + + +// to see the output of this file use the command: node src/03-array/09-arrays-typescript.ts \ No newline at end of file diff --git a/src/03-array/10-todo-list-example.html b/src/03-array/10-todo-list-example.html new file mode 100644 index 00000000..17886bb5 --- /dev/null +++ b/src/03-array/10-todo-list-example.html @@ -0,0 +1,54 @@ + + + + + Simple TODO List (Array-Based) + + +

My TODO List

+ + + + +
    + + + + \ No newline at end of file diff --git a/src/03-array/hackerrank/01-arrays-ds.js b/src/03-array/hackerrank/01-arrays-ds.js new file mode 100644 index 00000000..55348a14 --- /dev/null +++ b/src/03-array/hackerrank/01-arrays-ds.js @@ -0,0 +1,31 @@ +// Path: src/03-array/hackerrank/01-arrays-ds.js +// Problem: https://www.hackerrank.com/challenges/arrays-ds/problem +// Solution 1 +function reverseArray(a) { + return a.reverse(); +} +// Solution 2 +function reverseArray2(a) { + const result = []; + for (let i = a.length - 1; i >= 0; i--) { + result.push(a[i]); + } + return result; +} +// Solution 3 +function reverseArray3(a) { + return a.map((_, i) => a[a.length - 1 - i]); +} +// Solution 4 +function reverseArray4(a) { + const result = []; + for (let i = 0; i < a.length; i++) { + result.unshift(a[i]); + } + return result; +} +// Test cases +console.log(reverseArray([1, 4, 3, 2])); // [2, 3, 4, 1] +console.log(reverseArray2([1, 4, 3, 2])); // [2, 3, 4, 1] +console.log(reverseArray3([1, 4, 3, 2])); // [2, 3, 4, 1] +console.log(reverseArray4([1, 4, 3, 2])); // [2, 3, 4, 1] diff --git a/src/03-array/hackerrank/01-arrays-ds.ts b/src/03-array/hackerrank/01-arrays-ds.ts new file mode 100644 index 00000000..e0ae8044 --- /dev/null +++ b/src/03-array/hackerrank/01-arrays-ds.ts @@ -0,0 +1,47 @@ +// Path: src/03-array/hackerrank/01-arrays-ds.ts +// Problem: https://www.hackerrank.com/challenges/arrays-ds/problem + +// Solution 1 +function reverseArray(a: number[]): number[] { + return a.reverse(); +} + +// Solution 2 +function reverseArray2(a: number[]): number[] { + const result = []; + for (let i = a.length - 1; i >= 0; i--) { + result.push(a[i]); + } + return result; +} + +// Solution 3 +function reverseArray3(a: number[]): number[] { + return a.map((_, i) => a[a.length - 1 - i]); +} + +// Solution 4 +function reverseArray4(a: number[]): number[] { + const result = []; + for (let i = 0; i < a.length; i++) { + result.unshift(a[i]); + } + return result; +} + +// Solution 5, swap +function reverseArray5(a: number[]): number[] { + for (let i = 0; i < a.length / 2; i++) { + const temp = a[i]; + a[i] = a[a.length - 1 - i]; + a[a.length - 1 - i] = temp; + } + return a; +} + +// Test cases +console.log(reverseArray([1, 4, 3, 2])); // [2, 3, 4, 1] +console.log(reverseArray2([1, 4, 3, 2])); // [2, 3, 4, 1] +console.log(reverseArray3([1, 4, 3, 2])); // [2, 3, 4, 1] +console.log(reverseArray4([1, 4, 3, 2])); // [2, 3, 4, 1] + diff --git a/src/03-array/hackerrank/02-array-left-rotation.js b/src/03-array/hackerrank/02-array-left-rotation.js new file mode 100644 index 00000000..34a5bdb0 --- /dev/null +++ b/src/03-array/hackerrank/02-array-left-rotation.js @@ -0,0 +1,13 @@ +// Path: src/03-array/hackerrank/02-array-left-rotation.js +// Problem: https://www.hackerrank.com/challenges/array-left-rotation/problem +// Solution 1 +function rotLeft(a, d) { + return a.concat(a.splice(0, d)); +} +// Solution 2 +function rotLeft2(a, d) { + return [...a.slice(d), ...a.slice(0, d)]; +} +// Test cases +console.log(rotLeft([1, 2, 3, 4, 5], 4)); // [5, 1, 2, 3, 4] +console.log(rotLeft2([1, 2, 3, 4, 5], 4)); // [5, 1, 2, 3, 4] diff --git a/src/03-array/hackerrank/02-array-left-rotation.ts b/src/03-array/hackerrank/02-array-left-rotation.ts new file mode 100644 index 00000000..f171baaf --- /dev/null +++ b/src/03-array/hackerrank/02-array-left-rotation.ts @@ -0,0 +1,29 @@ +// Path: src/03-array/hackerrank/02-array-left-rotation.ts +// Problem: https://www.hackerrank.com/challenges/array-left-rotation/problem + +// Solution 1 +function rotLeft(a: number[], d: number): number[] { + return a.concat(a.splice(0, d)); +} + +// Solution 2 +function rotLeft2(a: number[], d: number): number[] { + return [...a.slice(d), ...a.slice(0, d)]; +} + +// Solution 3, swap the elements d times +function rotLeft3(a: number[], d: number): number[] { + for (let i = 0; i < d; i++) { + const temp = a[0]; + for (let j = 0; j < a.length - 1; j++) { + a[j] = a[j + 1]; + } + a[a.length - 1] = temp; + } + return a; +} + + +// Test cases +console.log(rotLeft([1, 2, 3, 4, 5], 4)); // [5, 1, 2, 3, 4] +console.log(rotLeft2([1, 2, 3, 4, 5], 4)); // [5, 1, 2, 3, 4] diff --git a/src/04-stack/01-undo-feature.js b/src/04-stack/01-undo-feature.js new file mode 100644 index 00000000..c4ada225 --- /dev/null +++ b/src/04-stack/01-undo-feature.js @@ -0,0 +1,34 @@ +// src/04-stack/01-undo-feature.js + +const Stack = require('./stack'); +// import { Stack } from './stack'; // or './stack.js' if you are using ES modules + +const undoFeature = new Stack(); + +console.log(undoFeature.isEmpty()); // true + +undoFeature.push({action: 'typing', text: 'S'}); +undoFeature.push({action: 'typing', text: 't'}); + +console.log(undoFeature.peek()); // { action: 'typing', text: 't' } + +console.log(undoFeature.size); // 2 + +undoFeature.push({action: 'typing', text: 'a'}); +undoFeature.push({action: 'typing', text: 'c'}); +undoFeature.push({action: 'typing', text: 'k'}); + +console.log(undoFeature.size); // 5 +console.log(undoFeature.isEmpty()); // false + +// removing two elements from the stack +undoFeature.pop(); +undoFeature.pop(); + +console.log(undoFeature.size); // 3 +console.log(undoFeature.peek()); // { action: 'typing', text: 'a' } + +// toString +console.log(undoFeature.toString()); + +// to see the output of this file use the command: node src/04-stack/01-undo-feature.js \ No newline at end of file diff --git a/src/04-stack/01-using-stack-class.ts b/src/04-stack/01-using-stack-class.ts new file mode 100644 index 00000000..4d8a31e3 --- /dev/null +++ b/src/04-stack/01-using-stack-class.ts @@ -0,0 +1,45 @@ +// src/04-stack/01-using-stack-class.ts + +import Stack from './stack'; + +enum Action { + TYPE = 'typing', + // Add more actions like DELETE, FORMAT, etc. +} + +interface EditorAction { + action: Action; + text?: string; // Optional text for typing actions +} + +const stack = new Stack(); + +console.log(stack.isEmpty()); // true + +console.log(stack.peek()); // undefined + +stack.push({action: Action.TYPE, text: 'S'}); +stack.push({action: Action.TYPE, text: 't'}); + +console.log(stack.peek()); // { action: 'typing', text: 't' } + +console.log(stack.size); // 2 + +stack.push({action: Action.TYPE, text: 'a'}); +stack.push({action: Action.TYPE, text: 'c'}); +stack.push({action: Action.TYPE, text: 'k'}); + +console.log(stack.size); // 5 +console.log(stack.isEmpty()); // false + +// removing two elements from the stack +stack.pop(); +stack.pop(); + +console.log(stack.size); // 3 +console.log(stack.peek()); // { action: 'typing', text: 'a' } + +// toString +console.log(stack.toString()); + +// to see the output of this file use the command: npx ts-node src/04-stack/01-using-stack-class.ts \ No newline at end of file diff --git a/src/04-stack/02-base-converter-examples.js b/src/04-stack/02-base-converter-examples.js new file mode 100644 index 00000000..1145a408 --- /dev/null +++ b/src/04-stack/02-base-converter-examples.js @@ -0,0 +1,24 @@ +// src/04-stack/03-base-converter-examples.js + +const decimalToBinary = require('./decimal-to-binary'); +const converters = require('./decimal-to-base'); + +// Decimal to binary +console.log(decimalToBinary(0)); // 0 +console.log(decimalToBinary(1)); // 1 +console.log(decimalToBinary(2)); // 10 +console.log(decimalToBinary(13)); // 1101 +console.log(decimalToBinary(233)); // 11101001 +console.log(decimalToBinary(10)); // 1010 +console.log(decimalToBinary(1000)); // 1111101000 + +// Decimal to base +console.log(converters.decimalToBase(100345, 2)); // 11000011111111001 +console.log(converters.decimalToBase(100345, 8)); // 303771 +console.log(converters.decimalToBase(100345, 16)); // 187F9 +console.log(converters.decimalToBase(100345, 35)); // 2BW0 + +// Decimal to base 64 +console.log(converters.decimalToBase64(100345, 64)); // Yf5= + +// to see the output of this file use the command: node src/04-stack/03-base-converter-examples.js \ No newline at end of file diff --git a/src/04-stack/02-base-converter-examples.ts b/src/04-stack/02-base-converter-examples.ts new file mode 100644 index 00000000..78cea812 --- /dev/null +++ b/src/04-stack/02-base-converter-examples.ts @@ -0,0 +1,24 @@ +// src/04-stack/03-base-converter-examples.ts + +import decimalToBinary from './decimal-to-binary'; +import { decimalToBase, decimalToBase64 } from './decimal-to-base'; + +// Decimal to binary +console.log(decimalToBinary(0)); // 0 +console.log(decimalToBinary(1)); // 1 +console.log(decimalToBinary(2)); // 10 +console.log(decimalToBinary(13)); // 1101 +console.log(decimalToBinary(233)); // 11101001 +console.log(decimalToBinary(10)); // 1010 +console.log(decimalToBinary(1000)); // 1111101000 + +// Decimal to base +console.log(decimalToBase(100345, 2)); // 11000011111111001 +console.log(decimalToBase(100345, 8)); // 303771 +console.log(decimalToBase(100345, 16)); // 187F9 +console.log(decimalToBase(100345, 35)); // 2BW0 + +// Decimal to base 64 +console.log(decimalToBase64(100345, 64)); // Yf5= + +// to see the output of this file use the command: npx ts-node src/04-stack/03-base-converter-examples.js \ No newline at end of file diff --git a/src/04-stack/__test__/decimal-to-base.test.ts b/src/04-stack/__test__/decimal-to-base.test.ts new file mode 100644 index 00000000..8c0de9f1 --- /dev/null +++ b/src/04-stack/__test__/decimal-to-base.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, test } from '@jest/globals'; +import decimalToBinary from '../decimal-to-binary'; + +describe('decimalToBinary', () => { + test('should convert decimal number 0 to binary', () => { + expect(decimalToBinary(0)).toBe('0'); + }); + + test('should convert decimal number 1 to binary', () => { + expect(decimalToBinary(1)).toBe('1'); + }); + + test('should convert decimal number 10 to binary', () => { + expect(decimalToBinary(10)).toBe('1010'); + }); + + test('should convert decimal number 15 to binary', () => { + expect(decimalToBinary(15)).toBe('1111'); + }); + + test('should convert decimal number 100 to binary', () => { + expect(decimalToBinary(100)).toBe('1100100'); + }); + + test('should convert decimal number 255 to binary', () => { + expect(decimalToBinary(255)).toBe('11111111'); + }); +}); \ No newline at end of file diff --git a/src/04-stack/__test__/decimal-to-binary.test.ts b/src/04-stack/__test__/decimal-to-binary.test.ts new file mode 100644 index 00000000..8c0de9f1 --- /dev/null +++ b/src/04-stack/__test__/decimal-to-binary.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, test } from '@jest/globals'; +import decimalToBinary from '../decimal-to-binary'; + +describe('decimalToBinary', () => { + test('should convert decimal number 0 to binary', () => { + expect(decimalToBinary(0)).toBe('0'); + }); + + test('should convert decimal number 1 to binary', () => { + expect(decimalToBinary(1)).toBe('1'); + }); + + test('should convert decimal number 10 to binary', () => { + expect(decimalToBinary(10)).toBe('1010'); + }); + + test('should convert decimal number 15 to binary', () => { + expect(decimalToBinary(15)).toBe('1111'); + }); + + test('should convert decimal number 100 to binary', () => { + expect(decimalToBinary(100)).toBe('1100100'); + }); + + test('should convert decimal number 255 to binary', () => { + expect(decimalToBinary(255)).toBe('11111111'); + }); +}); \ No newline at end of file diff --git a/src/04-stack/__test__/stack.test.ts b/src/04-stack/__test__/stack.test.ts new file mode 100644 index 00000000..d01c3aad --- /dev/null +++ b/src/04-stack/__test__/stack.test.ts @@ -0,0 +1,92 @@ +import {describe, expect, test, beforeEach} from '@jest/globals'; +import Stack from '../stack'; + +describe('Stack', () => { + let stack: Stack; + + beforeEach(() => { + stack = new Stack(); + }); + + test('push should add an item to the stack', () => { + stack.push(1); + stack.push(2); + stack.push(3); + + expect(stack.size).toBe(3); + }); + + test('pop should remove and return the top item from the stack', () => { + stack.push(1); + stack.push(2); + stack.push(3); + + const poppedItem = stack.pop(); + + expect(poppedItem).toBe(3); + expect(stack.size).toBe(2); + }); + + test('peek should return the top item from the stack without removing it', () => { + stack.push(1); + stack.push(2); + stack.push(3); + + const topItem = stack.peek(); + + expect(topItem).toBe(3); + expect(stack.size).toBe(3); + }); + + test('isEmpty should return true if the stack is empty', () => { + expect(stack.isEmpty()).toBe(true); + + stack.push(1); + + expect(stack.isEmpty()).toBe(false); + }); + + test('size should return the number of items in the stack', () => { + expect(stack.size).toBe(0); + + stack.push(1); + stack.push(2); + stack.push(3); + + expect(stack.size).toBe(3); + }); + + test('clear should remove all items from the stack', () => { + stack.push(1); + stack.push(2); + stack.push(3); + + stack.clear(); + + expect(stack.size).toBe(0); + expect(stack.isEmpty()).toBe(true); + }); + + test('toString should return a string representation of the stack', () => { + stack.push(1); + stack.push(2); + stack.push(3); + + expect(stack.toString()).toBe('1, 2, 3'); + }); + + test('toString should return an empty string if the stack is empty', () => { + expect(stack.toString()).toBe('Empty Stack'); + }); + + test('toString should return a string representation of the stack with custom object', () => { + const stack = new Stack<{key: string, value: number}>(); + + stack.push({key: 'a', value: 1}); + stack.push({key: 'b', value: 2}); + stack.push({key: 'c', value: 3}); + + expect(stack.toString()).toBe('{"key":"a","value":1}, {"key":"b","value":2}, {"key":"c","value":3}'); + }); + +}); \ No newline at end of file diff --git a/src/04-stack/decimal-to-base.js b/src/04-stack/decimal-to-base.js new file mode 100644 index 00000000..d3644866 --- /dev/null +++ b/src/04-stack/decimal-to-base.js @@ -0,0 +1,83 @@ +// src/04-stack/decimal-to-base.js + +const Stack = require('./stack'); + +/** + * Converts a decimal number to a given base + * @param {number} decimalNumber - decimal number to be converted + * @param {number} base - base to convert the decimal number to + * @returns {string} base representation of the decimal number + */ +function decimalToBase(decimalNumber, base) { + + if (base < 2 || base > 36) { + throw new Error('Base must be between 2 and 36'); + } + + if (decimalNumber === 0) { return '0'; } + + if (decimalNumber < 0) { + throw new Error('Negative numbers are not supported'); + } + + const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // Digits for base 36 + const remainderStack = new Stack(); + let baseString = ''; + + while (decimalNumber > 0) { + const remainder = Math.floor(decimalNumber % base); + remainderStack.push(remainder); + decimalNumber = Math.floor(decimalNumber / base); + } + + while (!remainderStack.isEmpty()) { + baseString += digits[remainderStack.pop()]; // Use digit mapping + } + + return baseString; +} + +/** + * Converts a decimal number to a given base + * @param {number} decimalNumber - decimal number to be converted (between 2 and 36 or 64) + * @param {number} base - base to convert the decimal number to + * @returns {string} base representation of the decimal number + */ +function decimalToBase64(decimalNumber, base) { + if (base < 2 || (base > 36 && base !== 64)) { + throw new Error('Base must be between 2 and 36 or 64'); + } + + const digits = base === 64 ? + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' : + '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + const remainderStack = new Stack(); + let baseString = ''; + + while (decimalNumber > 0) { + const remainder = Math.floor(decimalNumber % base); + remainderStack.push(remainder); + decimalNumber = Math.floor(decimalNumber / base); + } + + while (!remainderStack.isEmpty()) { + baseString += digits[remainderStack.pop()]; + } + + // Handle padding for Base64 (if necessary) + /* Base64 encodes data in groups of 3 bytes (24 bits). + Each group is represented by four Base64 characters (6 bits per character). + If the input data length isn't divisible by 3, padding characters (=) are added to the end of the output + to ensure that the total length is a multiple of 4. + This is important for proper decoding of the Base64 string back to its original data. */ + if (base === 64) { + while (baseString.length % 4 !== 0) { + baseString += '='; + } + } + + return baseString; +} + +module.exports = { decimalToBase, decimalToBase64 }; \ No newline at end of file diff --git a/src/04-stack/decimal-to-base.ts b/src/04-stack/decimal-to-base.ts new file mode 100644 index 00000000..1b5e8540 --- /dev/null +++ b/src/04-stack/decimal-to-base.ts @@ -0,0 +1,77 @@ +// src/04-stack/decimal-to-base.js + +import Stack from './stack'; + +/** + * Converts a decimal number to a given base + * @param {number} decimalNumber - decimal number to be converted + * @param {number} base - base to convert the decimal number to + * @returns {string} base representation of the decimal number + */ +function decimalToBase(decimalNumber: number, base : number) { + + if (base < 2 || base > 36) { + throw new Error('Base must be between 2 and 36'); + } + + const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // Digits for base 36 + const remainderStack = new Stack(); + let baseString = ''; + + while (decimalNumber > 0) { + const remainder = Math.floor(decimalNumber % base); + remainderStack.push(remainder); + decimalNumber = Math.floor(decimalNumber / base); + } + + while (!remainderStack.isEmpty()) { + baseString += digits[remainderStack.pop()]; // Use digit mapping + } + + return baseString; +} + +/** + * Converts a decimal number to a given base + * @param {number} decimalNumber - decimal number to be converted (between 2 and 36 or 64) + * @param {number} base - base to convert the decimal number to + * @returns {string} base representation of the decimal number + */ +function decimalToBase64(decimalNumber: number, base: number) { + if (base < 2 || (base > 36 && base !== 64)) { + throw new Error('Base must be between 2 and 36 or 64'); + } + + const digits = base === 64 ? + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' : + '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + const remainderStack = new Stack(); + let baseString = ''; + + while (decimalNumber > 0) { + const remainder = Math.floor(decimalNumber % base); + remainderStack.push(remainder); + decimalNumber = Math.floor(decimalNumber / base); + } + + while (!remainderStack.isEmpty()) { + baseString += digits[remainderStack.pop()]; + } + + // Handle padding for Base64 (if necessary) + /* Base64 encodes data in groups of 3 bytes (24 bits). + Each group is represented by four Base64 characters (6 bits per character). + If the input data length isn't divisible by 3, padding characters (=) are added to the end of the output + to ensure that the total length is a multiple of 4. + This is important for proper decoding of the Base64 string back to its original data. */ + if (base === 64) { + while (baseString.length % 4 !== 0) { + baseString += '='; + } + } + + return baseString; +} + +export { decimalToBase, decimalToBase64 }; \ No newline at end of file diff --git a/src/04-stack/decimal-to-binary.js b/src/04-stack/decimal-to-binary.js new file mode 100644 index 00000000..37f62656 --- /dev/null +++ b/src/04-stack/decimal-to-binary.js @@ -0,0 +1,31 @@ +// src/04-stack/decimal-to-binary.js + +const Stack = require('./stack'); + +/** + * Converts a decimal number to binary + * @param {number} decimalNumber - decimal number to be converted + * @returns {string} binary representation of the decimal number + */ +function decimalToBinary(decimalNumber) { + const remainderStack = new Stack(); + let binaryString = ''; + + if (decimalNumber === 0) { + return '0'; + } + + while (decimalNumber > 0) { + const remainder = Math.floor(decimalNumber % 2); + remainderStack.push(remainder); + decimalNumber = Math.floor(decimalNumber / 2); + } + + while (!remainderStack.isEmpty()) { + binaryString += remainderStack.pop().toString(); + } + + return binaryString; +} + +module.exports = decimalToBinary; \ No newline at end of file diff --git a/src/04-stack/decimal-to-binary.ts b/src/04-stack/decimal-to-binary.ts new file mode 100644 index 00000000..96804489 --- /dev/null +++ b/src/04-stack/decimal-to-binary.ts @@ -0,0 +1,31 @@ +// src/04-stack/decimal-to-binary.js + +import Stack from './stack'; + +/** + * Converts a decimal number to binary + * @param {number} decimalNumber - decimal number to be converted + * @returns {string} binary representation of the decimal number + */ +function decimalToBinary(decimalNumber: number) { + const remainderStack = new Stack(); + let binaryString = ''; + + if (decimalNumber === 0) { + return '0'; + } + + while (decimalNumber > 0) { // {1} + const remainder = Math.floor(decimalNumber % 2); // {2} + remainderStack.push(remainder); // {3} + decimalNumber = Math.floor(decimalNumber / 2); // {4} + } + + while (!remainderStack.isEmpty()) { // {5} + binaryString += remainderStack.pop().toString(); + } + + return binaryString; +} + +export default decimalToBinary; \ No newline at end of file diff --git a/src/04-stack/leetcode/min-stack.ts b/src/04-stack/leetcode/min-stack.ts new file mode 100644 index 00000000..1b1d9c2f --- /dev/null +++ b/src/04-stack/leetcode/min-stack.ts @@ -0,0 +1,107 @@ +// Path: src/04-stack/leetcode/min-stack.ts +// https://leetcode.com/problems/min-stack/description/ + +class MinStack { + stack: number[]; + minStack: number[]; + + constructor() { + this.stack = []; + this.minStack = []; + } + + push(x: number) { + this.stack.push(x); + if (this.minStack.length === 0 || x <= this.minStack[this.minStack.length - 1]) { + this.minStack.push(x); + } + } + + pop() { + const x = this.stack.pop(); + if (x === this.minStack[this.minStack.length - 1]) { + this.minStack.pop(); + } + } + + top() { + return this.stack[this.stack.length - 1]; + } + + getMin() { + return this.minStack[this.minStack.length - 1]; + } +} + +// test +const minStack = new MinStack(); +minStack.push(-2); +minStack.push(0); +minStack.push(-3); +console.log(minStack.getMin()); // -3 +minStack.pop(); +console.log(minStack.top()); // 0 +console.log(minStack.getMin()); // -2 + +// time complexity: O(1) +// space complexity: O(n) + +// optimized solution +class MinStack2 { + stack: number[] = []; + min: number = +Infinity; + + push(val: number): void { + this.min = Math.min(val, this.min); + this.stack.push(val); + } + + pop(): void { + const val = this.stack.pop(); + if (this.min === val) this.min = Math.min(...this.stack); + } + + top(): number { + return this.stack[this.stack.length - 1]; + } + + getMin(): number { + return this.min; + } +} + +class MinStack3 { + private stack: number[]; + private minStack: number[]; + + constructor() { + this.stack = []; + this.minStack = []; + } + + push(val: number): void { + this.stack.push(val); + + if (this.minStack.length === 0) this.minStack.push(val); + else { + const currentMin = this.minStack[this.minStack.length - 1]; + + this.minStack.push(val < currentMin ? val : currentMin); + } + } + + pop(): void { + this.stack.pop(); + this.minStack.pop(); + } + + top(): number { + return this.stack[this.stack.length - 1]; + } + + getMin(): number { + return this.minStack[this.minStack.length - 1]; + } +} + +// to see the output of this file use the command: node src/04-stack/leetcode/min-stack.ts \ No newline at end of file diff --git a/src/04-stack/leetcode/simplify-path.ts b/src/04-stack/leetcode/simplify-path.ts new file mode 100644 index 00000000..b7228b89 --- /dev/null +++ b/src/04-stack/leetcode/simplify-path.ts @@ -0,0 +1,43 @@ +// Path: src/04-stack/leetcode/simplify-path.ts +// https://leetcode.com/problems/simplify-path/description/ + +/** + * @param {string} path + * @return {string} + */ +const simplifyPath = function(path) { + const stack = []; + const paths = path.split('/'); + + for (let i = 0; i < paths.length; i++) { + if (paths[i] === '' || paths[i] === '.') { + continue; + } else if (paths[i] === '..') { + stack.pop(); + } else { + stack.push(paths[i]); + } + } + return '/' + stack.join('/'); +} + +// test +console.log(simplifyPath('/home/')); // '/home' +console.log(simplifyPath('/../')); // '/' +console.log(simplifyPath('/home//foo/')); // '/home/foo' +console.log(simplifyPath('/a/./b/../../c/')); // '/c' +console.log(simplifyPath('/a/../../b/../c//.//')); // '/c' +console.log(simplifyPath('/a//b////c/d//././/..')); // '/a/b/c' + +// additional tests +console.log(simplifyPath('/home/user/Documents/../Pictures')); // '/home/user/Pictures' +console.log(simplifyPath('/../home/user/Documents')); // '/home/user/Documents' +console.log(simplifyPath('/home/user/../../usr/local/bin')); // '/usr/local/bin' +console.log(simplifyPath('/home/user/./Downloads/../Pictures/././')); // '/home/user/Pictures' +console.log(simplifyPath('/home/user/Documents/../../usr/local/bin')); // '/usr/local/bin' +console.log(simplifyPath('/home/user/Documents/../../../usr/local/bin')); // '/usr/local/bin' + +// time complexity: O(n) +// space complexity: O(n) + +// to see the output of this file use the command: node src/04-stack/leetcode/simplify-path.ts \ No newline at end of file diff --git a/src/04-stack/leetcode/valid-parentheses.ts b/src/04-stack/leetcode/valid-parentheses.ts new file mode 100644 index 00000000..8c22c6a3 --- /dev/null +++ b/src/04-stack/leetcode/valid-parentheses.ts @@ -0,0 +1,91 @@ +// Path: src/04-stack/leetcode/valid-parentheses.ts +// https://leetcode.com/problems/valid-parentheses/description/ + +/** + * @param {string} s + * @return {boolean} + */ +const isValid = function(s) { + const stack = []; + const open = ['(', '[', '{']; + const close = [')', ']', '}']; + + for (let i = 0; i < s.length; i++) { + if (open.includes(s[i])) { + stack.push(s[i]); + } else if (close.includes(s[i])) { + const last = stack.pop(); + if (open.indexOf(last) !== close.indexOf(s[i])) { + return false; + } + } + } + return stack.length === 0; +} + +// test +console.log(isValid('()')); // true +console.log(isValid('()[]{}')); // true +console.log(isValid('(]')); // false +console.log(isValid('(')); // false +console.log(isValid(')')); // false + +// time complexity: O(n) +// space complexity: O(n) + +// rewrite the code using a map +const isValid2 = function(s) { + const stack = []; + const map = { + '(': ')', + '[': ']', + '{': '}' + }; + + for (let i = 0; i < s.length; i++) { + if (map[s[i]]) { + stack.push(s[i]); + } else if (s[i] !== map[stack.pop()]) { + return false; + } + } + return stack.length === 0; +} + +// test +console.log(isValid2('()')); // true +console.log(isValid2('()[]{}')); // true +console.log(isValid2('(]')); // false +console.log(isValid2('(')); // false + +// time complexity: O(n) +// space complexity: O(n) + +// optimize the code +const isValid3 = function(s) { + + // optimization 1: if the length of the string is odd, return false + if (s.length % 2 === 1) return false; + + // optimization 2: if the first character is a closing bracket, return false + if (s[0] === ')' || s[0] === ']' || s[0] === '}') return false; + + // optimization 3: if the last character is an opening bracket, return false + if (s[s.length - 1] === '(' || s[s.length - 1] === '[' || s[s.length - 1] === '{') return false; + + const stack = []; + for (let i = 0; i < s.length; i++) { + if (s[i] === '(' || s[i] === '[' || s[i] === '{') stack.push(s[i]) + else { + const top = stack.pop() + if (top === '(' && s[i] !== ')') return false + if (top === '[' && s[i] !== ']') return false + if (top === '{' && s[i] !== '}') return false + if (top === undefined) return false + } + } + + return stack.length === 0 +} + +// to see the output of this file use the command: node src/04-stack/leetcode/valid-parentheses.ts \ No newline at end of file diff --git a/src/04-stack/stack.js b/src/04-stack/stack.js new file mode 100644 index 00000000..22677113 --- /dev/null +++ b/src/04-stack/stack.js @@ -0,0 +1,75 @@ +// src/04-stack/stack.js + +// @ts-ignore +class Stack { + + // private property + #items = []; // {1} + + /** + * Adds a new element to the top of the stack + * @param {*} item - new element to be added to the stack + */ + push(item) { + this.#items.push(item); + } + + /** + * Removes the top element from the stack and returns it. If the stack is empty, undefined is returned and the stack is not modified. + */ + pop() { + return this.#items.pop(); + } + + /** + * Returns the top element of the stack without removing it. The stack is not modified (it does not remove the element; it only returns the element for information purposes). + */ + peek() { + return this.#items[this.#items.length - 1]; + } + + /** + * Returns true if the stack does not contain any elements and false if the size of the stack is bigger than 0. + */ + isEmpty() { + return this.#items.length === 0; + } + + /** + * Returns the number of elements in the stack. It is similar to the length property of an array. + */ + get size() { + return this.#items.length; + } + + /** + * Removes all the elements from the stack + */ + clear() { + /* while (!this.isEmpty()) { + this.pop(); + } */ + this.#items = []; + } + + /** + * Returns a string representation of the stack, bottom to top, without modifying the stack + */ + toString() { + if (this.isEmpty()) { + return 'Empty Stack'; + } else { + return this.#items.map(item => { // {1} + if (typeof item === 'object' && item !== null) { // {2} + return JSON.stringify(item); // Handle objects + } else { + return item.toString(); // Handle other types {3} + } + }).join(', '); // {4} + } + } +} + +// export node module so it can be used in different files +// CommonJS export +module.exports = Stack; \ No newline at end of file diff --git a/src/04-stack/stack.ts b/src/04-stack/stack.ts new file mode 100644 index 00000000..5857e3db --- /dev/null +++ b/src/04-stack/stack.ts @@ -0,0 +1,45 @@ +// src/04-stack/stack.ts + +class Stack { + private items: T[] = []; + + push(item: T): void { + this.items.push(item); + } + + pop(): T | undefined { + return this.items.pop(); + } + + peek(): T | undefined { + return this.items[this.items.length - 1]; + } + + isEmpty(): boolean { + return this.items.length === 0; + } + + get size(): number { + return this.items.length; + } + + clear(): void { + this.items = []; + } + + toString(): string { + if (this.isEmpty()) { + return 'Empty Stack'; + } else { + return this.items.map(item => { + if (typeof item === 'object' && item !== null) { + return JSON.stringify(item); + } else { + return item.toString(); + } + }).join(', '); + } + } +} + +export default Stack; \ No newline at end of file diff --git a/src/04-stack/tower-of-hanoi.js b/src/04-stack/tower-of-hanoi.js new file mode 100644 index 00000000..eb9ac046 --- /dev/null +++ b/src/04-stack/tower-of-hanoi.js @@ -0,0 +1,32 @@ +// src/04-stack/tower-of-hanoi.js + +const Stack = require('./stack'); + +/** + * Solves the Tower of Hanoi puzzle + * @param {number} n - number of disks + * @param {Stack} source - source stack + * @param {Stack} auxiliary - auxiliary stack + * @param {Stack} destination - destination stack + */ +function towerOfHanoi(n, source, auxiliary, destination) { + if (n > 0) { + towerOfHanoi(n - 1, source, destination, auxiliary); + destination.push(source.pop()); + towerOfHanoi(n - 1, auxiliary, source, destination); + } +} + + +// Usage +// const source = new Stack(); +// const auxiliary = new Stack(); +// const destination = new Stack(); +// source.push(3); +// source.push(2); +// source.push(1); +// towerOfHanoi(3, source, auxiliary, destination); +// console.log(destination); // [1, 2, 3] + + +module.exports = towerOfHanoi; diff --git a/src/05-queue-deque/01-using-queue-class.js b/src/05-queue-deque/01-using-queue-class.js new file mode 100644 index 00000000..a921a27b --- /dev/null +++ b/src/05-queue-deque/01-using-queue-class.js @@ -0,0 +1,26 @@ +// src/05-queue-deque/01-using-queue-class.js + +const Queue = require('./queue'); + +const queue = new Queue(); + +console.log(queue.isEmpty()); // true + +queue.enqueue({ document: 'Chapter05.docx', pages: 20 }); +queue.enqueue({ document: 'JavaScript.pdf', pages: 60 }); +queue.enqueue({ document: 'TypeScript.pdf', pages: 80 }); + +console.log(queue.toString()); + +console.log(queue.size); // 3 + +console.log(queue.isEmpty()); // false + +console.log(queue.front()); // { document: 'Chapter05.docx', pages: 20 } + +// print all documents +while (!queue.isEmpty()) { + console.log(queue.dequeue()); +} + +// to see the output of this file use the command: node src/05-queue-deque/01-using-queue-class.js \ No newline at end of file diff --git a/src/05-queue-deque/02-using-queue-two-pointers.js b/src/05-queue-deque/02-using-queue-two-pointers.js new file mode 100644 index 00000000..8395a12f --- /dev/null +++ b/src/05-queue-deque/02-using-queue-two-pointers.js @@ -0,0 +1,33 @@ +// src/05-queue-deque/02-using-queue-two-pointers.js + +const Queue = require('./queue-two-pointers'); + +const queue = new Queue(); + +console.log(queue.isEmpty()); // true + +queue.enqueue({ document: 'Chapter05.docx', pages: 20 }); +queue.enqueue({ document: 'JavaScript.pdf', pages: 60 }); +queue.enqueue({ document: 'TypeScript.pdf', pages: 80 }); + +console.log(queue.toString()); + +console.log(queue.size); // 3 + +console.log(queue.isEmpty()); // false + +console.log(queue.front()); // { document: 'Chapter05.docx', pages: 20 } + +// print all documents +while (!queue.isEmpty()) { + console.log(queue.dequeue()); +} + +// add more documents +queue.enqueue({ document: 'DataStructures.pdf', pages: 400 }); + +console.log(queue.toString()); +console.log(queue.size); // 1 +console.log(queue.front()); // { document: 'DataStructures.pdf', pages: 400 } + +// to see the output of this file use the command: node src/05-queue-deque/02-using-queue-two-pointers.js \ No newline at end of file diff --git a/src/05-queue-deque/03-using-deque-class.js b/src/05-queue-deque/03-using-deque-class.js new file mode 100644 index 00000000..e78c4412 --- /dev/null +++ b/src/05-queue-deque/03-using-deque-class.js @@ -0,0 +1,44 @@ +// src/05-queue-deque/03-using-deque-class.js + +const Deque = require('./deque'); + +class BrowserHistory { + #history = new Deque(); // Stores visited pages + #currentPage = null; + + visit(url) { + this.#history.addFront(url); + this.#currentPage = url; + } + + goBack() { + if (this.#history.size() > 1) { // Check if there's a previous page + this.#history.removeFront(); // Remove the current page + this.#currentPage = this.#history.peekFront(); // Set current to the previous + } + } + + goForward() { + if (this.#currentPage !== this.#history.peekBack()) { // Check if there's a next page + this.#history.addFront(this.#currentPage); // Add the current page back + this.#currentPage = this.#history.removeFront(); // Set current to the next page + } + } + + get currentPage() { + return this.#currentPage; + } +} + +const browser = new BrowserHistory(); +browser.visit('loiane.com'); +browser.visit('https://loiane.com/about'); // click on About menu + +browser.goBack(); +console.log(browser.currentPage); // loiane.com + +browser.goForward(); +console.log(browser.currentPage); // https://loiane.com/about + + +// to see the output of this file use the command: node src/05-queue-deque/03-using-deque-class.js \ No newline at end of file diff --git a/src/05-queue-deque/__test__/deque.test.ts b/src/05-queue-deque/__test__/deque.test.ts new file mode 100644 index 00000000..4a79feae --- /dev/null +++ b/src/05-queue-deque/__test__/deque.test.ts @@ -0,0 +1,95 @@ +import {describe, expect, test, beforeEach} from '@jest/globals'; +import Deque from '../deque'; + +describe('Deque', () => { + let deque: Deque; + + beforeEach(() => { + deque = new Deque(); + }); + + test('should add an element to the front of the deque', () => { + deque.addFront(1); + deque.addFront(2); + expect(deque.toString()).toBe('2, 1'); + }); + + test('should add an element to the rear of the deque', () => { + deque.addRear(1); + deque.addRear(2); + expect(deque.toString()).toBe('1, 2'); + }); + + test('should remove an element from the front of the deque', () => { + deque.addFront(1); + deque.addFront(2); + deque.removeFront(); + expect(deque.toString()).toBe('1'); + }); + + test('should return undefined when removing from an empty deque', () => { + expect(deque.removeFront()).toBeUndefined(); + }); + + test('should remove an element from the rear of the deque', () => { + deque.addRear(1); + deque.addRear(2); + deque.removeRear(); + expect(deque.toString()).toBe('1'); + }); + + test('should return undefined when removing from an empty deque', () => { + expect(deque.removeRear()).toBeUndefined(); + }); + + test('should return the front element of the deque', () => { + deque.addFront(1); + deque.addFront(2); + expect(deque.peekFront()).toBe(2); + }); + + test('should return undefined when peeking from an empty deque', () => { + expect(deque.peekFront()).toBeUndefined(); + }); + + test('should return the rear element of the deque', () => { + deque.addRear(1); + deque.addRear(2); + expect(deque.peekRear()).toBe(2); + }); + + test('should return undefined when peeking from an empty deque', () => { + expect(deque.peekRear()).toBeUndefined(); + }); + + test('should return true if the deque is empty', () => { + expect(deque.isEmpty()).toBe(true); + }); + + test('should return the size of the deque', () => { + deque.addFront(1); + deque.addFront(2); + expect(deque.size).toBe(2); + }); + + test('should clear the deque', () => { + deque.addFront(1); + deque.addFront(2); + deque.clear(); + expect(deque.isEmpty()).toBe(true); + }); + + test('should convert the deque to a string', () => { + expect(deque.toString()).toBe('Empty Deque'); + }); + + test('should convert the deque to a string with objects', () => { + const deque = new Deque<{key: string, value: number}>(); + + deque.addFront({key: 'a', value: 1}); + deque.addFront({key: 'b', value: 2}); + deque.addFront({key: 'c', value: 3}); + + expect(deque.toString()).toBe('{"key":"c","value":3}, {"key":"b","value":2}, {"key":"a","value":1}'); + }); +}); diff --git a/src/05-queue-deque/__test__/queue.test.ts b/src/05-queue-deque/__test__/queue.test.ts new file mode 100644 index 00000000..e38b597b --- /dev/null +++ b/src/05-queue-deque/__test__/queue.test.ts @@ -0,0 +1,83 @@ +import {describe, expect, test, beforeEach} from '@jest/globals'; +import Queue from '../queue'; + +describe('Queue', () => { + let queue; + + beforeEach(() => { + queue = new Queue(); + }); + + test('should enqueue and dequeue elements correctly', () => { + queue.enqueue(1); + queue.enqueue(2); + queue.enqueue(3); + + expect(queue.dequeue()).toBe(1); + expect(queue.dequeue()).toBe(2); + expect(queue.dequeue()).toBe(3); + expect(queue.isEmpty()).toBe(true); + }); + + test('should return undefined when dequeueing from an empty queue', () => { + expect(queue.dequeue()).toBeUndefined(); + }); + + test('should return the correct size after enqueueing and dequeueing elements', () => { + queue.enqueue(1); + queue.enqueue(2); + queue.enqueue(3); + + queue.dequeue(); + queue.dequeue(); + + expect(queue.size).toBe(1); + }); + + test('should return the correct front element after enqueueing and dequeueing elements', () => { + queue.enqueue(1); + queue.enqueue(2); + queue.enqueue(3); + + queue.dequeue(); + + expect(queue.front()).toBe(2); + }); + + test('should return undefined when calling front on an empty queue', () => { + expect(queue.front()).toBeUndefined(); + }); + + test('should clear the queue and return the correct size', () => { + queue.enqueue(1); + queue.enqueue(2); + queue.enqueue(3); + + queue.clear(); + + expect(queue.isEmpty()).toBe(true); + expect(queue.size).toBe(0); + }); + + test('should convert the queue to a string', () => { + queue.enqueue(1); + queue.enqueue(2); + queue.enqueue(3); + + expect(queue.toString()).toBe('1, 2, 3'); + }); + + test('should convert the queue to a string with empty queue', () => { + expect(queue.toString()).toBe('Empty Queue'); + }); + + test('should convert the queue to a string with object', () => { + queue.enqueue({name: 'John', age: 30}); + queue.enqueue({name: 'Jane', age: 25}); + queue.enqueue({name: 'Doe', age: 40}); + + expect(queue.toString()).toBe( + '{"name":"John","age":30}, {"name":"Jane","age":25}, {"name":"Doe","age":40}', + ); + }); +}); diff --git a/src/05-queue-deque/deque.js b/src/05-queue-deque/deque.js new file mode 100644 index 00000000..1d2eaebd --- /dev/null +++ b/src/05-queue-deque/deque.js @@ -0,0 +1,57 @@ +// src/05-queue-deque/deque.js + +class Deque { + #items = []; + + addFront(item) { + this.#items.unshift(item); + } + + addRear(item) { + this.#items.push(item); + } + + removeFront() { + return this.#items.shift(); + } + + removeRear() { + return this.#items.pop(); + } + + peekFront() { + return this.#items[0]; + } + + peekRear() { + return this.#items[this.#items.length - 1]; + } + + isEmpty() { + return this.#items.length === 0; + } + + get size() { + return this.#items.length; + } + + clear() { + this.#items = []; + } + + toString() { + if (this.isEmpty()) { + return 'Empty Deque'; + } else { + return this.#items.map(item => { // {1} + if (typeof item === 'object' && item !== null) { // {2} + return JSON.stringify(item); // Handle objects + } else { + return item.toString(); // Handle other types {3} + } + }).join(', '); // {4} + } + } +} + +module.exports = Deque; \ No newline at end of file diff --git a/src/05-queue-deque/deque.ts b/src/05-queue-deque/deque.ts new file mode 100644 index 00000000..49a4e3ba --- /dev/null +++ b/src/05-queue-deque/deque.ts @@ -0,0 +1,69 @@ +// src/05-queue-deque/deque.ts + +class Deque { + private items: T[] = []; + + addFront(item: T): void { + this.items.unshift(item); + } + + addRear(item: T): void { + this.items.push(item); + } + + removeFront(): T | undefined { + if (this.isEmpty()) { + return undefined; + } + return this.items.shift(); + } + + removeRear(): T | undefined { + if (this.isEmpty()) { + return undefined; + } + return this.items.pop(); + } + + peekFront(): T | undefined { + if (this.isEmpty()) { + return undefined; + } + return this.items[0]; + } + + peekRear(): T | undefined { + if (this.isEmpty()) { + return undefined; + } + return this.items[this.items.length - 1]; + } + + isEmpty(): boolean { + return this.items.length === 0; + } + + get size(): number { + return this.items.length; + } + + clear(): void { + this.items = []; + } + + toString(): string { + if (this.isEmpty()) { + return 'Empty Deque'; + } else { + return this.items.map(item => { // {1} + if (typeof item === 'object' && item !== null) { // {2} + return JSON.stringify(item); // Handle objects + } else { + return item.toString(); // Handle other types {3} + } + }).join(', '); // {4} + } + } +} + +export default Deque; \ No newline at end of file diff --git a/src/05-queue-deque/hot-potato.js b/src/05-queue-deque/hot-potato.js new file mode 100644 index 00000000..c20ecfdc --- /dev/null +++ b/src/05-queue-deque/hot-potato.js @@ -0,0 +1,72 @@ +class CircularQueue { + #items = []; + #capacity = 0; + #front = 0; + #rear = -1; + #size = 0; + + constructor(capacity) { + this.#items = new Array(capacity); + this.#capacity = capacity; + } + + enqueue(item) { + if (this.isFull()) { + throw new Error("Queue is full"); + } + this.#rear = (this.#rear + 1) % this.#capacity; + this.#items[this.#rear] = item; + this.#size++; + } + + dequeue() { + if (this.isEmpty()) { throw new Error("Queue is empty"); } + + const item = this.#items[this.#front]; + this.#size--; + + if (this.isEmpty()) { + this.#front = 0; + this.#rear = -1; + } else { + this.#front = (this.#front + 1) % this.#capacity; + } + + return item; + } + + isEmpty() { return this.#size === 0; } + isFull() { return this.#size === this.#capacity; } + get size() { return this.#size; } +} + +// Hot Potato Game Function +function hotPotato(players, numPasses) { + const queue = new CircularQueue(players.length); + for (const player of players) { + queue.enqueue(player); + } + + while (queue.size > 1) { + for (let i = 0; i < numPasses; i++) { + queue.enqueue(queue.dequeue()); + } + console.log(`${queue.dequeue()} is eliminated!`); + } + + return queue.dequeue(); // The winner +} + +// Example Usage +const players = ["Violet", "Feyre", "Poppy", "Oraya", "Aelin"]; +const winner = hotPotato(players, 7); +console.log(`The winner is: ${winner}!`); + +// Output +// Poppy is eliminated! +// Feyre is eliminated! +// Aelin is eliminated! +// Oraya is eliminated! +// The winner is: Violet! + +// to see the output of this file use the command: node src/05-queue-deque/hot-potato.js \ No newline at end of file diff --git a/src/05-queue-deque/leetcode/ex.md b/src/05-queue-deque/leetcode/ex.md new file mode 100644 index 00000000..f6a1b8cb --- /dev/null +++ b/src/05-queue-deque/leetcode/ex.md @@ -0,0 +1,36 @@ +Explanation + +Count Preferences: + +Create an array counts to store how many students want each sandwich type. +Iterate through the students array. For each student, increment the corresponding count in the counts array. +Process Sandwiches: + +Iterate through the sandwiches array. For each sandwich: +If the count for that sandwich type is zero, it means no one left wants it. Break the loop. +Otherwise, decrement the count for that sandwich type, as one student took it. +Return Result: + +After processing all sandwiches (or breaking early), the remaining counts in the counts array represent the students who didn't get their preferred sandwich. Add these counts and return the result. +Why This is More Efficient + +Avoiding Array Manipulation: The optimized version avoids repeated shifting and pushing of elements in the students array. This reduces the computational overhead, especially with large inputs. + +Early Termination: By checking if the count of a sandwich type reaches zero, the loop can exit early, potentially saving many iterations if a lot of sandwiches remain that no one wants. + +Simpler Logic: The logic is more straightforward, making it easier to understand and maintain. + +Example + +Let's use the same example as before: + +students = [1, 1, 0, 0] +sandwiches = [0, 1, 0, 1] +counts becomes [2, 2] (two students for each type). +The first sandwich (0) is taken, counts is now [1, 2]. +The second sandwich (1) is taken, counts is now [1, 1]. +This continues until all sandwiches are gone and counts becomes [0, 0]. +The function returns 0 + 0 = 0. +Key Improvement + +The main optimization comes from avoiding the costly includes check and array manipulations inside the loop. Instead, we directly track the number of students who still want each sandwich type. This allows us to efficiently determine when no one wants a particular sandwich anymore, leading to early termination. \ No newline at end of file diff --git a/src/05-queue-deque/leetcode/number-of-students-unable-to-eat-lunch.ts b/src/05-queue-deque/leetcode/number-of-students-unable-to-eat-lunch.ts new file mode 100644 index 00000000..a09c1109 --- /dev/null +++ b/src/05-queue-deque/leetcode/number-of-students-unable-to-eat-lunch.ts @@ -0,0 +1,74 @@ +// Path: src/05-queue-deque/leetcode/number-of-students-unable-to-eat-lunch.ts +// https://leetcode.com/problems/number-of-students-unable-to-eat-lunch/ + +// 1700. Number of Students Unable to Eat Lunch +// Easy + +// hint 1: Simulate the process of giving sandwiches to students. +// hint 2: Calculate those who will eat instead of those who will not. + +// Use two queues to simulate the process of giving sandwiches to students. + +function countStudents(students: number[], sandwiches: number[]): number { + + let count = 0; + while(students.length > 0 && count < students.length) { + if(students[0] === sandwiches[0]) { + students.shift(); + sandwiches.shift(); + count = 0; + } else { + students.push(students.shift()); + count++; + } + } + + return students.length; +}; + +// Time complexity: O(n) +// Space complexity: O(n) + +// Input: students = [1,1,0,0], sandwiches = [0,1,0,1] +// Output: 0 +console.log(countStudents([1,1,0,0], [0,1,0,1])); // 0 +console.log(countStudents([1,1,1,0,0,1], [1,0,0,0,1,1])); // 3 + +// optimized solution +function countStudents2(students: number[], sandwiches: number[]): number { + while (students.length > 0) { + if (students[0] === sandwiches[0]) { + students.shift(); + sandwiches.shift(); + } else { + // check if there is a student who prefers the sandwich on the top of the stack to continue the loop + if (students.includes(sandwiches[0])) { + let num = students.shift(); + students.push(num); + } else { + break; // if there is no student who prefers the sandwich on the top of the stack, break the loop + } + } + } + return students.length; +}; + +// Time complexity: O(nˆ2) +// Space complexity: O(1) + +function countStudentsOptimized(students, sandwiches) { + const counts = [0, 0]; // Track counts of each preference (0 or 1) + for (const student of students) { + counts[student]++; + } + + for (const sandwich of sandwiches) { + if (counts[sandwich] === 0) { + break; // No one wants this sandwich type anymore + } + counts[sandwich]--; + } + + return counts[0] + counts[1]; // Remaining students who couldn't eat + } + \ No newline at end of file diff --git a/src/05-queue-deque/leetcode/time-needed-to-buy-tickets.ts b/src/05-queue-deque/leetcode/time-needed-to-buy-tickets.ts new file mode 100644 index 00000000..91a7ae3d --- /dev/null +++ b/src/05-queue-deque/leetcode/time-needed-to-buy-tickets.ts @@ -0,0 +1,30 @@ +// Path: src/05-queue-deque/leetcode/time-needed-to-buy-tickets.ts +// https://leetcode.com/problems/time-needed-to-buy-tickets/ + +// 2034. Time Needed to Buy Tickets +// Medium + +function timeRequiredToBuy(tickets: number[], k: number): number { + + let queue = tickets.map((t, i) => [t, i]); + let time = 0; + while(queue.length > 0) { + let [t, i] = queue.shift(); + if(t - k <= 0) { + time += t; + break; + } else { + time += k; + queue.push([t - k, i]); + } + } + + return time; +}; + +// Time complexity: O(n) +// Space complexity: O(n) + +console.log(timeRequiredToBuy([2,6,3,4,5], 2)); // 14 +console.log(timeRequiredToBuy([2,3,2], 2)); // 6 +console.log(timeRequiredToBuy([5,1,1,1], 0)); // 11 diff --git a/src/05-queue-deque/palindrome-checker.js b/src/05-queue-deque/palindrome-checker.js new file mode 100644 index 00000000..25ebb3da --- /dev/null +++ b/src/05-queue-deque/palindrome-checker.js @@ -0,0 +1,27 @@ +const Deque = require('./deque'); + +function isPalindrome(word) { + + if (word === undefined || word === null || (typeof word === 'string' && word.length === 0)) { + return false; + } + + const deque = new Deque(); + word = word.toLowerCase().replace(/\s/g, ''); + + for (let i = 0; i < word.length; i++) { + deque.addRear(word[i]); + } + + // Check if the word is a palindrome + while (deque.size() > 1) { + if (deque.removeFront() !== deque.removeRear()) { + return false; + } + } + + return true; +} + +// Test the palindrome checker +console.log(isPalindrome("racecar")); // Output: true \ No newline at end of file diff --git a/src/05-queue-deque/queue.js b/src/05-queue-deque/queue.js new file mode 100644 index 00000000..abbf3bd7 --- /dev/null +++ b/src/05-queue-deque/queue.js @@ -0,0 +1,46 @@ +// src/05-queue-deque/queue.js + +class Queue { + + #items = []; + + enqueue(item) { + this.#items.push(item); + } + + dequeue() { + return this.#items.shift(); + } + + front() { + return this.#items[0]; + } + + isEmpty() { + return this.#items.length === 0; + } + + get size() { + return this.#items.length; + } + + clear() { + this.#items = []; + } + + toString() { + if (this.isEmpty()) { + return 'Empty Queue'; + } else { + return this.#items.map(item => { // {1} + if (typeof item === 'object' && item !== null) { // {2} + return JSON.stringify(item); // Handle objects + } else { + return item.toString(); // Handle other types {3} + } + }).join(', '); // {4} + } + } +} + +module.exports = Queue; \ No newline at end of file diff --git a/src/05-queue-deque/queue.ts b/src/05-queue-deque/queue.ts new file mode 100644 index 00000000..4d795e7b --- /dev/null +++ b/src/05-queue-deque/queue.ts @@ -0,0 +1,52 @@ +// src/05-queue-deque/queue.ts + +class Queue { + + private items: T[] = []; + + enqueue(item: T): void { + this.items.push(item); + } + + dequeue(): T | undefined { + if (this.isEmpty()) { + return undefined; + } + return this.items.shift(); + } + + front(): T | undefined { + if (this.isEmpty()) { + return undefined; + } + return this.items[0]; + } + + isEmpty(): boolean { + return this.items.length === 0; + } + + get size(): number { + return this.items.length; + } + + clear(): void { + this.items = []; + } + + toString(): string { + if (this.isEmpty()) { + return 'Empty Queue'; + } else { + return this.items.map(item => { // {1} + if (typeof item === 'object' && item !== null) { // {2} + return JSON.stringify(item); // Handle objects + } else { + return item.toString(); // Handle other types {3} + } + }).join(', '); // {4} + } + } +} + +export default Queue; \ No newline at end of file diff --git a/src/06-linked-list/__test__/doubly-linked-list.test.ts b/src/06-linked-list/__test__/doubly-linked-list.test.ts new file mode 100644 index 00000000..b8a1110e --- /dev/null +++ b/src/06-linked-list/__test__/doubly-linked-list.test.ts @@ -0,0 +1,122 @@ +import {describe, expect, test, beforeEach} from '@jest/globals'; +import DoublyLinkedList from '../doubly-linked-list'; + +describe('DoublyLinkedList', () => { + let doublyLinkedList: DoublyLinkedList; + + beforeEach(() => { + doublyLinkedList = new DoublyLinkedList(); + }); + + test('should create an empty doubly linked list', () => { + expect(doublyLinkedList.toString()).toBe(''); + }); + + test('should append node to doubly linked list', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(2); + doublyLinkedList.append(3); + expect(doublyLinkedList.toString()).toBe('1, 2, 3'); + }); + + test('should prepend node to doubly linked list', () => { + doublyLinkedList.prepend(2); + expect(doublyLinkedList.toString()).toBe('2'); + doublyLinkedList.append(1); + doublyLinkedList.prepend(3); + expect(doublyLinkedList.toString()).toBe('3, 2, 1'); + }); + + test('should insert node at position 0', () => { + doublyLinkedList.append(1); + doublyLinkedList.insert(2, 0); + expect(doublyLinkedList.toString()).toBe('2, 1'); + }); + + test('should insert node at given position', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(3); + doublyLinkedList.insert(2, 1); + expect(doublyLinkedList.toString()).toBe('1, 2, 3'); + }); + + test('should insert node at invalid position', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(3); + expect(doublyLinkedList.insert(3, 2)).toBe(false); + expect(doublyLinkedList.toString()).toBe('1, 3'); + }); + + test('should remove node from doubly linked list', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(2); + doublyLinkedList.append(3); + doublyLinkedList.removeAt(1); + expect(doublyLinkedList.toString()).toBe('1, 3'); + }); + + test('should remove node at position 0', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(2); + doublyLinkedList.removeAt(0); + expect(doublyLinkedList.toString()).toBe('2'); + }); + + test('should remove node at invalid position', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(2); + //expect(doublyLinkedList.removeAt(3)).toThrowError(RangeError('Invalid position')); + expect(doublyLinkedList.toString()).toBe('1, 2'); + }); + + test('should remove element from doubly linked list', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(2); + doublyLinkedList.append(3); + doublyLinkedList.remove(3); + expect(doublyLinkedList.toString()).toBe('1, 2'); + doublyLinkedList.remove(1); + expect(doublyLinkedList.toString()).toBe('2'); + doublyLinkedList.remove(2); + expect(doublyLinkedList.toString()).toBe(''); + }); + + test('should remove element that is not in doubly linked list', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(2); + expect(doublyLinkedList.remove(3)).toBe(null); + expect(doublyLinkedList.toString()).toBe('1, 2'); + }); + + test('should find element in doubly linked list', () => { + doublyLinkedList.append(1); + doublyLinkedList.append(2); + doublyLinkedList.append(3); + expect(doublyLinkedList.indexOf(1)).toBe(0); + expect(doublyLinkedList.indexOf(2)).toBe(1); + expect(doublyLinkedList.indexOf(3)).toBe(2); + expect(doublyLinkedList.indexOf(4)).toBe(-1); + }); + + test('should check if doubly linked list is empty', () => { + expect(doublyLinkedList.isEmpty()).toBe(true); + doublyLinkedList.append(1); + expect(doublyLinkedList.isEmpty()).toBe(false); + }); + + test('should return the size of the doubly linked list', () => { + expect(doublyLinkedList.getSize()).toBe(0); + doublyLinkedList.append(1); + expect(doublyLinkedList.getSize()).toBe(1); + doublyLinkedList.append(2); + expect(doublyLinkedList.getSize()).toBe(2); + }); + + test('should convert doubly linked list to string', () => { + doublyLinkedList.append(1); + expect(doublyLinkedList.toString()).toBe('1'); + doublyLinkedList.append(2); + expect(doublyLinkedList.toString()).toBe('1, 2'); + }); + +}); \ No newline at end of file diff --git a/src/06-linked-list/__test__/linked-list.test.ts b/src/06-linked-list/__test__/linked-list.test.ts new file mode 100644 index 00000000..ab9d879a --- /dev/null +++ b/src/06-linked-list/__test__/linked-list.test.ts @@ -0,0 +1,165 @@ +import {describe, expect, test, beforeEach} from '@jest/globals'; +import LinkedList from '../linked-list'; + +describe('LinkedList', () => { + let linkedList: LinkedList; + + beforeEach(() => { + linkedList = new LinkedList(); + }); + + test('should create an empty linked list', () => { + expect(linkedList.toString()).toBe(''); + }); + + test('should append node to linked list', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.append(3); + expect(linkedList.toString()).toBe('1, 2, 3'); + }); + + test('should prepend node to linked list', () => { + linkedList.prepend(2); + expect(linkedList.toString()).toBe('2'); + linkedList.append(1); + linkedList.prepend(3); + expect(linkedList.toString()).toBe('3, 2, 1'); + }); + + test('should insert node at position 0', () => { + linkedList.append(1); + linkedList.insert(0, 2); + expect(linkedList.toString()).toBe('2, 1'); + }); + + test('should insert node at given position', () => { + linkedList.append(1); + linkedList.append(3); + linkedList.insert(1, 2); + expect(linkedList.toString()).toBe('1, 2, 3'); + }); + + test('should insert node at invalid position', () => { + linkedList.append(1); + linkedList.append(3); + expect(linkedList.insert(3, 2)).toBe(false); + expect(linkedList.toString()).toBe('1, 3'); + }); + + test('should remove node from linked list', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.append(3); + linkedList.removeAt(1); + expect(linkedList.toString()).toBe('1, 3'); + }); + + test('should remove node at position 0', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.removeAt(0); + expect(linkedList.toString()).toBe('2'); + }); + + test('should remove node at invalid position', () => { + linkedList.append(1); + linkedList.append(2); + expect(() => linkedList.removeAt(2)).toThrowError('Invalid position'); + }); + + test('should remove element from linked list', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.append(3); + linkedList.remove(2); + expect(linkedList.toString()).toBe('1, 3'); + }); + + test('should remove element from linked list head', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.remove(1); + expect(linkedList.toString()).toBe('2'); + }); + + test('should remove element from linked list tail', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.remove(2); + expect(linkedList.toString()).toBe('1'); + }); + + test('should return null if element was not found', () => { + linkedList.append(1); + linkedList.append(2); + expect(linkedList.remove(3)).toBeNull(); + }); + + test('should find element index in linked list', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.append(3); + expect(linkedList.indexOf(1)).toBe(0); + expect(linkedList.indexOf(2)).toBe(1); + expect(linkedList.indexOf(3)).toBe(2); + }); + + test('should return -1 when element was not found', () => { + linkedList.append(1); + linkedList.append(2); + expect(linkedList.indexOf(3)).toBe(-1); + }); + + test('should return true if list is empty', () => { + expect(linkedList.isEmpty()).toBe(true); + }); + + test('should return false if list is not empty', () => { + linkedList.append(1); + expect(linkedList.isEmpty()).toBe(false); + }); + + test('should return the size of the linked list', () => { + expect(linkedList.getSize()).toBe(0); + linkedList.append(1); + expect(linkedList.getSize()).toBe(1); + linkedList.append(2); + expect(linkedList.getSize()).toBe(2); + }); + + test('should convert linked list to string', () => { + linkedList.append(1); + expect(linkedList.toString()).toBe('1'); + linkedList.append(2); + expect(linkedList.toString()).toBe('1, 2'); + }); + + test('should convert linked list to string with custom stringifier', () => { + const customList = new LinkedList<{value: number; key: string}>(); + customList.append({value: 1, key: 'key1'}); + expect(customList.toString()).toBe('{"value":1,"key":"key1"}'); + }); + + test('should reverse the linked list', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.append(3); + linkedList.reverse(); + expect(linkedList.toString()).toBe('3, 2, 1'); + }); + + test('should reverse the linked list with one element', () => { + linkedList.append(1); + linkedList.reverse(); + expect(linkedList.toString()).toBe('1'); + }); + + test('should clear the linked list', () => { + linkedList.append(1); + linkedList.append(2); + linkedList.append(3); + linkedList.clear(); + expect(linkedList.toString()).toBe(''); + }); +}); \ No newline at end of file diff --git a/src/06-linked-list/circular-linked-list.ts b/src/06-linked-list/circular-linked-list.ts new file mode 100644 index 00000000..5152ad37 --- /dev/null +++ b/src/06-linked-list/circular-linked-list.ts @@ -0,0 +1,161 @@ +// src/06-linked-list/circular-linked-list.ts + +class LinkedListNode { + constructor(public element: T, public next?: LinkedListNode) {} +} + +class CircularLinkedList { + + private head: LinkedListNode | null; + private size = 0; + + append(element: T) { + const node = new LinkedListNode(element, null); + if (!this.head) { + this.head = node; + node.next = this.head; + } else { + let current = this.head; + while (current.next !== this.head) { + current = current.next; + } + current.next = node; + node.next = this.head; + } + this.size++; + } + + prepend(element: T) { + const node = new LinkedListNode(element, this.head); + let current = this.head; + while (current.next !== this.head) { + current = current.next; + } + current.next = node; + this.head = node; + this.size++; + } + + insert(position: number, element: T): boolean { + if (this.isInvalidPosition(position)) { + return false; + } + const node = new LinkedListNode(element, null); + if (position === 0) { + this.prepend(element); + return true; + } + let current = this.head; + let previous = null; + let index = 0; + while (index++ < position) { + previous = current; + current = current.next; + } + node.next = current; + previous.next = node; + this.size++; + return true; + } + + removeAt(position: number): T { + if (this.isInvalidPosition(position)) { + throw new Error('Invalid position'); + } + let current = this.head; + let previous = null; + if (position === 0) { + let last = this.head; + while (last.next !== this.head) { + last = last.next; + } + this.head = current.next; + last.next = this.head; + } else { + let index = 0; + while (index++ < position) { + previous = current; + current = current.next; + } + previous.next = current.next; + } + this.size--; + return current.element; + } + + private isInvalidPosition(position: number): boolean { + return position < 0 || position >= this.size; + } + + getSize(): number { + return this.size; + } + + isEmpty(): boolean { + return this.size === 0; + } + + getHead(): LinkedListNode | null { + return this.head; + } + + clear() { + this.head = null; + this.size = 0; + } + + remove(element: T): T | null { + const index = this.indexOf(element); + if (index === -1) { + return null; + } + return this.removeAt(index); + } + + indexOf(element: T): number { + let current = this.head; + let index = 0; + while (current) { + if (current.element === element) { + return index; + } + index++; + current = current.next; + if (current === this.head) { + return -1; + } + } + return -1; + } + + toString() { + let current = this.head; + let result = ''; + while (current) { + result += current.element + (current.next !== this.head ? ' -> ' : ''); + current = current.next; + if (current === this.head) { + break; + } + } + return result; + } + + reverse() { + let current = this.head; + let previous = null; + let next = null; + while (current) { + next = current.next; + current.next = previous; + previous = current; + current = next; + if (current === this.head) { + break; + } + } + this.head = previous; + } +} + +export default CircularLinkedList; diff --git a/src/06-linked-list/circular-linked-list_.js b/src/06-linked-list/circular-linked-list_.js new file mode 100644 index 00000000..e85f3888 --- /dev/null +++ b/src/06-linked-list/circular-linked-list_.js @@ -0,0 +1,193 @@ +// src/06-linked-list/circular-linked-list.js + +class LinkedListNode { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class CircularLinkedList { + + #head; + #size = 0; + + append(data) { + const newNode = new LinkedListNode(data); + if (!this.#head) { // empty list + this.#head = newNode; + newNode.next = this.#head; // point to itself + } else { // non-empty list + let current = this.#head; + while (current.next !== this.#head) { + current = current.next; + } + current.next = newNode; + newNode.next = this.#head; // circular reference + } + this.#size++; + } + + prepend(data) { + const newNode = new LinkedListNode(data, this.#head); + if (!this.head) { + this.head = newNode; + newNode.next = this.head; // make it circular + } else { + // Find the last node + let current = this.head; + while (current.next !== this.head) { + current = current.next; + } + current.next = newNode; + this.head = newNode; + } + this.#size++; + } + + insert(data, position) { + if (this.#isInvalidPosition(position)) { + return false; + } + const node = new LinkedListNode(data, null); + if (position === 0) { + this.prepend(data); + return true; + } + let current = this.#head; + let previous = null; + let index = 0; + while (index++ < position) { + previous = current; + current = current.next; + } + node.next = current; + previous.next = node; + this.#size++; + return true; + } + + removeAt(position) { + if (this.#size === 0) { + throw new RangeError('Cannot remove from an empty list.'); + } + if (this.#isInvalidPosition(position)) { + throw new RangeError('Invalid position.'); + } + if (position === 0) { + return this.#removeFromHead(); + } else if (position === this.#size - 1) { + return this.#removeFromTail(); + } else { + return this.#removeFromMiddle(position); + } + } + + #removeFromHead() { + const nodeToRemove = this.#head; + let lastNode = this.#head; + while (lastNode.next !== this.#head) { // Find the last node + lastNode = lastNode.next; + } + this.#head = nodeToRemove.next; // skip the head + lastNode.next = this.#head; // make it circular + + if (this.#size === 1) { // only one node + this.#head = null; + } + this.#size--; + return nodeToRemove.data; + } + + #removeFromTail() { + if (this.#head.next === this.#head) { // single node case + const nodeToRemove = this.#head; + this.#head = null; + this.#size--; + return nodeToRemove.data; + } else { + let lastNode = this.#head; + let previousNode = null; + while (lastNode.next !== this.#head) { // Find the last node + previousNode = lastNode; + lastNode = lastNode.next; + } + previousNode.next = this.#head; // skip the last node to remove it + this.#size--; + return lastNode.data; + } + } + + + #isInvalidPosition(position) { + return position < 0 || position >= this.#size; + } + + get size() { + return this.#size; + } + + isEmpty() { + return this.#size === 0; + } + + clear() { + this.#head = null; + this.#size = 0; + } + + remove(data: T): T | null { + const index = this.indexOf(data); + if (index === -1) { + return null; + } + return this.removeAt(index); + } + + indexOf(data: T): number { + let current = this.#head; + let index = 0; + while (current) { + if (current.data === data) { + return index; + } + index++; + current = current.next; + if (current === this.#head) { + return -1; + } + } + return -1; + } + + toString() { + let current = this.#head; + let result = ''; + while (current) { + result += current.data + (current.next !== this.#head ? ' -> ' : ''); + current = current.next; + if (current === this.#head) { + break; + } + } + return result; + } + + reverse() { + let current = this.#head; + let previous = null; + let next = null; + while (current) { + next = current.next; + current.next = previous; + previous = current; + current = next; + if (current === this.#head) { + break; + } + } + this.#head = previous; + } +} + +module.exports = CircularLinkedList; diff --git a/src/06-linked-list/doubly-linked-list.ts b/src/06-linked-list/doubly-linked-list.ts new file mode 100644 index 00000000..b77005b6 --- /dev/null +++ b/src/06-linked-list/doubly-linked-list.ts @@ -0,0 +1,188 @@ +// src/06-linked-list/doubly-linked-list.ts + +class DoublyLinkedListNode { + constructor( + public data: T, + public next?: DoublyLinkedListNode, + public previous?: DoublyLinkedListNode + ) {} +} + +class DoublyLinkedList { + private head: DoublyLinkedListNode | null; + private tail: DoublyLinkedListNode | null; + private size = 0; + + append(data: T) { + const node = new DoublyLinkedListNode(data); + if (!this.head) { + this.head = node; + this.tail = node; + } else { + node.previous = this.tail; + this.tail.next = node; + this.tail = node; + } + this.size++; + } + + prepend(data: T) { + const node = new DoublyLinkedListNode(data); + if (!this.head) { + this.head = node; + this.tail = node; + } else { + node.next = this.head; + this.head.previous = node; + this.head = node; + } + this.size++; + } + + insert(data: T, position: number): boolean { + if (this.isInvalidPosition(position)) { + return false; + } + if (position === 0) { + this.prepend(data); + return true; + } + if (position === this.size) { + this.append(data); + return true; + } + const newNode = new DoublyLinkedListNode(data); + let current = this.head; + let previous = null; + for (let index = 0; index < position; index++) { + previous = current; + current = current.next; + } + newNode.next = current; + newNode.previous = previous; + current.previous = newNode; + previous.next = newNode; + this.size++; + return true; + } + + removeAt(position: number): T { + if (this.isInvalidPosition(position)) { + throw new RangeError('Invalid position'); + } + let nodeToRemove = this.head; + let previousNode = null; + + if (position === 0) { + this.head = nodeToRemove.next; + if (this.head) { // Check if new head exists + this.head.previous = null; + } else { + this.tail = null; // List becomes empty + } + } else if (position === this.size - 1) { + nodeToRemove = this.tail; + this.tail = nodeToRemove.previous; + this.tail.next = null; + } else { + let index = 0; + while (index < position) { + previousNode = nodeToRemove; + nodeToRemove = nodeToRemove.next; + index++; + } + previousNode.next = nodeToRemove.next; + nodeToRemove.next.previous = previousNode; + } + this.size--; + return nodeToRemove.data; + } + + private isInvalidPosition(position: number) { + return position < 0 || position >= this.size; + } + + getSize() { + return this.size; + } + + isEmpty() { + return this.size === 0; + } + + indexOf(data: T) { + let current = this.head; + let index = 0; + while (current) { + if (current.data === data) { + return index; + } + index++; + current = current.next; + } + return -1; + } + + remove(data: T): T | null { + const index = this.indexOf(data); + if (index === -1) { + return null; + } + return this.removeAt(index); + } + + clear() { + this.head = null; + this.tail = null; + this.size = 0; + } + + toString() { + let current = this.head; + let objString = ''; + while (current) { + objString += this.elementToString(current.data); + current = current.next; + if (current) { + objString += ', '; + } + } + return objString; + } + + // inverse toString + inverseToString() { + let current = this.tail; + let objString = ''; + while (current) { + objString += this.elementToString(current.data); + current = current.previous; + } + return objString; + } + + private elementToString(data: T): string { + if (typeof data === 'object' && data !== null) { + return JSON.stringify(data); + } else { + return data.toString(); + } + } + + reverse() { + let current = this.head; + let previous = null; + let next = null; + while (current) { + next = current.next; + current.next = previous; + current.previous = next; + previous = current; + current = next; + } + this.tail = this.head; + this.head = previous; + } +} + +export default DoublyLinkedList; \ No newline at end of file diff --git a/src/06-linked-list/doubly-linked-list_.js b/src/06-linked-list/doubly-linked-list_.js new file mode 100644 index 00000000..68e0a98b --- /dev/null +++ b/src/06-linked-list/doubly-linked-list_.js @@ -0,0 +1,220 @@ +// src/06-linked-list/doubly-linked-list.js + +class DoublyLinkedListNode { + constructor(data, next = null, previous = null) { + this.data = data; + this.next = next; + this.previous = previous; // new + } +} + +class DoublyLinkedList { + #head; + #tail; + #size = 0; + + append(data) { + const newNode = new DoublyLinkedListNode(data); + if (!this.#head) { // empty list + this.#head = newNode; + this.#tail = newNode; + } else { // non-empty list + newNode.previous = this.#tail; + this.#tail.next = newNode; + this.#tail = newNode; + } + this.#size++; + } + + prepend(data) { + const newNode = new DoublyLinkedListNode(data); + if (!this.#head) { // empty list + this.#head = newNode; + this.#tail = newNode; + } else { // non-empty list + newNode.next = this.#head; + this.#head.previous = newNode; + this.#head = newNode; + } + this.#size++; + } + + insert(data, position) { + if (this.#isInvalidPosition(position)) { + return false; + } + + if (position === 0) { // first position + this.prepend(data); + return true; + } + + if (position === this.#size) { // last position + this.append(data); + return true; + } + + // middle position + return this.#insertInTheMiddle(data, position); + } + + #insertInTheMiddle(data, position) { + const newNode = new DoublyLinkedListNode(data); + let currentNode = this.#head; + let previousNode; + + for (let index = 0; index < position; index++) { + previousNode = currentNode; + currentNode = currentNode.next; + } + + newNode.next = currentNode; + newNode.previous = previousNode; + currentNode.previous = newNode; + previousNode.next = newNode; + + this.#size++; + return true; + } + + removeAt(position) { + if (this.#size === 0) { + throw new RangeError('Cannot remove from an empty list.'); + } + if (this.#isInvalidPosition(position)) { + throw new RangeError('Invalid position.'); + } + + if (position === 0) { + return this.#removeFromHead(); + } + if (position === this.#size - 1) { + return this.#removeFromTail(); + } + return this.#removeFromMiddle(position); + } + + #removeFromHead() { + const nodeToRemove = this.#head; + this.#head = nodeToRemove.next; + if (this.#head) { + this.#head.previous = null; + } else { + this.#tail = null; // List becomes empty + } + this.#size--; + nodeToRemove.next = null; + return nodeToRemove.data; + } + + #removeFromTail() { + const nodeToRemove = this.#tail; + this.#tail = nodeToRemove.previous; + if (this.#tail) { + this.#tail.next = null; + } else { + this.#head = null; // List becomes empty + } + this.#size--; + nodeToRemove.previous = null; + return nodeToRemove.data; + } + + #removeFromMiddle(position) { + let nodeToRemove = this.#head; + let previousNode; + for (let index = 0; index < position; index++) { + previousNode = nodeToRemove; + nodeToRemove = nodeToRemove.next; + } + + previousNode.next = nodeToRemove.next; + nodeToRemove.next.previous = previousNode; + + nodeToRemove.next = null; + nodeToRemove.previous = null; + + this.#size--; + return nodeToRemove.data; + } + + #isInvalidPosition(position) { + return position < 0 || position >= this.#size; + } + + get size() { + return this.#size; + } + + isEmpty() { + return this.#size === 0; + } + + indexOf(data, compareFunction = (a, b) => a === b) { + let current = this.#head; + let index = 0; + while (current) { + if (compareFunction(current.data, data)) { + return index; + } + index++; + current = current.next; + } + return -1; + } + + + clear() { + this.#head = null; + this.#size = 0; + } + + toString() { + let current = this.#head; + let objString = ''; + while (current) { + objString += this.#elementToString(current.data); + current = current.next; + if (current) { + objString += ', '; + } + } + return objString; + } + + // inverse toString + inverseToString() { + let current = this.#tail; + let objString = ''; + while (current) { + objString += this.#elementToString(current.data); + current = current.previous; + } + return objString; + } + + #elementToString(data) { + if (typeof data === 'object' && data !== null) { + return JSON.stringify(data); + } else { + return data.toString(); + } + } + + reverse() { + let current = this.#head; + let previous = null; + let next = null; + while (current) { + next = current.next; + current.next = previous; + current.previous = next; + previous = current; + current = next; + } + this.#tail = this.#head; + this.#head = previous; + } +} + +module.exports = DoublyLinkedList; \ No newline at end of file diff --git a/src/06-linked-list/leetcode/reverse-linked-list.ts b/src/06-linked-list/leetcode/reverse-linked-list.ts new file mode 100644 index 00000000..d910426d --- /dev/null +++ b/src/06-linked-list/leetcode/reverse-linked-list.ts @@ -0,0 +1,34 @@ + +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +class ListNode { + val: number + next: ListNode | null + constructor(val?: number, next?: ListNode | null) { + this.val = (val === undefined ? 0 : val) + this.next = (next === undefined ? null : next) + } +} + +function reverseList(head: ListNode | null): ListNode | null { + let current = head; + let newHead = null; + let nextNode = null; + while (current) { + nextNode = current.next; + current.next = newHead; + newHead = current; + current = nextNode; + } + return newHead; +} \ No newline at end of file diff --git a/src/06-linked-list/linked-list.ts b/src/06-linked-list/linked-list.ts new file mode 100644 index 00000000..cf59437b --- /dev/null +++ b/src/06-linked-list/linked-list.ts @@ -0,0 +1,146 @@ +// src/06-linked-list/linked-list.ts + +class LinkedListNode { + constructor(public element: T, public next?: LinkedListNode) {} +} + +class LinkedList { + + private head: LinkedListNode | null; + private size = 0; + + append(element: T) { + const node = new LinkedListNode(element, null); + if (!this.head) { + this.head = node; + } else { + let current = this.head; + while (current.next) { + current = current.next; + } + current.next = node; + } + this.size++; + } + + prepend(element: T) { + const node = new LinkedListNode(element, this.head); + this.head = node; + this.size++; + } + + insert(position: number, element: T): boolean { + if (this.isInvalidPosition(position)) { + return false; + } + const node = new LinkedListNode(element, null); + if (position === 0) { + this.prepend(element); + return true + } + let current = this.head; + let previous = null; + let index = 0; + while (index++ < position) { + previous = current; + current = current.next; + } + node.next = current; + previous.next = node; + this.size++; + return true; + } + + removeAt(position: number): T { + if (this.isInvalidPosition(position)) { + throw new Error('Invalid position'); + } + let current = this.head; + let previous = null; + if (position === 0) { + this.head = current.next; + } else { + for (let index = 0; index < position; index++) { + previous = current; + current = current.next; + } + previous.next = current.next; + } + this.size--; + return current.element; + } + + private isInvalidPosition(position: number) { + return position < 0 || position >= this.size; + } + + remove(element: T): T | null { + const index = this.indexOf(element); + if (index === -1) { + return null; + } + return this.removeAt(index); + } + + indexOf(element: T) { + let current = this.head; + let index = 0; + while (current) { + if (current.element === element) { + return index; + } + index++; + current = current.next; + } + return -1; + } + + isEmpty() { + return this.size === 0; + } + + clear() { + this.head = null; + this.size = 0; + } + + getSize() { + return this.size; + } + + reverse() { + let current = this.head; + let previous = null; + let next = null; + while (current) { + next = current.next; + current.next = previous; + previous = current; + current = next; + } + this.head = previous; + } + + toString() { + let current = this.head; + let objString = ''; + while (current) { + objString += this.elementToString(current.element); + current = current.next; + if (current) { + objString += ', '; + } + } + return objString; + } + + private elementToString(element: T): string { + if (typeof element === 'object' && element !== null) { + return JSON.stringify(element); + } else { + return element.toString(); + } + } +} + +export default LinkedList; \ No newline at end of file diff --git a/src/06-linked-list/linked-list_.js b/src/06-linked-list/linked-list_.js new file mode 100644 index 00000000..91ec6345 --- /dev/null +++ b/src/06-linked-list/linked-list_.js @@ -0,0 +1,174 @@ +// src/06-linked-list/linked-list.js + +class LinkedListNode { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class LinkedList { + + #head; + #size = 0; + + append(data) { + const newNode = new LinkedListNode(data); + if (!this.#head) { + this.#head = newNode; + } else { + let current = this.#head; + while (current.next !== null) { + current = current.next; + } + current.next = newNode; + } + this.#size++; + } + + prepend(data) { + const newNode = new LinkedListNode(data, this.#head); + this.#head = newNode; + this.#size++; + } + + insert(data, position) { + if (this.#isInvalidPosition(position)) { + return false; + } + const newNode = new LinkedListNode(data); + if (position === 0) { + this.prepend(data); + return true; + } + let current = this.#head; + let previous = null; + let index = 0; + while (index++ < position) { + previous = current; + current = current.next; + } + newNode.next = current; + previous.next = newNode; + this.#size++; + return true; + } + + #isInvalidPosition(position) { + return position < 0 || position >= this.size; + } + + removeAt(position) { + if (this.#size === 0) { + throw new RangeError('Cannot remove from an empty list.'); + } + if (this.#isInvalidPosition(position)) { + throw new RangeError('Invalid position'); + } + if (position === 0) { // Handle removal at head + return this.#removeFromHead(); + } + return this.#removeFromMiddleOrEnd(position); + } + + #removeFromHead() { + const nodeToRemove = this.#head; + this.#head = this.#head.next; + this.#size--; + return nodeToRemove.data; + } + + #removeFromMiddleOrEnd(position) { + let nodeToRemove = this.#head; + let previous; + + for (let index = 0; index < position; index++) { // traverse to the position + previous = nodeToRemove; + nodeToRemove = nodeToRemove.next; + } + + previous.next = nodeToRemove.next; // Unlink the node to be removed + this.#size--; + return nodeToRemove.data; // Return removed data + } + + remove(data, compareFunction = (a, b) => a === b) { + const index = this.indexOf(data, compareFunction); + if (index === -1) { + return null; + } + return this.removeAt(index); + } + + indexOf(data, compareFunction = (a, b) => a === b) { + let current = this.#head; + let index = 0; + while (current) { + if (compareFunction(current.data, data)) { + return index; + } + index++; + current = current.next; + } + return -1; + } + + isEmpty() { + return this.#size === 0; + } + + clear() { + this.#head = null; + this.#size = 0; + } + + get size() { + return this.#size; + } + + forEach(callback) { + let current = this.#head; + let index = 0; + while (current) { + callback(current.data, index); + current = current.next; + index++; + } + } + + toString() { + let current = this.#head; + let objString = ''; + while (current) { + objString += this.#elementToString(current.data); + current = current.next; + if (current) { + objString += ', '; + } + } + return objString; + } + + #elementToString(data) { + if (typeof data === 'object' && data !== null) { + return JSON.stringify(data); + } else { + return data.toString(); + } + } + + reverse() { + let current = this.#head; + let newHead; + let nextNode; + while (current) { + nextNode = current.next; + current.next = newHead; + newHead = current; + current = nextNode; + } + this.#head = newHead; + } +} + +module.exports = LinkedList; \ No newline at end of file diff --git a/src/06-linked-list/media-player.js b/src/06-linked-list/media-player.js new file mode 100644 index 00000000..b67ba703 --- /dev/null +++ b/src/06-linked-list/media-player.js @@ -0,0 +1,141 @@ +class MediaPlayerSong { + constructor(songTitle) { + this.songTitle = songTitle; + this.previous = null; + this.next = null; + } +} + +class MediaPlayer { + #firstSong; + #lastSong; + #size = 0; + #playingSong; + + addSongByTitle(newSongTitle) { + const newSong = new MediaPlayerSong(newSongTitle); + if (this.#size === 0) { // empty list + this.#insertEmptyPlayList(newSong); + } else { + const position = this.#findIndexOfSortedSong(newSongTitle); + if (position === 0) { // insert at the beginning + this.#insertAtBeginning(newSong); + } else if (position === this.#size) { // insert at the end + this.#insertAtEnd(newSong); + } else { // insert in the middle + this.#insertInMiddle(newSong, position); + } + } + this.#size++; + } + + #insertEmptyPlayList(newSong) { + this.#firstSong = newSong; + this.#lastSong = newSong; + newSong.next = newSong; // points to itself + newSong.previous = newSong; // points to itself + } + + #insertAtBeginning(newSong) { + newSong.next = this.#firstSong; + newSong.previous = this.#lastSong; + this.#firstSong.previous = newSong; + this.#lastSong.next = newSong; + this.#firstSong = newSong; + } + + #insertAtEnd(newSong) { + newSong.next = this.#firstSong; + newSong.previous = this.#lastSong; + this.#lastSong.next = newSong; + this.#firstSong.previous = newSong; + this.#lastSong = newSong; + } + + #insertInMiddle(newSong, position) { + let currentSong = this.#firstSong; + for (let i = 0; i < position - 1; i++) { + currentSong = currentSong.next; + } + newSong.next = currentSong.next; + newSong.previous = currentSong; + currentSong.next.previous = newSong; + currentSong.next = newSong; + } + + #findIndexOfSortedSong(newSongTitle) { + let currentSong = this.#firstSong; + let i = 0; + for (; i < this.#size && currentSong; i++) { + const currentSongTitle = currentSong.songTitle; + if (this.#compareSongs(currentSongTitle, newSongTitle) >= 0) { + return i; + } + currentSong = currentSong.next; + } + return 0; + } + + #compareSongs(songTitle1, songTitle2) { + return songTitle1.localeCompare(songTitle2); + } + + play() { + if (this.#size === 0) { + return null; + } + this.#playingSong = this.#firstSong; + return this.#playingSong.songTitle; + } + + next() { + if (this.#size === 0) { + return null; + } + if (!this.#playingSong) { + return this.play(); + } + this.#playingSong = this.#playingSong.next; + return this.#playingSong.songTitle; + } + + previous() { + if (this.#size === 0) { + return null; + } + if (!this.#playingSong) { + return this.play(); + } + this.#playingSong = this.#playingSong.previous; + return this.#playingSong.songTitle; + } + + showPlaylist() { + let currentSong = this.#firstSong; + let result = ''; + for (let i = 0; i < this.#size - 1; i++) { + result += currentSong.songTitle + ' -> '; + currentSong = currentSong.next; + } + result += currentSong.songTitle; + return result; + } +} + +const mediaPlayer = new MediaPlayer(); +mediaPlayer.addSongByTitle('The Bard\'s Song'); +mediaPlayer.addSongByTitle('Florida!!!'); +mediaPlayer.addSongByTitle('Run to the Hills'); +mediaPlayer.addSongByTitle('Nothing Else Matters'); + +console.log('Playing:', mediaPlayer.play()); // Florida!!! +console.log('Next:', mediaPlayer.next()); // Nothing Else Matters +console.log('Next:', mediaPlayer.next()); // Run to the Hills +console.log('Next:', mediaPlayer.next()); // The Bard's Song +console.log('Next:', mediaPlayer.next()); // Florida!!! +console.log('Previous:', mediaPlayer.previous()); // The Bard's Song +console.log('Previous:', mediaPlayer.previous()); // Run to the Hills +console.log('Previous:', mediaPlayer.previous()); // Nothing Else Matters +console.log('Previous:', mediaPlayer.previous()); // Florida!!! + +// to see the output of this file use the command: node src/06-linked-list/media-player.js \ No newline at end of file diff --git a/src/07-set/01-using-myset-class.js b/src/07-set/01-using-myset-class.js new file mode 100644 index 00000000..ec4722dc --- /dev/null +++ b/src/07-set/01-using-myset-class.js @@ -0,0 +1,145 @@ +// src/07-set/01-using-myset-class.js + +const MySet = require('./set'); + +const article = { + title: 'The importance of data structures in programming', + content: '...', + tags: new MySet() // using MySet to store tags +}; + +// add tags +article.tags.add('programming'); +article.tags.add('data structures'); +article.tags.add('algorithms'); +article.tags.add('programming'); + +console.log(article.tags.size); // 3 +console.log(article.tags.has('data structures')); // true +console.log(article.tags.has('algorithms')); // true +console.log(article.tags.has('programming')); // true +console.log(article.tags.has('javascript')); // false +console.log(article.tags.values()); // ['programming', 'data structures', 'algorithms'] + +// remove tags +article.tags.delete('programming'); +article.tags.add('JavaScript'); +console.log(article.tags.values()); // ['data structures', 'algorithms', 'JavaScript'] + +// union example +const interestsFromWebsites = new MySet(); +interestsFromWebsites.addAll(['technology', 'politics', 'photography']); + +const interestsFromSocialMedia = new MySet(); +interestsFromSocialMedia.addAll(['technology', 'movies', 'books']); + +const allInterests = interestsFromWebsites.union(interestsFromSocialMedia); +console.log(allInterests.values()); // ['technology', 'politics', 'photography', 'movies', 'books'] + +// intersection example +const job1Skills = new MySet(); +job1Skills.addAll(['JavaScript', 'Angular', 'Java', 'SQL']); +const job2Skills = new MySet(); +job2Skills.addAll(['Python', 'Machine Learning', 'SQL', 'Statistics']); +const jobPostings = + [{ + title: 'Software Engineer', + skills: job1Skills + }, + { + title: 'Data Scientist', + skills: job2Skills + }]; + +const candidateSkills = new MySet(); +candidateSkills.addAll(['JavaScript', 'Angular', 'TypeScript', 'AWS']); +const candidate = { + name: 'Loiane', + skills: candidateSkills +}; + +// Function to match candidate with jobs +function matchCandidateWithJobs(candidate, jobPostings) { + const matches = []; + for (const job of jobPostings) { + const matchingSkillsSet = candidate.skills.intersection(job.skills); + if (!matchingSkillsSet.isEmpty()){ + matches.push({ + title: job.title, + matchingSkills: matchingSkillsSet.values() + }); + } + } + return matches; +} + +// Find matching jobs for the candidate +const matchingJobs = matchCandidateWithJobs(candidate, jobPostings); +console.log(matchingJobs); +// output: [{ title: 'Software Engineer', matchingSkills: [ 'JavaScript', 'Angular' ] }] + +// difference example +// Sets representing subscriber interests +const allSubscribers = new MySet(); +allSubscribers.addAll(['Aelin', 'Rowan', 'Xaden', 'Poppy', 'Violet']); +const booksInterested = new MySet(); +booksInterested.addAll(['Aelin', 'Poppy', 'Violet']); +const alreadyPurchasedBooks = new MySet(); +alreadyPurchasedBooks.addAll(['Poppy']); + +// Find subscribers interested in books but haven't purchased yet +const targetSubscribers = booksInterested.difference(alreadyPurchasedBooks); + +// Send targeted email +targetSubscribers.values().forEach(subscriber => { + sendEmail(subscriber, 'New books you will love!'); +}); + +function sendEmail(subscriber, message) { + console.log(`Sending email to ${subscriber}: ${message}`); +} +// Sending email to Aelin: New books you will love! +// Sending email to Violet: New books you will love! + +// subset example +// Example Recipe Data + +const chickenIngredients = new MySet() +chickenIngredients.addAll(['chicken', 'tomato', 'onion', 'garlic', 'ginger', 'spices']); + +const spaghettiIngredients = new MySet(); +spaghettiIngredients.addAll(['spaghetti', 'eggs', 'bacon', 'parmesan', 'pepper']); + +const recipes = +[{ + name: 'Chicken Tikka Masala', + ingredients: chickenIngredients + }, + { + name: 'Spaghetti Carbonara', + ingredients: spaghettiIngredients + }]; + +// User's available ingredients +const userIngredients = new MySet(); +userIngredients.addAll(['chicken', 'onion', 'garlic', 'ginger']); + +// Function to filter recipes +function filterRecipes(recipes, userIngredients) { + const filteredRecipes = []; + for (const recipe of recipes) { + if (userIngredients.isSubsetOf(recipe.ingredients)) { + filteredRecipes.push({ name: recipe.name }); + } + } + return filteredRecipes; +} + +// Filter recipes based on user's ingredients +const matchingRecipes = filterRecipes(recipes, userIngredients); +console.log(matchingRecipes); +// [ { name: 'Chicken Tikka Masala' } ] + + + +// to see the output of this file use the command: node src/07-set/01-using-myset-class.js \ No newline at end of file diff --git a/src/07-set/02-using-set-class.js b/src/07-set/02-using-set-class.js new file mode 100644 index 00000000..4756b2f0 --- /dev/null +++ b/src/07-set/02-using-set-class.js @@ -0,0 +1,29 @@ +// src/07-set/02-using-set-class.js + +const article = { + title: 'The importance of data structures in programming', + content: '...', + tags: new Set() + tags: new Set(['programming', 'data structures', 'algorithms']) +}; + +// add tags +article.tags.add('programming'); +article.tags.add('data structures'); +article.tags.add('algorithms'); +article.tags.add('programming'); + +console.log(article.tags.size); // 3 +console.log(article.tags.has('data structures')); // true +console.log(article.tags.has('algorithms')); // true +console.log(article.tags.has('programming')); // true +console.log(article.tags.has('javascript')); // false +console.log(article.tags.values()); // ['programming', 'data structures', 'algorithms'] + +// remove tags +article.tags.delete('programming'); +article.tags.add('JavaScript'); +console.log(article.tags.values()); // ['data structures', 'algorithms', 'JavaScript'] + + +// to see the output of this file use the command: node src/07-set/02-using-set-class.js \ No newline at end of file diff --git a/src/07-set/leetcode/remove-duplicates-from-sorted-array.ts b/src/07-set/leetcode/remove-duplicates-from-sorted-array.ts new file mode 100644 index 00000000..56f62d53 --- /dev/null +++ b/src/07-set/leetcode/remove-duplicates-from-sorted-array.ts @@ -0,0 +1,36 @@ +// https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/ + +/** + * @param {number[]} nums + * @return {number} + */ +export function removeDuplicates(nums: number[]): number { + if (nums.length === 0) { + return 0; + } + let i = 0; + for (let j = 1; j < nums.length; j++) { + if (nums[j] !== nums[i]) { + i++; + nums[i] = nums[j]; + } + } + return i + 1; +} + +// resolve this problem using Set +export function removeDuplicates2(nums: number[]): number { + const set = new Set(nums); + const arr = Array.from(set); + for (let i = 0; i < arr.length; i++) { + nums[i] = arr[i]; + } + return arr.length; +} + +// explain above solution +// 1. create a set from the array +// 2. create an array from the set +// 3. copy the array to the original array +// 4. return the length of the array +// Time complexity: O(n) \ No newline at end of file diff --git a/src/07-set/set.js b/src/07-set/set.js new file mode 100644 index 00000000..f681a8dc --- /dev/null +++ b/src/07-set/set.js @@ -0,0 +1,105 @@ +class MySet { + #items = {}; + #size = 0; + + add(value) { + if (!this.has(value)) { + this.#items[value] = true; // mark the value as present + this.#size++; + return true; + } + return false; + } + + addAll(values) { + values.forEach(value => this.add(value)); + } + + delete(value) { + if (this.has(value)) { + delete this.#items[value]; + this.#size--; + return true; + } + return false; + } + + has(value) { + return this.#items.hasOwnProperty(value); + } + + values() { + return Object.keys(this.#items); + } + + get size() { + return this.#size; + } + + getSizeWithoutSizeProperty() { + let count = 0; + for (const key in this.#items) { + if (this.#items.hasOwnProperty(key)) { + count++; + } + } + return count; + } + + isEmpty() { + return this.#size === 0; + } + + clear() { + this.#items = {}; + this.#size = 0; + } + + union(otherSet) { + const unionSet = new MySet(); + this.values().forEach(value => unionSet.add(value)); + otherSet.values().forEach(value => unionSet.add(value)); + return unionSet; + } + + intersection(otherSet) { + const intersectionSet = new MySet(); + const [smallerSet, largerSet] = this.size <= otherSet.size ? [this, otherSet] : [otherSet, this]; + smallerSet.values().forEach(value => { + if (largerSet.has(value)) { + intersectionSet.add(value); + } + }); + return intersectionSet; + } + + difference(otherSet) { + const differenceSet = new MySet(); + this.values().forEach(value => { + if (!otherSet.has(value)) { + differenceSet.add(value); + } + }); + return differenceSet; + } + + isSubsetOf(otherSet) { + if (this.size > otherSet.size) { + return false; + } + return this.values().every(value => otherSet.has(value)); + } + + isSupersetOf(otherSet) { + if (this.size < otherSet.size) { + return false; + } + return otherSet.values().every(value => this.has(value)); + } + + toString() { + return this.values().join(', '); + } +} + +module.exports = MySet; diff --git a/src/08-dictionary-hash/01-using-dictionary-class.js b/src/08-dictionary-hash/01-using-dictionary-class.js new file mode 100644 index 00000000..9dab635b --- /dev/null +++ b/src/08-dictionary-hash/01-using-dictionary-class.js @@ -0,0 +1,42 @@ +// src/08-dictionary-hash/01-using-dictionary-class.js + +const Dictionary = require('./dictionary'); + +const translations = new Dictionary(); + +// Add some translations - English to Portuguese +translations.set("hello", "olá"); +translations.set("thank you", "obrigado"); +translations.set("book", "livro"); +translations.set("cat", "gato"); +translations.set("computer", "computador"); + +// User interaction +function translateWord(word) { + if (translations.hasKey(word)) { + const translation = translations.get(word); + console.log(`The translation of "${word}" is "${translation}"`); + } else { + console.log(`Sorry, no translation found for "${word}"`); + } +} + +// Example usage +translateWord("hello"); // Output: The translation of "hello" is "olá" +translateWord("dog"); // Output: Sorry, no translation found for "dog" + +// Get all translations +console.log("All translations:", translations.values()); +// All translations: [ 'olá', 'obrigado', 'livro', 'gato', 'computador' ] + +// Get all words +console.log("All words:", translations.keys()); +// All words: [ 'hello', 'thank you', 'book', 'cat', 'computer' ] + +// Iterate through all translations +translations.forEach((value, key) => { + console.log(`${key}: ${value}`); +}); + + +// to see the output of this file use the command: node src/08-dictionary-hash/01-using-dictionary-class.js \ No newline at end of file diff --git a/src/08-dictionary-hash/02-using-map-class.js b/src/08-dictionary-hash/02-using-map-class.js new file mode 100644 index 00000000..28a904fb --- /dev/null +++ b/src/08-dictionary-hash/02-using-map-class.js @@ -0,0 +1,40 @@ +// src/08-dictionary-hash/02-using-map-class.js + +const translations = new Map(); + +// Add some translations - English to Portuguese +translations.set("hello", "olá"); +translations.set("thank you", "obrigado"); +translations.set("book", "livro"); +translations.set("cat", "gato"); +translations.set("computer", "computador"); + +// User interaction +function translateWord(word) { + if (translations.has(word)) { + const translation = translations.get(word); + console.log(`The translation of "${word}" is "${translation}"`); + } else { + console.log(`Sorry, no translation found for "${word}"`); + } +} + +// Example usage +translateWord("hello"); // Output: The translation of "hello" is "olá" +translateWord("dog"); // Output: Sorry, no translation found for "dog" + +// Get all translations +console.log("All translations:", translations.values()); +// All translations: [ 'olá', 'obrigado', 'livro', 'gato', 'computador' ] + +// Get all words +console.log("All words:", translations.keys()); +// All words: [ 'hello', 'thank you', 'book', 'cat', 'computer' ] + +// Iterate through all translations +translations.forEach((value, key) => { + console.log(`${key}: ${value}`); +}); + + +// to see the output of this file use the command: node src/08-dictionary-hash/01-using-dictionary-class.js \ No newline at end of file diff --git a/src/08-dictionary-hash/03-using-weakmap-class.js b/src/08-dictionary-hash/03-using-weakmap-class.js new file mode 100644 index 00000000..49a8a494 --- /dev/null +++ b/src/08-dictionary-hash/03-using-weakmap-class.js @@ -0,0 +1,19 @@ +const privateData = new WeakMap(); + +class Person { + constructor(name, age) { + this.name = name; + this.age = age; + privateData.set(this, { ssn: 'XXX-XX-XXXX', medicalHistory: [] }); + } + + getSSN() { + return privateData.get(this)?.ssn; + } +} + +const alice = new Person("Penelope", 20); +console.log(alice.name); // Penelope +console.log(alice.getSSN()); // XXX-XX-XXXX + +// Try to access private data \ No newline at end of file diff --git a/src/08-dictionary-hash/04-using-hashmap-class.js b/src/08-dictionary-hash/04-using-hashmap-class.js new file mode 100644 index 00000000..7e727871 --- /dev/null +++ b/src/08-dictionary-hash/04-using-hashmap-class.js @@ -0,0 +1,26 @@ +// src/08-dictionary-hash/04-using-hashmap-class.js + +const HashTable = require('./hash-table'); + +const addressBook = new HashTable(); + +// Add contacts +addressBook.put('Gandalf', 'gandalf@email.com'); +addressBook.put('John', 'johnsnow@email.com'); +addressBook.put('Tyrion', 'tyrion@email.com'); + +// Retrieve the hash code of a contact +console.log(addressBook.hash('Gandalf')); // 19 +console.log(addressBook.hash('John')); // 29 +console.log(addressBook.hash('Tyrion')); // 16 + +// Retrieve contacts +console.log(addressBook.get('Gandalf')); // gandalf@email.com +console.log(addressBook.get('Loiane')); // undefined + +// Remove contacts +console.log(addressBook.remove('Gandalf')); // true +console.log(addressBook.get('Gandalf')); // undefined + + +// to see the output of this file use the command: node src/08-dictionary-hash/04-using-hashmap-class.js \ No newline at end of file diff --git a/src/08-dictionary-hash/05-hashmap-collision.js b/src/08-dictionary-hash/05-hashmap-collision.js new file mode 100644 index 00000000..3a020ca3 --- /dev/null +++ b/src/08-dictionary-hash/05-hashmap-collision.js @@ -0,0 +1,42 @@ +// src/08-dictionary-hash/05-hashmap-collision.js + +const HashTable = require('./hash-table'); + +const addressBook = new HashTable(); + +// Add contacts +addressBook.put('Ygritte', 'ygritte@email.com'); +addressBook.put('Jonathan', 'jonathan@email.com'); +addressBook.put('Jamie', 'jamie@email.com'); +addressBook.put('Jack', 'jack@email.com'); +addressBook.put('Jasmine', 'jasmine@email.com'); +addressBook.put('Jake', 'jake@email.com'); +addressBook.put('Nathan', 'nathan@email.com'); +addressBook.put('Athelstan', 'athelstan@email.com'); +addressBook.put('Sue', 'sue@email.com'); +addressBook.put('Aethelwulf', 'aethelwulf@email.com'); +addressBook.put('Sargeras', 'sargeras@email.com'); + +// Retrieve the hash code of a contact +console.log(addressBook.hash('Ygritte'), '- Ygritte'); // 4 +console.log(addressBook.hash('Jonathan'), '- Jonathan'); // 5 +console.log(addressBook.hash('Jamie'), '- Jamie'); // 5 +console.log(addressBook.hash('Jack'), '- Jack'); // 7 +console.log(addressBook.hash('Jasmine'), '- Jasmine'); // 8 +console.log(addressBook.hash('Jake'), '- Jake'); // 9 +console.log(addressBook.hash('Nathan'), '- Nathan'); // 10 +console.log(addressBook.hash('Athelstan'), '- Athelstan'); // 7 +console.log(addressBook.hash('Sue'), '- Sue'); // 5 +console.log(addressBook.hash('Aethelwulf'), '- Aethelwulf'); // 5 +console.log(addressBook.hash('Sargeras'), '- Sargeras'); // 10 + +console.log(addressBook.toString()); +// {4 => ygritte@email.com} +// {5 => aethelwulf@email.com} +// {7 => athelstan@email.com} +// {8 => jasmine@email.com} +// {9 => jake@email.com} +// {10 => sargeras@email.com} + + +// to see the output of this file use the command: node src/08-dictionary-hash/05-hashmap-collision.js \ No newline at end of file diff --git a/src/08-dictionary-hash/dictionary.js b/src/08-dictionary-hash/dictionary.js new file mode 100644 index 00000000..47d568eb --- /dev/null +++ b/src/08-dictionary-hash/dictionary.js @@ -0,0 +1,59 @@ +// src/08-dictionary-hash/dictionary.js + +class Dictionary { + #items = {}; + #size = 0; + + hasKey(key) { + return this.#items[this.#elementToString(key)] != null; + } + + set(key, value) { + if (key != null && value != null) { + const tableKey = this.#elementToString(key); + this.#items[tableKey] = value; + this.#size++; + return true; + } + return false; + } + + delete(key) { + if (this.hasKey(key)) { + delete this.#items[this.#elementToString(key)]; + this.#size--; + return true; + } + return false; + } + + get(key) { + return this.#items[this.#elementToString(key)]; + } + + values() { + return Object.values(this.#items); + } + + keys() { + return Object.keys(this.#items); + } + + forEach(callbackFn) { + for (const key in this.#items) { + if (this.#items.hasOwnProperty(key)) { + callbackFn(this.#items[key], key); + } + } + } + + #elementToString(data) { + if (typeof data === 'object' && data !== null) { + return JSON.stringify(data); + } else { + return data.toString(); + } + } +} + +module.exports = Dictionary; \ No newline at end of file diff --git a/src/08-dictionary-hash/hash-table-linear-probing.js b/src/08-dictionary-hash/hash-table-linear-probing.js new file mode 100644 index 00000000..9947d03d --- /dev/null +++ b/src/08-dictionary-hash/hash-table-linear-probing.js @@ -0,0 +1,101 @@ +// src/08-dictionary-hash/hash-table-linear-probing.js + +class HashTableLinearProbing { + #table = []; + + #loseLoseHashCode(key) { + if (typeof key !== 'string') { + key = this.#elementToString(key); + } + const calcASCIIValue = (acc, char) => acc + char.charCodeAt(0); + const hash = key.split('').reduce((acc, char) => calcASCIIValue, 0); + return hash % 37; // mod to reduce the hash code + } + + #djb2HashCode(key) { + if (typeof key !== 'string') { + key = this.#elementToString(key); + } + const calcASCIIValue = (acc, char) => (acc * 33) + char.charCodeAt(0); + const hash = key.split('').reduce((acc, char) => calcASCIIValue, 5381); + return hash % 1013; + } + + hash(key) { + return this.#loseLoseHashCode(key); + } + + #elementToString(data) { + if (typeof data === 'object' && data !== null) { + return JSON.stringify(data); + } else { + return data.toString(); + } + } + + put(key, value) { + if (key != null && value != null) { + let index = this.hash(key); + + // linear probing to find an empty slot + while (this.#table[index] != null) { + if (this.#table[index].key === key) { + this.#table[index].value = value; // update existing key + return true; + } + index++; + index %= this.#table.length; // wrap around if end is reached + } + + this.#table[index] = {key, value}; + return true; + } + return false; + } + + get(key) { + let index = this.hash(key); + + // Linear probing to search for the key + while (this.#table[index] != null) { + if (this.#table[index].key === key) { + return this.#table[index].value; + } + index++; + index %= this.#table.length; + } + + return undefined; // key not found + } + + remove(key) { + let index = this.hash(key); + while (this.#table[index] != null) { + if (this.#table[index].key === key) { + delete this.#table[index]; + this.#verifyRemoveSideEffect(key, index); + return true; + } + index++; + index %= this.#table.length; + } + return false; // key not found + } + + #verifyRemoveSideEffect(key, removedPosition) { + const size = this.#table.length; + let index = removedPosition + 1; + while (this.#table[index] != null) { + const currentKey = this.#table[index].key; + const currentHash = this.hash(currentKey); + // check if the element should be repositioned + if (currentHash <= removedPosition) { + this.#table[removedPosition] = this.#table[index]; + delete this.#table[index]; + removedPosition = index; + } + index++; + index %= size; // Wrap around if end is reached + } + } +} diff --git a/src/08-dictionary-hash/hash-table-separate-chaining.js b/src/08-dictionary-hash/hash-table-separate-chaining.js new file mode 100644 index 00000000..f8567ecf --- /dev/null +++ b/src/08-dictionary-hash/hash-table-separate-chaining.js @@ -0,0 +1,83 @@ +// src/08-dictionary-hash/hash-table-separate-chaining.js + +const LinkedList = require('../06-linked-list/linked-list_'); + +class HashTableSeparateChaining { + #table = []; + + #loseLoseHashCode(key) { + if (typeof key !== 'string') { + key = this.#elementToString(key); + } + const hash = key.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); + return hash % 37; // mod to reduce the hash code + } + + hash(key) { + return this.#loseLoseHashCode(key); + } + + + put(key, value) { + if (key != null && value != null) { + const index = this.hash(key); // Get hash code (index) + + if (this.#table[index] == null) { + this.#table[index] = new LinkedList(); // Create linked list if needed + } + + this.#table[index].append({key, value}); // Append to linked list + return true; + } + return false; + } + + get(key) { + const index = this.hash(key); + const linkedList = this.#table[index]; + if (linkedList != null) { + linkedList.forEach((element) => { + if (element.key === key) { + return element.value; + } + }); + } + return undefined; // key not found + } + + remove(key) { + const index = this.hash(key); + const linkedList = this.#table[index]; + if (linkedList != null) { + const compareFunction = (a, b) => a.key === b.key; + const toBeRemovedIndex = linkedList.indexOf({key}, compareFunction); + if (toBeRemovedIndex >= 0) { + linkedList.removeAt(toBeRemovedIndex); + if (linkedList.isEmpty()) { + this.#table[index] = undefined; + } + return true; + } + } + return false; // key not found + } + + #elementToString(data) { + if (typeof data === 'object' && data !== null) { + return JSON.stringify(data); + } else { + return data.toString(); + } + } + + toString() { + const keys = Object.keys(this.#table); + let objString = `{${keys[0]} => ${this.#table[keys[0]].toString()}}`; + for (let i = 1; i < keys.length; i++) { + const value = this.#elementToString(this.#table[keys[i]]).toString(); + objString = `${objString}\n{${keys[i]} => ${value}}`; + } + return objString; + } + +} diff --git a/src/08-dictionary-hash/hash-table.js b/src/08-dictionary-hash/hash-table.js new file mode 100644 index 00000000..3833eb72 --- /dev/null +++ b/src/08-dictionary-hash/hash-table.js @@ -0,0 +1,67 @@ +// src/08-dictionary-hash/hash-table.js + +class HashTable { + + #table = []; + + #loseLoseHashCode(key) { + if (typeof key !== 'string') { + key = this.#elementToString(key); + } + const hash = key.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); + return hash % 37; // mod to reduce the hash code + } + + hash(key) { + return this.#loseLoseHashCode(key); + } + + put(key, value) { + if (key == null && value == null) { + return false; + } + const index = this.hash(key); + this.#table[index] = value; + return true; + } + + get(key) { + if (key == null) { + return undefined; + } + const index = this.hash(key); + return this.#table[index]; + } + + remove(key) { + if (key == null) { + return false; + } + const index = this.hash(key); + if (this.#table[index]) { + delete this.#table[index]; + return true; + } + return false; + } + + #elementToString(data) { + if (typeof data === 'object' && data !== null) { + return JSON.stringify(data); + } else { + return data.toString(); + } + } + + toString() { + const keys = Object.keys(this.#table); + let objString = `{${keys[0]} => ${this.#table[keys[0]].toString()}}`; + for (let i = 1; i < keys.length; i++) { + const value = this.#elementToString(this.#table[keys[i]]).toString(); + objString = `${objString}\n{${keys[i]} => ${value}}`; + } + return objString; + } +} + +module.exports = HashTable; \ No newline at end of file diff --git a/src/08-dictionary-hash/hash-table.ts b/src/08-dictionary-hash/hash-table.ts new file mode 100644 index 00000000..ce35f904 --- /dev/null +++ b/src/08-dictionary-hash/hash-table.ts @@ -0,0 +1,62 @@ +// src/08-dictionary-hash/hash-table.ts + +class HashTable { + + private table: V[] = []; + + #loseLoseHashCode(key: string) { + // if (typeof key !== 'string') { + // key = this.#elementToString(key); + // } + const calcASCIIValue = (acc, char) => acc + char.charCodeAt(0); + const hash = key.split('').reduce(calcASCIIValue, 0); + return hash % 37; + } + + hash(key: string) { + return this.#loseLoseHashCode(key); + } + + put(key: string, value: V) { + const index = this.hash(key); + this.table[index] = value; + return true; + } + + get(key: string): V { + const index = this.hash(key); + return this.table[index]; + } + + remove(key: string) { + if (key == null) { + return false; + } + const index = this.hash(key); + if (this.table[index]) { + delete this.table[index]; + return true; + } + return false; + } + + #elementToString(data: V) { + if (typeof data === 'object' && data !== null) { + return JSON.stringify(data); + } else { + return data.toString(); + } + } + + toString() { + const keys = Object.keys(this.table); + let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; + for (let i = 1; i < keys.length; i++) { + const value = this.#elementToString(this.table[keys[i]]).toString(); + objString = `${objString}\n{${keys[i]} => ${value}}`; + } + return objString; + } +} + +export default HashTable; \ No newline at end of file diff --git a/src/08-dictionary-hash/leetcode/integer-to-roman.ts b/src/08-dictionary-hash/leetcode/integer-to-roman.ts new file mode 100644 index 00000000..2d87cd43 --- /dev/null +++ b/src/08-dictionary-hash/leetcode/integer-to-roman.ts @@ -0,0 +1,38 @@ +// https://leetcode.com/problems/integer-to-roman/description/ + +// Time complexity: O(1) +function intToRoman(num: number): string { + // define map + const romanMap = { + M:1000, + CM:900, + D:500, + CD:400, + C:100, + XC:90, + L:50, + XL:40, + X:10, + IX:9, + V:5, + IV:4, + I:1 + }; + + let result = ''; + for(let romanNum in romanMap){ + while (num >= romanMap[romanNum]) { + result += romanNum; + num -= romanMap[romanNum]; + } + } + return result; +}; + +// Test cases +console.log(intToRoman(3)); // "III" +console.log(intToRoman(4)); // "IV" +console.log(intToRoman(9)); // "IX" +console.log(intToRoman(58)); // "LVIII" +console.log(intToRoman(1994)); // "MCMXCIV" +console.log(intToRoman(3999)); // "MMMCM" diff --git a/src/08-dictionary-hash/leetcode/two-sum.ts b/src/08-dictionary-hash/leetcode/two-sum.ts new file mode 100644 index 00000000..55638892 --- /dev/null +++ b/src/08-dictionary-hash/leetcode/two-sum.ts @@ -0,0 +1,30 @@ +// https://leetcode.com/problems/two-sum/ + +// Time complexity: O(n) +// Space complexity: O(n) +function twoSum(nums: number[], target: number): number[] { + const map = new Map(); + for (let i = 0; i < nums.length; i++) { + const diff = target - nums[i]; + if (map.has(diff)) { + return [map.get(diff)!, i]; + } + map.set(nums[i], i); + } + return []; +} + +// Test cases +console.log(twoSum([2, 7, 11, 15], 9)); // [0, 1] +console.log(twoSum([3, 2, 4], 6)); // [1, 2] +console.log(twoSum([3, 3], 6)); // [0, 1] + +function twoSum2(nums: number[], target: number): number[] { + for (let i=0; i { + if (answer.toLowerCase() === 'y') { // Base case + console.log("Excellent! You've grasped recursion."); + readline.close(); // Exit the program + } else { + console.log("Let's try again..."); + understandRecursion(); // Recursive call + } + }); +} + +understandRecursion(); + +// to see the output of this file use the command: node src/09-recursion/01-intro-recursion.js diff --git a/src/09-recursion/02-factorial.js b/src/09-recursion/02-factorial.js new file mode 100644 index 00000000..e42fa188 --- /dev/null +++ b/src/09-recursion/02-factorial.js @@ -0,0 +1,29 @@ +// src/09-recursion/02-factorial.js + +// iterative approach +function factorialIterative(number) { + if (number < 0) { + return undefined; + } + let total = 1; + for (let n = number; n > 1; n--) { + total *= n; + } + return total; +} + +console.log('5! =',factorialIterative(5)); // 5! = 120 + +// recursive approach +function factorial(number) { + // console.trace(); + if (number < 0) { return undefined; } + if (number === 1 || number === 0) { // base case + return 1; + } + return number * factorial(number - 1); +} + +console.log('Recursive 5! =',factorial(5)); // Recursive 5! = 120 + +// to see the output of this file use the command: node src/09-recursion/02-factorial.js \ No newline at end of file diff --git a/src/09-recursion/03-callstack.js b/src/09-recursion/03-callstack.js new file mode 100644 index 00000000..011c1e45 --- /dev/null +++ b/src/09-recursion/03-callstack.js @@ -0,0 +1,17 @@ +// src/09-recursion/03-callstack.js + +// stack overflow +let count = 0; +function recursiveFn() { + count++; + recursiveFn(); +} + +try { + recursiveFn(); +} catch (ex) { + console.log('count = ' + count + ' error: ' + ex); +} + + +// to see the output of this file use the command: node src/09-recursion/03-callstack.js \ No newline at end of file diff --git a/src/09-recursion/04-fibonacci.js b/src/09-recursion/04-fibonacci.js new file mode 100644 index 00000000..abfdf541 --- /dev/null +++ b/src/09-recursion/04-fibonacci.js @@ -0,0 +1,54 @@ +// src/09-recursion/04-fibonacci.js + +// iterative approach +function fibonacciIterative(n) { + if (n < 0) { + throw new Error('Input must be a non-negative integer'); + } + if (n < 2) { return n; } + + let prevPrev = 0; + let prev = 1; + let current; + + for (let i = 2; i <= n; i++) { // n >= 2 + current = prev + prevPrev; // f(n-1) + f(n-2) + prevPrev = prev; + prev = current; + } + + return current; +} + +console.log('fibonacciIterative(2)', fibonacciIterative(2)); // 1 +console.log('fibonacciIterative(3)', fibonacciIterative(3)); // 2 +console.log('fibonacciIterative(4)', fibonacciIterative(4)); // 3 +console.log('fibonacciIterative(5)', fibonacciIterative(5)); // 5 + +// recursive approach +function fibonacci(n) { + if (n < 0) { + throw new Error('Input must be a non-negative integer'); + } + if (n < 2) { return n; } // base case + return fibonacci(n - 1) + fibonacci(n - 2); // recursive case +} + +console.log('fibonacci(5)', fibonacci(5)); // 5 + +// memoization approach +function fibonacciMemoization(n) { + if (n < 0) { + throw new Error('Input must be a non-negative integer'); + } + const memo = [0, 1]; + const fibonacci = (n) => { + if (memo[n] != null) return memo[n]; + return memo[n] = fibonacci(n - 1) + fibonacci(n - 2); + }; + return fibonacci(n); +} + +console.log('fibonacciMemoization(5)', fibonacciMemoization(5)); // 5 + +// to see the output of this file use the command: node src/09-recursion/04-fibonacci.js \ No newline at end of file diff --git a/src/09-recursion/leetcode/fibonacci-number.ts b/src/09-recursion/leetcode/fibonacci-number.ts new file mode 100644 index 00000000..e0130034 --- /dev/null +++ b/src/09-recursion/leetcode/fibonacci-number.ts @@ -0,0 +1,17 @@ +// https://leetcode.com/problems/fibonacci-number/description/ + +function fib(n: number): number { + if (n < 2) { return n; } + + let prevPrev = 0; + let prev = 1; + let current; + + for (let i = 2; i <= n; i++) { // n >= 2 + current = prev + prevPrev; // f(n-1) + f(n-2) + prevPrev = prev; + prev = current; + } + + return current; +}; \ No newline at end of file diff --git a/src/09-recursion/leetcode/power-of-two.ts b/src/09-recursion/leetcode/power-of-two.ts new file mode 100644 index 00000000..bfbbdf22 --- /dev/null +++ b/src/09-recursion/leetcode/power-of-two.ts @@ -0,0 +1,43 @@ +// https://leetcode.com/problems/power-of-two/ + +// function isPowerOfTwo(n: number): boolean { +// if (n <= 0) { +// return false; +// } + +// return (n & (n - 1)) === 0; +// } + +// Time complexity: O(1) +// Space complexity: O(1) + +// Test cases + + +// recursive solution +function isPowerOfTwo(n: number): boolean { + if (n <= 0) { // edge case for negative numbers + return false; + } + if (n % 2 !== 0) { // edge case for odd numbers + return false; + } + + if (n === 1) { // base case + return true; + } + + return isPowerOfTwo(n / 2); +} + +// Time complexity: O(log n) +// Space complexity: O(log n) + +// Test cases +console.log(isPowerOfTwo(1)); // true +console.log(isPowerOfTwo(16)); // true +console.log(isPowerOfTwo(3)); // false +console.log(isPowerOfTwo(4)); // true +console.log(isPowerOfTwo(5)); // false +console.log(isPowerOfTwo(0)); // false +console.log(isPowerOfTwo(-1)); // false diff --git a/src/10-tree/01-bst.js b/src/10-tree/01-bst.js new file mode 100644 index 00000000..69fe9e12 --- /dev/null +++ b/src/10-tree/01-bst.js @@ -0,0 +1,38 @@ +// src/10-tree/01-bst.js +const BinarySearchTree = require('./binary-search-tree'); + +class Student { + constructor(idNumber, name, gradeLevel, address) { + this.idNumber = idNumber; + this.name = name; + this.gradeLevel = gradeLevel; + } +} + +// create student comparator to compare idNumber +const studentComparator = (a, b) => a.idNumber - b.idNumber; + +const studentTree = new BinarySearchTree(studentComparator); + +studentTree.insert(new Student(11, 'Darcy', 10)); +studentTree.insert(new Student(7, 'Tory', 10)); +studentTree.insert(new Student(5, 'Caleb', 10)); +studentTree.insert(new Student(9, 'Sofia', 10)); +studentTree.insert(new Student(15, 'Max', 10)); + +// 11 +// / \ +// 7 15 +// / \ +// 5 9 + +studentTree.insert(new Student(12, 'Seth', 10)); + +// 11 +// / \ +// 7 15 +// / \ / +// 5 9 12 + + +// to see the output of this file use the command: node src/10-tree/01-bst.js diff --git a/src/10-tree/02-in-order-traversal.js b/src/10-tree/02-in-order-traversal.js new file mode 100644 index 00000000..16fbd015 --- /dev/null +++ b/src/10-tree/02-in-order-traversal.js @@ -0,0 +1,42 @@ +// src/10-tree/02-in-order-traversal.js +const BinarySearchTree = require('./binary-search-tree'); + +class Student { + constructor(idNumber, firstName, lastName) { + this.idNumber = idNumber; + this.lastName = lastName; + this.firstName = firstName; + } +} + +// create student comparator to compare lastName using localCompare +const studentComparator = (a, b) => a.lastName.localeCompare(b.lastName); + +const studentTree = new BinarySearchTree(studentComparator); + +studentTree.insert(new Student(9, 'Sofia', 'Cygnus')); +studentTree.insert(new Student(12, 'Seth', 'Capella')); +studentTree.insert(new Student(11, 'Darcy', 'Vega')); +studentTree.insert(new Student(7, 'Tory', 'Vega')); +studentTree.insert(new Student(5, 'Caleb', 'Altair')); +studentTree.insert(new Student(15, 'Max', 'Rigel')); + + +// in order traversal +const classRoster = []; +const addToRoster = (studentData) => { + classRoster.push(`${studentData.idNumber}: ${studentData.lastName}, ${studentData.firstName}`); +} +studentTree.inOrderTraverse(addToRoster); + +console.log(classRoster); +// [ +// '5: Altair, Caleb', +// '12: Capella, Seth', +// '9: Cygnus, Sofia', +// '15: Rigel, Max', +// '11: Vega, Darcy', +// '7: Vega, Tory' +// ] + +// to see the output of this file use the command: node src/10-tree/02-in-order-traversal.js \ No newline at end of file diff --git a/src/10-tree/03-pre-order-traversal.js b/src/10-tree/03-pre-order-traversal.js new file mode 100644 index 00000000..a84e0689 --- /dev/null +++ b/src/10-tree/03-pre-order-traversal.js @@ -0,0 +1,53 @@ +// src/10-tree/03-pre-order-traversal.js +const BinarySearchTree = require('./binary-search-tree'); + +class Employee { + constructor(id, name, title) { + this.id = id; + this.name = name; + this.title = title; + } +} + +// create title constant +const TITLE = { + CEO: 1, + VP: 2, + MANAGER: 3, + STAFF: 4 +} + +// create employee comparator to compare title +const employeeComparator = (a, b) => a.id - b.id; + +const employeeTree = new BinarySearchTree(employeeComparator); + +employeeTree.insert(new Employee(10, 'Gandalf', TITLE.CEO)); +employeeTree.insert(new Employee(5, 'Frodo', TITLE.VP)); +employeeTree.insert(new Employee(3,'Legolas', TITLE.MANAGER)); +employeeTree.insert(new Employee(1, 'Aragorn', TITLE.STAFF)); +employeeTree.insert(new Employee(4, 'Gimli', TITLE.STAFF)); + +employeeTree.insert(new Employee(14, 'Arya', TITLE.VP)); +employeeTree.insert(new Employee(12, 'John', TITLE.MANAGER)); +employeeTree.insert(new Employee(11, 'Brienne', TITLE.STAFF)); +employeeTree.insert(new Employee(13, 'Tyrion', TITLE.STAFF)); + +// pre order traversal +const sendEmergencyNotification = (employee, message) => { + console.log(`Notifying ${employee.name}: ${message}`); +} +const emergencyMessage = 'Tornado warning in the area. Seek shelter immediately!'; +employeeTree.preOrderTraverse((node) => sendEmergencyNotification(node, emergencyMessage)); + +// Notifying Gandalf: Tornado warning in the area. Seek shelter immediately! +// Notifying Frodo: Tornado warning in the area. Seek shelter immediately! +// Notifying Legolas: Tornado warning in the area. Seek shelter immediately! +// Notifying Arya: Tornado warning in the area. Seek shelter immediately! +// Notifying Aragorn: Tornado warning in the area. Seek shelter immediately! +// Notifying John: Tornado warning in the area. Seek shelter immediately! +// Notifying Gimli: Tornado warning in the area. Seek shelter immediately! +// Notifying Brienne: Tornado warning in the area. Seek shelter immediately! +// Notifying Tyrion: Tornado warning in the area. Seek shelter immediately! + +// to see the output of this file use the command: node src/10-tree/03-pre-order-traversal.js diff --git a/src/10-tree/04-post-order-traversal.js b/src/10-tree/04-post-order-traversal.js new file mode 100644 index 00000000..ef1fdaf6 --- /dev/null +++ b/src/10-tree/04-post-order-traversal.js @@ -0,0 +1,34 @@ +// src/10-tree/04-post-order-traversal.js +const BinarySearchTree = require('./binary-search-tree'); + +class FileOrDirectory { + constructor(name, isDirectory, size = 0) { + this.name = name; + this.isDirectory = isDirectory; // true for directory, false for file + } +} +const fileDirectoryComparator = (a, b) => a.name.localeCompare(b.name); + +const fileSystemTree = new BinarySearchTree(fileDirectoryComparator); +fileSystemTree.insert(new FileOrDirectory('Project', true)); +fileSystemTree.insert(new FileOrDirectory('Documents', true)); +fileSystemTree.insert(new FileOrDirectory('Code', true)); +fileSystemTree.insert(new FileOrDirectory('notes.txt', false)); +fileSystemTree.insert(new FileOrDirectory('design.pdf', false)); +fileSystemTree.insert(new FileOrDirectory('app.js', false)); + + +// post order traversal +const deleteFileOrDirectory = (fileDirectory) => { + console.log(`Deleting ${fileDirectory.name}`); +} +fileSystemTree.postOrderTraverse(deleteFileOrDirectory); + +// Deleting app.js +// Deleting design.pdf +// Deleting Code +// Deleting notes.txt +// Deleting Documents +// Deleting Project + +// to see the output of this file use the command: node src/10-tree/04-post-order-traversal.js \ No newline at end of file diff --git a/src/10-tree/05-avl.js b/src/10-tree/05-avl.js new file mode 100644 index 00000000..731d155f --- /dev/null +++ b/src/10-tree/05-avl.js @@ -0,0 +1,36 @@ +// src/10-tree/05-avl.js + +const AVLTree = require('./avl-tree'); + +class Student { + constructor(idNumber, name, gradeLevel, address) { + this.idNumber = idNumber; + this.name = name; + this.gradeLevel = gradeLevel; + } + toString() { + return `${this.idNumber} - ${this.name}`; + } +} + +// create student comparator to compare idNumber +const studentComparator = (a, b) => a.idNumber - b.idNumber; + +const studentTree = new AVLTree(studentComparator); + +studentTree.insert(new Student(11, 'Darcy', 10)); +studentTree.insert(new Student(7, 'Tory', 10)); +studentTree.insert(new Student(5, 'Caleb', 10)); +studentTree.insert(new Student(9, 'Sofia', 10)); +studentTree.insert(new Student(15, 'Max', 10)); +studentTree.insert(new Student(13, 'Geraldine', 10)); +studentTree.insert(new Student(12, 'Seth', 10)); + + +// 11 +// / \ +// 7 13 +// / \ / \ +// 5 9 12 15 + +// to see the output of this file use the command: node src/10-tree/05-avl.js \ No newline at end of file diff --git a/src/10-tree/06-red-black.js b/src/10-tree/06-red-black.js new file mode 100644 index 00000000..f660c91e --- /dev/null +++ b/src/10-tree/06-red-black.js @@ -0,0 +1,35 @@ +// src/10-tree/06-red-black.js + +const RedBlackTree = require('./red-black-tree'); + +class Student { + constructor(idNumber, name, gradeLevel, address) { + this.idNumber = idNumber; + this.name = name; + this.gradeLevel = gradeLevel; + } + toString() { + return `${this.idNumber} - ${this.name}`; + } +} + +// create student comparator to compare idNumber +const studentComparator = (a, b) => a.idNumber - b.idNumber; + +const studentTree = new RedBlackTree(studentComparator); + +studentTree.insert(new Student(11, 'Darcy', 10)); +studentTree.insert(new Student(7, 'Tory', 10)); +studentTree.insert(new Student(5, 'Caleb', 10)); +studentTree.insert(new Student(9, 'Sofia', 10)); +studentTree.insert(new Student(15, 'Max', 10)); +studentTree.insert(new Student(13, 'Geraldine', 10)); +studentTree.insert(new Student(12, 'Seth', 10)); + +studentTree.print(); + +// console.log('--- Removing 7'); +// studentTree.remove(new Student(7, 'Tory', 10)); +// studentTree.print(); + +// to see the output of this file use the command: node src/10-tree/06-red-black.js \ No newline at end of file diff --git a/src/10-tree/avl-tree.js b/src/10-tree/avl-tree.js new file mode 100644 index 00000000..a0b99884 --- /dev/null +++ b/src/10-tree/avl-tree.js @@ -0,0 +1,173 @@ +// src/10-tree/avl-tree.js +const Comparator = require('./comparator'); +const BinarySearchTree = require('./binary-search-tree'); + +const BalanceFactor = { + UNBALANCED_RIGHT: 1, + SLIGHTLY_UNBALANCED_RIGHT: 2, + BALANCED: 3, + SLIGHTLY_UNBALANCED_LEFT: 4, + UNBALANCED_LEFT: 5 +}; + +class AVLNode { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + this.height = 1; + } +} + +class AVLTree extends BinarySearchTree { + #root; + #compareFn; + + constructor(compareFn = Comparator.defaultCompareFn) { + super(compareFn); + this.#compareFn = new Comparator(compareFn); + this.#root = null; + } + + insert(data) { + this.#root = this.#insertNode(data, this.#root); + } + + #insertNode(data, currentNode) { + if (!currentNode) { + return new AVLNode(data); + } + + if (this.#compareFn.lessThan(data, currentNode.data)) { + currentNode.left = this.#insertNode(data, currentNode.left); + } else { + currentNode.right = this.#insertNode(data, currentNode.right); + } + + currentNode.height = this.#updateNodeHeight(currentNode); + + return this.#balance(currentNode); + } + + #updateNodeHeight(node) { + return 1 + Math.max(this.#getHeight(node.left), this.#getHeight(node.right)); + } + + #getHeight(node) { + return node ? node.height : 0; + } + + #getBalanceFactor(node) { + const heightDifference = this.#getHeight(node.left) - this.#getHeight(node.right); + switch (heightDifference) { + case -2: return BalanceFactor.UNBALANCED_RIGHT; + case -1: return BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT; + case 1: return BalanceFactor.SLIGHTLY_UNBALANCED_LEFT; + case 2: return BalanceFactor.UNBALANCED_LEFT; + default: return BalanceFactor.BALANCED; + } + } + + #balance(node) { + const balanceFactor = this.#getBalanceFactor(node); + if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) { + const leftChildBalanceFactor = this.#getBalanceFactor(node.left); + if (leftChildBalanceFactor === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT) { + return this.#rotateRight(node); + } else { + return this.#rotateLeftRight(node); + } + } else if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) { + const rightChildBalanceFactor = this.#getBalanceFactor(node.right); + if (rightChildBalanceFactor === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT) { + return this.#rotateLeft(node); + } else { + return this.#rotateRightLeft(node); + } + } + return node; + } + + #rotateRight(node) { + const newRoot = node.left; // Identify the pivot (left child) + const temp = newRoot.right; // Store the right child temporarily + + // Perform the rotation + newRoot.right = node; + node.left = temp; + + // Update heights of the affected nodes + node.height = this.#updateNodeHeight(node); + newRoot.height = this.#updateNodeHeight(newRoot); + + return newRoot; // Return the new root of the subtree + } + + #rotateLeft(node) { + const newRoot = node.right; // Identify the pivot (right child) + const temp = newRoot.left; // Store the left child temporarily + + newRoot.left = node; // Perform the rotation + node.right = temp; + + node.height = this.#updateNodeHeight(node); + newRoot.height = this.#updateNodeHeight(newRoot); + return newRoot; + } + + #rotateLeftRight(node) { + node.left = this.#rotateLeft(node.left); // First, rotate left on the left child + return this.#rotateRight(node); // Then, rotate right on the original node + } + + #rotateRightLeft(node) { + node.right = this.#rotateRight(node.right); // Rotate right on the right child + return this.#rotateLeft(node); // Then, rotate left on the original node + } + + remove(data) { + this.#root = this.#removeNode(data, this.#root); + } + + #removeNode(data, currentNode) { + if (!currentNode) { + return null; + } + + if (this.#compareFn.lessThan(data, currentNode.data)) { + currentNode.left = this.#removeNode(data, currentNode.left); + } else if (this.#compareFn.greaterThan(data, currentNode.data)) { + currentNode.right = this.#removeNode(data, currentNode.right); + } else { + if (!currentNode.left && !currentNode.right) { + return null; + } + + if (!currentNode.left) { + return currentNode.right; + } + + if (!currentNode.right) { + return currentNode.left; + } + + const minNode = this.#findMinNode(currentNode.right); + currentNode.data = minNode.data; + currentNode.right = this.#removeNode(minNode.data, currentNode.right); + } + + currentNode.height = this.#updateNodeHeight(currentNode); + + return this.#balance(currentNode); + } + + #findMinNode(node) { + if (!node.left) { + return node; + } + return this.#findMinNode(node.left); + } + +} + +module.exports = AVLTree; \ No newline at end of file diff --git a/src/10-tree/binary-search-tree.js b/src/10-tree/binary-search-tree.js new file mode 100644 index 00000000..598b73e7 --- /dev/null +++ b/src/10-tree/binary-search-tree.js @@ -0,0 +1,171 @@ +// src/10-tree/binary-search-tree.js + +const Comparator = require('./comparator'); + +class BSTNode { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + +class BinarySearchTree { + #root; + #compareFn; + + constructor(compareFn = Comparator.defaultCompareFn) { + this.#compareFn = new Comparator(compareFn); + this.#root = null; + } + + insert(data) { + if (!this.#root) { + this.#root = new BSTNode(data); + } else { + this.#insertNode(data, this.#root); + } + } + + #insertNode(data, currentNode) { + if (this.#compareFn.lessThan(data, currentNode.data)) { + if (!currentNode.left) { + currentNode.left = new BSTNode(data); + } else { + this.#insertNode(data, currentNode.left); + } + } else { + if (!currentNode.right) { + currentNode.right = new BSTNode(data); + } else { + this.#insertNode(data, currentNode.right); + } + } + } + + search(data) { + return this.#searchNode(data, this.#root); + } + + #searchNode(data, currentNode) { + if (!currentNode) { + return false; + } + + if (this.#compareFn.equal(data, currentNode.data)) { + return true; + } + + if (this.#compareFn.lessThan(data, currentNode.data)) { + return this.#searchNode(data, currentNode.left); + } else { + return this.#searchNode(data, currentNode.right); + } + } + + remove(data) { + this.#root = this.#removeNode(data, this.#root); + } + + #removeNode(data, currentNode) { + if (!currentNode) { + return null; + } + + if (this.#compareFn.lessThan(data, currentNode.data)) { + currentNode.left = this.#removeNode(data, currentNode.left); + return currentNode; + } else if (this.#compareFn.greaterThan(data, currentNode.data)) { + currentNode.right = this.#removeNode(data, currentNode.right); + return currentNode; + } else { + if (!currentNode.left && !currentNode.right) { + return null; + } + + if (!currentNode.left) { + return currentNode.right; + } + + if (!currentNode.right) { + return currentNode.left; + } + + const minNode = this.#findMinNode(currentNode.right); + currentNode.data = minNode.data; + currentNode.right = this.#removeNode(minNode.data, currentNode.right); + return currentNode; + } + } + + min() { + if (!this.#root) { + return null; + } + return this.#findMinNode(this.#root).data; + } + + #findMinNode(node) { + if (!node.left) { + return node; + } + return this.#findMinNode(node.left); + } + + max() { + if (!this.#root) { + return null; + } + return this.#findMaxNode(this.#root).data; + } + + #findMaxNode(node) { + if (!node.right) { + return node; + } + return this.#findMaxNode(node.right); + } + + get root() { + return this.#root; + } + + inOrderTraverse(callback) { + this.#inOrderTraverseNode(this.#root, callback); + } + + #inOrderTraverseNode(node, callback) { + if (node) { + this.#inOrderTraverseNode(node.left, callback); + callback(node.data); + this.#inOrderTraverseNode(node.right, callback); + } + } + + preOrderTraverse(callback) { + this.#preOrderTraverseNode(this.#root, callback); + } + + #preOrderTraverseNode(node, callback) { + if (node) { + callback(node.data); + this.#preOrderTraverseNode(node.left, callback); + this.#preOrderTraverseNode(node.right, callback); + } + } + + postOrderTraverse(callback) { + this.#postOrderTraverseNode(this.#root, callback); + } + + #postOrderTraverseNode(node, callback) { + if (node) { + this.#postOrderTraverseNode(node.left, callback); + this.#postOrderTraverseNode(node.right, callback); + callback(node.data); + } + } + +} + +module.exports = BinarySearchTree; \ No newline at end of file diff --git a/src/10-tree/comparator.js b/src/10-tree/comparator.js new file mode 100644 index 00000000..5f718e7b --- /dev/null +++ b/src/10-tree/comparator.js @@ -0,0 +1,33 @@ +// src/10-tree/comparator.js + +const Compare = require('./compare'); + +class Comparator { + #compareFn; + + constructor(compareFn = Comparator.defaultCompareFn) { + this.#compareFn = compareFn; + } + + static defaultCompareFn(a, b) { + if (a === b) { + return Compare.EQUALS; + } + return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN; + } + + equal(a, b) { + return this.#compareFn(a, b) === Compare.EQUALS; + } + + lessThan(a, b) { + return this.#compareFn(a, b) < Compare.EQUALS; + } + + greaterThan(a, b) { + return this.#compareFn(a, b) > Compare.EQUALS; + } + +} + +module.exports = Comparator; \ No newline at end of file diff --git a/src/10-tree/compare.js b/src/10-tree/compare.js new file mode 100644 index 00000000..9a23bee0 --- /dev/null +++ b/src/10-tree/compare.js @@ -0,0 +1,7 @@ +const Compare = { + LESS_THAN: -1, + BIGGER_THAN: 1, + EQUALS: 0 +}; + +module.exports = Compare; \ No newline at end of file diff --git a/src/10-tree/fenwick-tree.js b/src/10-tree/fenwick-tree.js new file mode 100644 index 00000000..342df8db --- /dev/null +++ b/src/10-tree/fenwick-tree.js @@ -0,0 +1,46 @@ +// Binary Indexed Tree (Fenwick Tree) +class FenwickTree { + #arraySize; + #tree; + + constructor(arraySize) { + this.#arraySize = arraySize; + this.#tree = Array(arraySize + 1).fill(0); + } + + update(index, value) { + if (index < 1 || index > this.#arraySize) { + throw new Error('Index is out of range'); + } + + for (let i = index; i <= this.#arraySize; i += this.#lowBit(i)) { + this.#tree[i] += value; + } + } + + query(index) { + if (index < 1 || index > this.#arraySize) { + throw new Error('Index is out of range'); + } + + let sum = 0; + + for (let i = index; i > 0; i -= this.#lowBit(i)) { + sum += this.#tree[i]; + } + + return sum; + } + + #lowBit(x) { + return x & -x; + } + + get arraySize() { + return this.#arraySize; + } + + toString() { + return this.#tree.join(', '); + } +} \ No newline at end of file diff --git a/src/10-tree/leetcode/binary-tree-inorder-traversal.ts b/src/10-tree/leetcode/binary-tree-inorder-traversal.ts new file mode 100644 index 00000000..896b547d --- /dev/null +++ b/src/10-tree/leetcode/binary-tree-inorder-traversal.ts @@ -0,0 +1,38 @@ +// https://leetcode.com/problems/binary-tree-inorder-traversal/ +// 94. Binary Tree Inorder Traversal + +class TreeNode { + val: number + left: TreeNode | null + right: TreeNode | null + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = (val === undefined ? 0 : val) + this.left = (left === undefined ? null : left) + this.right = (right === undefined ? null : right) + } +} + +function inorderTraversal(root: TreeNode | null): number[] { + // Recursive + //if (!root) return []; + //return [...inorderTraversal(root.left), root.val, ...inorderTraversal(root.right)]; + + // Iterative + const stack: TreeNode[] = []; + const result: number[] = []; + let current = root; + while (stack.length !== 0 || current !== null) { + if (current) { + stack.push(current) + current = current.left; + } else { + current = stack.pop(); + result.push(current.val); + current = current.right; + } + } + return result; +}; + +// Time complexity: O(n) +// Space complexity: O(n) (worst case) - O(log n) (average case) diff --git a/src/10-tree/leetcode/binary-tree-postorder-traversal.ts b/src/10-tree/leetcode/binary-tree-postorder-traversal.ts new file mode 100644 index 00000000..549af7fa --- /dev/null +++ b/src/10-tree/leetcode/binary-tree-postorder-traversal.ts @@ -0,0 +1,43 @@ +// https://leetcode.com/problems/binary-tree-postorder-traversal/description/ +// 145. Binary Tree Postorder Traversal + +class TreeNode { + val: number + left: TreeNode | null + right: TreeNode | null + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = (val === undefined ? 0 : val) + this.left = (left === undefined ? null : left) + this.right = (right === undefined ? null : right) + } +} + +function postorderTraversal(root: TreeNode | null): number[] { + // Recursive + //if (!root) return []; + //return [...postorderTraversal(root.left), ...postorderTraversal(root.right), root.val]; + + // Iterative + const stack: TreeNode[] = []; + const result: number[] = []; + let current = root; + let lastVisited: TreeNode | null = null; + while (stack.length !== 0 || current !== null) { + if (current) { + stack.push(current) + current = current.left; + } else { + const peek = stack[stack.length - 1]; + if (peek.right && peek.right !== lastVisited) { + current = peek.right; + } else { + result.push(peek.val); + lastVisited = stack.pop(); + } + } + } + return result; +}; + +// Time complexity: O(n) +// Space complexity: O(n) (worst case) - O(log n) (average case) \ No newline at end of file diff --git a/src/10-tree/leetcode/binary-tree-preorder-traversal.ts b/src/10-tree/leetcode/binary-tree-preorder-traversal.ts new file mode 100644 index 00000000..fd403226 --- /dev/null +++ b/src/10-tree/leetcode/binary-tree-preorder-traversal.ts @@ -0,0 +1,37 @@ +// https://leetcode.com/problems/binary-tree-preorder-traversal/ +// 144. Binary Tree Preorder Traversal + +class TreeNode { + val: number + left: TreeNode | null + right: TreeNode | null + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = (val === undefined ? 0 : val) + this.left = (left === undefined ? null : left) + this.right = (right === undefined ? null : right) + } +} + +function preorderTraversal(root: TreeNode | null): number[] { + // Recursive + //if (!root) return []; + //return [root.val, ...preorderTraversal(root.left), ...preorderTraversal(root.right)]; + + // Iterative + const stack: TreeNode[] = []; + const result: number[] = []; + let current = root; + while (stack.length !== 0 || current !== null) { + if (current) { + result.push(current.val); + if (current.right) stack.push(current.right); + current = current.left; + } else { + current = stack.pop(); + } + } + return result; +}; + +// Time complexity: O(n) +// Space complexity: O(n) (worst case) - O(log n) (average case) \ No newline at end of file diff --git a/src/10-tree/leetcode/convert-sorted-array-to-binary-search-tree.ts b/src/10-tree/leetcode/convert-sorted-array-to-binary-search-tree.ts new file mode 100644 index 00000000..26d08878 --- /dev/null +++ b/src/10-tree/leetcode/convert-sorted-array-to-binary-search-tree.ts @@ -0,0 +1,22 @@ +// https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/ +// 108. Convert Sorted Array to Binary Search Tree + +class TreeNode { + val: number + left: TreeNode | null + right: TreeNode | null + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = (val === undefined ? 0 : val) + this.left = (left === undefined ? null : left) + this.right = (right === undefined ? null : right) + } +} + +function sortedArrayToBST(nums: number[]): TreeNode | null { + if (nums.length === 0) return null; + const mid = Math.floor(nums.length / 2); + const root = new TreeNode(nums[mid]); + root.left = sortedArrayToBST(nums.slice(0, mid)); + root.right = sortedArrayToBST(nums.slice(mid + 1)); + return root; +} \ No newline at end of file diff --git a/src/10-tree/leetcode/maximum-depth-of-binary-tree.ts b/src/10-tree/leetcode/maximum-depth-of-binary-tree.ts new file mode 100644 index 00000000..836f6d85 --- /dev/null +++ b/src/10-tree/leetcode/maximum-depth-of-binary-tree.ts @@ -0,0 +1,18 @@ +// https://leetcode.com/problems/maximum-depth-of-binary-tree/description/ +// 104. Maximum Depth of Binary Tree + +class TreeNode { + val: number + left: TreeNode | null + right: TreeNode | null + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = (val === undefined ? 0 : val) + this.left = (left === undefined ? null : left) + this.right = (right === undefined ? null : right) + } +} + +function maxDepth(root: TreeNode | null): number { + if (!root) return 0; + return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); +} \ No newline at end of file diff --git a/src/10-tree/leetcode/minimum-depth-of-binary-tree.ts b/src/10-tree/leetcode/minimum-depth-of-binary-tree.ts new file mode 100644 index 00000000..6c49738f --- /dev/null +++ b/src/10-tree/leetcode/minimum-depth-of-binary-tree.ts @@ -0,0 +1,21 @@ +// https://leetcode.com/problems/minimum-depth-of-binary-tree/description/ +// 111. Minimum Depth of Binary Tree + +class TreeNode { + val: number + left: TreeNode | null + right: TreeNode | null + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = (val === undefined ? 0 : val) + this.left = (left === undefined ? null : left) + this.right = (right === undefined ? null : right) + } +} + +function minDepth(root: TreeNode | null): number { + if (!root) return 0; + if (!root.left && !root.right) return 1; + if (!root.left) return 1 + minDepth(root.right); + if (!root.right) return 1 + minDepth(root.left); + return 1 + Math.min(minDepth(root.left), minDepth(root.right)); +} \ No newline at end of file diff --git a/src/10-tree/leetcode/validate-binary-search-tree.ts b/src/10-tree/leetcode/validate-binary-search-tree.ts new file mode 100644 index 00000000..ea38c6a5 --- /dev/null +++ b/src/10-tree/leetcode/validate-binary-search-tree.ts @@ -0,0 +1,25 @@ +// https://leetcode.com/problems/validate-binary-search-tree/description/ +// 98. Validate Binary Search Tree + +class TreeNode { + val: number + left: TreeNode | null + right: TreeNode | null + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = (val === undefined ? 0 : val) + this.left = (left === undefined ? null : left) + this.right = (right === undefined ? null : right) + } +} + +function isValidBST(root: TreeNode | null): boolean { + return isValid(root, null, null); +} + +function isValid(node: TreeNode | null, min: number | null, max: number | null): boolean { + if (!node) return true; + if (min !== null && node.val <= min) return false; + if (max !== null && node.val >= max) return false; + return isValid(node.left, min, node.val) && isValid(node.right, node.val, max); +} + diff --git a/src/10-tree/red-black-tree.js b/src/10-tree/red-black-tree.js new file mode 100644 index 00000000..2b207d77 --- /dev/null +++ b/src/10-tree/red-black-tree.js @@ -0,0 +1,250 @@ +// src/10-tree/red-black-tree.js + +const Comparator = require('./comparator'); +const BinarySearchTree = require('./binary-search-tree'); + +const NodeColor = { + RED: 0, + BLACK: 1, +}; + +class RedBlackNode { + constructor(data) { + this.data = data; + this.color = NodeColor.RED; + this.left = null; + this.right = null; + this.parent = null; + } + isRed() { + return this.color === NodeColor.RED; + } +} + +class RedBlackTree extends BinarySearchTree { + #root; + #compareFn; + + constructor(compareFn = Comparator.defaultCompareFn) { + super(compareFn); + this.#compareFn = new Comparator(compareFn); + this.#root = null; + } + + + // Insert a node + insert(data) { + if (this.#root) { + const newNode = this.#insertNode(this.#root, data); + this.#fixTreeProperties(newNode); + } else { + this.#root = new RedBlackNode(data); + this.#root.color = NodeColor.BLACK; + } + } + + #insertNode(node, data) { + if (this.#compareFn.lessThan(data, node.data)) { + if (!node.left) { + node.left = new RedBlackNode(data); + node.left.parent = node; + return node.left; + } else { + return this.#insertNode(node.left, data); + } + } else { + if (!node.right) { + node.right = new RedBlackNode(data); + node.right.parent = node; + return node.right; + } else { + return this.#insertNode(node.right, data); + } + } + } + + #fixTreeProperties(node) { + while (node && node !== this.#root && node.isRed() && node.parent.isRed()) { + let parent = node.parent; + let grandParent = parent.parent; + + // case A: parent is left child of grand parent + if (parent === grandParent.left) { + const uncle = grandParent.right; + // case 1: uncle is red - only recoloring + if (uncle && uncle.isRed()) { + this.#flipColors(grandParent, parent, uncle); + node = grandParent; + } else { + // case 2: node is right child of parent - left rotate + if (node === parent.right) { + this.#rotateLeft(parent); + node = parent; + parent = node.parent; + } + // case 3: node is left child of parent - right rotate + this.#rotateRight(grandParent); + [parent.color, grandParent.color] = [grandParent.color, parent.color]; + node = parent; + } + } else { // case B: parent is right child of grand parent + const uncle = grandParent.left; + + // case 1: uncle is red - only recoloring + if (uncle && uncle.isRed()) { + this.#flipColors(grandParent, parent, uncle); + node = grandParent; + } else { + // case 2: node is left child of parent + if (node === parent.left) { + this.#rotateRight(parent); + node = parent; + parent = node.parent; + } + + // case 3: node is right child of parent + this.#rotateLeft(grandParent); + [parent.color, grandParent.color] = [grandParent.color, parent.color]; + node = parent; + } + } + } + this.#root.color = NodeColor.BLACK; // root should always be black + } + + #flipColors(grandParent, parent, uncle) { + grandParent.color = NodeColor.RED; + parent.color = NodeColor.BLACK; + uncle.color = NodeColor.BLACK; + } + + #rotateLeft(node) { + const newRoot = node.right; + node.right = newRoot.left; + + if (newRoot.left) { + newRoot.left.parent = node; + } + + newRoot.parent = node.parent; + + if (!node.parent) { + this.#root = newRoot; + } else if (node === node.parent.left) { + node.parent.left = newRoot; + } else { + node.parent.right = newRoot; + } + + newRoot.left = node; + node.parent = newRoot; + } + + #rotateRight(node) { + const newRoot = node.left; + node.left = newRoot.right; + + if (newRoot.right) { + newRoot.right.parent = node; + } + + newRoot.parent = node.parent; + + if (!node.parent) { + this.#root = newRoot; + } else if (node === node.parent.right) { + node.parent.right = newRoot; + } else { + node.parent.left = newRoot; + } + + newRoot.right = node; + node.parent = newRoot; + } + + remove(data) { + this.#root = this.#removeNode(data, this.#root); + } + + #removeNode(data, currentNode) { + if (!currentNode) { + return null; + } + + if (this.#compareFn.lessThan(data, currentNode.data)) { + currentNode.left = this.#removeNode(data, currentNode.left); + } else if (this.#compareFn.greaterThan(data, currentNode.data)) { + currentNode.right = this.#removeNode(data, currentNode.right); + } else { + if (!currentNode.left && !currentNode.right) { + return null; + } + + if (!currentNode.left) { + return currentNode.right; + } + + if (!currentNode.right) { + return currentNode.left; + } + + const minNode = this.#findMinNode(currentNode.right); + currentNode.data = minNode.data; + currentNode.right = this.#removeNode(minNode.data, currentNode.right); + } + + return this.#balance(currentNode); + } + + #findMinNode(node) { + if (!node.left) { + return node; + } + return this.#findMinNode(node.left); + } + + #balance(node) { + if (node.isRed()) { + return node; + } + + if (node.left && node.left.isRed()) { + if (node.left.left && node.left.left.isRed()) { + return this.#rotateRight(node); + } + + if (node.left.right && node.left.right.isRed()) { + node.left = this.#rotateLeft(node.left); + return this.#rotateRight(node); + } + } + + if (node.right && node.right.isRed()) { + if (node.right.right && node.right.right.isRed()) { + return this.#rotateLeft(node); + } + + if (node.right.left && node.right.left.isRed()) { + node.right = this.#rotateRight(node.right); + return this.#rotateLeft(node); + } + } + + return node; + } + + printInorder(node) { + if (node === null) { + return; + } + this.printInorder(node.left); + console.log(node.data, node.color); + this.printInorder(node.right); + } + + print() { + this.printInorder(this.#root); + } +} + +module.exports = RedBlackTree; \ No newline at end of file diff --git a/src/10-tree/segment-tree.js b/src/10-tree/segment-tree.js new file mode 100644 index 00000000..3bcc929a --- /dev/null +++ b/src/10-tree/segment-tree.js @@ -0,0 +1,86 @@ + +class SegmentTree { + #inputArray; + #segmentTree; + #operationFallback; + + constructor(inputArray, operationFallback) { + this.#inputArray = inputArray; + this.#operationFallback = operationFallback; + this.#segmentTree = Array(inputArray.length * 4).fill(0); + + this.#build(0, 0, inputArray.length - 1); + } + + #build(currentIndex, leftIndex, rightIndex) { + if (leftIndex === rightIndex) { + this.#segmentTree[currentIndex] = this.#inputArray[leftIndex]; + return; + } + + const middleIndex = Math.floor((leftIndex + rightIndex) / 2); + const leftChildIndex = 2 * currentIndex + 1; + const rightChildIndex = 2 * currentIndex + 2; + + this.#build(leftChildIndex, leftIndex, middleIndex); + this.#build(rightChildIndex, middleIndex + 1, rightIndex); + + this.#segmentTree[currentIndex] = this.#operationFallback( + this.#segmentTree[leftChildIndex], + this.#segmentTree[rightChildIndex] + ); + } + + query(leftIndex, rightIndex) { + return this.#query(0, 0, this.#inputArray.length - 1, leftIndex, rightIndex); + } + + #query(currentIndex, leftIndex, rightIndex, queryLeftIndex, queryRightIndex) { + if (queryLeftIndex > rightIndex || queryRightIndex < leftIndex) { + return 0; + } + + if (queryLeftIndex <= leftIndex && queryRightIndex >= rightIndex) { + return this.#segmentTree[currentIndex]; + } + + const middleIndex = Math.floor((leftIndex + rightIndex) / 2); + const leftChildIndex = 2 * currentIndex + 1; + const rightChildIndex = 2 * currentIndex + 2; + + return this.#operationFallback( + this.#query(leftChildIndex, leftIndex, middleIndex, queryLeftIndex, queryRightIndex), + this.#query(rightChildIndex, middleIndex + 1, rightIndex, queryLeftIndex, queryRightIndex) + ); + } + + update(index, value) { + this.#update(0, 0, this.#inputArray.length - 1, index, value); + } + + #update(currentIndex, leftIndex, rightIndex, index, value) { + if (leftIndex === rightIndex) { + this.#segmentTree[currentIndex] = value; + return; + } + + const middleIndex = Math.floor((leftIndex + rightIndex) / 2); + const leftChildIndex = 2 * currentIndex + 1; + const rightChildIndex = 2 * currentIndex + 2; + + if (index <= middleIndex) { + this.#update(leftChildIndex, leftIndex, middleIndex, index, value); + } else { + this.#update(rightChildIndex, middleIndex + 1, rightIndex, index, value); + } + + this.#segmentTree[currentIndex] = this.#operationFallback( + this.#segmentTree[leftChildIndex], + this.#segmentTree[rightChildIndex] + ); + } + + toString() { + return this.#segmentTree.join(', '); + } +} \ No newline at end of file diff --git a/src/11-heap/01-min-heap.js b/src/11-heap/01-min-heap.js new file mode 100644 index 00000000..61d03ab8 --- /dev/null +++ b/src/11-heap/01-min-heap.js @@ -0,0 +1,43 @@ +// src/11-heap/01-min-heap.js + +const Heap = require('./heap'); + +class Task { + constructor(id, priority, executionTime) { + this.id = id; + this.priority = priority; + this.executionTime = executionTime; + } +} + +class TaskScheduler { + constructor() { + this.taskQueue = new Heap((a,b) => a.priority - b.priority); + } + + addTask(task) { + this.taskQueue.insert(task); + } + + scheduleNextTask() { + if (this.taskQueue.isEmpty()) { + return null; // No tasks to schedule + } + return this.taskQueue.extract(); + } +} + +const scheduler = new TaskScheduler(); +scheduler.addTask(new Task(2, 2, 10)); +scheduler.addTask(new Task(3, 3, 5)); +scheduler.addTask(new Task(4, 4, 8)); +scheduler.addTask(new Task(5, 5, 15)); +scheduler.addTask(new Task(1, 1, 20)); + +console.log(scheduler.taskQueue.toArray()); + +console.log(scheduler.scheduleNextTask()); // Output: Task 1 (highest priority) + +console.log(scheduler.taskQueue.toArray()); + +// to see the output of this file use the command: node src/11-heap/01-min-heap.js diff --git a/src/11-heap/02-max-heap.js b/src/11-heap/02-max-heap.js new file mode 100644 index 00000000..ac1adde1 --- /dev/null +++ b/src/11-heap/02-max-heap.js @@ -0,0 +1,34 @@ +// src/11-heap/02-max-heap.js + +const Heap = require('./heap'); + +class Patient { + constructor(name, priority) { + this.name = name; + this.priority = priority; + } +} + +const PRIORITY = { LOW: 1, MEDIUM: 2, HIGH: 3 }; + +const erHeap = new Heap((a, b) => b.priority - a.priority); + +erHeap.insert(new Patient('Poppy', PRIORITY.LOW)); +erHeap.insert(new Patient('Kieran', PRIORITY.HIGH)); +erHeap.insert(new Patient('Camila', PRIORITY.MEDIUM)); +erHeap.insert(new Patient('Casteel', PRIORITY.LOW)); +erHeap.insert(new Patient('Mike', PRIORITY.HIGH)); + +console.log('Head', erHeap.toArray()); + +while (!erHeap.isEmpty()) { + const patient = erHeap.extract(); + console.log('Next patient:', patient.name, patient.priority); +} +// Next patient: Kieran 3 +// Next patient: Mike 3 +// Next patient: Camila 2 +// Next patient: Casteel 1 +// Next patient: Poppy 1 + +// to see the output of this file use the command: node src/11-heap/02-max-heap.js diff --git a/src/11-heap/03-heap-sort.js b/src/11-heap/03-heap-sort.js new file mode 100644 index 00000000..d6be093b --- /dev/null +++ b/src/11-heap/03-heap-sort.js @@ -0,0 +1,29 @@ +// src/11-heap/03-heap-sort.js + +const Comparator = require('../10-tree/comparator'); +const Heap = require('./heap'); +const HeapSort = require('./heap-sort'); + +const heapSort = (array, compareFn = Comparator.defaultCompareFn) => { + const heap = new Heap(compareFn); + heap.heapify(array); + + const sortedArray = []; + while (!heap.isEmpty()){ + sortedArray.push(heap.extract()); + } + + + return heap.toArray(); +}; + +// using the Heap class and the heapify method +let unsortedArray = [7, 6, 3, 5, 4, 1, 2]; +console.log(heapSort(unsortedArray)); // [1, 2, 3, 4, 5, 6, 7] + +// using the heap sort algorithm +const unsortedArray = [7, 6, 3, 5, 4, 1, 2]; +HeapSort(unsortedArray); // will modify the array in place +console.log(unsortedArray); // [1, 2, 3, 4, 5, 6, 7] + +// to see the output of this file use the command: node src/11-heap/03-heap-sort.js \ No newline at end of file diff --git a/src/11-heap/heap-sort.js b/src/11-heap/heap-sort.js new file mode 100644 index 00000000..ebd1509a --- /dev/null +++ b/src/11-heap/heap-sort.js @@ -0,0 +1,57 @@ +// src/11-heap/heap-sort.js + +const Comparator = require('../10-tree/comparator'); + +/** + * Heapify the array. + * @param {*} array to be heapified. + * @param {*} heapSize size of the heap. + * @param {*} rootIndex index of the root. + * @param {*} compareFn compare function. +*/ +const siftDown = (array, heapSize, rootIndex, compareFn) => { + let largest = rootIndex; + let left = 2 * rootIndex + 1; + let right = 2 * rootIndex + 2; + + if (left < heapSize && compareFn.greaterThan(array[left], array[largest])) { + largest = left; + } + + if (right < heapSize && compareFn.greaterThan(array[right], array[largest])) { + largest = right; + } + + if (largest !== rootIndex) { + [array[rootIndex], array[largest]] = [array[largest], array[rootIndex]]; + siftDown(array, heapSize, largest, compareFn); + } +}; + +/** + * Build max heap. + * @param {*} array to be heapified. + * @param {*} compareFn compare function. + */ +const buildMaxHeap = (array, compareFn) => { + const heapSize = array.length; + for (let i = Math.floor(heapSize / 2) - 1; i >= 0; i--) { + siftDown(array, heapSize, i, compareFn); + } +} + +/** + * Heap sort algorithm. + * @param {*} array to be sorted. + * @param {*} compareFn compare function. + */ +const HeapSort = (array, compareFn = Comparator.defaultCompareFn) => { + const defaultCompareFn = new Comparator(compareFn); + buildMaxHeap(array, defaultCompareFn); + for (let i = array.length - 1; i > 0; i--) { + [array[0], array[i]] = [array[i], array[0]]; + siftDown(array, i, 0, defaultCompareFn); + } +} + +module.exports = HeapSort; \ No newline at end of file diff --git a/src/11-heap/heap.js b/src/11-heap/heap.js new file mode 100644 index 00000000..85d210fc --- /dev/null +++ b/src/11-heap/heap.js @@ -0,0 +1,120 @@ +// src/11-heap/heap.js + +const Comparator = require('../10-tree/comparator'); + +class Heap { + #heap = []; + #compareFn; + + constructor(compareFn = Comparator.defaultCompareFn) { + this.#compareFn = new Comparator(compareFn); + } + + getLeftChildIndex(parentIndex) { + return 2 * parentIndex + 1; + } + + getRightChildIndex(parentIndex) { + return 2 * parentIndex + 2; + } + + getParentIndex(childIndex) { + if (childIndex === 0) { return undefined; } + return Math.floor((childIndex - 1) / 2); + } + + insert(value) { + if (value) { + const index = this.#heap.length; + this.#heap.push(value); + this.#siftUp(index); + return true; + } + return false; + } + + #siftUp(index) { + const parentIndex = this.getParentIndex(index); + + if (parentIndex !== undefined && parentIndex >= 0 && + this.#compareFn.greaterThan(this.#heap[parentIndex], this.#heap[index]) + ) { + [this.#heap[parentIndex], this.#heap[index]] = [this.#heap[index], this.#heap[parentIndex]]; + this.#siftUp(parentIndex); + } + } + + extract() { + if (this.#heap.length === 0) { + return undefined; + } + + if (this.#heap.length === 1) { + return this.#heap.shift(); + } + + const root = this.#heap[0]; + this.#heap[0] = this.#heap.pop(); + this.#siftDown(0); + return root; + } + + #siftDown(index) { + const leftIndex = this.getLeftChildIndex(index); + const rightIndex = this.getRightChildIndex(index); + let smallerIndex = index; + + if (leftIndex < this.#heap.length && + this.#compareFn.lessThan(this.#heap[leftIndex], this.#heap[smallerIndex]) + ) { + smallerIndex = leftIndex; + } + + if (rightIndex < this.#heap.length && + this.#compareFn.lessThan(this.#heap[rightIndex], this.#heap[smallerIndex]) + ) { + smallerIndex = rightIndex; + } + + if (smallerIndex !== index) { + [this.#heap[index], this.#heap[smallerIndex]] = [this.#heap[smallerIndex], this.#heap[index]]; + this.#siftDown(smallerIndex); + } + } + + heapify(array) { + this.#heap = array; + const lastParentIndex = this.getParentIndex(this.#heap.length - 1); + if (lastParentIndex !== undefined) { + for (let i = lastParentIndex; i >= 0; i--) { + this.#siftDown(i); + } + } + } + + peek() { + return this.#heap.length === 0 ? undefined : this.#heap[0]; + } + + get size() { + return this.#heap.length; + } + + isEmpty() { + return this.#heap.length === 0; + } + + toArray() { + return this.#heap.slice(); + } + + clear() { + this.#heap = []; + } + + toString() { + return this.#heap.toString(); + } +} + +module.exports = Heap; \ No newline at end of file diff --git a/src/11-heap/leetcode/minimum-number-game.ts b/src/11-heap/leetcode/minimum-number-game.ts new file mode 100644 index 00000000..1e1ecc13 --- /dev/null +++ b/src/11-heap/leetcode/minimum-number-game.ts @@ -0,0 +1,58 @@ +// https://leetcode.com/problems/minimum-number-game/description/ +// 2974. Minimum Number Game + +function siftDown (array: number[], heapSize: number, rootIndex: number) { + let largest = rootIndex; + let left = 2 * rootIndex + 1; + let right = 2 * rootIndex + 2; + + if (left < heapSize && array[left] > array[largest]) { + largest = left; + } + + if (right < heapSize && array[right] > array[largest]) { + largest = right; + } + + if (largest !== rootIndex) { + [array[rootIndex], array[largest]] = [array[largest], array[rootIndex]]; + siftDown(array, heapSize, largest); + } +}; + + +function buildMaxHeap (array: number[]) { + const heapSize = array.length; + for (let i = Math.floor(heapSize / 2) - 1; i >= 0; i--) { + siftDown(array, heapSize, i); + } +} + +function heapSort(array: number[]) { + buildMaxHeap(array); + for (let i = array.length - 1; i > 0; i--) { + [array[0], array[i]] = [array[i], array[0]]; + siftDown(array, i, 0); + } +} + +function numberGame(nums: number[]): number[] { + // nums.sort((a, b) => a - b); + heapSort(nums); + const arr: number[] = []; + while (nums.length > 0) { + const alice = nums.splice(0, 1)[0]; + const bob = nums.splice(0, 1)[0]; + arr.push(bob); + arr.push(alice); + } + return arr; +}; + +console.log(numberGame([5,4,2,3])); // [ 3, 2, 5, 4 ] +console.log(numberGame([2,5])); // [ 5, 2 ] + +// Time complexity: O(nlogn) +// Space complexity: O(n) + +// to see the output of this file use the command: npx ts-node src/11-heap/leetcode/minimum-number-game.ts \ No newline at end of file diff --git a/src/11-heap/leetcode/relative-ranks.ts b/src/11-heap/leetcode/relative-ranks.ts new file mode 100644 index 00000000..af05e336 --- /dev/null +++ b/src/11-heap/leetcode/relative-ranks.ts @@ -0,0 +1,90 @@ +// https://leetcode.com/problems/relative-ranks/description/ +// 506. Relative Ranks + +function findRelativeRanks(nums: number[]): string[] { + const sorted = [...nums].sort((a, b) => b - a); + const map = new Map(); + for (let i = 0; i < sorted.length; i++) { + if (i === 0) { + map.set(sorted[i], 'Gold Medal'); + } else if (i === 1) { + map.set(sorted[i], 'Silver Medal'); + } else if (i === 2) { + map.set(sorted[i], 'Bronze Medal'); + } else { + map.set(sorted[i], (i + 1).toString()); + } + } + + return nums.map((num) => map.get(num)!); +} + +// console.log(findRelativeRanks([5, 4, 3, 2, 1])); // ["Gold Medal","Silver Medal","Bronze Medal","4","5"] +// console.log(findRelativeRanks([10, 3, 8, 9, 4])); // ["Gold Medal","5","Bronze Medal","Silver Medal","4"] +// console.log(findRelativeRanks([1])); // ["Gold Medal"] +// console.log(findRelativeRanks([1, 2])); // ["Silver Medal","Gold Medal"] +// console.log(findRelativeRanks([1, 2, 3])); // ["Bronze Medal","Silver Medal","Gold Medal"] + +function siftDown (array: number[], heapSize: number, rootIndex: number) { + let largest = rootIndex; + let left = 2 * rootIndex + 1; + let right = 2 * rootIndex + 2; + + if (left < heapSize && array[left] < array[largest]) { + largest = left; + } + + if (right < heapSize && array[right] < array[largest]) { + largest = right; + } + + if (largest !== rootIndex) { + [array[rootIndex], array[largest]] = [array[largest], array[rootIndex]]; + siftDown(array, heapSize, largest); + } +}; + + +function buildMaxHeap (array: number[]) { + const heapSize = array.length; + for (let i = Math.floor(heapSize / 2) - 1; i >= 0; i--) { + siftDown(array, heapSize, i); + } +} + +function heapSort(array: number[]) { + buildMaxHeap(array); + for (let i = array.length - 1; i > 0; i--) { + [array[0], array[i]] = [array[i], array[0]]; + siftDown(array, i, 0); + } +} + +// rewrite the solution using heap +function findRelativeRanksHeap(nums: number[]): string[] { + + const sorted = [...nums]; + heapSort(sorted); + const map = new Map(); + for (let i = 0; i < sorted.length; i++) { + if (i === 0) { + map.set(sorted[i], 'Gold Medal'); + } else if (i === 1) { + map.set(sorted[i], 'Silver Medal'); + } else if (i === 2) { + map.set(sorted[i], 'Bronze Medal'); + } else { + map.set(sorted[i], (i + 1).toString()); + } + } + + return nums.map((num) => map.get(num)!); +} + +console.log(findRelativeRanksHeap([5, 4, 3, 2, 1])); // ["Gold Medal","Silver Medal","Bronze Medal","4","5"] +console.log(findRelativeRanksHeap([10, 3, 8, 9, 4])); // ["Gold Medal","5","Bronze Medal","Silver Medal","4"] +console.log(findRelativeRanksHeap([1])); // ["Gold Medal"] +console.log(findRelativeRanksHeap([1, 2])); // ["Silver Medal","Gold Medal"] +console.log(findRelativeRanksHeap([1, 2, 3])); // ["Bronze Medal","Silver Medal","Gold Medal"] + +// to see the output of this file use the command: npx ts-node src/11-heap/leetcode/relative-ranks.ts \ No newline at end of file diff --git a/src/12-trie/01-spell-checker.js b/src/12-trie/01-spell-checker.js new file mode 100644 index 00000000..f46e452d --- /dev/null +++ b/src/12-trie/01-spell-checker.js @@ -0,0 +1,53 @@ +// src/12-trie/01-spell-checker.js + +const Trie = require('./trie'); + +class SpellChecker { + #trie = new Trie(); + + buildDictionary(words) { + for (let word of words) { + this.#trie.insert(word); + } + } + + isWordInDictionary(word) { + return this.#trie.search(word); + } + + getSuggestions(word) { + const suggestions = []; + const wordArray = word.split(''); + for (let i = 0; i < wordArray.length; i++) { + const temp = wordArray[i]; + wordArray[i] = ''; + const newWord = wordArray.join(''); + if (this.#trie.startsWith(newWord)) { + suggestions.push(newWord); + } + wordArray[i] = temp; + } + return suggestions; + } + + removeWord(word) { + return this.#trie.remove(word); + } +} + +const spellChecker = new SpellChecker(); +spellChecker.buildDictionary(['cat', 'bat', 'rat', 'drat', 'dart', 'date']); +console.log(spellChecker.isWordInDictionary('bat')); // true +console.log(spellChecker.isWordInDictionary('drate')); // false +console.log(spellChecker.getSuggestions('drate')); // [ 'date', 'drat' ] + + +const trie = new Trie(); +trie.insert('she'); +trie.insert('sells'); +trie.insert('sea'); +trie.insert('shells'); +trie.insert('by'); +trie.insert('the'); + +// to see the output of this file use the command: node src/12-trie/01-spell-checker.js \ No newline at end of file diff --git a/src/12-trie/leetcode/design-add-and-search-words-data-structure.ts b/src/12-trie/leetcode/design-add-and-search-words-data-structure.ts new file mode 100644 index 00000000..e9dafd05 --- /dev/null +++ b/src/12-trie/leetcode/design-add-and-search-words-data-structure.ts @@ -0,0 +1,54 @@ +// https://leetcode.com/problems/design-add-and-search-words-data-structure/description/ +// 211. Design Add and Search Words Data Structure + +// @ts-ignore +class TrieNode { + children: Map; + isEndOfWord: boolean; + + constructor() { + this.children = new Map(); + this.isEndOfWord = false; + } +} + +class WordDictionary { + private root: TrieNode; + + constructor() { + this.root = new TrieNode(); + } + + addWord(word: string): void { + let node = this.root; + for (let char of word) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + node = node.children.get(char)!; + } + node.isEndOfWord = true; + } + + search(word: string): boolean { + return this.searchFromNode(word, this.root); + } + + private searchFromNode(word: string, node: TrieNode): boolean { + for (let i = 0; i < word.length; i++) { + const char = word[i]; + if (char === '.') { + for (let child of node.children.values()) { + if (this.searchFromNode(word.slice(i + 1), child)) { + return true; + } + } + return false; + } else if (!node.children.has(char)) { + return false; + } + node = node.children.get(char)!; + } + return node.isEndOfWord; + } +} \ No newline at end of file diff --git a/src/12-trie/leetcode/implement-trie-prefix-tree.ts b/src/12-trie/leetcode/implement-trie-prefix-tree.ts new file mode 100644 index 00000000..39ac3533 --- /dev/null +++ b/src/12-trie/leetcode/implement-trie-prefix-tree.ts @@ -0,0 +1,62 @@ +// https://leetcode.com/problems/implement-trie-prefix-tree/ +// 208. Implement Trie (Prefix Tree) + + +class TrieNode { + children: Map; + isEndOfWord: boolean; + + constructor() { + this.children = new Map(); + this.isEndOfWord = false; + } +} + +class Trie { + private root: TrieNode; + + constructor() { + this.root = new TrieNode(); + } + + insert(word: string): void { + let node = this.root; + for (let char of word) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + node = node.children.get(char)!; + } + node.isEndOfWord = true; + } + + search(word: string): boolean { + let node = this.root; + for (let char of word) { + if (!node.children.has(char)) { + return false; + } + node = node.children.get(char)!; + } + return node.isEndOfWord; + } + + startsWith(prefix: string): boolean { + let node = this.root; + for (let char of prefix) { + if (!node.children.has(char)) { + return false; + } + node = node.children.get(char)!; + } + return true; + } +} + +/** + * Your Trie object will be instantiated and called as such: + * var obj = new Trie() + * obj.insert(word) + * var param_2 = obj.search(word) + * var param_3 = obj.startsWith(prefix) + */ \ No newline at end of file diff --git a/src/12-trie/leetcode/longest-common-prefix.ts b/src/12-trie/leetcode/longest-common-prefix.ts new file mode 100644 index 00000000..26b751fd --- /dev/null +++ b/src/12-trie/leetcode/longest-common-prefix.ts @@ -0,0 +1,66 @@ +// https://leetcode.com/problems/longest-common-prefix/description/ +// 14. Longest Common Prefix + +function longestCommonPrefix(strs: string[]): string { + if (strs.length === 0) { return ''; } + let prefix = strs[0]; + for (let i = 1; i < strs.length; i++) { + while (strs[i].indexOf(prefix) !== 0) { + prefix = prefix.substring(0, prefix.length - 1); + } + } + return prefix; +} + +// @ts-ignore +class TrieNode { + children: Map = new Map(); + isEndOfWord: boolean = false; +} + +// @ts-ignore +class Trie { + private root: TrieNode; + + constructor() { + this.root = new TrieNode(); + } + + insert(word: string): void { + let node = this.root; + for (let char of word) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + node = node.children.get(char); + } + node.isEndOfWord = true; + } + + findLongestCommonPrefix(): string { + let node = this.root; + let prefix = ''; + while (node.children.size === 1 && !node.isEndOfWord) { + const char = Array.from(node.children.keys())[0]; + prefix += char; + node = node.children.get(char); + } + return prefix; + } +} + +function longestCommonPrefixTrie(strs: string[]): string { + if (strs.length === 0) { + return ''; + } + + let trie = new Trie(); + for (let str of strs) { + trie.insert(str); + } + + return trie.findLongestCommonPrefix(); +} + +console.log(longestCommonPrefix(['flower', 'flow', 'flight'])); // 'fl' +console.log(longestCommonPrefix(['dog', 'racecar', 'car'])); // '' diff --git a/src/12-trie/trie.js b/src/12-trie/trie.js new file mode 100644 index 00000000..d61298a2 --- /dev/null +++ b/src/12-trie/trie.js @@ -0,0 +1,70 @@ +class TrieNode { + constructor() { + this.children = new Map(); + this.isEndOfWord = false; + } +} + +class Trie { + #root = new TrieNode(); + + insert(word) { + let node = this.#root; + for (let char of word) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + node = node.children.get(char); + } + node.isEndOfWord = true; + } + + search(word) { + let node = this.#root; + for (let char of word) { + if (!node.children.has(char)) { + return false; + } + node = node.children.get(char); + } + return node.isEndOfWord; + } + + startsWith(prefix) { + let node = this.#root; + for (let char of prefix) { + if (!node.children.has(char)) { + return false; + } + node = node.children.get(char); + } + return true; + } + + remove(word) { + return this.#removeWord(this.#root, word, 0); + } + + #removeWord(node, word, index) { + if (index === word.length) { + if (!node.isEndOfWord) return false; + node.isEndOfWord = false; + return node.children.size === 0; + } + + const char = word[index]; + if (!node.children.has(char)) { + return false; + } + + const shouldDeleteCurrentNode = this.#removeWord(node.children.get(char), word, index + 1); + if (shouldDeleteCurrentNode) { + node.children.delete(char); + return node.children.size === 0; + } + + return false; + } +} + +module.exports = Trie; \ No newline at end of file diff --git a/src/12-trie/trie.ts b/src/12-trie/trie.ts new file mode 100644 index 00000000..080921b8 --- /dev/null +++ b/src/12-trie/trie.ts @@ -0,0 +1,77 @@ +class TrieNode { + children: Map; + isEndOfWord: boolean; + + constructor() { + this.children = new Map(); + this.isEndOfWord = false; + } +} + +class Trie { + private root: TrieNode; + + constructor() { + this.root = new TrieNode(); + } + + insert(word: string): void { + let node = this.root; + for (let char of word) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + node = node.children.get(char)!; + } + node.isEndOfWord = true; + } + + search(word: string): boolean { + let node = this.root; + for (let char of word) { + if (!node.children.has(char)) { + return false; + } + node = node.children.get(char)!; + } + return node.isEndOfWord; + } + + startsWith(prefix: string): boolean { + let node = this.root; + for (let char of prefix) { + if (!node.children.has(char)) { + return false; + } + node = node.children.get(char)!; + } + return true; + } + + remove(word: string): boolean { + return this.#removeWord(this.root, word, 0); + } + + #removeWord(node: TrieNode, word: string, index: number): boolean { + if (index === word.length) { + if (!node.isEndOfWord) return false; + node.isEndOfWord = false; + return node.children.size === 0; + } + + const char = word[index]; + if (!node.children.has(char)) { + return false; + } + + const shouldDeleteCurrentNode = this.#removeWord(node.children.get(char)!, word, index + 1); + if (shouldDeleteCurrentNode) { + node.children.delete(char); + return node.children.size === 0; + } + + return false; + } +} + +export default Trie; \ No newline at end of file diff --git a/src/13-graph/01-airline-system.js b/src/13-graph/01-airline-system.js new file mode 100644 index 00000000..d7586724 --- /dev/null +++ b/src/13-graph/01-airline-system.js @@ -0,0 +1,31 @@ +// src/13-graph/01-airline-system.js + +// import the Graph class +const Graph = require('./graph'); + +const airline = new Graph(); + +const airports = 'MCO TPA JFK LAX SFO'.split(' '); + +airports.forEach(airport => + airline.addVertex(airport) +); + +airline.addEdge('MCO', 'JFK'); +airline.addEdge('MCO', 'LAX'); +airline.addEdge('TPA', 'JFK'); +airline.addEdge('TPA', 'LAX'); +airline.addEdge('JFK', 'LAX'); +airline.addEdge('JFK', 'SFO'); +airline.addEdge('LAX', 'SFO'); + +console.log(airline.toString()); + +// Output: +// MCO -> JFK LAX +// TPA -> JFK LAX +// JFK -> MCO TPA LAX SFO +// LAX -> MCO TPA JFK SFO +// SFO -> JFK LAX + +// to see the output of this file use the command: node src/13-graph/01-airline-system.js \ No newline at end of file diff --git a/src/13-graph/02-using-bfs.js b/src/13-graph/02-using-bfs.js new file mode 100644 index 00000000..33cc8a44 --- /dev/null +++ b/src/13-graph/02-using-bfs.js @@ -0,0 +1,87 @@ +// src/13-graph/02-using-bfs.js + +const Graph = require('./graph'); +const { breadthFirstSearch, bfsShortestPath} = require('./bfs'); + +const airline = new Graph(); + +const airports = 'SEA SFO LAX LAS DEN DFW STL MDW JFK ATL MCO MIA'.split(' '); + +airports.forEach(airport => + airline.addVertex(airport) +); + +airline.addEdge('SEA', 'SFO'); +airline.addEdge('SEA', 'DEN'); +airline.addEdge('SEA', 'MDW'); +airline.addEdge('SFO', 'LAX'); +airline.addEdge('LAX', 'LAS'); +airline.addEdge('DEN', 'DFW'); +airline.addEdge('DEN', 'STL'); +airline.addEdge('STL', 'MDW'); +airline.addEdge('STL', 'MCO'); +airline.addEdge('MDW', 'ATL'); +airline.addEdge('MDW', 'JFK'); +airline.addEdge('ATL', 'JFK'); +airline.addEdge('JFK', 'MCO'); +airline.addEdge('JFK', 'MIA'); + +console.log(airline.toString()); + +// Output: +// SEA -> SFO DEN MDW +// SFO -> SEA LAX +// LAX -> SFO LAS +// LAS -> LAX +// DEN -> SEA DFW STL +// DFW -> DEN +// STL -> DEN MDW MCO +// MDW -> SEA STL ATL JFK +// JFK -> MDW ATL MCO MIA +// ATL -> MDW JFK +// MCO -> STL JFK +// MIA -> JFK + +console.log('--- BFS ---'); + +const printAirport = (value) => console.log('Visited airport: ' + value); + +breadthFirstSearch(airline,'SEA', printAirport); + +// Output: +// --- BFS --- +// Visited airport: SEA +// Visited airport: SFO +// Visited airport: DEN +// Visited airport: MDW +// Visited airport: LAX +// Visited airport: DFW +// Visited airport: STL +// Visited airport: ATL +// Visited airport: JFK +// Visited airport: LAS +// Visited airport: MCO +// Visited airport: MIA + +console.log('--- BFS Shortest Path ---'); + +const shortestPath = bfsShortestPath(airline, 'SEA'); +console.log(shortestPath); + +// { distances: { SEA: 0, SFO: 1, LAX: 2, LAS: 3, DEN: 1, DFW: 2, STL: 2, MDW: 1, JFK: 2, ATL: 2, MCO: 3, MIA: 3 }, +// predecessors: { SEA: null, SFO: 'SEA', LAX: 'SFO', LAS: 'LAX', DEN: 'SEA', DFW: 'DEN', STL: 'DEN', MDW: 'SEA', JFK: 'MDW', ATL: 'MDW', MCO: 'STL', MIA: 'JFK'} +// } + +// find the shortest path from SEA to JFK +let path = []; +for (let v = 'JFK'; v !== 'SEA'; v = shortestPath.predecessors[v]) { + path.push(v); +} +path.push('SEA'); +path.reverse(); + +console.log('Shortest path from SEA to JFK: ' + path.join(' -> ')); + +// Shortest path from SEA to JFK: SEA -> MDW -> JFK + +// to see the output of this file use the command: node src/13-graph/02-using-bfs.js \ No newline at end of file diff --git a/src/13-graph/03-using-dfs.js b/src/13-graph/03-using-dfs.js new file mode 100644 index 00000000..981313eb --- /dev/null +++ b/src/13-graph/03-using-dfs.js @@ -0,0 +1,70 @@ +// src/13-graph/03-using-dfs.js + +const Graph = require('./graph'); +const { depthFirstSearch, enhancedDepthFirstSearch } = require('./dfs'); + +const caveSystem = new Graph(); + +const caves = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; + +caves.forEach(cave => caveSystem.addVertex(cave)); + + +caveSystem.addEdge('A', 'B'); +caveSystem.addEdge('A', 'C'); +caveSystem.addEdge('A', 'D'); +caveSystem.addEdge('C', 'D'); +caveSystem.addEdge('C', 'G'); +caveSystem.addEdge('D', 'G'); +caveSystem.addEdge('D', 'H'); +caveSystem.addEdge('B', 'E'); +caveSystem.addEdge('B', 'F'); +caveSystem.addEdge('E', 'I'); + +console.log('********* DFS - cave ***********'); +depthFirstSearch(caveSystem, (cave) => console.log('Visited cave:',cave)); + +// ********* DFS - cave *********** +// Visited cave: A +// Visited cave: B +// Visited cave: E +// Visited cave: I +// Visited cave: F +// Visited cave: C +// Visited cave: D +// Visited cave: G +// Visited cave: H + +console.log('********* Enhanced DFS - cave ***********'); +const result = enhancedDepthFirstSearch(caveSystem); + +console.log(result); + +console.log('********* Topological sort using DFS ***********'); + +const tasks = new Graph(true); // this is a directed graph +['A', 'B', 'C', 'D', 'E', 'F'].forEach(task => tasks.addVertex(task)); +// add the arrows, task dependencies: +tasks.addEdge('A', 'C'); +tasks.addEdge('A', 'D'); +tasks.addEdge('B', 'D'); +tasks.addEdge('B', 'E'); +tasks.addEdge('C', 'F'); +tasks.addEdge('F', 'E'); + +// DFS traversal +const dfsTasks = enhancedDepthFirstSearch(tasks); +console.log(dfsTasks); +// { +// discovery: { A: 1, B: 11, C: 2, D: 8, E: 4, F: 3 }, +// finished: { A: 10, B: 12, C: 7, D: 9, E: 5, F: 6 }, +// predecessors: { A: null, B: null, C: 'A', D: 'A', E: 'F', F: 'C' } +// } + +// sort tasks in decreasing order of finish time +// dfsTasks.finished = { A: 10, B: 12, C: 7, D: 9, E: 5, F: 6 } +const sortedTasks = Object.keys(dfsTasks.finished).sort((a, b) => dfsTasks.finished[b] - dfsTasks.finished[a]); +console.log(sortedTasks); +// [ 'B', 'A', 'D', 'C', 'F', 'E' ] + +// to see the output of this file use the command: node src/13-graph/03-using-dfs.js \ No newline at end of file diff --git a/src/13-graph/04-using-dijkstra.js b/src/13-graph/04-using-dijkstra.js new file mode 100644 index 00000000..2992b251 --- /dev/null +++ b/src/13-graph/04-using-dijkstra.js @@ -0,0 +1,51 @@ +// src/13-graph/04-using-dijkstra.js + +const Graph = require('./graph'); +const dijkstra = require('./dijkstra'); + +const flightCosts = [ +// SEA, MDW, DEN, MCO, STL, JFK, ATL + [0, 300, 220, 1000, 0, 0, 0], // SEA + [300, 0, 0, 0, 50, 210, 190], // MDW + [220, 0, 0, 0, 350, 0, 0], // DEN + [1000, 0, 0, 0, 150, 250, 0], // MCO + [0, 50, 350, 150, 0, 0, 0], // STL + [0, 210, 0, 250, 0, 0, 200], // JFK + [0, 190, 0, 0, 0, 200, 0], // ATL +]; + +console.log('********* Dijkstra\'s Algorithm - Shortest Path ***********'); + +const prices = dijkstra(flightCosts, 0); // SEA +// prices output: +// { +// distances: [ +// 0, 300, 220, +// 500, 350, 510, +// 490 +// ], +// predecessors: { +// '0': [ 0 ], +// '1': [ 0, 1 ], +// '2': [ 0, 2 ], +// '3': [ 0, 1, 4, 3 ], +// '4': [ 0, 1, 4 ], +// '5': [ 0, 1, 5 ], +// '6': [ 0, 1, 6 ] +// } +// } +console.log('Prices from SEA to all airports:'); +const airports = ['SEA', 'MDW', 'DEN', 'MCO', 'STL', 'JFK', 'ATL']; +for (let i = 1; i < airports.length; i++) { + const flights = prices.predecessors[i].map(airport => airports[airport]).join(' -> '); + console.log(`SEA -> ${airports[i]}: $${prices.distances[i]} via ${flights}`); +} +// Prices from SEA to all airports: +// SEA -> MDW: $300 via SEA -> MDW +// SEA -> DEN: $220 via SEA -> DEN +// SEA -> MCO: $500 via SEA -> MDW -> STL -> MCO +// SEA -> STL: $350 via SEA -> MDW -> STL +// SEA -> JFK: $510 via SEA -> MDW -> JFK +// SEA -> ATL: $490 via SEA -> MDW -> ATL + +// to see the output of this file use the command: node src/13-graph/04-using-dijkstra.js diff --git a/src/13-graph/05-using-floyd-warshall.js b/src/13-graph/05-using-floyd-warshall.js new file mode 100644 index 00000000..688c6b84 --- /dev/null +++ b/src/13-graph/05-using-floyd-warshall.js @@ -0,0 +1,42 @@ +// src/13-graph/05-using-floyd-warshall.js + +const floydWarshall = require('./floyd-warshall'); + +const INF = Infinity; +const flightCosts = [ +// SEA, MDW, DEN, MCO, STL, JFK, ATL + [INF, 300, 220, 1000, INF, INF, INF], // SEA + [300, INF, INF, INF, 50, 210, 190], // MDW + [220, INF, INF, INF, 350, INF, INF], // DEN + [1000, INF, INF, INF, 150, 250, INF], // MCO + [INF, 50, 350, 150, INF, INF, INF], // STL + [INF, 210, INF, 250, INF, INF, 200], // JFK + [INF, 190, INF, INF, INF, 200, INF], // ATL +]; + +console.log('********* Floyd-Warshall Algorithm - Shortest Path ***********'); + +const distances = floydWarshall(flightCosts); +console.log('Distances between all airports:'); + +const airports = ['SEA', 'MDW', 'DEN', 'MCO', 'STL', 'JFK', 'ATL']; +console.table(airports.map((airport, i) => { + return airports.reduce((acc, dest, j) => { + acc[dest] = distances[i][j]; + return acc; + }, {}); +})); + +// ┌─────────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ +// │ Airport │ SEA │ MDW │ DEN │ MCO │ STL │ JFK │ ATL │ +// ├─────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤ +// │ SEA │ 0 │ 300 │ 220 │ 500 │ 350 │ 510 │ 490 │ +// │ MDW │ 300 │ 0 │ 400 │ 200 │ 50 │ 210 │ 190 │ +// │ DEN │ 220 │ 400 │ 0 │ 500 │ 350 │ 610 │ 590 │ +// │ MCO │ 500 │ 200 │ 500 │ 0 │ 150 │ 250 │ 390 │ +// │ STL │ 350 │ 50 │ 350 │ 150 │ 0 │ 260 │ 240 │ +// │ JFK │ 510 │ 210 │ 610 │ 250 │ 260 │ 0 │ 200 │ +// │ ATL │ 490 │ 190 │ 590 │ 390 │ 240 │ 200 │ 0 │ +// └─────────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ + +// to see the output of this file use the command: node src/13-graph/05-using-floyd-warshall.js \ No newline at end of file diff --git a/src/13-graph/06-using-prim.js b/src/13-graph/06-using-prim.js new file mode 100644 index 00000000..52a7c00a --- /dev/null +++ b/src/13-graph/06-using-prim.js @@ -0,0 +1,21 @@ +// src/13-graph/06-using-prim.js + +const prim = require('./prim'); + +const cityNames = ['Erebor', 'Rivendell', 'Hobbiton', 'Isengard', 'Rohan', 'Lothlorien']; + +const cities = [ + [0, 2, 4, 0, 0, 0], + [2, 0, 2, 4, 2, 0], + [4, 2, 0, 0, 3, 0], + [0, 4, 0, 0, 3, 2], + [0, 2, 3, 3, 0, 2], + [0, 0, 0, 2, 2, 0] +]; + +const mst = prim(cities); +console.log('Minimum Spanning Tree:', mst); + +// [ -1, 0, 1, 5, 1, 4 ] + +// to see the output of this file use the command: node src/13-graph/06-using-prim.js \ No newline at end of file diff --git a/src/13-graph/07-using-kruskal.js b/src/13-graph/07-using-kruskal.js new file mode 100644 index 00000000..1e67340b --- /dev/null +++ b/src/13-graph/07-using-kruskal.js @@ -0,0 +1,22 @@ +// src/13-graph/07-using-kruskal.js + +const kruskal = require('./kruskal'); + +const cityNames = ['Erebor', 'Rivendell', 'Hobbiton', 'Isengard', 'Rohan', 'Lothlorien']; + +const cities = [ + [0, 2, 4, 0, 0, 0], + [2, 0, 2, 4, 2, 0], + [4, 2, 0, 0, 3, 0], + [0, 4, 0, 0, 3, 2], + [0, 2, 3, 3, 0, 2], + [0, 0, 0, 2, 2, 0] +]; + +const mst = kruskal(cities); + +console.log('Minimum Spanning Tree with Kruskal:', mst); + +// [ [ 0, 1 ], [ 1, 2 ], [ 1, 4 ], [ 3, 5 ], [ 4, 5 ] ] + +// to see the output of this file use the command: node src/13-graph/07-using-kruskal.js \ No newline at end of file diff --git a/src/13-graph/bfs.js b/src/13-graph/bfs.js new file mode 100644 index 00000000..bcfb80c0 --- /dev/null +++ b/src/13-graph/bfs.js @@ -0,0 +1,77 @@ +// src/13-graph/bfs.js + +const Colors = { + WHITE: 0, + GREY: 1, + BLACK: 2 +}; + +const initializeColor = vertices => { + const color = {}; + vertices.forEach(vertex => { + color[vertex] = Colors.WHITE; + }); + return color; +}; + +const breadthFirstSearch = (graph, startVertex, callback) => { + const vertices = graph.vertices; + const adjList = graph.adjList; + const color = initializeColor(vertices); + const queue = [startVertex]; + + while (queue.length) { + const visiting = queue.shift(); + const neighbors = adjList.get(visiting); + color[visiting] = Colors.GREY; + for (let i = 0; i < neighbors.length; i++) { + const neighbor = neighbors[i]; + if (color[neighbor] === Colors.WHITE) { + color[neighbor] = Colors.GREY; + queue.push(neighbor); + } + } + color[visiting] = Colors.BLACK; + if (callback) { + callback(visiting); + } + } +}; + +const bfsShortestPath = (graph, startVertex) => { + const vertices = graph.vertices; + const adjList = graph.adjList; + const color = {}; + const dist = {}; + const pred = {}; + const queue = [startVertex]; + + vertices.forEach(vertex => { + color[vertex] = Colors.WHITE; + dist[vertex] = 0; + pred[vertex] = null; + }); + + while (queue.length) { + const visiting = queue.shift(); + const neighbors = adjList.get(visiting); + color[visiting] = Colors.GREY; + for (let i = 0; i < neighbors.length; i++) { + const neighbor = neighbors[i]; + if (color[neighbor] === Colors.WHITE) { + color[neighbor] = Colors.GREY; + dist[neighbor] = dist[visiting] + 1; + pred[neighbor] = visiting; + queue.push(neighbor); + } + } + color[visiting] = Colors.BLACK; + } + + return { + distances: dist, + predecessors: pred + }; +}; + +module.exports = { breadthFirstSearch , bfsShortestPath }; \ No newline at end of file diff --git a/src/13-graph/dfs.js b/src/13-graph/dfs.js new file mode 100644 index 00000000..51638b0b --- /dev/null +++ b/src/13-graph/dfs.js @@ -0,0 +1,83 @@ +// src/13-graph/dfs.js + +const Colors = { + WHITE: 0, + GREY: 1, + BLACK: 2 +}; + +const initializeColor = vertices => { + const color = {}; + vertices.forEach(vertex => { + color[vertex] = Colors.WHITE; + }); + return color; +} + +const depthFirstSearch = (graph, callback) => { + const vertices = graph.vertices; + const adjList = graph.adjList; + const color = initializeColor(vertices); + + for (let i = 0; i < vertices.length; i++) { + if (color[vertices[i]] === Colors.WHITE) { + depthFirstSearchVisit(vertices[i], color, adjList, callback); + } + } +} + +const depthFirstSearchVisit = (vertex, color, adjList, callback) => { + color[vertex] = Colors.GREY; // Mark as discovered + if (callback) { + callback(vertex); + } + const neighbors = adjList.get(vertex); + for (let i = 0; i < neighbors.length; i++) { + const neighbor = neighbors[i]; + if (color[neighbor] === Colors.WHITE) { // If unvisited - recursive call + depthFirstSearchVisit(neighbor, color, adjList, callback); + } + } + color[vertex] = Colors.BLACK; // Mark as explored +} + +const enhancedDepthFirstSearch = (graph, callback) => { + const vertices = graph.vertices; + const adjList = graph.adjList; + const color = initializeColor(vertices); + const discovery = {}; // Discovery times + const finished = {}; // Finish times + const predecessors = {}; + const time = { count: 0 }; + + for (let i = 0; i < vertices.length; i++) { + finished[vertices[i]] = 0; + discovery[vertices[i]] = 0; + predecessors[vertices[i]] = null; + } + + for (let i = 0; i < vertices.length; i++) { + if (color[vertices[i]] === Colors.WHITE) { + enhancedDFSVisit(vertices[i], color, discovery, finished, predecessors, time, adjList); + } + } + + return { discovery, finished, predecessors}; +} + +const enhancedDFSVisit = (vertex, color, discovery, finished, predecessors, time, adjList) => { + color[vertex] = Colors.GREY; + discovery[vertex] = ++time.count; // Record discovery time + const neighbors = adjList.get(vertex); + for (let i = 0; i < neighbors.length; i++) { + const neighbor = neighbors[i]; + if (color[neighbor] === Colors.WHITE) { + predecessors[neighbor] = vertex; // Record predecessor + enhancedDFSVisit(neighbor, color, discovery, finished, predecessors, time, adjList); + } + } + color[vertex] = Colors.BLACK; + finished[vertex] = ++time.count; // Record finish time +}; + +module.exports = { depthFirstSearch, enhancedDepthFirstSearch}; \ No newline at end of file diff --git a/src/13-graph/dijkstra.js b/src/13-graph/dijkstra.js new file mode 100644 index 00000000..230a696e --- /dev/null +++ b/src/13-graph/dijkstra.js @@ -0,0 +1,54 @@ +// src/13-graph/dijkstra.js + +const INF = Number.MAX_SAFE_INTEGER; // Infinity + +const dijkstra = (graph, src) => { + const dist = []; + const visited = []; + const pred = []; // Predecessor array + const { length } = graph; + for (let i = 0; i < length; i++) { + dist[i] = INF; + visited[i] = false; + pred[i] = null; // Initialize predecessors + } + dist[src] = 0; + for (let i = 0; i < length - 1; i++) { + const unv = minDistance(dist, visited); + visited[unv] = true; + for (let v = 0; v < length; v++) { + if (!visited[v] && graph[unv][v] !== 0 && dist[unv] !== INF && dist[unv] + graph[unv][v] < dist[v]) { + dist[v] = dist[unv] + graph[unv][v]; + pred[v] = unv; // Update predecessor + } + } + } + + // Construct paths from predecessors + const paths = {}; + for (let i = 0; i < length; i++) { + paths[i] = []; + let crawl = i; + paths[i].push(crawl); + while (pred[crawl] !== null) { + paths[i].push(pred[crawl]); + crawl = pred[crawl]; + } + paths[i].reverse(); + } + return { distances: dist, predecessors: paths }; +}; + +const minDistance = (dist, visited) => { + let min = INF; + let minIndex = -1; + for (let v = 0; v < dist.length; v++) { + if (visited[v] === false && dist[v] <= min) { + min = dist[v]; + minIndex = v; + } + } + return minIndex; +}; + +module.exports = dijkstra; \ No newline at end of file diff --git a/src/js/algorithms/graph/floyd-warshall.js b/src/13-graph/floyd-warshall.js similarity index 55% rename from src/js/algorithms/graph/floyd-warshall.js rename to src/13-graph/floyd-warshall.js index d8bb875e..df4fd4db 100644 --- a/src/js/algorithms/graph/floyd-warshall.js +++ b/src/13-graph/floyd-warshall.js @@ -1,4 +1,8 @@ -export const floydWarshall = graph => { +// src/13-graph/floyd-warshall.js + +const INF = Number.MAX_SAFE_INTEGER; // Infinity + +const initializeMatrix = (graph) => { const dist = []; const { length } = graph; for (let i = 0; i < length; i++) { @@ -7,20 +11,31 @@ export const floydWarshall = graph => { if (i === j) { dist[i][j] = 0; } else if (!isFinite(graph[i][j])) { - dist[i][j] = Infinity; + dist[i][j] = INF; } else { dist[i][j] = graph[i][j]; } } } + return dist; +} + +const floydWarshall = (graph) => { + const { length } = graph; + const dist = initializeMatrix(graph); + + // Consider each airport as an intermediate point for (let k = 0; k < length; k++) { for (let i = 0; i < length; i++) { for (let j = 0; j < length; j++) { + // If a shorter path is found through an intermediate airport, update the distance if (dist[i][k] + dist[k][j] < dist[i][j]) { dist[i][j] = dist[i][k] + dist[k][j]; } } } } - return dist; + return dist; }; + +module.exports = floydWarshall; \ No newline at end of file diff --git a/src/13-graph/graph.js b/src/13-graph/graph.js new file mode 100644 index 00000000..fcdcf73f --- /dev/null +++ b/src/13-graph/graph.js @@ -0,0 +1,55 @@ +// src/13-graph/graph.js + +// Graph class +class Graph { + + #isDirected = false; + #vertices = []; + #adjList = new Map(); + + constructor(isDirected = false) { + this.#isDirected = isDirected; + } + + addVertex(vertex) { + if (!this.#vertices.includes(vertex)) { + this.#vertices.push(vertex); + this.#adjList.set(vertex, []); + } + } + + addEdge(vertex, edge) { + if (!this.#adjList.get(vertex)) { + this.addVertex(vertex); + } + if (!this.#adjList.get(edge)) { + this.addVertex(edge); + } + this.#adjList.get(vertex).push(edge); + if (!this.#isDirected) { + this.#adjList.get(edge).push(vertex); + } + } + + get vertices() { + return this.#vertices; + } + + get adjList() { + return this.#adjList; + } + + toString() { + let s = ''; + this.#vertices.forEach(vertex => { + s += `${vertex} -> `; + this.#adjList.get(vertex).forEach(neighbor => { + s += `${neighbor} `; + }); + s += '\n'; + }); + return s; + } +} + +module.exports = Graph; \ No newline at end of file diff --git a/src/13-graph/kruskal.js b/src/13-graph/kruskal.js new file mode 100644 index 00000000..e23153e2 --- /dev/null +++ b/src/13-graph/kruskal.js @@ -0,0 +1,69 @@ + +const INF = Number.MAX_SAFE_INTEGER; + +const kruskal = (graph) => { + const { length } = graph; + const parent = []; // Stores the MST + let ne = 0; // Number of edges in the MST + let a; let b; let u; let v; + const cost = initializeCost(graph); // Create a copy of the graph + + // While the MST has fewer edges than the total number of vertices - 1 + while (ne < length - 1) { + for (let i = 0, min = INF; i < length; i++) { + for (let j = 0; j < length; j++) { + // Find the edge with the minimum cost + if (cost[i][j] < min) { + min = cost[i][j]; + a = u = i; + b = v = j; + } + } + } + + u = find(u, parent); // Find the set of vertex u + v = find(v, parent); // Find the set of vertex v + + // If adding the edge doesn't create a cycle, add it to the MST + if (union(u, v, parent)) { + ne++; + } + + cost[a][b] = cost[b][a] = INF; // Remove the edge from the cost matrix + } + + return parent; // Return the MST +}; + +// Helper function to initialize the cost matrix +const initializeCost = (graph) => { + const { length } = graph; + const cost = Array(length).fill(null).map(() => Array(length).fill(null)); + + for (let i = 0; i < length; i++) { + for (let j = 0; j < length; j++) { + cost[i][j] = graph[i][j] || INF; + } + } + + return cost; +}; + +// Helper function to find the set of an element i +const find = (i, parent) => { + while (parent[i]) { + i = parent[i]; + } + return i; +}; + +// Helper function to union two sets of i and j +const union = (i, j, parent) => { + if (i !== j) { + parent[j] = i; + return true; + } + return false; +}; + +module.exports = kruskal; \ No newline at end of file diff --git a/src/13-graph/leetcode/course-schedule.ts b/src/13-graph/leetcode/course-schedule.ts new file mode 100644 index 00000000..ec850f89 --- /dev/null +++ b/src/13-graph/leetcode/course-schedule.ts @@ -0,0 +1,56 @@ +// 207. Course Schedule +// https://leetcode.com/problems/course-schedule/ + +// Time complexity: O(V + E) +// Space complexity: O(V + E) + +function canFinish(numCourses: number, prerequisites: number[][]): boolean { + const adjList = new Map(); + const visited = new Set(); + + // Create adjacency list + for (let i = 0; i < numCourses; i++) { + adjList.set(i, []); + } + for (const [course, pre] of prerequisites) { + adjList.get(pre).push(course); + } + + // DFS function to check for cycles + const dfs = (course, cycle) => { + if (cycle.has(course)) { + return true; + } + if (visited.has(course)) { + return false; + } + cycle.add(course); + visited.add(course); + for (const neighbor of adjList.get(course)) { + if (dfs(neighbor, cycle)) { + return true; + } + } + cycle.delete(course); + return false; + } + + // Check for cycles starting from each course + for (let i = 0; i < numCourses; i++) { + if (dfs(i, new Set())) { + return false; // Cycle found + } + } + + return true; // No cycles found +} + +// Test cases +const numCourses = 2; +const prerequisites = [ + [1, 0], + [0, 1], +]; +console.log(canFinish(numCourses, prerequisites)); // false + +// to see the output of this file use the command: npx ts-node src/13-graph/leetcode/course-schedule.ts \ No newline at end of file diff --git a/src/13-graph/leetcode/number-of-islands.ts b/src/13-graph/leetcode/number-of-islands.ts new file mode 100644 index 00000000..3473d5dd --- /dev/null +++ b/src/13-graph/leetcode/number-of-islands.ts @@ -0,0 +1,52 @@ +// 200. Number of Islands +// https://leetcode.com/problems/number-of-islands/ + +function numIslands(grid: string[][]): number { + let count = 0; + for (let i = 0; i < grid.length; i++) { + for (let j = 0; j < grid[0].length; j++) { + if (grid[i][j] === "1") { + count++; + dfs(grid, i, j); + } + } + } + return count; +} + +function dfs(grid: string[][], i: number, j: number) { + if ( + i < 0 || + j < 0 || + i >= grid.length || + j >= grid[0].length || + grid[i][j] === "0" + ) { + return; + } + grid[i][j] = "0"; + dfs(grid, i + 1, j); + dfs(grid, i - 1, j); + dfs(grid, i, j + 1); + dfs(grid, i, j - 1); +} + +console.log( + numIslands([ + ["1", "1", "1", "1", "0"], + ["1", "1", "0", "1", "0"], + ["1", "1", "0", "0", "0"], + ["0", "0", "0", "0", "0"], + ]) +); // 1 + +console.log( + numIslands([ + ["1","1","0","0","0"], + ["1","1","0","0","0"], + ["0","0","1","0","0"], + ["0","0","0","1","1"], + ]) +); // 3 + +// to see the output of this file use the command: npx ts-node src/13-graph/leetcode/number-of-islands.ts \ No newline at end of file diff --git a/src/13-graph/prim.js b/src/13-graph/prim.js new file mode 100644 index 00000000..1b03fa65 --- /dev/null +++ b/src/13-graph/prim.js @@ -0,0 +1,47 @@ +const INF = Number.MAX_SAFE_INTEGER; + +const minKey = (graph, key, visited) => { + let min = INF; + let minIndex = 0; + for (let v = 0; v < graph.length; v++) { + if (visited[v] === false && key[v] < min) { + min = key[v]; + minIndex = v; + } + } + return minIndex; +}; + +const prim = (graph) => { + const parent = []; // Stores the MST + const key = []; // Keeps track of the minimum edge weights + const visited = []; // Marks visited vertices + const { length } = graph; + + // Initialize all key values as infinite and visited as false + for (let i = 0; i < length; i++) { + key[i] = INF; + visited[i] = false; + } + + key[0] = 0; // Start with the first vertex + parent[0] = -1; // The first vertex is the root of the MST + + // Find the MST for all vertices + for (let i = 0; i < length - 1; i++) { + const u = minKey(graph, key, visited); // Select the vertex with the minimum key value + visited[u] = true; // Mark the selected vertex as visited + + // Update key values and parent for adjacent vertices + for (let v = 0; v < length; v++) { + if (graph[u][v] && !visited[v] && graph[u][v] < key[v]) { + parent[v] = u; // Update parent to store the edge in the MST + key[v] = graph[u][v]; // Update key value to the minimum edge weight + } + } + } + + return parent; // Return the MST +}; + +module.exports = prim; \ No newline at end of file diff --git a/src/js/algorithms/backtracking/rat-in-maze.js b/src/js/algorithms/backtracking/rat-in-maze.js deleted file mode 100644 index ff433130..00000000 --- a/src/js/algorithms/backtracking/rat-in-maze.js +++ /dev/null @@ -1,41 +0,0 @@ -function isSafe(maze, x, y) { - const n = maze.length; - if (x >= 0 && y >= 0 && x < n && y < n && maze[x][y] !== 0) { - return true; - } - return false; -} - -function findPath(maze, x, y, solution) { - const n = maze.length; - if (x === n - 1 && y === n - 1) { - solution[x][y] = 1; - return true; - } - if (isSafe(maze, x, y) === true) { - solution[x][y] = 1; - if (findPath(maze, x + 1, y, solution)) { - return true; - } - if (findPath(maze, x, y + 1, solution)) { - return true; - } - solution[x][y] = 0; - return false; - } - return false; -} - -export function ratInAMaze(maze) { - const solution = []; - for (let i = 0; i < maze.length; i++) { - solution[i] = []; - for (let j = 0; j < maze[i].length; j++) { - solution[i][j] = 0; - } - } - if (findPath(maze, 0, 0, solution) === true) { - return solution; - } - return 'NO PATH FOUND'; -} diff --git a/src/js/algorithms/backtracking/sudoku-solver.js b/src/js/algorithms/backtracking/sudoku-solver.js deleted file mode 100644 index 6e1a76fc..00000000 --- a/src/js/algorithms/backtracking/sudoku-solver.js +++ /dev/null @@ -1,76 +0,0 @@ -const UNASSIGNED = 0; - -function usedInRow(matrix, row, num) { - for (let col = 0; col < matrix.length; col++) { - if (matrix[row][col] === num) { - return true; - } - } - return false; -} - -function usedInCol(matrix, col, num) { - for (let row = 0; row < matrix.length; row++) { - if (matrix[row][col] === num) { - return true; - } - } - return false; -} - -function usedInBox(matrix, boxStartRow, boxStartCol, num) { - for (let row = 0; row < 3; row++) { - for (let col = 0; col < 3; col++) { - if (matrix[row + boxStartRow][col + boxStartCol] === num) { - return true; - } - } - } - return false; -} - -function isSafe(matrix, row, col, num) { - return ( - !usedInRow(matrix, row, num) - && !usedInCol(matrix, col, num) - && !usedInBox(matrix, row - (row % 3), col - (col % 3), num) - ); -} -function solveSudoku(matrix) { - let row = 0; - let col = 0; - let checkBlankSpaces = false; - - for (row = 0; row < matrix.length; row++) { - for (col = 0; col < matrix[row].length; col++) { - if (matrix[row][col] === UNASSIGNED) { - checkBlankSpaces = true; - break; - } - } - if (checkBlankSpaces === true) { - break; - } - } - if (checkBlankSpaces === false) { - return true; - } - - for (let num = 1; num <= 9; num++) { - if (isSafe(matrix, row, col, num)) { - matrix[row][col] = num; - if (solveSudoku(matrix)) { - return true; - } - matrix[row][col] = UNASSIGNED; - } - } - return false; -} - -export function sudokuSolver(matrix) { - if (solveSudoku(matrix) === true) { - return matrix; - } - return 'NO SOLUTION EXISTS!'; -} diff --git a/src/js/algorithms/dynamic-programing/knapsack-recursive.js b/src/js/algorithms/dynamic-programing/knapsack-recursive.js deleted file mode 100644 index fbe646e1..00000000 --- a/src/js/algorithms/dynamic-programing/knapsack-recursive.js +++ /dev/null @@ -1,11 +0,0 @@ -export function knapSack(capacity, weights, values, n) { - if (n === 0 || capacity === 0) { - return 0; - } - if (weights[n - 1] > capacity) { - return knapSack(capacity, weights, values, n - 1); - } - const a = values[n - 1] + knapSack(capacity - weights[n - 1], weights, values, n - 1); - const b = knapSack(capacity, weights, values, n - 1); - return a > b ? a : b; -} diff --git a/src/js/algorithms/dynamic-programing/knapsack.js b/src/js/algorithms/dynamic-programing/knapsack.js deleted file mode 100644 index 9c979360..00000000 --- a/src/js/algorithms/dynamic-programing/knapsack.js +++ /dev/null @@ -1,41 +0,0 @@ -function findValues(n, capacity, kS) { - let i = n; - let k = capacity; - // console.log('Items that are part of the solution:'); - while (i > 0 && k > 0) { - if (kS[i][k] !== kS[i - 1][k]) { - // console.log( - // item ' + i + ' can be part of solution w,v: ' + weights[i - 1] + ',' + values[i - 1] - // ); - i--; - k -= kS[i][k]; - } else { - i--; - } - } -} - -export function knapSack(capacity, weights, values, n) { - const kS = []; - for (let i = 0; i <= n; i++) { - kS[i] = []; - } - for (let i = 0; i <= n; i++) { - for (let w = 0; w <= capacity; w++) { - if (i === 0 || w === 0) { - kS[i][w] = 0; - } else if (weights[i - 1] <= w) { - const a = values[i - 1] + kS[i - 1][w - weights[i - 1]]; - const b = kS[i - 1][w]; - kS[i][w] = a > b ? a : b; // max(a,b) - // console.log(a + ' can be part of the solution'); - } else { - kS[i][w] = kS[i - 1][w]; - } - } - // console.log(kS[i].join()); - } - // extra algorithm to find the items that are part of the solution - findValues(n, capacity, kS); - return kS[n][capacity]; -} diff --git a/src/js/algorithms/dynamic-programing/longest-common-subsequence-print.js b/src/js/algorithms/dynamic-programing/longest-common-subsequence-print.js deleted file mode 100644 index e18c6e11..00000000 --- a/src/js/algorithms/dynamic-programing/longest-common-subsequence-print.js +++ /dev/null @@ -1,51 +0,0 @@ -function printSolution(solution, wordX, m, n) { - let a = m; - let b = n; - let x = solution[a][b]; - let answer = ''; - while (x !== '0') { - if (solution[a][b] === 'diagonal') { - answer = wordX[a - 1] + answer; - a--; - b--; - } else if (solution[a][b] === 'left') { - b--; - } else if (solution[a][b] === 'top') { - a--; - } - x = solution[a][b]; - } - return answer; -} -export function lcs(wordX, wordY) { - const m = wordX.length; - const n = wordY.length; - const l = []; - const solution = []; - for (let i = 0; i <= m; i++) { - l[i] = []; - solution[i] = []; - for (let j = 0; j <= n; j++) { - l[i][j] = 0; - solution[i][j] = '0'; - } - } - for (let i = 0; i <= m; i++) { - for (let j = 0; j <= n; j++) { - if (i === 0 || j === 0) { - l[i][j] = 0; - } else if (wordX[i - 1] === wordY[j - 1]) { - l[i][j] = l[i - 1][j - 1] + 1; - solution[i][j] = 'diagonal'; - } else { - const a = l[i - 1][j]; - const b = l[i][j - 1]; - l[i][j] = a > b ? a : b; // max(a,b) - solution[i][j] = l[i][j] === l[i - 1][j] ? 'top' : 'left'; - } - } - // console.log(l[i].join()); - // console.log(solution[i].join()); - } - return printSolution(solution, wordX, m, n); -} diff --git a/src/js/algorithms/dynamic-programing/longest-common-subsequence.js b/src/js/algorithms/dynamic-programing/longest-common-subsequence.js deleted file mode 100644 index 762c70c6..00000000 --- a/src/js/algorithms/dynamic-programing/longest-common-subsequence.js +++ /dev/null @@ -1,26 +0,0 @@ -export function lcs(wordX, wordY) { - const m = wordX.length; - const n = wordY.length; - const l = []; - for (let i = 0; i <= m; i++) { - l[i] = []; - for (let j = 0; j <= n; j++) { - l[i][j] = 0; - } - } - for (let i = 0; i <= m; i++) { - for (let j = 0; j <= n; j++) { - if (i === 0 || j === 0) { - l[i][j] = 0; - } else if (wordX[i - 1] === wordY[j - 1]) { - l[i][j] = l[i - 1][j - 1] + 1; - } else { - const a = l[i - 1][j]; - const b = l[i][j - 1]; - l[i][j] = a > b ? a : b; // max(a,b) - } - } - // console.log(l[i].join()); - } - return l[m][n]; -} diff --git a/src/js/algorithms/dynamic-programing/matrix-chain-multiplication.js b/src/js/algorithms/dynamic-programing/matrix-chain-multiplication.js deleted file mode 100644 index 143f5772..00000000 --- a/src/js/algorithms/dynamic-programing/matrix-chain-multiplication.js +++ /dev/null @@ -1,45 +0,0 @@ -function printOptimalParenthesis(s, i, j) { - if (i === j) { - // console.log('A[' + i + ']'); - } else { - // console.log('('); - printOptimalParenthesis(s, i, s[i][j]); - printOptimalParenthesis(s, s[i][j] + 1, j); - // console.log(')'); - } -} - -export function matrixChainOrder(p) { - const n = p.length; - const m = []; - const s = []; - for (let i = 1; i <= n; i++) { - m[i] = []; - m[i][i] = 0; - } - for (let i = 0; i <= n; i++) { - // to help printing the optimal solution - s[i] = []; // auxiliary - for (let j = 0; j <= n; j++) { - s[i][j] = 0; - } - } - for (let l = 2; l < n; l++) { - for (let i = 1; i <= (n - l) + 1; i++) { - const j = (i + l) - 1; - m[i][j] = Number.MAX_SAFE_INTEGER; - for (let k = i; k <= j - 1; k++) { - // q = cost/scalar multiplications - const q = m[i][k] + m[k + 1][j] + ((p[i - 1] * p[k]) * p[j]); - if (q < m[i][j]) { - m[i][j] = q; - s[i][j] = k; // s[i,j] = Second auxiliary table that stores k - } - } - } - } - // console.log(m); - // console.log(s); - printOptimalParenthesis(s, 1, n - 1); - return m[1][n - 1]; -} diff --git a/src/js/algorithms/dynamic-programing/min-coin-change.js b/src/js/algorithms/dynamic-programing/min-coin-change.js deleted file mode 100644 index a477c804..00000000 --- a/src/js/algorithms/dynamic-programing/min-coin-change.js +++ /dev/null @@ -1,32 +0,0 @@ -export function minCoinChange(coins, amount) { - const cache = []; - - const makeChange = (value) => { - if (!value) { - return []; - } - if (cache[value]) { - return cache[value]; - } - let min = []; - let newMin; - let newAmount; - for (let i = 0; i < coins.length; i++) { - const coin = coins[i]; - newAmount = value - coin; - if (newAmount >= 0) { - newMin = makeChange(newAmount); - } - if ( - newAmount >= 0 - && (newMin.length < min.length - 1 || !min.length) - && (newMin.length || !newAmount) - ) { - min = [coin].concat(newMin); - // console.log('new Min ' + min + ' for ' + amount); - } - } - return (cache[value] = min); - }; - return makeChange(amount); -} diff --git a/src/js/algorithms/graph/breadth-first-search.js b/src/js/algorithms/graph/breadth-first-search.js deleted file mode 100644 index 7cf3f395..00000000 --- a/src/js/algorithms/graph/breadth-first-search.js +++ /dev/null @@ -1,74 +0,0 @@ -import Queue from '../../data-structures/queue'; - -const Colors = { - WHITE: 0, - GREY: 1, - BLACK: 2 -}; - -const initializeColor = vertices => { - const color = {}; - for (let i = 0; i < vertices.length; i++) { - color[vertices[i]] = Colors.WHITE; - } - return color; -}; - -export const breadthFirstSearch = (graph, startVertex, callback) => { - const vertices = graph.getVertices(); - const adjList = graph.getAdjList(); - const color = initializeColor(vertices); - const queue = new Queue(); - - queue.enqueue(startVertex); - - while (!queue.isEmpty()) { - const u = queue.dequeue(); - const neighbors = adjList.get(u); - color[u] = Colors.GREY; - for (let i = 0; i < neighbors.length; i++) { - const w = neighbors[i]; - if (color[w] === Colors.WHITE) { - color[w] = Colors.GREY; - queue.enqueue(w); - } - } - color[u] = Colors.BLACK; - if (callback) { - callback(u); - } - } -}; - -export const BFS = (graph, startVertex) => { - const vertices = graph.getVertices(); - const adjList = graph.getAdjList(); - const color = initializeColor(vertices); - const queue = new Queue(); - const distances = {}; - const predecessors = {}; - queue.enqueue(startVertex); - for (let i = 0; i < vertices.length; i++) { - distances[vertices[i]] = 0; - predecessors[vertices[i]] = null; - } - while (!queue.isEmpty()) { - const u = queue.dequeue(); - const neighbors = adjList.get(u); - color[u] = Colors.GREY; - for (let i = 0; i < neighbors.length; i++) { - const w = neighbors[i]; - if (color[w] === Colors.WHITE) { - color[w] = Colors.GREY; - distances[w] = distances[u] + 1; - predecessors[w] = u; - queue.enqueue(w); - } - } - color[u] = Colors.BLACK; - } - return { - distances, - predecessors - }; -}; diff --git a/src/js/algorithms/graph/depth-first-search.js b/src/js/algorithms/graph/depth-first-search.js deleted file mode 100644 index 8427659f..00000000 --- a/src/js/algorithms/graph/depth-first-search.js +++ /dev/null @@ -1,86 +0,0 @@ -// import Graph from '../../data-structures/graph'; - -const Colors = { - WHITE: 0, - GREY: 1, - BLACK: 2 -}; - -const initializeColor = vertices => { - const color = {}; - for (let i = 0; i < vertices.length; i++) { - color[vertices[i]] = Colors.WHITE; - } - return color; -}; - -const depthFirstSearchVisit = (u, color, adjList, callback) => { - color[u] = Colors.GREY; - if (callback) { - callback(u); - } - // console.log('Discovered ' + u); - const neighbors = adjList.get(u); - for (let i = 0; i < neighbors.length; i++) { - const w = neighbors[i]; - if (color[w] === Colors.WHITE) { - depthFirstSearchVisit(w, color, adjList, callback); - } - } - color[u] = Colors.BLACK; - // console.log('explored ' + u); -}; - -export const depthFirstSearch = (graph, callback) => { - const vertices = graph.getVertices(); - const adjList = graph.getAdjList(); - const color = initializeColor(vertices); - - for (let i = 0; i < vertices.length; i++) { - if (color[vertices[i]] === Colors.WHITE) { - depthFirstSearchVisit(vertices[i], color, adjList, callback); - } - } -}; - -const DFSVisit = (u, color, d, f, p, time, adjList) => { - // console.log('discovered ' + u); - color[u] = Colors.GREY; - d[u] = ++time.count; - const neighbors = adjList.get(u); - for (let i = 0; i < neighbors.length; i++) { - const w = neighbors[i]; - if (color[w] === Colors.WHITE) { - p[w] = u; - DFSVisit(w, color, d, f, p, time, adjList); - } - } - color[u] = Colors.BLACK; - f[u] = ++time.count; - // console.log('explored ' + u); -}; - -export const DFS = graph => { - const vertices = graph.getVertices(); - const adjList = graph.getAdjList(); - const color = initializeColor(vertices); - const d = {}; - const f = {}; - const p = {}; - const time = { count: 0 }; - for (let i = 0; i < vertices.length; i++) { - f[vertices[i]] = 0; - d[vertices[i]] = 0; - p[vertices[i]] = null; - } - for (let i = 0; i < vertices.length; i++) { - if (color[vertices[i]] === Colors.WHITE) { - DFSVisit(vertices[i], color, d, f, p, time, adjList); - } - } - return { - discovery: d, - finished: f, - predecessors: p - }; -}; diff --git a/src/js/algorithms/graph/dijkstra.js b/src/js/algorithms/graph/dijkstra.js deleted file mode 100644 index ec223687..00000000 --- a/src/js/algorithms/graph/dijkstra.js +++ /dev/null @@ -1,32 +0,0 @@ -const INF = Number.MAX_SAFE_INTEGER; -const minDistance = (dist, visited) => { - let min = INF; - let minIndex = -1; - for (let v = 0; v < dist.length; v++) { - if (visited[v] === false && dist[v] <= min) { - min = dist[v]; - minIndex = v; - } - } - return minIndex; -}; -export const dijkstra = (graph, src) => { - const dist = []; - const visited = []; - const { length } = graph; - for (let i = 0; i < length; i++) { - dist[i] = INF; - visited[i] = false; - } - dist[src] = 0; - for (let i = 0; i < length - 1; i++) { - const u = minDistance(dist, visited); - visited[u] = true; - for (let v = 0; v < length; v++) { - if (!visited[v] && graph[u][v] !== 0 && dist[u] !== INF && dist[u] + graph[u][v] < dist[v]) { - dist[v] = dist[u] + graph[u][v]; - } - } - } - return dist; -}; diff --git a/src/js/algorithms/graph/gale-shapley.js b/src/js/algorithms/graph/gale-shapley.js deleted file mode 100644 index b0d52689..00000000 --- a/src/js/algorithms/graph/gale-shapley.js +++ /dev/null @@ -1,77 +0,0 @@ -class Person { - constructor(id, gender, ranks, rankIndex, status = "single") { - this.id = id - this.gender = gender - this.ranks = ranks - this.i = rankIndex - this.status = status - this.partner = null - } -} - -function galeShapley(proposers, reviewers) { - let perfectMatching = new Map() - for (let [pid, p] of proposers) { - while (p.i < p.ranks.length) { - let rid = p.ranks[p.i] - let r = reviewers.get(rid) - p.i++ - if (r.status === "single") { - r.status = "engaged" - r.partner = p - p.partner = r - perfectMatching.set(pid, rid) - proposers.delete(pid) - break - } else if (r.status === "engaged" && r.ranks.get(pid) < r.ranks.get(r.partner.id)) { - perfectMatching.delete(r.partner.id) - proposers.set(r.partner.id, r.partner) - proposers.delete(pid) - r.partner.partner = null - r.partner = p - p.partner = r - perfectMatching.set(pid, rid) - break - } - } - } - return perfectMatching -} - -let men = new Map() -let women = new Map() -//O(n^2) -function createPeople(n, gender, set) { - for (let i = 0; i < n; i++) { - let id = i - let rankIndex = 0 - let g = gender - let ranks = new Array(n) - let p - for (let i = 0; i < n; i++) ranks[i] = i - shuffle(ranks) - if (gender == 'w') { - let wRanks = new Map() - for (let i = 0; i < n; i++) wRanks.set(i, ranks[i]) - p = new Person(id, g, wRanks, null) - } else { - p = new Person(id, g, ranks, rankIndex) - } - set.set(i, p) - } -} - -//fisher-yates shuffle O(n) -function shuffle(array) { - for (let i = array.length - 1; i >= 0; i--) { - let j = Math.floor(Math.random() * (i + 1)) - let temp = array[i] - array[i] = array[j] - array[j] = temp - } -} - -createPeople(4, 'm', men) -createPeople(4, 'w', women) -let stableMatching = galeShapley(men, women) -console.log(stableMatching) diff --git a/src/js/algorithms/graph/kruskal.js b/src/js/algorithms/graph/kruskal.js deleted file mode 100644 index d1435c28..00000000 --- a/src/js/algorithms/graph/kruskal.js +++ /dev/null @@ -1,57 +0,0 @@ -const INF = Number.MAX_SAFE_INTEGER; -const find = (i, parent) => { - while (parent[i]) { - i = parent[i]; // eslint-disable-line prefer-destructuring - } - return i; -}; -const union = (i, j, parent) => { - if (i !== j) { - parent[j] = i; - return true; - } - return false; -}; -const initializeCost = graph => { - const cost = []; - const { length } = graph; - for (let i = 0; i < length; i++) { - cost[i] = []; - for (let j = 0; j < length; j++) { - if (graph[i][j] === 0) { - cost[i][j] = INF; - } else { - cost[i][j] = graph[i][j]; - } - } - } - return cost; -}; -export const kruskal = graph => { - const { length } = graph; - const parent = []; - let ne = 0; - let a; - let b; - let u; - let v; - const cost = initializeCost(graph); - while (ne < length - 1) { - for (let i = 0, min = INF; i < length; i++) { - for (let j = 0; j < length; j++) { - if (cost[i][j] < min) { - min = cost[i][j]; - a = u = i; - b = v = j; - } - } - } - u = find(u, parent); - v = find(v, parent); - if (union(u, v, parent)) { - ne++; - } - cost[a][b] = cost[b][a] = INF; - } - return parent; -}; diff --git a/src/js/algorithms/graph/prim.js b/src/js/algorithms/graph/prim.js deleted file mode 100644 index bbb54e95..00000000 --- a/src/js/algorithms/graph/prim.js +++ /dev/null @@ -1,36 +0,0 @@ -const INF = Number.MAX_SAFE_INTEGER; -const minKey = (graph, key, visited) => { - // Initialize min value - let min = INF; - let minIndex = 0; - for (let v = 0; v < graph.length; v++) { - if (visited[v] === false && key[v] < min) { - min = key[v]; - minIndex = v; - } - } - return minIndex; -}; -export const prim = graph => { - const parent = []; - const key = []; - const visited = []; - const { length } = graph; - for (let i = 0; i < length; i++) { - key[i] = INF; - visited[i] = false; - } - key[0] = 0; - parent[0] = -1; - for (let i = 0; i < length - 1; i++) { - const u = minKey(graph, key, visited); - visited[u] = true; - for (let v = 0; v < length; v++) { - if (graph[u][v] && !visited[v] && graph[u][v] < key[v]) { - parent[v] = u; - key[v] = graph[u][v]; - } - } - } - return parent; -}; diff --git a/src/js/algorithms/greedy/knapsack.js b/src/js/algorithms/greedy/knapsack.js deleted file mode 100644 index 294def52..00000000 --- a/src/js/algorithms/greedy/knapsack.js +++ /dev/null @@ -1,18 +0,0 @@ -export function knapSack(capacity, weights, values) { - const n = values.length; - let load = 0; - let val = 0; - for (let i = 0; i < n && load < capacity; i++) { - if (weights[i] <= capacity - load) { - val += values[i]; - load += weights[i]; - // console.log('using item ' + (i + 1) + ' for the solution'); - } else { - const r = (capacity - load) / weights[i]; - val += r * values[i]; - load += weights[i]; - // console.log('using ratio of ' + r + ' for item ' + (i + 1) + ' for the solution'); - } - } - return val; -} diff --git a/src/js/algorithms/greedy/longest-common-subsequence.js b/src/js/algorithms/greedy/longest-common-subsequence.js deleted file mode 100644 index f7ec8272..00000000 --- a/src/js/algorithms/greedy/longest-common-subsequence.js +++ /dev/null @@ -1,11 +0,0 @@ -export function lcs(wordX, wordY, m = wordX.length, n = wordY.length) { - if (m === 0 || n === 0) { - return 0; - } - if (wordX[m - 1] === wordY[n - 1]) { - return 1 + lcs(wordX, wordY, m - 1, n - 1); - } - const a = lcs(wordX, wordY, m, n - 1); - const b = lcs(wordX, wordY, m - 1, n); - return a > b ? a : b; -} diff --git a/src/js/algorithms/greedy/matrix-chain-multiplication.js b/src/js/algorithms/greedy/matrix-chain-multiplication.js deleted file mode 100644 index 63c5b4ae..00000000 --- a/src/js/algorithms/greedy/matrix-chain-multiplication.js +++ /dev/null @@ -1,14 +0,0 @@ -export function matrixChainOrder(p, i = 1, j = p.length - 1) { - if (i === j) { - return 0; - } - let min = Number.MAX_SAFE_INTEGER; - for (let k = i; k < j; k++) { - const count = matrixChainOrder(p, i, k) - + matrixChainOrder(p, k + 1, j) + ((p[i - 1] * p[k]) * p[j]); - if (count < min) { - min = count; - } - } - return min; -} diff --git a/src/js/algorithms/greedy/min-coin-change.js b/src/js/algorithms/greedy/min-coin-change.js deleted file mode 100644 index 61abfe91..00000000 --- a/src/js/algorithms/greedy/min-coin-change.js +++ /dev/null @@ -1,12 +0,0 @@ -export function minCoinChange(coins, amount) { - const change = []; - let total = 0; - for (let i = coins.length; i >= 0; i--) { - const coin = coins[i]; - while (total + coin <= amount) { - change.push(coin); - total += coin; - } - } - return change; -} diff --git a/src/js/algorithms/search/binary-search-recursive.js b/src/js/algorithms/search/binary-search-recursive.js deleted file mode 100644 index d8daa439..00000000 --- a/src/js/algorithms/search/binary-search-recursive.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Compare, defaultCompare, DOES_NOT_EXIST } from '../../util'; -import { quickSort } from '../sorting/quicksort'; - -function binarySearchRecursive(array, value, low, high, compareFn = defaultCompare) { - if (low <= high) { - const mid = Math.floor((low + high) / 2); - const element = array[mid]; - if (compareFn(element, value) === Compare.LESS_THAN) { - return binarySearchRecursive(array, value, mid + 1, high, compareFn); - } - if (compareFn(element, value) === Compare.BIGGER_THAN) { - return binarySearchRecursive(array, value, low, mid - 1, compareFn); - } - return mid; - } - return DOES_NOT_EXIST; -} - -export function binarySearch(array, value, compareFn = defaultCompare) { - const sortedArray = quickSort(array); - const low = 0; - const high = sortedArray.length - 1; - return binarySearchRecursive(array, value, low, high, compareFn); -} diff --git a/src/js/algorithms/search/binary-search.js b/src/js/algorithms/search/binary-search.js deleted file mode 100644 index 0c2f9fba..00000000 --- a/src/js/algorithms/search/binary-search.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Compare, defaultCompare, DOES_NOT_EXIST } from '../../util'; -import { quickSort } from '../sorting/quicksort'; - -export function binarySearch(array, value, compareFn = defaultCompare) { - const sortedArray = quickSort(array); - let low = 0; - let high = sortedArray.length - 1; - while (low <= high) { - const mid = Math.floor((low + high) / 2); - const element = sortedArray[mid]; - // console.log('mid element is ' + element); - if (compareFn(element, value) === Compare.LESS_THAN) { - low = mid + 1; - // console.log('low is ' + low); - } else if (compareFn(element, value) === Compare.BIGGER_THAN) { - high = mid - 1; - // console.log('high is ' + high); - } else { - // console.log('found it'); - return mid; - } - } - return DOES_NOT_EXIST; -} diff --git a/src/js/algorithms/search/interpolation-search.js b/src/js/algorithms/search/interpolation-search.js deleted file mode 100644 index 2f9f7278..00000000 --- a/src/js/algorithms/search/interpolation-search.js +++ /dev/null @@ -1,40 +0,0 @@ -import { - biggerEquals, - Compare, - defaultCompare, - defaultEquals, - defaultDiff, - DOES_NOT_EXIST, - lesserEquals -} from '../../util'; - -export function interpolationSearch( - array, - value, - compareFn = defaultCompare, - equalsFn = defaultEquals, - diffFn = defaultDiff -) { - const { length } = array; - let low = 0; - let high = length - 1; - let position = -1; - let delta = -1; - while ( - low <= high - && biggerEquals(value, array[low], compareFn) - && lesserEquals(value, array[high], compareFn) - ) { - delta = diffFn(value, array[low]) / diffFn(array[high], array[low]); - position = low + Math.floor((high - low) * delta); - if (equalsFn(array[position], value)) { - return position; - } - if (compareFn(array[position], value) === Compare.LESS_THAN) { - low = position + 1; - } else { - high = position - 1; - } - } - return DOES_NOT_EXIST; -} diff --git a/src/js/algorithms/search/min-max-search.js b/src/js/algorithms/search/min-max-search.js deleted file mode 100644 index ddefb113..00000000 --- a/src/js/algorithms/search/min-max-search.js +++ /dev/null @@ -1,26 +0,0 @@ -import { defaultCompare, Compare } from '../../util'; - -export function findMaxValue(array, compareFn = defaultCompare) { - if (array && array.length > 0) { - let max = array[0]; - for (let i = 1; i < array.length; i++) { - if (compareFn(max, array[i]) === Compare.LESS_THAN) { - max = array[i]; - } - } - return max; - } - return undefined; -} -export function findMinValue(array, compareFn = defaultCompare) { - if (array && array.length > 0) { - let min = array[0]; - for (let i = 1; i < array.length; i++) { - if (compareFn(min, array[i]) === Compare.BIGGER_THAN) { - min = array[i]; - } - } - return min; - } - return undefined; -} diff --git a/src/js/algorithms/search/sequential-search.js b/src/js/algorithms/search/sequential-search.js deleted file mode 100644 index 346c23ac..00000000 --- a/src/js/algorithms/search/sequential-search.js +++ /dev/null @@ -1,10 +0,0 @@ -import { defaultEquals, DOES_NOT_EXIST } from '../../util'; - -export function sequentialSearch(array, value, equalsFn = defaultEquals) { - for (let i = 0; i < array.length; i++) { - if (equalsFn(value, array[i])) { - return i; - } - } - return DOES_NOT_EXIST; -} diff --git "a/src/js/algorithms/shuffle/fisher\342\200\223yates.js" "b/src/js/algorithms/shuffle/fisher\342\200\223yates.js" deleted file mode 100644 index f951a3ca..00000000 --- "a/src/js/algorithms/shuffle/fisher\342\200\223yates.js" +++ /dev/null @@ -1,11 +0,0 @@ -import { swap } from '../../util'; - -export function shuffle(array) { - let currentIndex = array.length; - while (currentIndex !== 0) { - const randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex--; - swap(array, currentIndex, randomIndex); - } - return array; -} diff --git a/src/js/algorithms/sorting/bubble-sort-improved.js b/src/js/algorithms/sorting/bubble-sort-improved.js deleted file mode 100644 index a0aba370..00000000 --- a/src/js/algorithms/sorting/bubble-sort-improved.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Compare, defaultCompare, swap } from '../../util'; - -export function modifiedBubbleSort(array, compareFn = defaultCompare) { - const { length } = array; - for (let i = 0; i < length; i++) { - // console.log('--- '); - for (let j = 0; j < length - 1 - i; j++) { - // console.log('compare ' + array[j] + ' with ' + array[j + 1]); - if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) { - // console.log('swap ' + array[j] + ' with ' + array[j + 1]); - swap(array, j, j + 1); - } - } - } - return array; -} diff --git a/src/js/algorithms/sorting/bubble-sort.js b/src/js/algorithms/sorting/bubble-sort.js deleted file mode 100644 index 7d5b928e..00000000 --- a/src/js/algorithms/sorting/bubble-sort.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Compare, defaultCompare, swap } from '../../util'; - -export function bubbleSort(array, compareFn = defaultCompare) { - const { length } = array; - for (let i = 0; i < length; i++) { - // console.log('--- '); - for (let j = 0; j < length - 1; j++) { - // console.log('compare ' + array[j] + ' with ' + array[j + 1]); - if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) { - // console.log('swap ' + array[j] + ' with ' + array[j + 1]); - swap(array, j, j + 1); - } - } - } - return array; -} diff --git a/src/js/algorithms/sorting/bucket-sort.js b/src/js/algorithms/sorting/bucket-sort.js deleted file mode 100644 index 1a11b699..00000000 --- a/src/js/algorithms/sorting/bucket-sort.js +++ /dev/null @@ -1,39 +0,0 @@ -import { insertionSort } from './insertion-sort'; - -function createBuckets(array, bucketSize) { - let minValue = array[0]; - let maxValue = array[0]; - for (let i = 1; i < array.length; i++) { - if (array[i] < minValue) { - minValue = array[i]; - } else if (array[i] > maxValue) { - maxValue = array[i]; - } - } - const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1; - const buckets = []; - for (let i = 0; i < bucketCount; i++) { - buckets[i] = []; - } - for (let i = 0; i < array.length; i++) { - buckets[Math.floor((array[i] - minValue) / bucketSize)].push(array[i]); - } - return buckets; -} -function sortBuckets(buckets) { - const sortedArray = []; - for (let i = 0; i < buckets.length; i++) { - if (buckets[i] != null) { - insertionSort(buckets[i]); - sortedArray.push(...buckets[i]); - } - } - return sortedArray; -} -export function bucketSort(array, bucketSize = 5) { - if (array.length < 2) { - return array; - } - const buckets = createBuckets(array, bucketSize); - return sortBuckets(buckets); -} diff --git a/src/js/algorithms/sorting/counting-sort.js b/src/js/algorithms/sorting/counting-sort.js deleted file mode 100644 index 9a19201b..00000000 --- a/src/js/algorithms/sorting/counting-sort.js +++ /dev/null @@ -1,24 +0,0 @@ -import { findMaxValue } from '../search/min-max-search'; - -export function countingSort(array) { - if (array.length < 2) { - return array; - } - const maxValue = findMaxValue(array); - let sortedIndex = 0; - const counts = new Array(maxValue + 1); - array.forEach(element => { - if (!counts[element]) { - counts[element] = 0; - } - counts[element]++; - }); - // console.log('Frequencies: ' + counts.join()); - counts.forEach((element, i) => { - while (element > 0) { - array[sortedIndex++] = i; - element--; - } - }); - return array; -} diff --git a/src/js/algorithms/sorting/heap-sort.js b/src/js/algorithms/sorting/heap-sort.js deleted file mode 100644 index ff1c10f1..00000000 --- a/src/js/algorithms/sorting/heap-sort.js +++ /dev/null @@ -1,34 +0,0 @@ -import { defaultCompare, swap } from '../../util'; - -function heapify(array, index, heapSize, compareFn) { - let largest = index; - const left = (2 * index) + 1; - const right = (2 * index) + 2; - if (left < heapSize && compareFn(array[left], array[index]) > 0) { - largest = left; - } - if (right < heapSize && compareFn(array[right], array[largest]) > 0) { - largest = right; - } - if (largest !== index) { - swap(array, index, largest); - heapify(array, largest, heapSize, compareFn); - } -} - -function buildMaxHeap(array, compareFn) { - for (let i = Math.floor(array.length / 2); i >= 0; i -= 1) { - heapify(array, i, array.length, compareFn); - } - return array; -} - -export default function heapSort(array, compareFn = defaultCompare) { - let heapSize = array.length; - buildMaxHeap(array, compareFn); - while (heapSize > 1) { - swap(array, 0, --heapSize); - heapify(array, 0, heapSize, compareFn); - } - return array; -} diff --git a/src/js/algorithms/sorting/insertion-sort.js b/src/js/algorithms/sorting/insertion-sort.js deleted file mode 100644 index e48689e6..00000000 --- a/src/js/algorithms/sorting/insertion-sort.js +++ /dev/null @@ -1,19 +0,0 @@ -import { Compare, defaultCompare } from '../../util'; - -export const insertionSort = (array, compareFn = defaultCompare) => { - const { length } = array; - let temp; - for (let i = 1; i < length; i++) { - let j = i; - temp = array[i]; - // console.log('to be inserted ' + temp); - while (j > 0 && compareFn(array[j - 1], temp) === Compare.BIGGER_THAN) { - // console.log('shift ' + array[j - 1]); - array[j] = array[j - 1]; - j--; - } - // console.log('insert ' + temp); - array[j] = temp; - } - return array; -}; diff --git a/src/js/algorithms/sorting/merge-sort.js b/src/js/algorithms/sorting/merge-sort.js deleted file mode 100644 index 5371e714..00000000 --- a/src/js/algorithms/sorting/merge-sort.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Compare, defaultCompare } from '../../util'; - -function merge(left, right, compareFn) { - let i = 0; - let j = 0; - const result = []; - while (i < left.length && j < right.length) { - result.push(compareFn(left[i], right[j]) === Compare.LESS_THAN ? left[i++] : right[j++]); - } - return result.concat(i < left.length ? left.slice(i) : right.slice(j)); -} -export function mergeSort(array, compareFn = defaultCompare) { - if (array.length > 1) { - const { length } = array; - const middle = Math.floor(length / 2); - const left = mergeSort(array.slice(0, middle), compareFn); - const right = mergeSort(array.slice(middle, length), compareFn); - array = merge(left, right, compareFn); - } - return array; -} diff --git a/src/js/algorithms/sorting/quicksort.js b/src/js/algorithms/sorting/quicksort.js deleted file mode 100644 index 6e27167c..00000000 --- a/src/js/algorithms/sorting/quicksort.js +++ /dev/null @@ -1,38 +0,0 @@ -import { Compare, defaultCompare, swap } from '../../util'; - -function partition(array, left, right, compareFn) { - const pivot = array[Math.floor((right + left) / 2)]; - let i = left; - let j = right; - - while (i <= j) { - while (compareFn(array[i], pivot) === Compare.LESS_THAN) { - i++; - } - while (compareFn(array[j], pivot) === Compare.BIGGER_THAN) { - j--; - } - if (i <= j) { - swap(array, i, j); - i++; - j--; - } - } - return i; -} -function quick(array, left, right, compareFn) { - let index; - if (array.length > 1) { - index = partition(array, left, right, compareFn); - if (left < index - 1) { - quick(array, left, index - 1, compareFn); - } - if (index < right) { - quick(array, index, right, compareFn); - } - } - return array; -} -export function quickSort(array, compareFn = defaultCompare) { - return quick(array, 0, array.length - 1, compareFn); -} diff --git a/src/js/algorithms/sorting/radix-sort.js b/src/js/algorithms/sorting/radix-sort.js deleted file mode 100644 index db21c37a..00000000 --- a/src/js/algorithms/sorting/radix-sort.js +++ /dev/null @@ -1,44 +0,0 @@ -import { findMaxValue, findMinValue } from '../search/min-max-search'; - -const getBucketIndex = (value, minValue, significantDigit, radixBase) => - Math.floor(((value - minValue) / significantDigit) % radixBase); - -const countingSortForRadix = (array, radixBase, significantDigit, minValue) => { - let bucketsIndex; - const buckets = []; - const aux = []; - for (let i = 0; i < radixBase; i++) { - buckets[i] = 0; - } - for (let i = 0; i < array.length; i++) { - bucketsIndex = getBucketIndex(array[i], minValue, significantDigit, radixBase); - buckets[bucketsIndex]++; - } - for (let i = 1; i < radixBase; i++) { - buckets[i] += buckets[i - 1]; - } - for (let i = array.length - 1; i >= 0; i--) { - bucketsIndex = getBucketIndex(array[i], minValue, significantDigit, radixBase); - aux[--buckets[bucketsIndex]] = array[i]; - } - for (let i = 0; i < array.length; i++) { - array[i] = aux[i]; - } - return array; -}; -export function radixSort(array, radixBase = 10) { - if (array.length < 2) { - return array; - } - const minValue = findMinValue(array); - const maxValue = findMaxValue(array); - // Perform counting sort for each significant digit, starting at 1 - let significantDigit = 1; - while ((maxValue - minValue) / significantDigit >= 1) { - // console.log('radix sort for digit ' + significantDigit); - array = countingSortForRadix(array, radixBase, significantDigit, minValue); - // console.log(array.join()); - significantDigit *= radixBase; - } - return array; -} diff --git a/src/js/algorithms/sorting/selection-sort.js b/src/js/algorithms/sorting/selection-sort.js deleted file mode 100644 index 55a9c2c0..00000000 --- a/src/js/algorithms/sorting/selection-sort.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Compare, defaultCompare, swap } from '../../util'; - -export const selectionSort = (array, compareFn = defaultCompare) => { - const { length } = array; - let indexMin; - for (let i = 0; i < length - 1; i++) { - indexMin = i; - // console.log('index ' + array[i]); - for (let j = i; j < length; j++) { - if (compareFn(array[indexMin], array[j]) === Compare.BIGGER_THAN) { - // console.log('new index min ' + array[j]); - indexMin = j; - } - } - if (i !== indexMin) { - // console.log('swap ' + array[i] + ' with ' + array[indexMin]); - swap(array, i, indexMin); - } - } - return array; -}; diff --git a/src/js/algorithms/sorting/shell-sort.js b/src/js/algorithms/sorting/shell-sort.js deleted file mode 100644 index e13127f1..00000000 --- a/src/js/algorithms/sorting/shell-sort.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Compare, defaultCompare } from '../../util'; - -export function shellSort(array, compareFn = defaultCompare) { - let increment = array.length / 2; - while (increment > 0) { - for (let i = increment; i < array.length; i++) { - let j = i; - const temp = array[i]; - while (j >= increment && compareFn(array[j - increment], temp) === Compare.BIGGER_THAN) { - array[j] = array[j - increment]; - j -= increment; - } - array[j] = temp; - } - if (increment === 2) { - increment = 1; - } else { - increment = Math.floor((increment * 5) / 11); - } - } - return array; -} diff --git a/src/js/data-structures/avl-tree.js b/src/js/data-structures/avl-tree.js deleted file mode 100644 index 6b4ee7c0..00000000 --- a/src/js/data-structures/avl-tree.js +++ /dev/null @@ -1,162 +0,0 @@ -import { Compare, defaultCompare } from '../util'; -import BinarySearchTree from './binary-search-tree'; -import { Node } from './models/node'; - -const BalanceFactor = { - UNBALANCED_RIGHT: 1, - SLIGHTLY_UNBALANCED_RIGHT: 2, - BALANCED: 3, - SLIGHTLY_UNBALANCED_LEFT: 4, - UNBALANCED_LEFT: 5 -}; - -export default class AVLTree extends BinarySearchTree { - constructor(compareFn = defaultCompare) { - super(compareFn); - this.compareFn = compareFn; - this.root = null; - } - - getNodeHeight(node) { - if (node == null) { - return -1; - } - return Math.max(this.getNodeHeight(node.left), this.getNodeHeight(node.right)) + 1; - } - - /** - * Left left case: rotate right - * - * b a - * / \ / \ - * a e -> rotationLL(b) -> c b - * / \ / \ - * c d d e - * - * @param node Node - */ - rotationLL(node) { - const tmp = node.left; - node.left = tmp.right; - tmp.right = node; - return tmp; - } - - /** - * Right right case: rotate left - * - * a b - * / \ / \ - * c b -> rotationRR(a) -> a e - * / \ / \ - * d e c d - * - * @param node Node - */ - rotationRR(node) { - const tmp = node.right; - node.right = tmp.left; - tmp.left = node; - return tmp; - } - - /** - * Left right case: rotate left then right - * @param node Node - */ - rotationLR(node) { - node.left = this.rotationRR(node.left); - return this.rotationLL(node); - } - - /** - * Right left case: rotate right then left - * @param node Node - */ - rotationRL(node) { - node.right = this.rotationLL(node.right); - return this.rotationRR(node); - } - - getBalanceFactor(node) { - const heightDifference = this.getNodeHeight(node.left) - this.getNodeHeight(node.right); - switch (heightDifference) { - case -2: - return BalanceFactor.UNBALANCED_RIGHT; - case -1: - return BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT; - case 1: - return BalanceFactor.SLIGHTLY_UNBALANCED_LEFT; - case 2: - return BalanceFactor.UNBALANCED_LEFT; - default: - return BalanceFactor.BALANCED; - } - } - - insert(key) { - this.root = this.insertNode(this.root, key); - } - - insertNode(node, key) { - if (node == null) { - return new Node(key); - } - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - node.left = this.insertNode(node.left, key); - } else { - node.right = this.insertNode(node.right, key); - } - - // verify if tree is balanced - const balanceFactor = this.getBalanceFactor(node); - if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) { - if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) { - // Left left case - node = this.rotationLL(node); - } else { - // Left right case - node = this.rotationLR(node); - } - } - if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) { - if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) { - // Right right case - node = this.rotationRR(node); - } else { - // Right left case - node = this.rotationRL(node); - } - } - return node; - } - - removeNode(node, key) { - node = super.removeNode(node, key); // {1} - if (node == null) { - return node; - } - - // verify if tree is balanced - const balanceFactor = this.getBalanceFactor(node); - if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) { - if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) { - // Left left case - node = this.rotationLL(node); - } else { - // Left right case - node = this.rotationLR(node); - } - } - if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) { - if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) { - // Right right case - node = this.rotationRR(node); - } else { - // Right left case - node = this.rotationRL(node); - } - } - return node; - } -} diff --git a/src/js/data-structures/binary-search-tree.js b/src/js/data-structures/binary-search-tree.js deleted file mode 100644 index 98795a16..00000000 --- a/src/js/data-structures/binary-search-tree.js +++ /dev/null @@ -1,152 +0,0 @@ -import { Compare, defaultCompare } from '../util'; -import { Node } from './models/node'; - -export default class BinarySearchTree { - constructor(compareFn = defaultCompare) { - this.compareFn = compareFn; - this.root = undefined; - } - - insert(key) { - // special case: first key - if (this.root == null) { - this.root = new Node(key); - } else { - this.insertNode(this.root, key); - } - } - - insertNode(node, key) { - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - if (node.left == null) { - node.left = new Node(key); - } else { - this.insertNode(node.left, key); - } - } else if (node.right == null) { - node.right = new Node(key); - } else { - this.insertNode(node.right, key); - } - } - - getRoot() { - return this.root; - } - - search(key) { - return this.searchNode(this.root, key); - } - - searchNode(node, key) { - if (node == null) { - return false; - } - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - return this.searchNode(node.left, key); - } if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) { - return this.searchNode(node.right, key); - } - return true; - } - - inOrderTraverse(callback) { - this.inOrderTraverseNode(this.root, callback); - } - - inOrderTraverseNode(node, callback) { - if (node != null) { - this.inOrderTraverseNode(node.left, callback); - callback(node.key); - this.inOrderTraverseNode(node.right, callback); - } - } - - preOrderTraverse(callback) { - this.preOrderTraverseNode(this.root, callback); - } - - preOrderTraverseNode(node, callback) { - if (node != null) { - callback(node.key); - this.preOrderTraverseNode(node.left, callback); - this.preOrderTraverseNode(node.right, callback); - } - } - - postOrderTraverse(callback) { - this.postOrderTraverseNode(this.root, callback); - } - - postOrderTraverseNode(node, callback) { - if (node != null) { - this.postOrderTraverseNode(node.left, callback); - this.postOrderTraverseNode(node.right, callback); - callback(node.key); - } - } - - min() { - return this.minNode(this.root); - } - - minNode(node) { - let current = node; - while (current != null && current.left != null) { - current = current.left; - } - return current; - } - - max() { - return this.maxNode(this.root); - } - - maxNode(node) { - let current = node; - while (current != null && current.right != null) { - current = current.right; - } - return current; - } - - remove(key) { - this.root = this.removeNode(this.root, key); - } - - removeNode(node, key) { - if (node == null) { - return undefined; - } - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - node.left = this.removeNode(node.left, key); - return node; - } if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) { - node.right = this.removeNode(node.right, key); - return node; - } - // key is equal to node.item - // handle 3 special conditions - // 1 - a leaf node - // 2 - a node with only 1 child - // 3 - a node with 2 children - // case 1 - if (node.left == null && node.right == null) { - node = undefined; - return node; - } - // case 2 - if (node.left == null) { - node = node.right; - return node; - } if (node.right == null) { - node = node.left; - return node; - } - // case 3 - const aux = this.minNode(node.right); - node.key = aux.key; - node.right = this.removeNode(node.right, aux.key); - return node; - } -} diff --git a/src/js/data-structures/circular-linked-list.js b/src/js/data-structures/circular-linked-list.js deleted file mode 100644 index 865fcb70..00000000 --- a/src/js/data-structures/circular-linked-list.js +++ /dev/null @@ -1,75 +0,0 @@ -import { defaultEquals } from '../util'; -import LinkedList from './linked-list'; -import { Node } from './models/linked-list-models'; - -export default class CircularLinkedList extends LinkedList { - constructor(equalsFn = defaultEquals) { - super(equalsFn); - } - - push(element) { - const node = new Node(element); - let current; - if (this.head == null) { - this.head = node; - } else { - current = this.getElementAt(this.size() - 1); - current.next = node; - } - // set node.next to head - to have circular list - node.next = this.head; - this.count++; - } - - insert(element, index) { - if (index >= 0 && index <= this.count) { - const node = new Node(element); - let current = this.head; - if (index === 0) { - if (this.head == null) { - // if no node in list - this.head = node; - node.next = this.head; - } else { - node.next = current; - current = this.getElementAt(this.size() - 1); - // update last element - this.head = node; - current.next = this.head; - } - } else { - const previous = this.getElementAt(index - 1); - node.next = previous.next; - previous.next = node; - } - this.count++; - return true; - } - return false; - } - - removeAt(index) { - if (index >= 0 && index < this.count) { - let current = this.head; - if (index === 0) { - if (this.size() === 1) { - this.head = undefined; - } else { - const removed = this.head; - current = this.getElementAt(this.size() - 1); - this.head = this.head.next; - current.next = this.head; - current = removed; - } - } else { - // no need to update last element for circular list - const previous = this.getElementAt(index - 1); - current = previous.next; - previous.next = current.next; - } - this.count--; - return current.element; - } - return undefined; - } -} diff --git a/src/js/data-structures/deque.js b/src/js/data-structures/deque.js deleted file mode 100644 index 82b50617..00000000 --- a/src/js/data-structures/deque.js +++ /dev/null @@ -1,88 +0,0 @@ -// @ts-check - -export default class Deque { - constructor() { - this.count = 0; - this.lowestCount = 0; - this.items = {}; - } - - addFront(element) { - if (this.isEmpty()) { - this.addBack(element); - } else if (this.lowestCount > 0) { - this.lowestCount--; - this.items[this.lowestCount] = element; - } else { - for (let i = this.count; i > 0; i--) { - this.items[i] = this.items[i - 1]; - } - this.count++; - this.items[0] = element; - } - } - - addBack(element) { - this.items[this.count] = element; - this.count++; - } - - removeFront() { - if (this.isEmpty()) { - return undefined; - } - const result = this.items[this.lowestCount]; - delete this.items[this.lowestCount]; - this.lowestCount++; - return result; - } - - removeBack() { - if (this.isEmpty()) { - return undefined; - } - this.count--; - const result = this.items[this.count]; - delete this.items[this.count]; - return result; - } - - peekFront() { - if (this.isEmpty()) { - return undefined; - } - return this.items[this.lowestCount]; - } - - peekBack() { - if (this.isEmpty()) { - return undefined; - } - return this.items[this.count - 1]; - } - - isEmpty() { - return this.size() === 0; - } - - clear() { - this.items = {}; - this.count = 0; - this.lowestCount = 0; - } - - size() { - return this.count - this.lowestCount; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - let objString = `${this.items[this.lowestCount]}`; - for (let i = this.lowestCount + 1; i < this.count; i++) { - objString = `${objString},${this.items[i]}`; - } - return objString; - } -} diff --git a/src/js/data-structures/dictionary.js b/src/js/data-structures/dictionary.js deleted file mode 100644 index 2b0568bd..00000000 --- a/src/js/data-structures/dictionary.js +++ /dev/null @@ -1,81 +0,0 @@ -import { defaultToString } from '../util'; -import { ValuePair } from './models/value-pair'; - -export default class Dictionary { - constructor(toStrFn = defaultToString) { - this.toStrFn = toStrFn; - this.table = {}; - } - - set(key, value) { - if (key != null && value != null) { - const tableKey = this.toStrFn(key); - this.table[tableKey] = new ValuePair(key, value); - return true; - } - return false; - } - - get(key) { - const valuePair = this.table[this.toStrFn(key)]; - return valuePair == null ? undefined : valuePair.value; - } - - hasKey(key) { - return this.table[this.toStrFn(key)] != null; - } - - remove(key) { - if (this.hasKey(key)) { - delete this.table[this.toStrFn(key)]; - return true; - } - return false; - } - - values() { - return this.keyValues().map(valuePair => valuePair.value); - } - - keys() { - return this.keyValues().map(valuePair => valuePair.key); - } - - keyValues() { - return Object.values(this.table); - } - - forEach(callbackFn) { - const valuePairs = this.keyValues(); - for (let i = 0; i < valuePairs.length; i++) { - const result = callbackFn(valuePairs[i].key, valuePairs[i].value); - if (result === false) { - break; - } - } - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return Object.keys(this.table).length; - } - - clear() { - this.table = {}; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const valuePairs = this.keyValues(); - let objString = `${valuePairs[0].toString()}`; - for (let i = 1; i < valuePairs.length; i++) { - objString = `${objString},${valuePairs[i].toString()}`; - } - return objString; - } -} diff --git a/src/js/data-structures/doubly-linked-list.js b/src/js/data-structures/doubly-linked-list.js deleted file mode 100644 index e6547ec4..00000000 --- a/src/js/data-structures/doubly-linked-list.js +++ /dev/null @@ -1,138 +0,0 @@ -import { defaultEquals } from '../util'; -import LinkedList from './linked-list'; -import { DoublyNode } from './models/linked-list-models'; - -export default class DoublyLinkedList extends LinkedList { - constructor(equalsFn = defaultEquals) { - super(equalsFn); - this.tail = undefined; - } - - push(element) { - const node = new DoublyNode(element); - if (this.head == null) { - this.head = node; - this.tail = node; // NEW - } else { - // attach to the tail node // NEW - this.tail.next = node; - node.prev = this.tail; - this.tail = node; - } - this.count++; - } - - insert(element, index) { - if (index >= 0 && index <= this.count) { - const node = new DoublyNode(element); - let current = this.head; - if (index === 0) { - if (this.head == null) { // NEW - this.head = node; - this.tail = node; // NEW - } else { - node.next = this.head; - this.head.prev = node; // NEW - this.head = node; - } - } else if (index === this.count) { // last item NEW - current = this.tail; - current.next = node; - node.prev = current; - this.tail = node; - } else { - const previous = this.getElementAt(index - 1); - current = previous.next; - node.next = current; - previous.next = node; - current.prev = node; // NEW - node.prev = previous; // NEW - } - this.count++; - return true; - } - return false; - } - - removeAt(index) { - if (index >= 0 && index < this.count) { - let current = this.head; - if (index === 0) { - this.head = this.head.next; - // if there is only one item, then we update tail as well //NEW - if (this.count === 1) { - // {2} - this.tail = undefined; - } else { - this.head.prev = undefined; - } - } else if (index === this.count - 1) { - // last item //NEW - current = this.tail; - this.tail = current.prev; - this.tail.next = undefined; - } else { - current = this.getElementAt(index); - const previous = current.prev; - // link previous with current's next - skip it to remove - previous.next = current.next; - current.next.prev = previous; // NEW - } - this.count--; - return current.element; - } - return undefined; - } - - indexOf(element) { - let current = this.head; - let index = 0; - while (current != null) { - if (this.equalsFn(element, current.element)) { - return index; - } - index++; - current = current.next; - } - return -1; - } - - getHead() { - return this.head; - } - - getTail() { - return this.tail; - } - - clear() { - super.clear(); - this.tail = undefined; - } - - toString() { - if (this.head == null) { - return ''; - } - let objString = `${this.head.element}`; - let current = this.head.next; - while (current != null) { - objString = `${objString},${current.element}`; - current = current.next; - } - return objString; - } - - inverseToString() { - if (this.tail == null) { - return ''; - } - let objString = `${this.tail.element}`; - let previous = this.tail.prev; - while (previous != null) { - objString = `${objString},${previous.element}`; - previous = previous.prev; - } - return objString; - } -} diff --git a/src/js/data-structures/graph.js b/src/js/data-structures/graph.js deleted file mode 100644 index f9bfbe51..00000000 --- a/src/js/data-structures/graph.js +++ /dev/null @@ -1,50 +0,0 @@ -import Dictionary from './dictionary'; - -export default class Graph { - constructor(isDirected = false) { - this.isDirected = isDirected; - this.vertices = []; - this.adjList = new Dictionary(); - } - - addVertex(v) { - if (!this.vertices.includes(v)) { - this.vertices.push(v); - this.adjList.set(v, []); // initialize adjacency list with array as well; - } - } - - addEdge(a, b) { - if (!this.adjList.get(a)) { - this.addVertex(a); - } - if (!this.adjList.get(b)) { - this.addVertex(b); - } - this.adjList.get(a).push(b); - if (this.isDirected !== true) { - this.adjList.get(b).push(a); - } - } - - getVertices() { - return this.vertices; - } - - getAdjList() { - return this.adjList; - } - - toString() { - let s = ''; - for (let i = 0; i < this.vertices.length; i++) { - s += `${this.vertices[i]} -> `; - const neighbors = this.adjList.get(this.vertices[i]); - for (let j = 0; j < neighbors.length; j++) { - s += `${neighbors[j]} `; - } - s += '\n'; - } - return s; - } -} diff --git a/src/js/data-structures/hash-table-linear-probing-lazy.js b/src/js/data-structures/hash-table-linear-probing-lazy.js deleted file mode 100644 index d7314f0e..00000000 --- a/src/js/data-structures/hash-table-linear-probing-lazy.js +++ /dev/null @@ -1,132 +0,0 @@ -import { defaultToString } from '../util'; -import { ValuePairLazy } from './models/value-pair-lazy'; - -export default class HashTableLinearProbingLazy { - constructor(toStrFn = defaultToString) { - this.toStrFn = toStrFn; - this.table = {}; - } - - loseloseHashCode(key) { - if (typeof key === 'number') { - return key; - } - const tableKey = this.toStrFn(key); - let hash = 0; - for (let i = 0; i < tableKey.length; i++) { - hash += tableKey.charCodeAt(i); - } - return hash % 37; - } - - hashCode(key) { - return this.loseloseHashCode(key); - } - - put(key, value) { - if (key != null && value != null) { - const position = this.hashCode(key); - if ( - this.table[position] == null - || (this.table[position] != null && this.table[position].isDeleted) - ) { - this.table[position] = new ValuePairLazy(key, value); - } else { - let index = position + 1; - while (this.table[index] != null && !this.table[position].isDeleted) { - index++; - } - this.table[index] = new ValuePairLazy(key, value); - } - return true; - } - return false; - } - - get(key) { - const position = this.hashCode(key); - if (this.table[position] != null) { - if (this.table[position].key === key && !this.table[position].isDeleted) { - return this.table[position].value; - } - let index = position + 1; - while ( - this.table[index] != null - && (this.table[index].key !== key || this.table[index].isDeleted) - ) { - if (this.table[index].key === key && this.table[index].isDeleted) { - return undefined; - } - index++; - } - if ( - this.table[index] != null - && this.table[index].key === key - && !this.table[index].isDeleted - ) { - return this.table[position].value; - } - } - return undefined; - } - - remove(key) { - const position = this.hashCode(key); - if (this.table[position] != null) { - if (this.table[position].key === key && !this.table[position].isDeleted) { - this.table[position].isDeleted = true; - return true; - } - let index = position + 1; - while ( - this.table[index] != null - && (this.table[index].key !== key || this.table[index].isDeleted) - ) { - index++; - } - if ( - this.table[index] != null - && this.table[index].key === key - && !this.table[index].isDeleted - ) { - this.table[index].isDeleted = true; - return true; - } - } - return false; - } - - isEmpty() { - return this.size() === 0; - } - - size() { - let count = 0; - Object.values(this.table).forEach(valuePair => { - count += valuePair.isDeleted === true ? 0 : 1; - }); - return count; - } - - clear() { - this.table = {}; - } - - getTable() { - return this.table; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const keys = Object.keys(this.table); - let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; - for (let i = 1; i < keys.length; i++) { - objString = `${objString},{${keys[i]} => ${this.table[ - keys[i] - ].toString()}}`; - } - return objString; - } -} diff --git a/src/js/data-structures/hash-table-linear-probing.js b/src/js/data-structures/hash-table-linear-probing.js deleted file mode 100644 index 73f70374..00000000 --- a/src/js/data-structures/hash-table-linear-probing.js +++ /dev/null @@ -1,124 +0,0 @@ -import { defaultToString } from '../util'; -import { ValuePair } from './models/value-pair'; - -export default class HashTableLinearProbing { - constructor(toStrFn = defaultToString) { - this.toStrFn = toStrFn; - this.table = {}; - } - - loseloseHashCode(key) { - if (typeof key === 'number') { - return key; - } - const tableKey = this.toStrFn(key); - let hash = 0; - for (let i = 0; i < tableKey.length; i++) { - hash += tableKey.charCodeAt(i); - } - return hash % 37; - } - - hashCode(key) { - return this.loseloseHashCode(key); - } - - put(key, value) { - if (key != null && value != null) { - const position = this.hashCode(key); - if (this.table[position] == null) { - this.table[position] = new ValuePair(key, value); - } else { - let index = position + 1; - while (this.table[index] != null) { - index++; - } - this.table[index] = new ValuePair(key, value); - } - return true; - } - return false; - } - - get(key) { - const position = this.hashCode(key); - if (this.table[position] != null) { - if (this.table[position].key === key) { - return this.table[position].value; - } - let index = position + 1; - while (this.table[index] != null && this.table[index].key !== key) { - index++; - } - if (this.table[index] != null && this.table[index].key === key) { - return this.table[index].value; - } - } - return undefined; - } - - remove(key) { - const position = this.hashCode(key); - if (this.table[position] != null) { - if (this.table[position].key === key) { - delete this.table[position]; - this.verifyRemoveSideEffect(key, position); - return true; - } - let index = position + 1; - while (this.table[index] != null && this.table[index].key !== key) { - index++; - } - if (this.table[index] != null && this.table[index].key === key) { - delete this.table[index]; - this.verifyRemoveSideEffect(key, index); - return true; - } - } - return false; - } - - verifyRemoveSideEffect(key, removedPosition) { - const hash = this.hashCode(key); - let index = removedPosition + 1; - while (this.table[index] != null) { - const posHash = this.hashCode(this.table[index].key); - if (posHash <= hash || posHash <= removedPosition) { - this.table[removedPosition] = this.table[index]; - delete this.table[index]; - removedPosition = index; - } - index++; - } - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return Object.keys(this.table).length; - } - - clear() { - this.table = {}; - } - - getTable() { - return this.table; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const keys = Object.keys(this.table); - let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; - for (let i = 1; i < keys.length; i++) { - objString = `${objString},{${keys[i]} => ${this.table[ - keys[i] - ].toString()}}`; - } - return objString; - } -} diff --git a/src/js/data-structures/hash-table-separate-chaining.js b/src/js/data-structures/hash-table-separate-chaining.js deleted file mode 100644 index c8646ae9..00000000 --- a/src/js/data-structures/hash-table-separate-chaining.js +++ /dev/null @@ -1,106 +0,0 @@ -import { defaultToString } from '../util'; -import LinkedList from './linked-list'; -import { ValuePair } from './models/value-pair'; - -export default class HashTableSeparateChaining { - constructor(toStrFn = defaultToString) { - this.toStrFn = toStrFn; - this.table = {}; - } - - loseloseHashCode(key) { - if (typeof key === 'number') { - return key; - } - const tableKey = this.toStrFn(key); - let hash = 0; - for (let i = 0; i < tableKey.length; i++) { - hash += tableKey.charCodeAt(i); - } - return hash % 37; - } - - hashCode(key) { - return this.loseloseHashCode(key); - } - - put(key, value) { - if (key != null && value != null) { - const position = this.hashCode(key); - if (this.table[position] == null) { - this.table[position] = new LinkedList(); - } - this.table[position].push(new ValuePair(key, value)); - return true; - } - return false; - } - - get(key) { - const position = this.hashCode(key); - const linkedList = this.table[position]; - if (linkedList != null && !linkedList.isEmpty()) { - let current = linkedList.getHead(); - while (current != null) { - if (current.element.key === key) { - return current.element.value; - } - current = current.next; - } - } - return undefined; - } - - remove(key) { - const position = this.hashCode(key); - const linkedList = this.table[position]; - if (linkedList != null && !linkedList.isEmpty()) { - let current = linkedList.getHead(); - while (current != null) { - if (current.element.key === key) { - linkedList.remove(current.element); - if (linkedList.isEmpty()) { - delete this.table[position]; - } - return true; - } - current = current.next; - } - } - return false; - } - - isEmpty() { - return this.size() === 0; - } - - size() { - let count = 0; - Object.values(this.table).forEach(linkedList => { - count += linkedList.size(); - }); - return count; - } - - clear() { - this.table = {}; - } - - getTable() { - return this.table; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const keys = Object.keys(this.table); - let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; - for (let i = 1; i < keys.length; i++) { - objString = `${objString},{${keys[i]} => ${this.table[ - keys[i] - ].toString()}}`; - } - return objString; - } -} diff --git a/src/js/data-structures/hash-table.js b/src/js/data-structures/hash-table.js deleted file mode 100644 index 79bc51fd..00000000 --- a/src/js/data-structures/hash-table.js +++ /dev/null @@ -1,85 +0,0 @@ -import { defaultToString } from '../util'; -import { ValuePair } from './models/value-pair'; - -export default class HashTable { - constructor(toStrFn = defaultToString) { - this.toStrFn = toStrFn; - this.table = {}; - } - - loseloseHashCode(key) { - if (typeof key === 'number') { - return key; - } - const tableKey = this.toStrFn(key); - let hash = 0; - for (let i = 0; i < tableKey.length; i++) { - hash += tableKey.charCodeAt(i); - } - return hash % 37; - } - - /* djb2HashCode(key) { - const tableKey = this.toStrFn(key); - let hash = 5381; - for (let i = 0; i < tableKey.length; i++) { - hash = (hash * 33) + tableKey.charCodeAt(i); - } - return hash % 1013; - } */ - hashCode(key) { - return this.loseloseHashCode(key); - } - - put(key, value) { - if (key != null && value != null) { - const position = this.hashCode(key); - this.table[position] = new ValuePair(key, value); - return true; - } - return false; - } - - get(key) { - const valuePair = this.table[this.hashCode(key)]; - return valuePair == null ? undefined : valuePair.value; - } - - remove(key) { - const hash = this.hashCode(key); - const valuePair = this.table[hash]; - if (valuePair != null) { - delete this.table[hash]; - return true; - } - return false; - } - - getTable() { - return this.table; - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return Object.keys(this.table).length; - } - - clear() { - this.table = {}; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const keys = Object.keys(this.table); - let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; - for (let i = 1; i < keys.length; i++) { - objString = `${objString},{${keys[i]} => ${this.table[keys[i]].toString()}}`; - } - return objString; - } -} diff --git a/src/js/data-structures/heap.js b/src/js/data-structures/heap.js deleted file mode 100644 index 889e5957..00000000 --- a/src/js/data-structures/heap.js +++ /dev/null @@ -1,121 +0,0 @@ -import { - Compare, defaultCompare, reverseCompare, swap -} from '../util'; - -export class MinHeap { - constructor(compareFn = defaultCompare) { - this.compareFn = compareFn; - this.heap = []; - } - - getLeftIndex(index) { - return (2 * index) + 1; - } - - getRightIndex(index) { - return (2 * index) + 2; - } - - getParentIndex(index) { - if (index === 0) { - return undefined; - } - return Math.floor((index - 1) / 2); - } - - size() { - return this.heap.length; - } - - isEmpty() { - return this.size() <= 0; - } - - clear() { - this.heap = []; - } - - findMinimum() { - return this.isEmpty() ? undefined : this.heap[0]; - } - - insert(value) { - if (value != null) { - const index = this.heap.length; - this.heap.push(value); - this.siftUp(index); - return true; - } - return false; - } - - siftDown(index) { - let element = index; - const left = this.getLeftIndex(index); - const right = this.getRightIndex(index); - const size = this.size(); - if ( - left < size - && this.compareFn(this.heap[element], this.heap[left]) === Compare.BIGGER_THAN - ) { - element = left; - } - if ( - right < size - && this.compareFn(this.heap[element], this.heap[right]) === Compare.BIGGER_THAN - ) { - element = right; - } - if (index !== element) { - swap(this.heap, index, element); - this.siftDown(element); - } - } - - siftUp(index) { - let parent = this.getParentIndex(index); - while ( - index > 0 - && this.compareFn(this.heap[parent], this.heap[index]) === Compare.BIGGER_THAN - ) { - swap(this.heap, parent, index); - index = parent; - parent = this.getParentIndex(index); - } - } - - extract() { - if (this.isEmpty()) { - return undefined; - } - if (this.size() === 1) { - return this.heap.shift(); - } - const removedValue = this.heap[0]; - this.heap[0] = this.heap.pop(); - this.siftDown(0); - return removedValue; - } - - heapify(array) { - if (array) { - this.heap = array; - } - const maxIndex = Math.floor(this.size() / 2) - 1; - for (let i = 0; i <= maxIndex; i++) { - this.siftDown(i); - } - return this.heap; - } - - getAsArray() { - return this.heap; - } -} -export class MaxHeap extends MinHeap { - constructor(compareFn = defaultCompare) { - super(compareFn); - this.compareFn = compareFn; - this.compareFn = reverseCompare(compareFn); - } -} diff --git a/src/js/data-structures/linked-list.js b/src/js/data-structures/linked-list.js deleted file mode 100644 index fdd32d8b..00000000 --- a/src/js/data-structures/linked-list.js +++ /dev/null @@ -1,117 +0,0 @@ -import { defaultEquals } from '../util'; -import { Node } from './models/linked-list-models'; - -export default class LinkedList { - constructor(equalsFn = defaultEquals) { - this.equalsFn = equalsFn; - this.count = 0; - this.head = undefined; - } - - push(element) { - const node = new Node(element); - let current; - if (this.head == null) { - // catches null && undefined - this.head = node; - } else { - current = this.head; - while (current.next != null) { - current = current.next; - } - current.next = node; - } - this.count++; - } - - getElementAt(index) { - if (index >= 0 && index <= this.count) { - let node = this.head; - for (let i = 0; i < index && node != null; i++) { - node = node.next; - } - return node; - } - return undefined; - } - - insert(element, index) { - if (index >= 0 && index <= this.count) { - const node = new Node(element); - if (index === 0) { - const current = this.head; - node.next = current; - this.head = node; - } else { - const previous = this.getElementAt(index - 1); - node.next = previous.next; - previous.next = node; - } - this.count++; - return true; - } - return false; - } - - removeAt(index) { - if (index >= 0 && index < this.count) { - let current = this.head; - if (index === 0) { - this.head = current.next; - } else { - const previous = this.getElementAt(index - 1); - current = previous.next; - previous.next = current.next; - } - this.count--; - return current.element; - } - return undefined; - } - - remove(element) { - const index = this.indexOf(element); - return this.removeAt(index); - } - - indexOf(element) { - let current = this.head; - for (let i = 0; i < this.size() && current != null; i++) { - if (this.equalsFn(element, current.element)) { - return i; - } - current = current.next; - } - return -1; - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return this.count; - } - - getHead() { - return this.head; - } - - clear() { - this.head = undefined; - this.count = 0; - } - - toString() { - if (this.head == null) { - return ''; - } - let objString = `${this.head.element}`; - let current = this.head.next; - for (let i = 1; i < this.size() && current != null; i++) { - objString = `${objString},${current.element}`; - current = current.next; - } - return objString; - } -} diff --git a/src/js/data-structures/models/linked-list-models.js b/src/js/data-structures/models/linked-list-models.js deleted file mode 100644 index 31f5dd95..00000000 --- a/src/js/data-structures/models/linked-list-models.js +++ /dev/null @@ -1,12 +0,0 @@ -export class Node { - constructor(element, next) { - this.element = element; - this.next = next; - } -} -export class DoublyNode extends Node { - constructor(element, next, prev) { - super(element, next); - this.prev = prev; - } -} diff --git a/src/js/data-structures/models/node.js b/src/js/data-structures/models/node.js deleted file mode 100644 index 33b4f371..00000000 --- a/src/js/data-structures/models/node.js +++ /dev/null @@ -1,11 +0,0 @@ -export class Node { - constructor(key) { - this.key = key; - this.left = undefined; - this.right = undefined; - } - - toString() { - return `${this.key}`; - } -} diff --git a/src/js/data-structures/models/value-pair-lazy.js b/src/js/data-structures/models/value-pair-lazy.js deleted file mode 100644 index ff2e4398..00000000 --- a/src/js/data-structures/models/value-pair-lazy.js +++ /dev/null @@ -1,10 +0,0 @@ -import { ValuePair } from './value-pair'; - -export class ValuePairLazy extends ValuePair { - constructor(key, value, isDeleted = false) { - super(key, value); - this.key = key; - this.value = value; - this.isDeleted = isDeleted; - } -} diff --git a/src/js/data-structures/models/value-pair.js b/src/js/data-structures/models/value-pair.js deleted file mode 100644 index 7aa20025..00000000 --- a/src/js/data-structures/models/value-pair.js +++ /dev/null @@ -1,10 +0,0 @@ -export class ValuePair { - constructor(key, value) { - this.key = key; - this.value = value; - } - - toString() { - return `[#${this.key}: ${this.value}]`; - } -} diff --git a/src/js/data-structures/queue.js b/src/js/data-structures/queue.js deleted file mode 100644 index 6c879004..00000000 --- a/src/js/data-structures/queue.js +++ /dev/null @@ -1,56 +0,0 @@ -// @ts-check - -export default class Queue { - constructor() { - this.count = 0; - this.lowestCount = 0; - this.items = {}; - } - - enqueue(element) { - this.items[this.count] = element; - this.count++; - } - - dequeue() { - if (this.isEmpty()) { - return undefined; - } - const result = this.items[this.lowestCount]; - delete this.items[this.lowestCount]; - this.lowestCount++; - return result; - } - - peek() { - if (this.isEmpty()) { - return undefined; - } - return this.items[this.lowestCount]; - } - - isEmpty() { - return this.size() === 0; - } - - clear() { - this.items = {}; - this.count = 0; - this.lowestCount = 0; - } - - size() { - return this.count - this.lowestCount; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - let objString = `${this.items[this.lowestCount]}`; - for (let i = this.lowestCount + 1; i < this.count; i++) { - objString = `${objString},${this.items[i]}`; - } - return objString; - } -} diff --git a/src/js/data-structures/set.js b/src/js/data-structures/set.js deleted file mode 100644 index 996316ac..00000000 --- a/src/js/data-structures/set.js +++ /dev/null @@ -1,93 +0,0 @@ -export default class Set { - constructor() { - this.items = {}; - } - - add(element) { - if (!this.has(element)) { - this.items[element] = element; - return true; - } - return false; - } - - delete(element) { - if (this.has(element)) { - delete this.items[element]; - return true; - } - return false; - } - - has(element) { - return Object.prototype.hasOwnProperty.call(this.items, element); - } - - values() { - return Object.values(this.items); - } - - union(otherSet) { - const unionSet = new Set(); - this.values().forEach(value => unionSet.add(value)); - otherSet.values().forEach(value => unionSet.add(value)); - return unionSet; - } - - intersection(otherSet) { - const intersectionSet = new Set(); - const values = this.values(); - const otherValues = otherSet.values(); - let biggerSet = values; - let smallerSet = otherValues; - if (otherValues.length - values.length > 0) { - biggerSet = otherValues; - smallerSet = values; - } - smallerSet.forEach(value => { - if (biggerSet.includes(value)) { - intersectionSet.add(value); - } - }); - return intersectionSet; - } - - difference(otherSet) { - const differenceSet = new Set(); - this.values().forEach(value => { - if (!otherSet.has(value)) { - differenceSet.add(value); - } - }); - return differenceSet; - } - - isSubsetOf(otherSet) { - const values = this.values(); - return values.every((value) => otherSet.has(value)); - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return Object.keys(this.items).length; - } - - clear() { - this.items = {}; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const values = this.values(); - let objString = `${values[0]}`; - for (let i = 1; i < values.length; i++) { - objString = `${objString},${values[i].toString()}`; - } - return objString; - } -} diff --git a/src/js/data-structures/sorted-linked-list.js b/src/js/data-structures/sorted-linked-list.js deleted file mode 100644 index 6712f6a8..00000000 --- a/src/js/data-structures/sorted-linked-list.js +++ /dev/null @@ -1,40 +0,0 @@ -import { Compare, defaultCompare, defaultEquals } from '../util'; -import LinkedList from './linked-list'; - -export default class SortedLinkedList extends LinkedList { - constructor(equalsFn = defaultEquals, compareFn = defaultCompare) { - super(equalsFn); - this.equalsFn = equalsFn; - this.compareFn = compareFn; - } - - push(element) { - if (this.isEmpty()) { - super.push(element); - } else { - const index = this.getIndexNextSortedElement(element); - super.insert(element, index); - } - } - - insert(element, index = 0) { - if (this.isEmpty()) { - return super.insert(element, index === 0 ? index : 0); - } - const pos = this.getIndexNextSortedElement(element); - return super.insert(element, pos); - } - - getIndexNextSortedElement(element) { - let current = this.head; - let i = 0; - for (; i < this.size() && current; i++) { - const comp = this.compareFn(element, current.element); - if (comp === Compare.LESS_THAN) { - return i; - } - current = current.next; - } - return i; - } -} diff --git a/src/js/data-structures/stack-array.js b/src/js/data-structures/stack-array.js deleted file mode 100644 index 1491eb2c..00000000 --- a/src/js/data-structures/stack-array.js +++ /dev/null @@ -1,39 +0,0 @@ -// @ts-check - -export default class StackArray { - constructor() { - this.items = []; - } - - push(element) { - this.items.push(element); - } - - pop() { - return this.items.pop(); - } - - peek() { - return this.items[this.items.length - 1]; - } - - isEmpty() { - return this.items.length === 0; - } - - size() { - return this.items.length; - } - - clear() { - this.items = []; - } - - toArray() { - return this.items; - } - - toString() { - return this.items.toString(); - } -} diff --git a/src/js/data-structures/stack-linked-list.js b/src/js/data-structures/stack-linked-list.js deleted file mode 100644 index 902a5d78..00000000 --- a/src/js/data-structures/stack-linked-list.js +++ /dev/null @@ -1,42 +0,0 @@ -import DoublyLinkedList from './doubly-linked-list'; - -export default class StackLinkedList { - constructor() { - this.items = new DoublyLinkedList(); - } - - push(element) { - this.items.push(element); - } - - pop() { - if (this.isEmpty()) { - return undefined; - } - const result = this.items.removeAt(this.size() - 1); - return result; - } - - peek() { - if (this.isEmpty()) { - return undefined; - } - return this.items.getElementAt(this.size() - 1).element; - } - - isEmpty() { - return this.items.isEmpty(); - } - - size() { - return this.items.size(); - } - - clear() { - this.items.clear(); - } - - toString() { - return this.items.toString(); - } -} diff --git a/src/js/data-structures/stack.js b/src/js/data-structures/stack.js deleted file mode 100644 index af9b297b..00000000 --- a/src/js/data-structures/stack.js +++ /dev/null @@ -1,57 +0,0 @@ -// @ts-check - -export default class Stack { - constructor() { - this.count = 0; - this.items = {}; - } - - push(element) { - this.items[this.count] = element; - this.count++; - } - - pop() { - if (this.isEmpty()) { - return undefined; - } - this.count--; - const result = this.items[this.count]; - delete this.items[this.count]; - return result; - } - - peek() { - if (this.isEmpty()) { - return undefined; - } - return this.items[this.count - 1]; - } - - isEmpty() { - return this.count === 0; - } - - size() { - return this.count; - } - - clear() { - /* while (!this.isEmpty()) { - this.pop(); - } */ - this.items = {}; - this.count = 0; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - let objString = `${this.items[0]}`; - for (let i = 1; i < this.count; i++) { - objString = `${objString},${this.items[i]}`; - } - return objString; - } -} diff --git a/src/js/index.js b/src/js/index.js deleted file mode 100644 index fa359f81..00000000 --- a/src/js/index.js +++ /dev/null @@ -1,98 +0,0 @@ -import * as _util from './util'; - -// chapters 05 and 07 -export const util = _util; - -// chapter 03 -export { default as StackArray } from './data-structures/stack-array'; -export { default as Stack } from './data-structures/stack'; -export { hanoi } from './others/hanoi'; -export { hanoiStack } from './others/hanoi'; -export { baseConverter } from './others/base-converter'; -export { decimalToBinary } from './others/base-converter'; -export { parenthesesChecker } from './others/balanced-symbols'; - -// chapter 04 -export { default as Queue } from './data-structures/queue'; -export { default as Deque } from './data-structures/deque'; -export { hotPotato } from './others/hot-potato'; -export { palindromeChecker } from './others/palindrome-checker'; - -// chapter 05 -export { default as LinkedList } from './data-structures/linked-list'; -export { default as DoublyLinkedList } from './data-structures/doubly-linked-list'; -export { default as CircularLinkedList } from './data-structures/circular-linked-list'; -export { default as SortedLinkedList } from './data-structures/sorted-linked-list'; -export { default as StackLinkedList } from './data-structures/stack-linked-list'; - -// chapter 06 -export { default as Set } from './data-structures/set'; - -// chapter 07 -export { default as Dictionary } from './data-structures/dictionary'; -export { default as HashTable } from './data-structures/hash-table'; -export { default as HashTableSeparateChaining } from './data-structures/hash-table-separate-chaining'; -export { default as HashTableLinearProbing } from './data-structures/hash-table-linear-probing'; -export { default as HashTableLinearProbingLazy } from './data-structures/hash-table-linear-probing-lazy'; - -// chapter 08 -export { factorialIterative } from './others/factorial'; -export { factorial } from './others/factorial'; -export { fibonacci } from './others/fibonacci'; -export { fibonacciIterative } from './others/fibonacci'; -export { fibonacciMemoization } from './others/fibonacci'; - -// chapter 09 -export { default as BinarySearchTree } from './data-structures/binary-search-tree'; -export { default as AVLTree } from './data-structures/avl-tree'; - -// chapter 10 -export { MinHeap } from './data-structures/heap'; -export { MaxHeap } from './data-structures/heap'; -export { default as heapSort } from './algorithms/sorting/heap-sort'; - -// chapter 11 -export { default as Graph } from './data-structures/graph'; -export { breadthFirstSearch } from './algorithms/graph/breadth-first-search'; -export { BFS } from './algorithms/graph/breadth-first-search'; -export { depthFirstSearch } from './algorithms/graph/depth-first-search'; -export { DFS } from './algorithms/graph/depth-first-search'; -export { dijkstra } from './algorithms/graph/dijkstra'; -export { floydWarshall } from './algorithms/graph/floyd-warshall'; -export { prim } from './algorithms/graph/prim'; -export { kruskal } from './algorithms/graph/kruskal'; - -// chapter 12 -export { shuffle } from './algorithms/shuffle/fisher–yates'; - -export { bubbleSort } from './algorithms/sorting/bubble-sort'; -export { modifiedBubbleSort } from './algorithms/sorting/bubble-sort-improved'; -export { bucketSort } from './algorithms/sorting/bucket-sort'; -export { countingSort } from './algorithms/sorting/counting-sort'; -export { insertionSort } from './algorithms/sorting/insertion-sort'; -export { mergeSort } from './algorithms/sorting/merge-sort'; -export { quickSort } from './algorithms/sorting/quicksort'; -export { radixSort } from './algorithms/sorting/radix-sort'; -export { selectionSort } from './algorithms/sorting/selection-sort'; -export { shellSort } from './algorithms/sorting/shell-sort'; - -export { binarySearch } from './algorithms/search/binary-search'; -export { interpolationSearch } from './algorithms/search/interpolation-search'; -export { sequentialSearch } from './algorithms/search/sequential-search'; -export { findMaxValue } from './algorithms/search/min-max-search'; -export { findMinValue } from './algorithms/search/min-max-search'; - -// chapter 14 -export { binarySearch as binarySearchRecursive } from './algorithms/search/binary-search-recursive'; -export { minCoinChange } from './algorithms/dynamic-programing/min-coin-change'; -export { minCoinChange as minCoinChangeGreedy } from './algorithms/greedy/min-coin-change'; -export { knapSack } from './algorithms/dynamic-programing/knapsack'; -export { knapSack as knapSackRecursive } from './algorithms/dynamic-programing/knapsack-recursive'; -export { knapSack as knapSackGreedy } from './algorithms/greedy/knapsack'; -export { lcs } from './algorithms/dynamic-programing/longest-common-subsequence'; -export { lcs as lcsPrint } from './algorithms/dynamic-programing/longest-common-subsequence-print'; -export { lcs as lcsRecursive } from './algorithms/greedy/longest-common-subsequence'; -export { matrixChainOrder } from './algorithms/dynamic-programing/matrix-chain-multiplication'; -export { matrixChainOrder as matrixChainOrderGreedy } from './algorithms/greedy/matrix-chain-multiplication'; -export { ratInAMaze } from './algorithms/backtracking/rat-in-maze'; -export { sudokuSolver } from './algorithms/backtracking/sudoku-solver'; diff --git a/src/js/others/balanced-symbols.js b/src/js/others/balanced-symbols.js deleted file mode 100644 index 70bcd27d..00000000 --- a/src/js/others/balanced-symbols.js +++ /dev/null @@ -1,28 +0,0 @@ -// @ts-check -import Stack from '../data-structures/stack'; - -export function parenthesesChecker(symbols) { - const stack = new Stack(); - const opens = '([{'; - const closers = ')]}'; - let balanced = true; - let index = 0; - let symbol; - let top; - - while (index < symbols.length && balanced) { - symbol = symbols[index]; - if (opens.indexOf(symbol) >= 0) { - stack.push(symbol); - } else if (stack.isEmpty()) { - balanced = false; - } else { - top = stack.pop(); - if (!(opens.indexOf(top) === closers.indexOf(symbol))) { - balanced = false; - } - } - index++; - } - return balanced && stack.isEmpty(); -} diff --git a/src/js/others/base-converter.js b/src/js/others/base-converter.js deleted file mode 100644 index 0213b1d7..00000000 --- a/src/js/others/base-converter.js +++ /dev/null @@ -1,45 +0,0 @@ -// @ts-check -import Stack from '../data-structures/stack'; - -export function decimalToBinary(decNumber) { - const remStack = new Stack(); - let number = decNumber; - let rem; - let binaryString = ''; - - while (number > 0) { - rem = Math.floor(number % 2); - remStack.push(rem); - number = Math.floor(number / 2); - } - - while (!remStack.isEmpty()) { - binaryString += remStack.pop().toString(); - } - - return binaryString; -} - -export function baseConverter(decNumber, base) { - const remStack = new Stack(); - const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - let number = decNumber; - let rem; - let baseString = ''; - - if (!(base >= 2 && base <= 36)) { - return ''; - } - - while (number > 0) { - rem = Math.floor(number % base); - remStack.push(rem); - number = Math.floor(number / base); - } - - while (!remStack.isEmpty()) { - baseString += digits[remStack.pop()]; - } - - return baseString; -} diff --git a/src/js/others/factorial.js b/src/js/others/factorial.js deleted file mode 100644 index 8592c36e..00000000 --- a/src/js/others/factorial.js +++ /dev/null @@ -1,20 +0,0 @@ -export function factorialIterative(number) { - if (number < 0) { - return undefined; - } - let total = 1; - for (let n = number; n > 1; n--) { - total *= n; - } - return total; -} - -export function factorial(n) { - if (n < 0) { - return undefined; - } - if (n === 1 || n === 0) { - return 1; - } - return n * factorial(n - 1); -} diff --git a/src/js/others/fibonacci.js b/src/js/others/fibonacci.js deleted file mode 100644 index e0ded2f9..00000000 --- a/src/js/others/fibonacci.js +++ /dev/null @@ -1,32 +0,0 @@ -export function fibonacci(n) { - if (n < 1) { - return 0; - } - if (n <= 2) { - return 1; - } - return fibonacci(n - 1) + fibonacci(n - 2); -} - -export function fibonacciIterative(n) { - if (n < 1) { return 0; } - let fibNMinus2 = 0; - let fibNMinus1 = 1; - let fibN = n; - for (let i = 2; i <= n; i++) { - fibN = fibNMinus1 + fibNMinus2; - fibNMinus2 = fibNMinus1; - fibNMinus1 = fibN; - } - return fibN; -} - -export function fibonacciMemoization(n) { - if (n < 1) { return 0; } - const memo = [0, 1]; - const fibonacciMem = num => { - if (memo[num] != null) { return memo[num]; } - return (memo[num] = fibonacciMem(num - 1) + fibonacciMem(num - 2)); - }; - return fibonacciMem(n); -} diff --git a/src/js/others/hanoi.js b/src/js/others/hanoi.js deleted file mode 100644 index b1ab2d0e..00000000 --- a/src/js/others/hanoi.js +++ /dev/null @@ -1,52 +0,0 @@ -// @ts-check -import Stack from '../data-structures/stack'; - -function towerOfHanoi(plates, source, helper, dest, sourceName, helperName, destName, moves = []) { - if (plates <= 0) { - return moves; - } - if (plates === 1) { - dest.push(source.pop()); - const move = {}; - move[sourceName] = source.toString(); - move[helperName] = helper.toString(); - move[destName] = dest.toString(); - moves.push(move); - } else { - towerOfHanoi(plates - 1, source, dest, helper, sourceName, destName, helperName, moves); - dest.push(source.pop()); - const move = {}; - move[sourceName] = source.toString(); - move[helperName] = helper.toString(); - move[destName] = dest.toString(); - moves.push(move); - towerOfHanoi(plates - 1, helper, source, dest, helperName, sourceName, destName, moves); - } - return moves; -} - -export function hanoiStack(plates) { - const source = new Stack(); - const dest = new Stack(); - const helper = new Stack(); - - for (let i = plates; i > 0; i--) { - source.push(i); - } - - return towerOfHanoi(plates, source, helper, dest, 'source', 'helper', 'dest'); -} - -export function hanoi(plates, source, helper, dest, moves = []) { - if (plates <= 0) { - return moves; - } - if (plates === 1) { - moves.push([source, dest]); - } else { - hanoi(plates - 1, source, dest, helper, moves); - moves.push([source, dest]); - hanoi(plates - 1, helper, source, dest, moves); - } - return moves; -} diff --git a/src/js/others/hot-potato.js b/src/js/others/hot-potato.js deleted file mode 100644 index b34fcc64..00000000 --- a/src/js/others/hot-potato.js +++ /dev/null @@ -1,22 +0,0 @@ -import Queue from '../data-structures/queue'; - -export function hotPotato(elementsList, num) { - const queue = new Queue(); - const elimitatedList = []; - - for (let i = 0; i < elementsList.length; i++) { - queue.enqueue(elementsList[i]); - } - - while (queue.size() > 1) { - for (let i = 0; i < num; i++) { - queue.enqueue(queue.dequeue()); - } - elimitatedList.push(queue.dequeue()); - } - - return { - eliminated: elimitatedList, - winner: queue.dequeue() - }; -} diff --git a/src/js/others/palindrome-checker.js b/src/js/others/palindrome-checker.js deleted file mode 100644 index 1551e26a..00000000 --- a/src/js/others/palindrome-checker.js +++ /dev/null @@ -1,29 +0,0 @@ -import Deque from '../data-structures/deque'; - -export function palindromeChecker(aString) { - if ( - aString === undefined - || aString === null - || (aString !== null && aString.length === 0) - ) { - return false; - } - const deque = new Deque(); - const lowerString = aString.toLocaleLowerCase().split(' ').join(''); - let firstChar; - let lastChar; - - for (let i = 0; i < lowerString.length; i++) { - deque.addBack(lowerString.charAt(i)); - } - - while (deque.size() > 1) { - firstChar = deque.removeFront(); - lastChar = deque.removeBack(); - if (firstChar !== lastChar) { - return false; - } - } - - return true; -} diff --git a/src/js/util.js b/src/js/util.js deleted file mode 100644 index 9e780fba..00000000 --- a/src/js/util.js +++ /dev/null @@ -1,53 +0,0 @@ -export const Compare = { - LESS_THAN: -1, - BIGGER_THAN: 1, - EQUALS: 0 -}; - -export const DOES_NOT_EXIST = -1; - -export function lesserEquals(a, b, compareFn) { - const comp = compareFn(a, b); - return comp === Compare.LESS_THAN || comp === Compare.EQUALS; -} - -export function biggerEquals(a, b, compareFn) { - const comp = compareFn(a, b); - return comp === Compare.BIGGER_THAN || comp === Compare.EQUALS; -} - -export function defaultCompare(a, b) { - if (a === b) { - return Compare.EQUALS; - } - return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN; -} - -export function defaultEquals(a, b) { - return a === b; -} - -export function defaultToString(item) { - if (item === null) { - return 'NULL'; - } if (item === undefined) { - return 'UNDEFINED'; - } if (typeof item === 'string' || item instanceof String) { - return `${item}`; - } - return item.toString(); -} - -export function swap(array, a, b) { - /* const temp = array[a]; - array[a] = array[b]; - array[b] = temp; */ - [array[a], array[b]] = [array[b], array[a]]; -} -export function reverseCompare(compareFn) { - return (a, b) => compareFn(b, a); -} - -export function defaultDiff(a, b) { - return Number(a) - Number(b); -} diff --git a/src/ts/algorithms/backtracking/rat-in-maze.ts b/src/ts/algorithms/backtracking/rat-in-maze.ts deleted file mode 100644 index 047d4982..00000000 --- a/src/ts/algorithms/backtracking/rat-in-maze.ts +++ /dev/null @@ -1,54 +0,0 @@ -export function ratInAMaze(maze: Array>) { - const solution: Array> = []; - - for (let i = 0; i < maze.length; i++) { - solution[i] = []; - for (let j = 0; j < maze[i].length; j++) { - solution[i][j] = 0; - } - } - - if (findPath(maze, 0, 0, solution) === true) { - return solution; - } else { - return 'NO PATH FOUND'; - } -} - -function findPath( - maze: Array>, - x: number, - y: number, - solution: Array> -) { - const n = maze.length; - if (x === n - 1 && y === n - 1) { - solution[x][y] = 1; - return true; - } - - if (isSafe(maze, x, y) === true) { - solution[x][y] = 1; - - if (findPath(maze, x + 1, y, solution)) { - return true; - } - - if (findPath(maze, x, y + 1, solution)) { - return true; - } - - solution[x][y] = 0; - return false; - } - - return false; -} - -function isSafe(maze: Array>, x: number, y: number) { - const n = maze.length; - if (x >= 0 && y >= 0 && x < n && y < n && maze[x][y] !== 0) { - return true; - } - return false; -} diff --git a/src/ts/algorithms/backtracking/sudoku-solver.ts b/src/ts/algorithms/backtracking/sudoku-solver.ts deleted file mode 100644 index 3ada1069..00000000 --- a/src/ts/algorithms/backtracking/sudoku-solver.ts +++ /dev/null @@ -1,87 +0,0 @@ -const UNASSIGNED = 0; - -export function sudokuSolver(grid: Array>) { - if (solveSudoku(grid) === true) { - return grid; - } else { - return 'NO SOLUTION EXISTS!'; - } -} - -function solveSudoku(grid: Array>) { - let row = 0; - let col = 0; - let checkBlankSpaces = false; - - for (row = 0; row < grid.length; row++) { - for (col = 0; col < grid[row].length; col++) { - if (grid[row][col] === UNASSIGNED) { - checkBlankSpaces = true; - break; - } - } - if (checkBlankSpaces === true) { - break; - } - } - - if (checkBlankSpaces === false) { - return true; - } - - for (let num = 1; num <= 9; num++) { - if (isSafe(grid, row, col, num)) { - grid[row][col] = num; - - if (solveSudoku(grid)) { - return true; - } - - grid[row][col] = UNASSIGNED; - } - } - - return false; -} - -function usedInRow(grid: Array>, row: number, num: number) { - for (let col = 0; col < grid.length; col++) { - if (grid[row][col] === num) { - return true; - } - } - return false; -} - -function usedInCol(grid: Array>, col: number, num: number) { - for (let row = 0; row < grid.length; row++) { - if (grid[row][col] === num) { - return true; - } - } - return false; -} - -function usedInBox( - grid: Array>, - boxStartRow: number, - boxStartCol: number, - num: number -) { - for (let row = 0; row < 3; row++) { - for (let col = 0; col < 3; col++) { - if (grid[row + boxStartRow][col + boxStartCol] === num) { - return true; - } - } - } - return false; -} - -function isSafe(grid: Array>, row: number, col: number, num: number) { - return ( - !usedInRow(grid, row, num) && - !usedInCol(grid, col, num) && - !usedInBox(grid, row - row % 3, col - col % 3, num) - ); -} diff --git a/src/ts/algorithms/dynamic-programing/knapsack-recursive.ts b/src/ts/algorithms/dynamic-programing/knapsack-recursive.ts deleted file mode 100644 index 0fce59a5..00000000 --- a/src/ts/algorithms/dynamic-programing/knapsack-recursive.ts +++ /dev/null @@ -1,13 +0,0 @@ -export function knapSack(capacity: number, weights: number[], values: number[], n: number): number { - if (n === 0 || capacity === 0) { - return 0; - } - - if (weights[n - 1] > capacity) { - return knapSack(capacity, weights, values, n - 1); - } else { - const a: number = values[n - 1] + knapSack(capacity - weights[n - 1], weights, values, n - 1); - const b: number = knapSack(capacity, weights, values, n - 1); - return a > b ? a : b; - } -} diff --git a/src/ts/algorithms/dynamic-programing/knapsack.ts b/src/ts/algorithms/dynamic-programing/knapsack.ts deleted file mode 100644 index bfa42398..00000000 --- a/src/ts/algorithms/dynamic-programing/knapsack.ts +++ /dev/null @@ -1,51 +0,0 @@ -export function knapSack(capacity: number, weights: number[], values: number[], n: number) { - const kS: Array> = []; - - for (let i = 0; i <= n; i++) { - kS[i] = []; - } - - for (let i = 0; i <= n; i++) { - for (let w = 0; w <= capacity; w++) { - if (i === 0 || w === 0) { - kS[i][w] = 0; - } else if (weights[i - 1] <= w) { - const a = values[i - 1] + kS[i - 1][w - weights[i - 1]]; - const b = kS[i - 1][w]; - kS[i][w] = a > b ? a : b; // max(a,b) - // console.log(a + ' can be part of the solution'); - } else { - kS[i][w] = kS[i - 1][w]; - } - } - // console.log(kS[i].join()); - } - - // extra algorithm to find the items that are part of the solution - findValues(n, capacity, kS); - - return kS[n][capacity]; -} - -function findValues( - n: number, - capacity: number, - kS: Array> -) { - let i = n; - let k = capacity; - - // console.log('Items that are part of the solution:'); - - while (i > 0 && k > 0) { - if (kS[i][k] !== kS[i - 1][k]) { - /* console.log( - 'item ' + i + ' can be part of solution w,v: ' + weights[i - 1] + ',' + values[i - 1] - ); */ - i--; - k = k - kS[i][k]; - } else { - i--; - } - } -} diff --git a/src/ts/algorithms/dynamic-programing/longest-common-subsequence-print.ts b/src/ts/algorithms/dynamic-programing/longest-common-subsequence-print.ts deleted file mode 100644 index 7c26b986..00000000 --- a/src/ts/algorithms/dynamic-programing/longest-common-subsequence-print.ts +++ /dev/null @@ -1,60 +0,0 @@ -export function lcs(wordX: string, wordY: string) { - const m = wordX.length; - const n = wordY.length; - const l: Array> = []; - const solution: Array> = []; - - for (let i = 0; i <= m; i++) { - l[i] = []; - solution[i] = []; - for (let j = 0; j <= n; j++) { - l[i][j] = 0; - solution[i][j] = '0'; - } - } - - for (let i = 0; i <= m; i++) { - for (let j = 0; j <= n; j++) { - if (i === 0 || j === 0) { - l[i][j] = 0; - } else if (wordX[i - 1] === wordY[j - 1]) { - l[i][j] = l[i - 1][j - 1] + 1; - solution[i][j] = 'diagonal'; - } else { - const a = l[i - 1][j]; - const b = l[i][j - 1]; - l[i][j] = a > b ? a : b; // max(a,b) - solution[i][j] = l[i][j] === l[i - 1][j] ? 'top' : 'left'; - } - } - // console.log(l[i].join()); - // console.log(solution[i].join()); - } - - return printSolution(solution, wordX, m, n); - - // return l[m][n]; -} - -function printSolution(solution: Array>, wordX: string, m: number, n: number) { - let a = m; - let b = n; - let x = solution[a][b]; - let answer = ''; - - while (x !== '0') { - if (solution[a][b] === 'diagonal') { - answer = wordX[a - 1] + answer; - a--; - b--; - } else if (solution[a][b] === 'left') { - b--; - } else if (solution[a][b] === 'top') { - a--; - } - x = solution[a][b]; - } - - return answer; - // console.log('lcs: ' + answer); -} diff --git a/src/ts/algorithms/dynamic-programing/longest-common-subsequence.ts b/src/ts/algorithms/dynamic-programing/longest-common-subsequence.ts deleted file mode 100644 index 9aa48054..00000000 --- a/src/ts/algorithms/dynamic-programing/longest-common-subsequence.ts +++ /dev/null @@ -1,29 +0,0 @@ -export function lcs(wordX: string, wordY: string) { - const m = wordX.length; - const n = wordY.length; - const l: Array> = []; - - for (let i = 0; i <= m; i++) { - l[i] = []; - for (let j = 0; j <= n; j++) { - l[i][j] = 0; - } - } - - for (let i = 0; i <= m; i++) { - for (let j = 0; j <= n; j++) { - if (i === 0 || j === 0) { - l[i][j] = 0; - } else if (wordX[i - 1] === wordY[j - 1]) { - l[i][j] = l[i - 1][j - 1] + 1; - } else { - const a = l[i - 1][j]; - const b = l[i][j - 1]; - l[i][j] = a > b ? a : b; // max(a,b) - } - } - // console.log(l[i].join()); - } - - return l[m][n]; -} diff --git a/src/ts/algorithms/dynamic-programing/matrix-chain-multiplication.ts b/src/ts/algorithms/dynamic-programing/matrix-chain-multiplication.ts deleted file mode 100644 index c2743ec5..00000000 --- a/src/ts/algorithms/dynamic-programing/matrix-chain-multiplication.ts +++ /dev/null @@ -1,52 +0,0 @@ -export function matrixChainOrder(p: number[]): number { - const n = p.length; - - const m: Array> = []; - const s: Array> = []; - - for (let i = 1; i <= n; i++) { - m[i] = []; - m[i][i] = 0; - } - - for (let i = 0; i <= n; i++) { - // to help printing the optimal solution - s[i] = []; // auxiliary - for (let j = 0; j <= n; j++) { - s[i][j] = 0; - } - } - - for (let l = 2; l < n; l++) { - for (let i = 1; i <= n - l + 1; i++) { - const j = i + l - 1; - m[i][j] = Number.MAX_SAFE_INTEGER; - for (let k = i; k <= j - 1; k++) { - // q = cost/scalar multiplications - const q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]; - if (q < m[i][j]) { - m[i][j] = q; - s[i][j] = k; // s[i,j] = Second auxiliary table that stores k - } - } - } - } - - // console.log(m); - // console.log(s); - - printOptimalParenthesis(s, 1, n - 1); - - return m[1][n - 1]; -} - -function printOptimalParenthesis(s: Array>, i: number, j: number) { - if (i === j) { - // console.log('A[' + i + ']'); - } else { - // console.log('('); - printOptimalParenthesis(s, i, s[i][j]); - printOptimalParenthesis(s, s[i][j] + 1, j); - // console.log(')'); - } -} diff --git a/src/ts/algorithms/dynamic-programing/min-coin-change.ts b/src/ts/algorithms/dynamic-programing/min-coin-change.ts deleted file mode 100644 index 85baeb83..00000000 --- a/src/ts/algorithms/dynamic-programing/min-coin-change.ts +++ /dev/null @@ -1,34 +0,0 @@ -export function minCoinChange(coins: number[], amount: number) { - const cache: Array> = []; - - // tslint:disable-next-line:no-shadowed-variable - const makeChange = function(amount: number) { - if (!amount) { - return []; - } - if (cache[amount]) { - return cache[amount]; - } - let min: number[] = [], - newMin, - newAmount; - for (let i = 0; i < coins.length; i++) { - const coin = coins[i]; - newAmount = amount - coin; - if (newAmount >= 0) { - newMin = makeChange(newAmount); - } - if ( - newAmount >= 0 && - (newMin.length < min.length - 1 || !min.length) && - (newMin.length || !newAmount) - ) { - min = [coin].concat(newMin); - // console.log('new Min ' + min + ' for ' + amount); - } - } - return (cache[amount] = min); - }; - - return makeChange(amount); -} diff --git a/src/ts/algorithms/graph/breadth-first-search.ts b/src/ts/algorithms/graph/breadth-first-search.ts deleted file mode 100644 index 95438007..00000000 --- a/src/ts/algorithms/graph/breadth-first-search.ts +++ /dev/null @@ -1,78 +0,0 @@ -import Graph from '../../data-structures/graph'; -import Queue from '../../data-structures/queue'; - -enum Colors { - WHITE = 0, - GREY = 1, - BLACK = 2 -} - -const initializeColor = (vertices: (string | number)[]) => { - const color: any = {}; - for (let i = 0; i < vertices.length; i++) { - color[vertices[i]] = Colors.WHITE; - } - return color; -}; - -export const breadthFirstSearch = (graph: Graph, startVertex: any, callback: Function) => { - const vertices = graph.getVertices(); - const adjList = graph.getAdjList(); - const color = initializeColor(vertices); - const queue = new Queue(); - - queue.enqueue(startVertex); - - while (!queue.isEmpty()) { - const u = queue.dequeue(); - const neighbors = adjList.get(u); - color[u] = Colors.GREY; - for (let i = 0; i < neighbors.length; i++) { - const w = neighbors[i]; - if (color[w] === Colors.WHITE) { - color[w] = Colors.GREY; - queue.enqueue(w); - } - } - color[u] = Colors.BLACK; - if (callback) { - callback(u); - } - } -}; - -export const bfs = (graph: Graph, startVertex: any) => { - const vertices = graph.getVertices(); - const adjList = graph.getAdjList(); - const color = initializeColor(vertices); - const queue = new Queue(); - const distances: any = {}; - const predecessors: any = {}; - queue.enqueue(startVertex); - - for (let i = 0; i < vertices.length; i++) { - distances[vertices[i]] = 0; - predecessors[vertices[i]] = null; - } - - while (!queue.isEmpty()) { - const u = queue.dequeue(), - neighbors = adjList.get(u); - color[u] = Colors.GREY; - for (let i = 0; i < neighbors.length; i++) { - const w = neighbors[i]; - if (color[w] === Colors.WHITE) { - color[w] = Colors.GREY; - distances[w] = distances[u] + 1; - predecessors[w] = u; - queue.enqueue(w); - } - } - color[u] = Colors.BLACK; - } - - return { - distances: distances, - predecessors: predecessors - }; -}; diff --git a/src/ts/algorithms/graph/depth-first-search.ts b/src/ts/algorithms/graph/depth-first-search.ts deleted file mode 100644 index de47c93f..00000000 --- a/src/ts/algorithms/graph/depth-first-search.ts +++ /dev/null @@ -1,102 +0,0 @@ -import Graph from '../../data-structures/graph'; - -enum Colors { - WHITE = 0, - GREY = 1, - BLACK = 2 -} - -const initializeColor = (vertices: (string | number)[]) => { - const color: any = {}; - for (let i = 0; i < vertices.length; i++) { - color[vertices[i]] = Colors.WHITE; - } - return color; -}; - -const depthFirstSearchVisit = ( - u: string | number, - color: any, - adjList: any, - callback: Function -) => { - color[u] = 'grey'; - if (callback) { - callback(u); - } - // console.log('Discovered ' + u); - const neighbors = adjList.get(u); - for (let i = 0; i < neighbors.length; i++) { - const w = neighbors[i]; - if (color[w] === Colors.WHITE) { - depthFirstSearchVisit(w, color, adjList, callback); - } - } - color[u] = Colors.BLACK; - // console.log('explored ' + u); -}; - -export const depthFirstSearch = (graph: Graph, callback: Function) => { - const vertices = graph.getVertices(); - const adjList = graph.getAdjList(); - const color = initializeColor(vertices); - - for (let i = 0; i < vertices.length; i++) { - if (color[vertices[i]] === Colors.WHITE) { - depthFirstSearchVisit(vertices[i], color, adjList, callback); - } - } -}; - -const DFSVisit = ( - u: string | number, - color: any, - d: any, - f: any, - p: any, - time: any, - adjList: any -) => { - // console.log('discovered ' + u); - color[u] = Colors.GREY; - d[u] = ++time.count; - const neighbors = adjList.get(u); - for (let i = 0; i < neighbors.length; i++) { - const w = neighbors[i]; - if (color[w] === Colors.WHITE) { - p[w] = u; - DFSVisit(w, color, d, f, p, time, adjList); - } - } - color[u] = Colors.BLACK; - f[u] = ++time.count; - // console.log('explored ' + u); -}; - -export const DFS = (graph: Graph) => { - const vertices = graph.getVertices(); - const adjList = graph.getAdjList(); - const color = initializeColor(vertices); - const d: any = {}; - const f: any = {}; - const p: any = {}; - const time = { count: 0 }; - - for (let i = 0; i < vertices.length; i++) { - f[vertices[i]] = 0; - d[vertices[i]] = 0; - p[vertices[i]] = null; - } - - for (let i = 0; i < vertices.length; i++) { - if (color[vertices[i]] === Colors.WHITE) { - DFSVisit(vertices[i], color, d, f, p, time, adjList); - } - } - - return { - discovery: d, - finished: f, - predecessors: p - }; -}; diff --git a/src/ts/algorithms/graph/dijkstra.ts b/src/ts/algorithms/graph/dijkstra.ts deleted file mode 100644 index a3dd4752..00000000 --- a/src/ts/algorithms/graph/dijkstra.ts +++ /dev/null @@ -1,42 +0,0 @@ -const INF = Number.MAX_SAFE_INTEGER; - -const minDistance = (dist: number[], visited: boolean[]) => { - let min = INF; - let minIndex = -1; - - for (let v = 0; v < dist.length; v++) { - if (visited[v] === false && dist[v] <= min) { - min = dist[v]; - minIndex = v; - } - } - - return minIndex; -}; - -export const dijkstra = (graph: number[][], src: number) => { - const dist: number[] = []; - const visited: boolean[] = []; - const length = graph.length; - - for (let i = 0; i < length; i++) { - dist[i] = INF; - visited[i] = false; - } - - dist[src] = 0; - - for (let i = 0; i < length - 1; i++) { - const u = minDistance(dist, visited); - - visited[u] = true; - - for (let v = 0; v < length; v++) { - if (!visited[v] && graph[u][v] !== 0 && dist[u] !== INF && dist[u] + graph[u][v] < dist[v]) { - dist[v] = dist[u] + graph[u][v]; - } - } - } - - return dist; -}; diff --git a/src/ts/algorithms/graph/floyd-warshall.ts b/src/ts/algorithms/graph/floyd-warshall.ts deleted file mode 100644 index 7699c6e8..00000000 --- a/src/ts/algorithms/graph/floyd-warshall.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const floydWarshall = (graph: number[][]) => { - const dist: number[][] = []; - const length = graph.length; - - for (let i = 0; i < length; i++) { - dist[i] = []; - for (let j = 0; j < length; j++) { - if (i === j) { - dist[i][j] = 0; - } else if (!isFinite(graph[i][j])) { - dist[i][j] = Infinity; - } else { - dist[i][j] = graph[i][j]; - } - } - } - - for (let k = 0; k < length; k++) { - for (let i = 0; i < length; i++) { - for (let j = 0; j < length; j++) { - if (dist[i][k] + dist[k][j] < dist[i][j]) { - dist[i][j] = dist[i][k] + dist[k][j]; - } - } - } - } - - return dist; -}; diff --git a/src/ts/algorithms/graph/kruskal.ts b/src/ts/algorithms/graph/kruskal.ts deleted file mode 100644 index 978b1e3b..00000000 --- a/src/ts/algorithms/graph/kruskal.ts +++ /dev/null @@ -1,67 +0,0 @@ -const INF = Number.MAX_SAFE_INTEGER; - -const find = (i: number, parent: number[]) => { - while (parent[i]) { - i = parent[i]; - } - return i; -}; - -const union = (i: number, j: number, parent: number[]) => { - if (i !== j) { - parent[j] = i; - return true; - } - return false; -}; - -const initializeCost = (graph: number[][]) => { - const cost: number[][] = []; - const length = graph.length; - for (let i = 0; i < length; i++) { - cost[i] = []; - for (let j = 0; j < length; j++) { - if (graph[i][j] === 0) { - cost[i][j] = INF; - } else { - cost[i][j] = graph[i][j]; - } - } - } - return cost; -}; - -export const kruskal = (graph: number[][]) => { - const length = graph.length; - const parent: number[] = []; - let ne = 0; - let a; - let b; - let u; - let v; - - const cost = initializeCost(graph); - - while (ne < length - 1) { - for (let i = 0, min = INF; i < length; i++) { - for (let j = 0; j < length; j++) { - if (cost[i][j] < min) { - min = cost[i][j]; - a = u = i; - b = v = j; - } - } - } - - u = find(u, parent); - v = find(v, parent); - - if (union(u, v, parent)) { - ne++; - } - - cost[a][b] = cost[b][a] = INF; - } - - return parent; -}; diff --git a/src/ts/algorithms/graph/prim.ts b/src/ts/algorithms/graph/prim.ts deleted file mode 100644 index 85892d03..00000000 --- a/src/ts/algorithms/graph/prim.ts +++ /dev/null @@ -1,45 +0,0 @@ -const INF = Number.MAX_SAFE_INTEGER; - -const minKey = (graph: number[][], key: number[], visited: boolean[]) => { - // Initialize min value - let min = INF; - let minIndex = 0; - - for (let v = 0; v < graph.length; v++) { - if (visited[v] === false && key[v] < min) { - min = key[v]; - minIndex = v; - } - } - - return minIndex; -}; - -export const prim = (graph: number[][]) => { - const parent: number[] = []; - const key: number[] = []; - const visited: boolean[] = []; - const length = graph.length; - - for (let i = 0; i < length; i++) { - key[i] = INF; - visited[i] = false; - } - - key[0] = 0; - parent[0] = -1; - - for (let i = 0; i < length - 1; i++) { - const u = minKey(graph, key, visited); - visited[u] = true; - - for (let v = 0; v < length; v++) { - if (graph[u][v] && visited[v] === false && graph[u][v] < key[v]) { - parent[v] = u; - key[v] = graph[u][v]; - } - } - } - - return parent; -}; diff --git a/src/ts/algorithms/greedy/knapsack.ts b/src/ts/algorithms/greedy/knapsack.ts deleted file mode 100644 index 101ebae5..00000000 --- a/src/ts/algorithms/greedy/knapsack.ts +++ /dev/null @@ -1,19 +0,0 @@ -export function knapSack(capacity: number, weights: number[], values: number[]) { - const n = values.length; - let load = 0; - let val = 0; - - for (let i = 0; i < n && load < capacity; i++) { - if (weights[i] <= capacity - load) { - val += values[i]; - load += weights[i]; - // console.log('using item ' + (i + 1) + ' for the solution'); - } else { - const r = (capacity - load) / weights[i]; - val += r * values[i]; - load += weights[i]; - // console.log('using ratio of ' + r + ' for item ' + (i + 1) + ' for the solution'); - } - } - return val; -} diff --git a/src/ts/algorithms/greedy/longest-common-subsequence.ts b/src/ts/algorithms/greedy/longest-common-subsequence.ts deleted file mode 100644 index a7239f66..00000000 --- a/src/ts/algorithms/greedy/longest-common-subsequence.ts +++ /dev/null @@ -1,13 +0,0 @@ -export function lcs(wordX: string, wordY: string, m = wordX.length, n = wordY.length): number { - if (m === 0 || n === 0) { - return 0; - } - - if (wordX[m - 1] === wordY[n - 1]) { - return 1 + lcs(wordX, wordY, m - 1, n - 1); - } else { - const a = lcs(wordX, wordY, m, n - 1); - const b = lcs(wordX, wordY, m - 1, n); - return a > b ? a : b; - } -} diff --git a/src/ts/algorithms/greedy/matrix-chain-multiplication.ts b/src/ts/algorithms/greedy/matrix-chain-multiplication.ts deleted file mode 100644 index fc23fced..00000000 --- a/src/ts/algorithms/greedy/matrix-chain-multiplication.ts +++ /dev/null @@ -1,18 +0,0 @@ -export function matrixChainOrder(p: number[], i = 1, j = p.length - 1): number { - if (i === j) { - return 0; - } - - let min = Number.MAX_SAFE_INTEGER; - - for (let k = i; k < j; k++) { - const count = - matrixChainOrder(p, i, k) + matrixChainOrder(p, k + 1, j) + p[i - 1] * p[k] * p[j]; - - if (count < min) { - min = count; - } - } - - return min; -} diff --git a/src/ts/algorithms/greedy/min-coin-change.ts b/src/ts/algorithms/greedy/min-coin-change.ts deleted file mode 100644 index 14f3fbf6..00000000 --- a/src/ts/algorithms/greedy/min-coin-change.ts +++ /dev/null @@ -1,12 +0,0 @@ -export function minCoinChange(coins: number[], amount: number) { - const change: number[] = []; - let total = 0; - for (let i = coins.length; i >= 0; i--) { - const coin = coins[i]; - while (total + coin <= amount) { - change.push(coin); - total += coin; - } - } - return change; -} diff --git a/src/ts/algorithms/math/find-divisors.ts b/src/ts/algorithms/math/find-divisors.ts deleted file mode 100644 index ea454418..00000000 --- a/src/ts/algorithms/math/find-divisors.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const findDivisors = (num: number) => { - const divisors = []; - - const sqrt = Math.floor(Math.sqrt(num)); - - for (let i = 1; i <= sqrt; i++) { - if (num % i === 0) { - divisors.push(i); - if (i !== sqrt) { - divisors.push(Math.floor(num / i)); - } - } - } - - if (num >= 2 && !divisors.includes(num)) { - divisors.push(num); - } - - divisors.sort((a, b) => a - b); - - return divisors; -}; diff --git a/src/ts/algorithms/math/gcd.ts b/src/ts/algorithms/math/gcd.ts deleted file mode 100644 index 02a6fbbc..00000000 --- a/src/ts/algorithms/math/gcd.ts +++ /dev/null @@ -1,25 +0,0 @@ -export const gcd = (num1: number, num2: number): number => { - if (num1 < 0 || num2 < 0) { - return gcd(Math.abs(num1), Math.abs(num2)); - } - if (num1 === 0) { - return num2; - } - if (num2 === 0) { - return num1; - } - if (num1 > num2) { - return gcd(num1 % num2, num2); - } - return gcd(num1, num2 % num1); -}; - -export const gcdArray = (num: number[]) => { - let result = num[0]; - - for (let i = 1; i < num.length; i++) { - result = gcd(num[i], result); - } - - return result; -}; diff --git a/src/ts/algorithms/math/greatest-difference.ts b/src/ts/algorithms/math/greatest-difference.ts deleted file mode 100644 index a0412445..00000000 --- a/src/ts/algorithms/math/greatest-difference.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const greatestDifference = (numbers: number[]) => { - let index = 0; - let largest = numbers[0]; - const length = numbers.length; - let number; - let smallest = numbers[0]; - - for (index; index < length; index++) { - number = numbers[index]; - - if (number > largest) { - largest = number; - } - if (number < smallest) { - smallest = number; - } - } - - return largest - smallest; -}; diff --git a/src/ts/algorithms/math/lcm.ts b/src/ts/algorithms/math/lcm.ts deleted file mode 100644 index a4c4ac37..00000000 --- a/src/ts/algorithms/math/lcm.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { gcd } from './gcd'; - -export const lcm = (num1: number, num2: number) => { - if (num1 === 0 || num2 === 0) { - return 0; - } - num1 = Math.abs(num1); - num2 = Math.abs(num2); - return (num1 * num2) / gcd(num1, num2); -}; - -export const lcmArray = (num: number[]) => { - let result = num[0]; - - for (let i = 1; i < num.length; i++) { - result = num[i] * result / gcd(num[i], result); - } - - return result; -}; diff --git a/src/ts/algorithms/math/primality-test.ts b/src/ts/algorithms/math/primality-test.ts deleted file mode 100644 index f04e899d..00000000 --- a/src/ts/algorithms/math/primality-test.ts +++ /dev/null @@ -1,37 +0,0 @@ -export const isPrime = (n: number) => { - if (n <= 1) { - return false; - } - - const sqrt = Math.floor(Math.sqrt(n)); - for (let i = 2; i <= sqrt; i++) { - if (n % i === 0) { - return false; - } - } - - return true; -}; - -export const testPrime = (n: number) => { - if (n <= 1) { - return false; - } else { - if (n === 2 || n === 3) { - return true; - } else if (n % 2 === 0) { - return false; - } else { - const sqrt = Math.floor(Math.sqrt(n)); - for (let i = 3; i <= sqrt; i += 2) { - if (n % i === 0) { - return false; - } - } - } - } - return true; -}; - -// tslint:disable-next-line:max-line-length -export const isPrime2 = (n: number) => (n >= 2) ? (![...Array(n).keys()].slice(2).map(i => !(n % i)).includes(true) && ![0, 1].includes(n)) : false; diff --git a/src/ts/algorithms/math/sieve-eratosthenes.ts b/src/ts/algorithms/math/sieve-eratosthenes.ts deleted file mode 100644 index 353389a1..00000000 --- a/src/ts/algorithms/math/sieve-eratosthenes.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const sieveOfEratosthenes = (n: number) => { - - const sieve: boolean[] = []; - const primes: number[] = []; - - sieve[1] = false; - - for (let i = 2; i <= n; i++) { - sieve[i] = true; - } - - for (let p = 2; p * p <= n; p++) { - if (sieve[p]) { - for (let i = p * 2; i <= n; i += p) { - sieve[i] = false; - } - } - } - - sieve.forEach((value, index) => { - if (value) { - primes.push(index); - } - }, primes); - - return primes; -}; diff --git a/src/ts/algorithms/search/binary-search-recursive.ts b/src/ts/algorithms/search/binary-search-recursive.ts deleted file mode 100644 index 6d902139..00000000 --- a/src/ts/algorithms/search/binary-search-recursive.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Compare, defaultCompare, DOES_NOT_EXIST } from '../../util'; -import { quickSort } from '../sorting/quicksort'; - -function binarySearchRecursive( - array: T[], - value: T, - low: number, - high: number, - compareFn = defaultCompare -): number { - if (low <= high) { - const mid = Math.floor((low + high) / 2); - const element = array[mid]; - - if (compareFn(element, value) === Compare.LESS_THAN) { - return binarySearchRecursive(array, value, mid + 1, high, compareFn); - } else if (compareFn(element, value) === Compare.BIGGER_THAN) { - return binarySearchRecursive(array, value, low, mid - 1, compareFn); - } else { - return mid; - } - } - return DOES_NOT_EXIST; -} - -export function binarySearch(array: T[], value: T, compareFn = defaultCompare) { - const sortedArray = quickSort(array); - const low = 0; - const high = sortedArray.length - 1; - - return binarySearchRecursive(array, value, low, high, compareFn); -} diff --git a/src/ts/algorithms/search/binary-search.ts b/src/ts/algorithms/search/binary-search.ts deleted file mode 100644 index 2e8513bf..00000000 --- a/src/ts/algorithms/search/binary-search.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Compare, defaultCompare, DOES_NOT_EXIST } from '../../util'; -import { quickSort } from '../sorting/quicksort'; - -export function binarySearch (array: T[], value: T, compareFn = defaultCompare) { - const sortedArray = quickSort(array); - let low = 0; - let high = sortedArray.length - 1; - - while (low <= high) { - const mid = Math.floor((low + high) / 2); - const element = sortedArray[mid]; - // console.log('mid element is ' + element); - if (compareFn(element, value) === Compare.LESS_THAN) { - low = mid + 1; - // console.log('low is ' + low); - } else if (compareFn(element, value) === Compare.BIGGER_THAN) { - high = mid - 1; - // console.log('high is ' + high); - } else { - // console.log('found it'); - return mid; - } - } - return DOES_NOT_EXIST; -} diff --git a/src/ts/algorithms/search/interpolation-search.ts b/src/ts/algorithms/search/interpolation-search.ts deleted file mode 100644 index aebdeb09..00000000 --- a/src/ts/algorithms/search/interpolation-search.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - biggerEquals, - Compare, - defaultCompare, - defaultEquals, - defaultDiff, - DOES_NOT_EXIST, - lesserEquals -} from '../../util'; - -export function interpolationSearch( - array: T[], - value: T, - compareFn = defaultCompare, - equalsFn = defaultEquals, - diffFn = defaultDiff -) { - const { length } = array; - let low = 0; - let high = length - 1; - let position = -1; - let delta = -1; - while ( - low <= high && - biggerEquals(value, array[low], compareFn) && - lesserEquals(value, array[high], compareFn) - ) { - delta = diffFn(value, array[low]) / diffFn(array[high], array[low]); - position = low + Math.floor((high - low) * delta); - if (equalsFn(array[position], value)) { - return position; - } - if (compareFn(array[position], value) === Compare.LESS_THAN) { - low = position + 1; - } else { - high = position - 1; - } - } - - return DOES_NOT_EXIST; -} diff --git a/src/ts/algorithms/search/min-max-search.ts b/src/ts/algorithms/search/min-max-search.ts deleted file mode 100644 index 1869f412..00000000 --- a/src/ts/algorithms/search/min-max-search.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { defaultCompare, Compare } from '../../util'; - -export function findMaxValue(array: T[], compareFn = defaultCompare) { - if (array && array.length > 0) { - let max = array[0]; - for (let i = 1; i < array.length; i++) { - if (compareFn(max, array[i]) === Compare.LESS_THAN) { - max = array[i]; - } - } - return max; - } - return undefined; -} - -export function findMinValue(array: T[], compareFn = defaultCompare) { - if (array && array.length > 0) { - let min = array[0]; - for (let i = 1; i < array.length; i++) { - if (compareFn(min, array[i]) === Compare.BIGGER_THAN) { - min = array[i]; - } - } - return min; - } - return undefined; -} diff --git a/src/ts/algorithms/search/sequential-search.ts b/src/ts/algorithms/search/sequential-search.ts deleted file mode 100644 index ba9ddf6c..00000000 --- a/src/ts/algorithms/search/sequential-search.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { defaultEquals, DOES_NOT_EXIST, IEqualsFunction } from '../../util'; - -export function sequentialSearch(array: T[], value: T, equalsFn: IEqualsFunction = defaultEquals) { - for (let i = 0; i < array.length; i++) { - if (equalsFn(value, array[i])) { - return i; - } - } - return DOES_NOT_EXIST; -} diff --git "a/src/ts/algorithms/shuffle/fisher\342\200\223yates.ts" "b/src/ts/algorithms/shuffle/fisher\342\200\223yates.ts" deleted file mode 100644 index b5869692..00000000 --- "a/src/ts/algorithms/shuffle/fisher\342\200\223yates.ts" +++ /dev/null @@ -1,10 +0,0 @@ -import { swap } from '../../util'; - -export function shuffle(array: T[]) { - for (let i = array.length - 1; i > 0; i--) { - const randomIndex = Math.floor(Math.random() * (i + 1)); - swap(array, i, randomIndex); - } - - return array; -} diff --git a/src/ts/algorithms/sorting/bubble-sort-improved.ts b/src/ts/algorithms/sorting/bubble-sort-improved.ts deleted file mode 100644 index 6e016d4d..00000000 --- a/src/ts/algorithms/sorting/bubble-sort-improved.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Compare, defaultCompare, swap } from '../../util'; - -export function modifiedBubbleSort(array: T[], compareFn = defaultCompare) { - const { length } = array; - - for (let i = 0; i < length; i++) { - // console.log('--- '); - for (let j = 0; j < length - 1 - i; j++) { - // console.log('compare ' + array[j] + ' with ' + array[j + 1]); - if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) { - // console.log('swap ' + array[j] + ' with ' + array[j + 1]); - swap(array, j, j + 1); - } - } - } - - return array; -} diff --git a/src/ts/algorithms/sorting/bubble-sort.ts b/src/ts/algorithms/sorting/bubble-sort.ts deleted file mode 100644 index 41074f6f..00000000 --- a/src/ts/algorithms/sorting/bubble-sort.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Compare, defaultCompare, swap } from '../../util'; - -export function bubbleSort(array: T[], compareFn = defaultCompare) { - const { length } = array; - - for (let i = 0; i < length; i++) { - // console.log('--- '); - for (let j = 0; j < length - 1; j++) { - // console.log('compare ' + array[j] + ' with ' + array[j + 1]); - if (compareFn(array[j], array[j + 1]) === Compare.BIGGER_THAN) { - // console.log('swap ' + array[j] + ' with ' + array[j + 1]); - swap(array, j, j + 1); - } - } - } - - return array; -} diff --git a/src/ts/algorithms/sorting/bucket-sort.ts b/src/ts/algorithms/sorting/bucket-sort.ts deleted file mode 100644 index bcb8f61b..00000000 --- a/src/ts/algorithms/sorting/bucket-sort.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { insertionSort } from './insertion-sort'; - -function createBuckets(array: number[], bucketSize: number): number[][] { - let minValue = array[0]; - let maxValue = array[0]; - for (let i = 1; i < array.length; i++) { - if (array[i] < minValue) { - minValue = array[i]; - } else if (array[i] > maxValue) { - maxValue = array[i]; - } - } - - const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1; - const buckets = []; - for (let i = 0; i < bucketCount; i++) { - buckets[i] = []; - } - - for (let i = 0; i < array.length; i++) { - buckets[Math.floor((array[i] - minValue) / bucketSize)].push(array[i]); - } - - return buckets; -} - -function sortBuckets(buckets: number[][]) { - const sortedArray = []; - for (let i = 0; i < buckets.length; i++) { - if (buckets[i] != null) { - insertionSort(buckets[i]); - - sortedArray.push(...buckets[i]); - } - } - - return sortedArray; -} - -export function bucketSort(array: number[], bucketSize = 5) { - if (array.length < 2) { - return array; - } - - const buckets = createBuckets(array, bucketSize); - - return sortBuckets(buckets); -} diff --git a/src/ts/algorithms/sorting/counting-sort.ts b/src/ts/algorithms/sorting/counting-sort.ts deleted file mode 100644 index be3d9046..00000000 --- a/src/ts/algorithms/sorting/counting-sort.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { findMaxValue } from '../search/min-max-search'; - -export function countingSort(array: number[]) { - - if (array.length < 2) { - return array; - } - - const maxValue = findMaxValue(array); - let sortedIndex = 0; - const counts = new Array(maxValue + 1); - - array.forEach(element => { - if (!counts[element]) { - counts[element] = 0; - } - counts[element]++; - }); - - // console.log('Frequencies: ' + counts.join()); - - counts.forEach((element, i) => { - while (element > 0) { - array[sortedIndex++] = i; - element--; - } - }); - - return array; -} diff --git a/src/ts/algorithms/sorting/heap-sort.ts b/src/ts/algorithms/sorting/heap-sort.ts deleted file mode 100644 index 7f461860..00000000 --- a/src/ts/algorithms/sorting/heap-sort.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { defaultCompare, ICompareFunction, swap } from '../../util'; - -function heapify(array: any[], index: number, heapSize: number, compareFn: ICompareFunction) { - let largest = index; - const left = (2 * index) + 1; - const right = (2 * index) + 2; - - if (left < heapSize && compareFn(array[left], array[index]) > 0) { - largest = left; - } - - if (right < heapSize && compareFn(array[right], array[largest]) > 0) { - largest = right; - } - - if (largest !== index) { - swap(array, index, largest); - heapify(array, largest, heapSize, compareFn); - } -} - -function buildMaxHeap(array: any[], compareFn: ICompareFunction) { - for (let i = Math.floor(array.length / 2); i >= 0; i -= 1) { - heapify(array, i, array.length, compareFn); - } - return array; -} - -export default function heapSort(array: any[], compareFn = defaultCompare) { - let heapSize = array.length; - buildMaxHeap(array, compareFn); - while (heapSize > 1) { - swap(array, 0, --heapSize); - heapify(array, 0, heapSize, compareFn); - } - return array; -} diff --git a/src/ts/algorithms/sorting/insertion-sort.ts b/src/ts/algorithms/sorting/insertion-sort.ts deleted file mode 100644 index e67c4f34..00000000 --- a/src/ts/algorithms/sorting/insertion-sort.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Compare, defaultCompare } from '../../util'; - -export const insertionSort = (array: any[], compareFn = defaultCompare) => { - const { length } = array; - let temp; - for (let i = 1; i < length; i++) { - let j = i; - temp = array[i]; - // console.log('to be inserted ' + temp); - while (j > 0 && compareFn(array[j - 1], temp) === Compare.BIGGER_THAN) { - // console.log('shift ' + array[j - 1]); - array[j] = array[j - 1]; - j--; - } - // console.log('insert ' + temp); - array[j] = temp; - } - - return array; -}; diff --git a/src/ts/algorithms/sorting/merge-sort.ts b/src/ts/algorithms/sorting/merge-sort.ts deleted file mode 100644 index b4f20f65..00000000 --- a/src/ts/algorithms/sorting/merge-sort.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Compare, defaultCompare, ICompareFunction } from '../../util'; - -function merge(left: T[], right: T[], compareFn: ICompareFunction) { - let i = 0; - let j = 0; - const result = []; - - while (i < left.length && j < right.length) { - result.push(compareFn(left[i], right[j]) === Compare.LESS_THAN ? left[i++] : right[j++]); - } - - return result.concat(i < left.length ? left.slice(i) : right.slice(j)); -} - -export function mergeSort(array: T[], compareFn = defaultCompare): T[] { - if (array.length > 1) { - const { length } = array; - const middle = Math.floor(length / 2); - const left = mergeSort(array.slice(0, middle), compareFn); - const right = mergeSort(array.slice(middle, length), compareFn); - array = merge(left, right, compareFn); - } - - return array; -} diff --git a/src/ts/algorithms/sorting/quicksort.ts b/src/ts/algorithms/sorting/quicksort.ts deleted file mode 100644 index f9336b19..00000000 --- a/src/ts/algorithms/sorting/quicksort.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Compare, defaultCompare, ICompareFunction, swap } from '../../util'; - -const partition = function(array: any[], left: number, right: number, compareFn: ICompareFunction) { - const pivot = array[Math.floor((right + left) / 2)]; - let i = left; - let j = right; - - // console.log('pivot is ' + pivot + '; left is ' + left + '; right is ' + right); - - while (i <= j) { - while (compareFn(array[i], pivot) === Compare.LESS_THAN) { - i++; - // console.log('i = ' + i); - } - - while (compareFn(array[j], pivot) === Compare.BIGGER_THAN) { - j--; - // console.log('j = ' + j); - } - - if (i <= j) { - // console.log('swap ' + array[i] + ' with ' + array[j]); - swap(array, i, j); - i++; - j--; - } - } - - return i; -}; - -const quick = function( - array: any[], - left: number, - right: number, - compareFn: ICompareFunction -) { - let index; - - if (array.length > 1) { - index = partition(array, left, right, compareFn); - - if (left < index - 1) { - quick(array, left, index - 1, compareFn); - } - - if (index < right) { - quick(array, index, right, compareFn); - } - } - return array; -}; - -export const quickSort = (array: any[], compareFn = defaultCompare) => { - return quick(array, 0, array.length - 1, compareFn); -}; diff --git a/src/ts/algorithms/sorting/radix-sort.ts b/src/ts/algorithms/sorting/radix-sort.ts deleted file mode 100644 index e6d1027a..00000000 --- a/src/ts/algorithms/sorting/radix-sort.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { findMaxValue, findMinValue } from '../search/min-max-search'; - -const countingSortForRadix = ( - array: number[], - radixBase: number, - significantDigit: number, - minValue: any -) => { - let bucketsIndex; - const buckets: number[] = []; - const aux: number[] = []; - - for (let i = 0; i < radixBase; i++) { - buckets[i] = 0; - } - - for (let i = 0; i < array.length; i++) { - bucketsIndex = Math.floor(((array[i] - minValue) / significantDigit) % radixBase); - buckets[bucketsIndex]++; - } - - for (let i = 1; i < radixBase; i++) { - buckets[i] += buckets[i - 1]; - } - - for (let i = array.length - 1; i >= 0; i--) { - bucketsIndex = Math.floor(((array[i] - minValue) / significantDigit) % radixBase); - aux[--buckets[bucketsIndex]] = array[i]; - } - - - // array = []; - // array.push(...aux); - for (let i = 0; i < array.length; i++) { - array[i] = aux[i]; - } - - return array; -}; - -export function radixSort(array: number[], radixBase = 10) { - - if (array.length < 2) { - return array; - } - - const minValue = findMinValue(array); - const maxValue = findMaxValue(array); - - // Perform counting sort for each significant digit, starting at 1 - let significantDigit = 1; - while ((maxValue - minValue) / significantDigit >= 1) { - // console.log('radix sort for digit ' + significantDigit); - array = countingSortForRadix(array, radixBase, significantDigit, minValue); - // console.log(array.join()); - significantDigit *= radixBase; - } - - return array; -} diff --git a/src/ts/algorithms/sorting/selection-sort.ts b/src/ts/algorithms/sorting/selection-sort.ts deleted file mode 100644 index 465e78a1..00000000 --- a/src/ts/algorithms/sorting/selection-sort.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Compare, defaultCompare, swap } from '../../util'; - -export const selectionSort = (array: any[], compareFn = defaultCompare) => { - const { length } = array; - let indexMin; - - for (let i = 0; i < length - 1; i++) { - indexMin = i; - // console.log('index ' + array[i]); - for (let j = i; j < length; j++) { - if (compareFn(array[indexMin], array[j]) === Compare.BIGGER_THAN) { - // console.log('new index min ' + array[j]); - indexMin = j; - } - } - if (i !== indexMin) { - // console.log('swap ' + array[i] + ' with ' + array[indexMin]); - swap(array, i, indexMin); - } - } - - return array; -}; diff --git a/src/ts/algorithms/sorting/shell-sort.ts b/src/ts/algorithms/sorting/shell-sort.ts deleted file mode 100644 index 19e11bf9..00000000 --- a/src/ts/algorithms/sorting/shell-sort.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Compare, defaultCompare } from '../../util'; - -export function shellSort(array: T[], compareFn = defaultCompare) { - let increment = array.length / 2; - while (increment > 0) { - for (let i = increment; i < array.length; i++) { - let j = i; - const temp = array[i]; - - while (j >= increment && compareFn(array[j - increment], temp) === Compare.BIGGER_THAN) { - array[j] = array[j - increment]; - j = j - increment; - } - - array[j] = temp; - } - - if (increment === 2) { - increment = 1; - } else { - increment = Math.floor(increment * 5 / 11); - } - } - return array; -} diff --git a/src/ts/algorithms/string/brute-force.ts b/src/ts/algorithms/string/brute-force.ts deleted file mode 100644 index 1bf21f85..00000000 --- a/src/ts/algorithms/string/brute-force.ts +++ /dev/null @@ -1,22 +0,0 @@ -const stringSearch = (text: string, pattern: string) => { - const n = text.length; - const m = pattern.length; - - if (m > n) { - return -1; - } - - for (let i = 0; i < n; i++) { - let j = 0; - for (j = 0; j < m && (i + j) < n; j++) { - if (text.charAt(i + j) !== pattern.charAt(j)) { - break; - } - } - if (j === m) { - return i; - } - } - - return -1; -}; diff --git a/src/ts/algorithms/string/huffman.ts b/src/ts/algorithms/string/huffman.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/ts/algorithms/string/knuth-morris-pratt.ts b/src/ts/algorithms/string/knuth-morris-pratt.ts deleted file mode 100644 index 4b0f2759..00000000 --- a/src/ts/algorithms/string/knuth-morris-pratt.ts +++ /dev/null @@ -1,46 +0,0 @@ -const buildTable = (pattern: string) => { - const length = pattern.length; - const table = []; - let position = 2; - let cnd = 0; - - table[0] = -1; - table[1] = 0; - - while (position < length) { - if (pattern[position - 1] === pattern[cnd]) { - table[position++] = ++cnd; - } else if (cnd > 0) { - cnd = table[cnd]; - } else { - table[position++] = 0; - } - } - - return table; -}; - -const knuthMorrisPratt = (text: string, pattern: string) => { - const textLength = text.length; - const patternLength = pattern.length; - let m = 0; - let i = 0; - const table = buildTable(pattern); - - while (m + i < textLength) { - if (pattern[i] === text[m + i]) { - if (i === patternLength - 1) { - return m; - } - i++; - } else if (table[i] >= 0) { - i = table[i]; - m = m + i - table[i]; - } else { - i = 0; - m++; - } - } - - return textLength; -}; diff --git a/src/ts/algorithms/string/longest-common-substring.ts b/src/ts/algorithms/string/longest-common-substring.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/ts/algorithms/string/rabin-karp.ts b/src/ts/algorithms/string/rabin-karp.ts deleted file mode 100644 index ab60fe3e..00000000 --- a/src/ts/algorithms/string/rabin-karp.ts +++ /dev/null @@ -1,39 +0,0 @@ -const base = 997; - -const hash = (word: string) => { - let h = 0; - - for (let i = 0; i < word.length; i++) { - h += word.charCodeAt(i) * Math.pow(base, word.length - i - 1); - } - - return h; -}; - -const rabinKarp = (text: string, pattern: string) => { - if (pattern == null || pattern.length === 0) { - return 0; - } - - const hashPattern = hash(pattern); - let currentSubstring = text.substring(0, pattern.length); - let hashCurrentSubstring; - - for (let i = pattern.length; i <= text.length; i++) { - if (hashCurrentSubstring === undefined) { - hashCurrentSubstring = hash(currentSubstring); - } else { - hashCurrentSubstring -= currentSubstring.charCodeAt(0) * Math.pow(base, pattern.length - 1); - hashCurrentSubstring *= base; - hashCurrentSubstring += text.charCodeAt(i); - - currentSubstring = currentSubstring.substring(1) + text[i]; - } - - if (hashPattern === hashCurrentSubstring && pattern === currentSubstring) { - return i === pattern.length ? 0 : i - pattern.length + 1; - } - } - - return -1; -}; diff --git a/src/ts/data-structures/avl-tree.ts b/src/ts/data-structures/avl-tree.ts deleted file mode 100644 index 266e204a..00000000 --- a/src/ts/data-structures/avl-tree.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { Compare, defaultCompare, ICompareFunction } from '../util'; -import BinarySearchTree from './binary-search-tree'; -import { Node } from './models/node'; - -enum BalanceFactor { - UNBALANCED_RIGHT = 1, - SLIGHTLY_UNBALANCED_RIGHT = 2, - BALANCED = 3, - SLIGHTLY_UNBALANCED_LEFT = 4, - UNBALANCED_LEFT = 5 -} - -export default class AVLTree extends BinarySearchTree { - - constructor(protected compareFn: ICompareFunction = defaultCompare) { - super(compareFn); - } - - private getNodeHeight(node: Node): number { - if (node == null) { - return -1; - } - return Math.max(this.getNodeHeight(node.left), this.getNodeHeight(node.right)) + 1; - } - - /** - * Left left case: rotate right - * - * b a - * / \ / \ - * a e -> rotationLL(b) -> c b - * / \ / \ - * c d d e - * - * @param node Node - */ - private rotationLL(node: Node) { - const tmp = node.left; - node.left = tmp.right; - tmp.right = node; - return tmp; - } - - /** - * Right right case: rotate left - * - * a b - * / \ / \ - * c b -> rotationRR(a) -> a e - * / \ / \ - * d e c d - * - * @param node Node - */ - private rotationRR(node: Node) { - const tmp = node.right; - node.right = tmp.left; - tmp.left = node; - return tmp; - } - - /** - * Left right case: rotate left then right - * @param node Node - */ - private rotationLR(node: Node) { - node.left = this.rotationRR(node.left); - return this.rotationLL(node); - } - - /** - * Right left case: rotate right then left - * @param node Node - */ - private rotationRL(node: Node) { - node.right = this.rotationLL(node.right); - return this.rotationRR(node); - } - - private getBalanceFactor(node: Node) { - const heightDifference = this.getNodeHeight(node.left) - this.getNodeHeight(node.right); - switch (heightDifference) { - case -2: - return BalanceFactor.UNBALANCED_RIGHT; - case -1: - return BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT; - case 1: - return BalanceFactor.SLIGHTLY_UNBALANCED_LEFT; - case 2: - return BalanceFactor.UNBALANCED_LEFT; - default: - return BalanceFactor.BALANCED; - } - } - - insert(key: T) { - this.root = this.insertNode(this.root, key); - } - - protected insertNode(node: Node, key: T) { - if (node == null) { - return new Node(key); - } - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - node.left = this.insertNode(node.left, key); - } else { - node.right = this.insertNode(node.right, key); - } - - // verify if tree is balanced - const balanceFactor = this.getBalanceFactor(node); - if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) { - if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) { - // Left left case - node = this.rotationLL(node); - } else { - // Left right case - node = this.rotationLR(node); - } - } - if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) { - if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) { - // Right right case - node = this.rotationRR(node); - } else { - // Right left case - node = this.rotationRL(node); - } - } - return node; - } - - protected removeNode(node: Node, key: T) { - node = super.removeNode(node, key); // {1} - if (node == null) { - return node; - } - - // verify if tree is balanced - const balanceFactor = this.getBalanceFactor(node); - if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) { - if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) { - // Left left case - node = this.rotationLL(node); - } else { - // Left right case - node = this.rotationLR(node); - } - } - if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) { - if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) { - // Right right case - node = this.rotationRR(node); - } else { - // Right left case - node = this.rotationRL(node); - } - } - return node; - } -} diff --git a/src/ts/data-structures/binary-search-tree.ts b/src/ts/data-structures/binary-search-tree.ts deleted file mode 100644 index dd7141ff..00000000 --- a/src/ts/data-structures/binary-search-tree.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Compare, defaultCompare, ICompareFunction } from '../util'; -import { Node } from './models/node'; - -export default class BinarySearchTree { - protected root: Node; - - constructor(protected compareFn: ICompareFunction = defaultCompare) {} - - insert(key: T) { - // special case: first key - if (this.root == null) { - this.root = new Node(key); - } else { - this.insertNode(this.root, key); - } - } - - protected insertNode(node: Node, key: T) { - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - if (node.left == null) { - node.left = new Node(key); - } else { - this.insertNode(node.left, key); - } - } else if (node.right == null) { - node.right = new Node(key); - } else { - this.insertNode(node.right, key); - } - } - - getRoot() { - return this.root; - } - - search(key: T) { - return this.searchNode(this.root, key); - } - - private searchNode(node: Node, key: T): boolean { - if (node == null) { - return false; - } - - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - return this.searchNode(node.left, key); - } else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) { - return this.searchNode(node.right, key); - } - // key is equal to node.item - return true; - } - - inOrderTraverse(callback: Function) { - this.inOrderTraverseNode(this.root, callback); - } - - private inOrderTraverseNode(node: Node, callback: Function) { - if (node != null) { - this.inOrderTraverseNode(node.left, callback); - callback(node.key); - this.inOrderTraverseNode(node.right, callback); - } - } - - preOrderTraverse(callback: Function) { - this.preOrderTraverseNode(this.root, callback); - } - - private preOrderTraverseNode(node: Node, callback: Function) { - if (node != null) { - callback(node.key); - this.preOrderTraverseNode(node.left, callback); - this.preOrderTraverseNode(node.right, callback); - } - } - - postOrderTraverse(callback: Function) { - this.postOrderTraverseNode(this.root, callback); - } - - private postOrderTraverseNode(node: Node, callback: Function) { - if (node != null) { - this.postOrderTraverseNode(node.left, callback); - this.postOrderTraverseNode(node.right, callback); - callback(node.key); - } - } - - min() { - return this.minNode(this.root); - } - - protected minNode(node: Node) { - let current = node; - while (current != null && current.left != null) { - current = current.left; - } - return current; - } - - max() { - return this.maxNode(this.root); - } - - protected maxNode(node: Node) { - let current = node; - while (current != null && current.right != null) { - current = current.right; - } - return current; - } - - remove(key: T) { - this.root = this.removeNode(this.root, key); - } - - protected removeNode(node: Node, key: T) { - if (node == null) { - return null; - } - - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - node.left = this.removeNode(node.left, key); - return node; - } else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) { - node.right = this.removeNode(node.right, key); - return node; - } else { - // key is equal to node.item - - // handle 3 special conditions - // 1 - a leaf node - // 2 - a node with only 1 child - // 3 - a node with 2 children - - // case 1 - if (node.left == null && node.right == null) { - node = null; - return node; - } - - // case 2 - if (node.left == null) { - node = node.right; - return node; - } else if (node.right == null) { - node = node.left; - return node; - } - - // case 3 - const aux = this.minNode(node.right); - node.key = aux.key; - node.right = this.removeNode(node.right, aux.key); - return node; - } - } -} diff --git a/src/ts/data-structures/circular-linked-list.ts b/src/ts/data-structures/circular-linked-list.ts deleted file mode 100644 index 802f6138..00000000 --- a/src/ts/data-structures/circular-linked-list.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { defaultEquals, IEqualsFunction } from '../util'; -import LinkedList from './linked-list'; -import { Node } from './models/linked-list-models'; - -export default class CircularLinkedList extends LinkedList { - constructor(protected equalsFn: IEqualsFunction = defaultEquals) { - super(equalsFn); - } - - push(element: T) { - const node = new Node(element); - let current; - - if (this.head == null) { - this.head = node; - } else { - current = this.getElementAt(this.size() - 1); - current.next = node; - } - - // set node.next to head - to have circular list - node.next = this.head; - - this.count++; - } - - insert(element: T, index: number) { - if (index >= 0 && index <= this.count) { - const node = new Node(element); - let current = this.head; - - if (index === 0) { - if (this.head == null) { - // if no node in list - this.head = node; - node.next = this.head; - } else { - node.next = current; - current = this.getElementAt(this.size() - 1); - // update last element - this.head = node; - current.next = this.head; - } - } else { - const previous = this.getElementAt(index - 1); - node.next = previous.next; - previous.next = node; - } - this.count++; - return true; - } - return false; - } - - removeAt(index: number) { - if (index >= 0 && index < this.count) { - let current = this.head; - - if (index === 0) { - if (this.size() === 1) { - this.head = undefined; - } else { - const removed = this.head; - current = this.getElementAt(this.size() - 1); - this.head = this.head.next; - current.next = this.head; - current = removed; - } - } else { - // no need to update last element for circular list - const previous = this.getElementAt(index - 1); - current = previous.next; - previous.next = current.next; - } - this.count--; - return current.element; - } - return undefined; - } -} diff --git a/src/ts/data-structures/deque.ts b/src/ts/data-structures/deque.ts deleted file mode 100644 index 155b735c..00000000 --- a/src/ts/data-structures/deque.ts +++ /dev/null @@ -1,90 +0,0 @@ -export default class Deque { - private count: number; - private lowestCount: number; - private items: any; - - constructor() { - this.count = 0; - this.lowestCount = 0; - this.items = {}; - } - - addFront(element: T) { - if (this.isEmpty()) { - this.addBack(element); - } else if (this.lowestCount > 0) { - this.lowestCount--; - this.items[this.lowestCount] = element; - } else { - for (let i = this.count; i > 0; i--) { - this.items[i] = this.items[i - 1]; - } - this.count++; - this.items[0] = element; - } - } - - addBack(element: T) { - this.items[this.count] = element; - this.count++; - } - - removeFront() { - if (this.isEmpty()) { - return undefined; - } - const result = this.items[this.lowestCount]; - delete this.items[this.lowestCount]; - this.lowestCount++; - return result; - } - - removeBack() { - if (this.isEmpty()) { - return undefined; - } - this.count--; - const result = this.items[this.count]; - delete this.items[this.count]; - return result; - } - - peekFront() { - if (this.isEmpty()) { - return undefined; - } - return this.items[this.lowestCount]; - } - - peekBack() { - if (this.isEmpty()) { - return undefined; - } - return this.items[this.count - 1]; - } - - isEmpty() { - return this.size() === 0; - } - - clear() { - this.items = {}; - this.count = 0; - this.lowestCount = 0; - } - - size() { - return this.count - this.lowestCount; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - let objString = `${this.items[this.lowestCount]}`; - for (let i = this.lowestCount + 1; i < this.count; i++) { - objString = `${objString},${this.items[i]}`; - } - return objString; - } -} diff --git a/src/ts/data-structures/dictionary.ts b/src/ts/data-structures/dictionary.ts deleted file mode 100644 index 98485718..00000000 --- a/src/ts/data-structures/dictionary.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { defaultToString } from '../util'; -import { ValuePair } from './models/value-pair'; - -export default class Dictionary { - private table: { [key: string]: ValuePair }; - - constructor(private toStrFn: (key: K) => string = defaultToString) { - this.table = {}; - } - - set(key: K, value: V) { - if (key != null && value != null) { - const tableKey = this.toStrFn(key); - this.table[tableKey] = new ValuePair(key, value); - return true; - } - return false; - } - - get(key: K): V { - const valuePair = this.table[this.toStrFn(key)]; - return valuePair == null ? undefined : valuePair.value; - } - - hasKey(key: K) { - return this.table[this.toStrFn(key)] != null; - } - - remove(key: K) { - if (this.hasKey(key)) { - delete this.table[this.toStrFn(key)]; - return true; - } - return false; - } - - values(): V[] { - return this.keyValues().map( - (valuePair: ValuePair) => valuePair.value - ); - } - - keys(): K[] { - return this.keyValues().map( - (valuePair: ValuePair) => valuePair.key - ); - } - - keyValues(): ValuePair[] { - return Object.values(this.table); - } - - forEach(callbackFn: (key: K, value: V) => any) { - const valuePairs = this.keyValues(); - for (let i = 0; i < valuePairs.length; i++) { - const result = callbackFn(valuePairs[i].key, valuePairs[i].value); - if (result === false) { - break; - } - } - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return Object.keys(this.table).length; - } - - clear() { - this.table = {}; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const valuePairs = this.keyValues(); - let objString = `${valuePairs[0].toString()}`; - for (let i = 1; i < valuePairs.length; i++) { - objString = `${objString},${valuePairs[i].toString()}`; - } - return objString; - } -} diff --git a/src/ts/data-structures/doubly-linked-list.ts b/src/ts/data-structures/doubly-linked-list.ts deleted file mode 100644 index a2d16e72..00000000 --- a/src/ts/data-structures/doubly-linked-list.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { defaultEquals, IEqualsFunction } from '../util'; -import LinkedList from './linked-list'; -import { DoublyNode } from './models/linked-list-models'; - -export default class DoublyLinkedList extends LinkedList { - protected head: DoublyNode | undefined; - protected tail: DoublyNode | undefined; - - constructor(protected equalsFn: IEqualsFunction = defaultEquals) { - super(equalsFn); - } - - push(element: T) { - const node = new DoublyNode(element); - - if (this.head == null) { - this.head = node; - this.tail = node; // NEW - } else { - // attach to the tail node // NEW - this.tail.next = node; - node.prev = this.tail; - this.tail = node; - } - this.count++; - } - - insert(element: T, index: number) { - if (index >= 0 && index <= this.count) { - const node = new DoublyNode(element); - let current = this.head; - - if (index === 0) { - if (this.head == null) { - // NEW - this.head = node; - this.tail = node; - } else { - node.next = this.head; - this.head.prev = node; // NEW - this.head = node; - } - } else if (index === this.count) { - // last item // NEW - current = this.tail; // {2} - current.next = node; - node.prev = current; - this.tail = node; - } else { - const previous = this.getElementAt(index - 1); - current = previous.next; - node.next = current; - previous.next = node; - - current.prev = node; // NEW - node.prev = previous; // NEW - } - this.count++; - return true; - } - return false; - } - - removeAt(index: number) { - if (index >= 0 && index < this.count) { - let current = this.head; - - if (index === 0) { - this.head = this.head.next; // {1} - // if there is only one item, then we update tail as well //NEW - if (this.count === 1) { - // {2} - this.tail = undefined; - } else { - this.head.prev = undefined; // {3} - } - } else if (index === this.count - 1) { - // last item //NEW - current = this.tail; // {4} - this.tail = current.prev; - this.tail.next = undefined; - } else { - current = this.getElementAt(index); - const previous = current.prev; - // link previous with current's next - skip it to remove - previous.next = current.next; // {6} - current.next.prev = previous; // NEW - } - this.count--; - return current.element; - } - return undefined; - } - - indexOf(element: T) { - let current = this.head; - let index = 0; - - while (current != null) { - if (this.equalsFn(element, current.element)) { - return index; - } - index++; - current = current.next; - } - - return -1; - } - - getHead() { - return this.head; - } - - getTail() { - return this.tail; - } - - clear() { - super.clear(); - this.tail = undefined; - } - - toString() { - if (this.head == null) { - return ''; - } - let objString = `${this.head.element}`; - let current = this.head.next; - while (current != null) { - objString = `${objString},${current.element}`; - current = current.next; - } - return objString; - } - - inverseToString() { - if (this.tail == null) { - return ''; - } - let objString = `${this.tail.element}`; - let previous = this.tail.prev; - while (previous != null) { - objString = `${objString},${previous.element}`; - previous = previous.prev; - } - return objString; - } -} diff --git a/src/ts/data-structures/graph.ts b/src/ts/data-structures/graph.ts deleted file mode 100644 index b07a4eb4..00000000 --- a/src/ts/data-structures/graph.ts +++ /dev/null @@ -1,49 +0,0 @@ -import Dictionary from './dictionary'; - -export default class Graph { - private vertices: (string | number)[] = []; - private adjList: Dictionary = new Dictionary(); - - constructor(private isDirected = false) {} - - addVertex(v: string | number) { - if (!this.vertices.includes(v)) { - this.vertices.push(v); - this.adjList.set(v, []); // initialize adjacency list with array as well; - } - } - - addEdge(a: string | number, b: string | number) { - if (!this.adjList.get(a)) { - this.addVertex(a); - } - if (!this.adjList.get(b)) { - this.addVertex(b); - } - this.adjList.get(a).push(b); - if (this.isDirected !== true) { - this.adjList.get(b).push(a); - } - } - - getVertices() { - return this.vertices; - } - - getAdjList() { - return this.adjList; - } - - toString() { - let s = ''; - for (let i = 0; i < this.vertices.length; i++) { - s += this.vertices[i] + ' -> '; - const neighbors = this.adjList.get(this.vertices[i]); - for (let j = 0; j < neighbors.length; j++) { - s += neighbors[j] + ' '; - } - s += '\n'; - } - return s; - } -} diff --git a/src/ts/data-structures/hash-table-linear-probing-lazy.ts b/src/ts/data-structures/hash-table-linear-probing-lazy.ts deleted file mode 100644 index 43817050..00000000 --- a/src/ts/data-structures/hash-table-linear-probing-lazy.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { defaultToString } from '../util'; -import { ValuePairLazy } from './models/value-pair-lazy'; - -export default class HashTableLinearProbingLazy { - protected table: { [key: string]: ValuePairLazy }; - - constructor(protected toStrFn: (key: K) => string = defaultToString) { - this.table = {}; - } - - private loseloseHashCode(key: K) { - if (typeof key === 'number') { - return key; - } - const tableKey = this.toStrFn(key); - let hash = 0; - for (let i = 0; i < tableKey.length; i++) { - hash += tableKey.charCodeAt(i); - } - return hash % 37; - } - - hashCode(key: K) { - return this.loseloseHashCode(key); - } - - put(key: K, value: V) { - if (key != null && value != null) { - const position = this.hashCode(key); - - if ( - this.table[position] == null || - (this.table[position] != null && this.table[position].isDeleted) - ) { - this.table[position] = new ValuePairLazy(key, value); - } else { - let index = position + 1; - while (this.table[index] != null && !this.table[position].isDeleted) { - index++; - } - this.table[index] = new ValuePairLazy(key, value); - } - return true; - } - return false; - } - - get(key: K) { - const position = this.hashCode(key); - - if (this.table[position] != null) { - if (this.table[position].key === key && !this.table[position].isDeleted) { - return this.table[position].value; - } - let index = position + 1; - while ( - this.table[index] != null && - (this.table[index].key !== key || this.table[index].isDeleted) - ) { - if (this.table[index].key === key && this.table[index].isDeleted) { - return undefined; - } - index++; - } - if ( - this.table[index] != null && - this.table[index].key === key && - !this.table[index].isDeleted - ) { - return this.table[position].value; - } - } - return undefined; - } - - remove(key: K) { - const position = this.hashCode(key); - - if (this.table[position] != null) { - if (this.table[position].key === key && !this.table[position].isDeleted) { - this.table[position].isDeleted = true; - return true; - } - let index = position + 1; - while ( - this.table[index] != null && - (this.table[index].key !== key || this.table[index].isDeleted) - ) { - index++; - } - if ( - this.table[index] != null && - this.table[index].key === key && - !this.table[index].isDeleted - ) { - this.table[index].isDeleted = true; - return true; - } - } - return false; - } - - isEmpty() { - return this.size() === 0; - } - - size() { - let count = 0; - Object.values(this.table).forEach(valuePair => { - count += valuePair.isDeleted === true ? 0 : 1; - }); - return count; - } - - clear() { - this.table = {}; - } - - getTable() { - return this.table; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const keys = Object.keys(this.table); - let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; - for (let i = 1; i < keys.length; i++) { - objString = `${objString},{${keys[i]} => ${this.table[ - keys[i] - ].toString()}}`; - } - return objString; - } -} diff --git a/src/ts/data-structures/hash-table-linear-probing.ts b/src/ts/data-structures/hash-table-linear-probing.ts deleted file mode 100644 index fb82d20a..00000000 --- a/src/ts/data-structures/hash-table-linear-probing.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { defaultToString } from '../util'; -import { ValuePair } from './models/value-pair'; - -export default class HashTableLinearProbing { - protected table: { [key: string]: ValuePair }; - - constructor(protected toStrFn: (key: K) => string = defaultToString) { - this.table = {}; - } - - private loseloseHashCode(key: K) { - if (typeof key === 'number') { - return key; - } - const tableKey = this.toStrFn(key); - let hash = 0; - for (let i = 0; i < tableKey.length; i++) { - hash += tableKey.charCodeAt(i); - } - return hash % 37; - } - - hashCode(key: K) { - return this.loseloseHashCode(key); - } - - put(key: K, value: V) { - if (key != null && value != null) { - const position = this.hashCode(key); - - if (this.table[position] == null) { - this.table[position] = new ValuePair(key, value); - } else { - let index = position + 1; - while (this.table[index] != null) { - index++; - } - this.table[index] = new ValuePair(key, value); - } - return true; - } - return false; - } - - get(key: K) { - const position = this.hashCode(key); - - if (this.table[position] != null) { - if (this.table[position].key === key) { - return this.table[position].value; - } - let index = position + 1; - while (this.table[index] != null && this.table[index].key !== key) { - index++; - } - if (this.table[index] != null && this.table[index].key === key) { - return this.table[index].value; - } - } - return undefined; - } - - remove(key: K) { - const position = this.hashCode(key); - - if (this.table[position] != null) { - if (this.table[position].key === key) { - delete this.table[position]; - this.verifyRemoveSideEffect(key, position); - return true; - } - let index = position + 1; - while (this.table[index] != null && this.table[index].key !== key) { - index++; - } - if (this.table[index] != null && this.table[index].key === key) { - delete this.table[index]; - this.verifyRemoveSideEffect(key, index); - return true; - } - } - return false; - } - - private verifyRemoveSideEffect(key: K, removedPosition: number) { - const hash = this.hashCode(key); - let index = removedPosition + 1; - while (this.table[index] != null) { - const posHash = this.hashCode(this.table[index].key); - if (posHash <= hash || posHash <= removedPosition) { - this.table[removedPosition] = this.table[index]; - delete this.table[index]; - removedPosition = index; - } - index++; - } - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return Object.keys(this.table).length; - } - - clear() { - this.table = {}; - } - - getTable() { - return this.table; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const keys = Object.keys(this.table); - let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; - for (let i = 1; i < keys.length; i++) { - objString = `${objString},{${keys[i]} => ${this.table[ - keys[i] - ].toString()}}`; - } - return objString; - } -} diff --git a/src/ts/data-structures/hash-table-separate-chaining.ts b/src/ts/data-structures/hash-table-separate-chaining.ts deleted file mode 100644 index 165ff15d..00000000 --- a/src/ts/data-structures/hash-table-separate-chaining.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { defaultToString } from '../util'; -import LinkedList from './linked-list'; -import { ValuePair } from './models/value-pair'; - -export default class HashTableSeparateChaining { - protected table: { [key: string]: LinkedList> }; - - constructor(protected toStrFn: (key: K) => string = defaultToString) { - this.table = {}; - } - - private loseloseHashCode(key: K) { - if (typeof key === 'number') { - return key; - } - const tableKey = this.toStrFn(key); - let hash = 0; - for (let i = 0; i < tableKey.length; i++) { - hash += tableKey.charCodeAt(i); - } - return hash % 37; - } - - hashCode(key: K) { - return this.loseloseHashCode(key); - } - - put(key: K, value: V) { - if (key != null && value != null) { - const position = this.hashCode(key); - - if (this.table[position] == null) { - this.table[position] = new LinkedList>(); - } - this.table[position].push(new ValuePair(key, value)); - return true; - } - return false; - } - - get(key: K) { - const position = this.hashCode(key); - const linkedList = this.table[position]; - if (linkedList != null && !linkedList.isEmpty()) { - let current = linkedList.getHead(); - while (current != null) { - if (current.element.key === key) { - return current.element.value; - } - current = current.next; - } - } - return undefined; - } - - remove(key: K) { - const position = this.hashCode(key); - const linkedList = this.table[position]; - if (linkedList != null && !linkedList.isEmpty()) { - let current = linkedList.getHead(); - while (current != null) { - if (current.element.key === key) { - linkedList.remove(current.element); - if (linkedList.isEmpty()) { - delete this.table[position]; - } - return true; - } - current = current.next; - } - } - return false; - } - - isEmpty() { - return this.size() === 0; - } - - size() { - let count = 0; - Object.values(this.table).forEach(linkedList => count += linkedList.size()); - return count; - } - - clear() { - this.table = {}; - } - - getTable() { - return this.table; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const keys = Object.keys(this.table); - let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; - for (let i = 1; i < keys.length; i++) { - objString = `${objString},{${keys[i]} => ${this.table[ - keys[i] - ].toString()}}`; - } - return objString; - } -} diff --git a/src/ts/data-structures/hash-table.ts b/src/ts/data-structures/hash-table.ts deleted file mode 100644 index 7b3c6983..00000000 --- a/src/ts/data-structures/hash-table.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { defaultToString } from '../util'; -import { ValuePair } from './models/value-pair'; - -export default class HashTable { - protected table: { [key: string]: ValuePair }; - - constructor(protected toStrFn: (key: K) => string = defaultToString) { - this.table = {}; - } - - private loseloseHashCode(key: K) { - if (typeof key === 'number') { - return key; - } - const tableKey = this.toStrFn(key); - let hash = 0; - for (let i = 0; i < tableKey.length; i++) { - hash += tableKey.charCodeAt(i); - } - return hash % 37; - } - - /* private djb2HashCode(key: K) { - const tableKey = this.toStrFn(key); - let hash = 5381; - for (let i = 0; i < tableKey.length; i++) { - hash = (hash * 33) + tableKey.charCodeAt(i); - } - return hash % 1013; - } */ - - hashCode(key: K) { - return this.loseloseHashCode(key); - } - - put(key: K, value: V) { - if (key != null && value != null) { - const position = this.hashCode(key); - this.table[position] = new ValuePair(key, value); - return true; - } - return false; - } - - get(key: K) { - const valuePair = this.table[this.hashCode(key)]; - return valuePair == null ? undefined : valuePair.value; - } - - remove(key: K) { - const hash = this.hashCode(key); - const valuePair = this.table[hash]; - if (valuePair != null) { - delete this.table[hash]; - return true; - } - return false; - } - - getTable() { - return this.table; - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return Object.keys(this.table).length; - } - - clear() { - this.table = {}; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const keys = Object.keys(this.table); - let objString = `{${keys[0]} => ${this.table[keys[0]].toString()}}`; - for (let i = 1; i < keys.length; i++) { - objString = `${objString},{${keys[i]} => ${this.table[keys[i]].toString()}}`; - } - return objString; - } -} diff --git a/src/ts/data-structures/heap.ts b/src/ts/data-structures/heap.ts deleted file mode 100644 index 5f27b089..00000000 --- a/src/ts/data-structures/heap.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Compare, defaultCompare, ICompareFunction, reverseCompare, swap } from '../util'; - -export class MinHeap { - protected heap: T[] = []; - - constructor(protected compareFn: ICompareFunction = defaultCompare) {} - - private getLeftIndex(index: number) { - return 2 * index + 1; - } - - private getRightIndex(index: number) { - return 2 * index + 2; - } - - private getParentIndex(index: number) { - if (index === 0) { - return undefined; - } - return Math.floor((index - 1) / 2); - } - - size() { - return this.heap.length; - } - - isEmpty() { - return this.size() <= 0; - } - - clear() { - this.heap = []; - } - - findMinimum() { - return this.isEmpty() ? undefined : this.heap[0]; - } - - insert(value: T) { - if (value != null) { - const index = this.heap.length; - this.heap.push(value); - this.siftUp(index); - return true; - } - return false; - } - - private siftDown(index: number) { - let element = index; - const left = this.getLeftIndex(index); - const right = this.getRightIndex(index); - const size = this.size(); - - if (left < size && this.compareFn(this.heap[element], this.heap[left]) === Compare.BIGGER_THAN) { - element = left; - } - - if ( - right < size && - this.compareFn(this.heap[element], this.heap[right]) === Compare.BIGGER_THAN - ) { - element = right; - } - - if (index !== element) { - swap(this.heap, index, element); - this.siftDown(element); - } - } - - private siftUp(index: number): void { - let parent = this.getParentIndex(index); - while ( - index > 0 && - this.compareFn(this.heap[parent], this.heap[index]) === Compare.BIGGER_THAN - ) { - swap(this.heap, parent, index); - index = parent; - parent = this.getParentIndex(index); - } - } - - extract() { - if (this.isEmpty()) { - return undefined; - } - if (this.size() === 1) { - return this.heap.shift(); - } - const removedValue = this.heap[0]; - this.heap[0] = this.heap.pop(); - this.siftDown(0); - return removedValue; - } - - heapify(array: T[]) { - if (array) { - this.heap = array; - } - - const maxIndex = Math.floor(this.size() / 2) - 1; - - for (let i = 0; i <= maxIndex; i++) { - this.siftDown(i); - } - - return this.heap; - } - - getAsArray() { - return this.heap; - } -} - -export class MaxHeap extends MinHeap { - constructor(protected compareFn: ICompareFunction = defaultCompare) { - super(compareFn); - this.compareFn = reverseCompare(compareFn); - } -} diff --git a/src/ts/data-structures/linked-list.ts b/src/ts/data-structures/linked-list.ts deleted file mode 100644 index f0460c90..00000000 --- a/src/ts/data-structures/linked-list.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { defaultEquals, IEqualsFunction } from '../util'; -import { Node } from './models/linked-list-models'; - -export default class LinkedList { - protected count = 0; - protected head: Node | undefined; - - constructor(protected equalsFn: IEqualsFunction = defaultEquals) {} - - push(element: T) { - const node = new Node(element); - let current; - - if (this.head == null) { - // catches null && undefined - this.head = node; - } else { - current = this.head; - - while (current.next != null) { - current = current.next; - } - - current.next = node; - } - this.count++; - } - - getElementAt(index: number) { - if (index >= 0 && index <= this.count) { - let node = this.head; - for (let i = 0; i < index && node != null; i++) { - node = node.next; - } - return node; - } - return undefined; - } - - insert(element: T, index: number) { - if (index >= 0 && index <= this.count) { - const node = new Node(element); - - if (index === 0) { - const current = this.head; - node.next = current; - this.head = node; - } else { - const previous = this.getElementAt(index - 1); - node.next = previous.next; - previous.next = node; - } - this.count++; - return true; - } - return false; - } - - removeAt(index: number) { - if (index >= 0 && index < this.count) { - let current = this.head; - - if (index === 0) { - this.head = current.next; - } else { - const previous = this.getElementAt(index - 1); - current = previous.next; - previous.next = current.next; - } - this.count--; - return current.element; - } - return undefined; - } - - remove(element: T) { - const index = this.indexOf(element); - return this.removeAt(index); - } - - indexOf(element: T) { - let current = this.head; - - for (let i = 0; i < this.size() && current != null; i++) { - if (this.equalsFn(element, current.element)) { - return i; - } - current = current.next; - } - - return -1; - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return this.count; - } - - getHead() { - return this.head; - } - - clear() { - this.head = undefined; - this.count = 0; - } - - toString() { - if (this.head == null) { - return ''; - } - let objString = `${this.head.element}`; - let current = this.head.next; - for (let i = 1; i < this.size() && current != null; i++) { - objString = `${objString},${current.element}`; - current = current.next; - } - return objString; - } -} diff --git a/src/ts/data-structures/models/linked-list-models.ts b/src/ts/data-structures/models/linked-list-models.ts deleted file mode 100644 index 168d640e..00000000 --- a/src/ts/data-structures/models/linked-list-models.ts +++ /dev/null @@ -1,13 +0,0 @@ -export class Node { - constructor(public element: T, public next?: Node) {} -} - -export class DoublyNode extends Node { - constructor( - public element: T, - public next?: DoublyNode, - public prev?: DoublyNode - ) { - super(element, next); - } -} diff --git a/src/ts/data-structures/models/node.ts b/src/ts/data-structures/models/node.ts deleted file mode 100644 index f3e3f9aa..00000000 --- a/src/ts/data-structures/models/node.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class Node { - left: Node; - right: Node; - - constructor(public key: K) {} - - toString() { - return `${this.key}`; - } -} diff --git a/src/ts/data-structures/models/red-black-node.ts b/src/ts/data-structures/models/red-black-node.ts deleted file mode 100644 index 76493d9e..00000000 --- a/src/ts/data-structures/models/red-black-node.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Node } from './node'; - -export enum Colors { - RED = 0, - BLACK = 1 -} - -export class RedBlackNode extends Node { - left: RedBlackNode; - right: RedBlackNode; - parent: RedBlackNode; - color: Colors; - - constructor(public key: K) { - super(key); - this.color = Colors.RED; - } - - isRed() { - return this.color === Colors.RED; - } -} diff --git a/src/ts/data-structures/models/value-pair-lazy.ts b/src/ts/data-structures/models/value-pair-lazy.ts deleted file mode 100644 index 57b6abbd..00000000 --- a/src/ts/data-structures/models/value-pair-lazy.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ValuePair } from './value-pair'; - -export class ValuePairLazy extends ValuePair { - constructor(public key: K, public value: V, public isDeleted = false) { - super(key, value); - } -} diff --git a/src/ts/data-structures/models/value-pair.ts b/src/ts/data-structures/models/value-pair.ts deleted file mode 100644 index eb4cff0a..00000000 --- a/src/ts/data-structures/models/value-pair.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class ValuePair { - constructor(public key: K, public value: V) {} - - toString() { - return `[#${this.key}: ${this.value}]`; - } -} diff --git a/src/ts/data-structures/priority-queue-array.ts b/src/ts/data-structures/priority-queue-array.ts deleted file mode 100644 index 6ad0d441..00000000 --- a/src/ts/data-structures/priority-queue-array.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Compare, defaultCompare, ICompareFunction } from '../util'; - -export default class PriorityQueue { - private items: T[]; - - constructor( - private compareFn: ICompareFunction = defaultCompare, - private compare: Compare = Compare.LESS_THAN - ) { - this.items = []; - } - - enqueue(element: T) { - let added = false; - - for (let i = 0; i < this.items.length; i++) { - if (this.compareFn(element, this.items[i]) === this.compare) { - this.items.splice(i, 0, element); - added = true; - break; - } - } - - if (!added) { - this.items.push(element); - } - } - - dequeue() { - return this.items.shift(); - } - - peek() { - if (this.isEmpty()) { - return undefined; - } - return this.items[0]; - } - - isEmpty() { - return this.items.length === 0; - } - - clear() { - this.items = []; - } - - size() { - return this.items.length; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - return this.items; - } -} diff --git a/src/ts/data-structures/queue.ts b/src/ts/data-structures/queue.ts deleted file mode 100644 index b6db45a5..00000000 --- a/src/ts/data-structures/queue.ts +++ /dev/null @@ -1,58 +0,0 @@ -export default class Queue { - private count: number; - private lowestCount: number; - private items: any; - - constructor() { - this.count = 0; - this.lowestCount = 0; - this.items = {}; - } - - enqueue(element: T) { - this.items[this.count] = element; - this.count++; - } - - dequeue() { - if (this.isEmpty()) { - return undefined; - } - const result = this.items[this.lowestCount]; - delete this.items[this.lowestCount]; - this.lowestCount++; - return result; - } - - peek() { - if (this.isEmpty()) { - return undefined; - } - return this.items[this.lowestCount]; - } - - isEmpty() { - return this.size() === 0; - } - - clear() { - this.items = {}; - this.count = 0; - this.lowestCount = 0; - } - - size() { - return this.count - this.lowestCount; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - let objString = `${this.items[this.lowestCount]}`; - for (let i = this.lowestCount + 1; i < this.count; i++) { - objString = `${objString},${this.items[i]}`; - } - return objString; - } -} diff --git a/src/ts/data-structures/red-black-tree.ts b/src/ts/data-structures/red-black-tree.ts deleted file mode 100644 index 0d206e2f..00000000 --- a/src/ts/data-structures/red-black-tree.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { defaultCompare, ICompareFunction, Compare } from '../util'; -import BinarySearchTree from './binary-search-tree'; -import { RedBlackNode, Colors } from './models/red-black-node'; - -export default class RedBlackTree extends BinarySearchTree { - protected root: RedBlackNode; - - constructor(protected compareFn: ICompareFunction = defaultCompare) { - super(compareFn); - } - - /** - * Left left case: rotate right - * - * b a - * / \ / \ - * a e -> rotationLL(b) -> c b - * / \ / \ - * c d d e - * - * @param node Node - */ - private rotationLL(node: RedBlackNode) { - const tmp = node.left; - node.left = tmp.right; - if (tmp.right && tmp.right.key) { - tmp.right.parent = node; - } - tmp.parent = node.parent; - if (!node.parent) { - this.root = tmp; - } else { - if (node === node.parent.left) { - node.parent.left = tmp; - } else { - node.parent.right = tmp; - } - } - tmp.right = node; - node.parent = tmp; - } - - /** - * Right right case: rotate left - * - * a b - * / \ / \ - * c b -> rotationRR(a) -> a e - * / \ / \ - * d e c d - * - * @param node Node - */ - private rotationRR(node: RedBlackNode) { - const tmp = node.right; - node.right = tmp.left; - if (tmp.left && tmp.left.key) { - tmp.left.parent = node; - } - tmp.parent = node.parent; - if (!node.parent) { - this.root = tmp; - } else { - if (node === node.parent.left) { - node.parent.left = tmp; - } else { - node.parent.right = tmp; - } - } - tmp.left = node; - node.parent = tmp; - } - - insert(key: T) { - // special case: first key - if (this.root == null) { - this.root = new RedBlackNode(key); - this.root.color = Colors.BLACK; - } else { - const newNode = this.insertNode(this.root, key); - this.fixTreeProperties(newNode); - } - } - - protected insertNode(node: RedBlackNode, key: T): RedBlackNode { - if (this.compareFn(key, node.key) === Compare.LESS_THAN) { - if (node.left == null) { - node.left = new RedBlackNode(key); - node.left.parent = node; - return node.left; - } else { - return this.insertNode(node.left, key); - } - } else if (node.right == null) { - node.right = new RedBlackNode(key); - node.right.parent = node; - return node.right; - } else { - return this.insertNode(node.right, key); - } - } - - private fixTreeProperties(node: RedBlackNode) { - while (node && node.parent && node.parent.color === Colors.RED && node.color !== Colors.BLACK) { - let parent = node.parent; - const grandParent = parent.parent; - - // case A - if (grandParent && grandParent.left === parent) { - - const uncle = grandParent.right; - - // case 1: uncle of node is also red - only recoloring - if (uncle && uncle.isRed()) { - grandParent.color = Colors.RED; - parent.color = Colors.BLACK; - uncle.color = Colors.BLACK; - node = grandParent; - } else { - // case 2: node is right child - left rotate - if (node === parent.right) { - this.rotationRR(parent); - node = parent; - parent = node.parent; - } - - // case 3: node is left child - right rotate - this.rotationLL(grandParent); - // swap color - parent.color = Colors.BLACK; - grandParent.color = Colors.RED; - node = parent; - } - - } else { // case B: parent is right child of grand parent - - const uncle = grandParent.left; - - // case 1: uncle is read - only recoloring - if (uncle && uncle.isRed()) { - grandParent.color = Colors.RED; - parent.color = Colors.BLACK; - uncle.color = Colors.BLACK; - node = grandParent; - } else { - // case 2: node is left child - left rotate - if (node === parent.left) { - this.rotationLL(parent); - node = parent; - parent = node.parent; - } - - // case 3: node is right child - left rotate - this.rotationRR(grandParent); - // swap color - parent.color = Colors.BLACK; - grandParent.color = Colors.RED; - node = parent; - } - } - } - this.root.color = Colors.BLACK; - } - - getRoot() { - return this.root; - } - - /* private flipColors(node: RedBlackNode) { - node.left.flipColor(); - node.right.flipColor(); - } - - private isRed(node: RedBlackNode) { - if (!node) { - return false; - } - return node.isRed(); - }*/ -} diff --git a/src/ts/data-structures/set.ts b/src/ts/data-structures/set.ts deleted file mode 100644 index a6d37373..00000000 --- a/src/ts/data-structures/set.ts +++ /dev/null @@ -1,105 +0,0 @@ -export default class Set { - private items: any; - - constructor() { - this.items = {}; - } - - add(element: T) { - if (!this.has(element)) { - this.items[element] = element; - return true; - } - return false; - } - - delete(element: T) { - if (this.has(element)) { - delete this.items[element]; - return true; - } - return false; - } - - has(element: T) { - // return this.items.hasOwnProperty(element); - return Object.prototype.hasOwnProperty.call(this.items, element); - } - - values(): T[] { - return Object.values(this.items); - } - - union(otherSet: Set) { - const unionSet = new Set(); - - this.values().forEach(value => unionSet.add(value)); - otherSet.values().forEach(value => unionSet.add(value)); - - return unionSet; - } - - intersection(otherSet: Set) { - const intersectionSet = new Set(); - - const values = this.values(); - const otherValues = otherSet.values(); - - let biggerSet = values; - let smallerSet = otherValues; - - if (otherValues.length - values.length > 0) { - biggerSet = otherValues; - smallerSet = values; - } - - smallerSet.forEach(value => { - if (biggerSet.includes(value)) { - intersectionSet.add(value); - } - }); - - return intersectionSet; - } - - difference(otherSet: Set) { - const differenceSet = new Set(); - - this.values().forEach(value => { - if (!otherSet.has(value)) { - differenceSet.add(value); - } - }); - - return differenceSet; - } - - isSubsetOf(otherSet: Set) { - const values = this.values(); - return values.every((value) => otherSet.has(value)); - } - - isEmpty() { - return this.size() === 0; - } - - size() { - return Object.keys(this.items).length; - } - - clear() { - this.items = {}; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - const values = this.values(); - let objString = `${values[0]}`; - for (let i = 1; i < values.length; i++) { - objString = `${objString},${values[i].toString()}`; - } - return objString; - } -} diff --git a/src/ts/data-structures/sorted-linked-list.ts b/src/ts/data-structures/sorted-linked-list.ts deleted file mode 100644 index f7832e81..00000000 --- a/src/ts/data-structures/sorted-linked-list.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Compare, defaultCompare, defaultEquals, ICompareFunction, IEqualsFunction } from '../util'; -import LinkedList from './linked-list'; - -export default class SortedLinkedList extends LinkedList { - constructor( - protected equalsFn: IEqualsFunction = defaultEquals, - protected compareFn: ICompareFunction = defaultCompare - ) { - super(equalsFn); - } - - push(element: T) { - if (this.isEmpty()) { - super.push(element); - } else { - const index = this.getIndexNextSortedElement(element); - super.insert(element, index); - } - } - - insert(element: T, index: number = 0) { - if (this.isEmpty()) { - return super.insert(element, 0); - } - index = this.getIndexNextSortedElement(element); - return super.insert(element, index); - } - - private getIndexNextSortedElement(element: T) { - let current = this.head; - let i = 0; - - for (; i < this.size() && current; i++) { - const comp = this.compareFn(element, current.element); - if (comp === Compare.LESS_THAN) { - return i; - } - current = current.next; - } - - return i; - } -} diff --git a/src/ts/data-structures/stack-array.ts b/src/ts/data-structures/stack-array.ts deleted file mode 100644 index 44bf91da..00000000 --- a/src/ts/data-structures/stack-array.ts +++ /dev/null @@ -1,39 +0,0 @@ -export default class StackArray { - private items: T[]; - - constructor() { - this.items = []; - } - - push(element: T) { - this.items.push(element); - } - - pop() { - return this.items.pop(); - } - - peek() { - return this.items[this.items.length - 1]; - } - - isEmpty() { - return this.items.length === 0; - } - - size() { - return this.items.length; - } - - clear() { - this.items = []; - } - - toArray() { - return this.items; - } - - toString() { - return this.items.toString(); - } -} diff --git a/src/ts/data-structures/stack-linked-list.ts b/src/ts/data-structures/stack-linked-list.ts deleted file mode 100644 index fa39023b..00000000 --- a/src/ts/data-structures/stack-linked-list.ts +++ /dev/null @@ -1,44 +0,0 @@ -import DoublyLinkedList from './doubly-linked-list'; - -export default class StackLinkedList { - private items: DoublyLinkedList; - - constructor() { - this.items = new DoublyLinkedList(); - } - - push(element: T) { - this.items.push(element); - } - - pop() { - if (this.isEmpty()) { - return undefined; - } - const result = this.items.removeAt(this.size() - 1); - return result; - } - - peek() { - if (this.isEmpty()) { - return undefined; - } - return this.items.getElementAt(this.size() - 1).element; - } - - isEmpty() { - return this.items.isEmpty(); - } - - size() { - return this.items.size(); - } - - clear() { - this.items.clear(); - } - - toString() { - return this.items.toString(); - } -} diff --git a/src/ts/data-structures/stack.ts b/src/ts/data-structures/stack.ts deleted file mode 100644 index 4ea30351..00000000 --- a/src/ts/data-structures/stack.ts +++ /dev/null @@ -1,59 +0,0 @@ -export default class Stack { - private count: number; - private items: any; - - constructor() { - this.count = 0; - this.items = {}; - } - - push(element: T) { - this.items[this.count] = element; - this.count++; - } - - pop() { - if (this.isEmpty()) { - return undefined; - } - this.count--; - const result = this.items[this.count]; - delete this.items[this.count]; - return result; - } - - peek() { - if (this.isEmpty()) { - return undefined; - } - return this.items[this.count - 1]; - } - - isEmpty() { - return this.count === 0; - } - - size() { - return this.count; - } - - clear() { - /* while (!this.isEmpty()) { - this.pop(); - } */ - - this.items = {}; - this.count = 0; - } - - toString() { - if (this.isEmpty()) { - return ''; - } - let objString = `${this.items[0]}`; - for (let i = 1; i < this.count; i++) { - objString = `${objString},${this.items[i]}`; - } - return objString; - } -} diff --git a/src/ts/index.ts b/src/ts/index.ts deleted file mode 100644 index cc8aec85..00000000 --- a/src/ts/index.ts +++ /dev/null @@ -1,116 +0,0 @@ -import * as _util from './util'; -export const util = _util; - -export { default as Stack } from './data-structures/stack'; - -export { default as LinkedList } from './data-structures/linked-list'; -export { default as DoublyLinkedList } from './data-structures/doubly-linked-list'; -export { default as CircularLinkedList } from './data-structures/circular-linked-list'; -export { default as SortedLinkedList } from './data-structures/sorted-linked-list'; -export { default as StackLinkedList } from './data-structures/stack-linked-list'; -export { default as Set } from './data-structures/set'; -export { default as Dictionary } from './data-structures/dictionary'; -export { default as HashTable } from './data-structures/hash-table'; -export { default as HashTableSeparateChaining } from './data-structures/hash-table-separate-chaining'; -export { default as HashTableLinearProbing } from './data-structures/hash-table-linear-probing'; -export { default as HashTableLinearProbingLazy } from './data-structures/hash-table-linear-probing-lazy'; - -// chapter 08 -export { factorialIterative as factorialIterative } from './others/factorial'; -export { factorial as factorial} from './others/factorial'; -export { fibonacci as fibonacci} from './others/fibonacci'; -export { fibonacciIterative as fibonacciIterative} from './others/fibonacci'; -export { fibonacciMemoization as fibonacciMemoization} from './others/fibonacci'; - -// chapter 09 -export { default as BinarySearchTree } from './data-structures/binary-search-tree'; -export { default as AVLTree } from './data-structures/avl-tree'; -export { default as RedBlackTree } from './data-structures/red-black-tree'; - -// chapter 10 -export { MinHeap as MinHeap } from './data-structures/heap'; -export { MaxHeap as MaxHeap } from './data-structures/heap'; -export { default as heapSort } from './algorithms/sorting/heap-sort'; - -// chapter 11 -export { default as Graph } from './data-structures/graph'; -export { breadthFirstSearch as breadthFirstSearch } from './algorithms/graph/breadth-first-search'; -export { bfs as BFS } from './algorithms/graph/breadth-first-search'; -export { depthFirstSearch as depthFirstSearch } from './algorithms/graph/depth-first-search'; -export { DFS as DFS } from './algorithms/graph/depth-first-search'; -export { dijkstra as dijkstra } from './algorithms/graph/dijkstra'; -export { floydWarshall as floydWarshall } from './algorithms/graph/floyd-warshall'; -export { prim as prim } from './algorithms/graph/prim'; -export { kruskal as kruskal } from './algorithms/graph/kruskal'; - -// chapter 12 -export { shuffle as shuffle } from './algorithms/shuffle/fisher–yates'; - -export { bubbleSort as bubbleSort } from './algorithms/sorting/bubble-sort'; -export { modifiedBubbleSort as modifiedBubbleSort } from './algorithms/sorting/bubble-sort-improved'; -export { bucketSort as bucketSort } from './algorithms/sorting/bucket-sort'; -export { countingSort as countingSort } from './algorithms/sorting/counting-sort'; -export { insertionSort as insertionSort } from './algorithms/sorting/insertion-sort'; -export { mergeSort as mergeSort } from './algorithms/sorting/merge-sort'; -export { quickSort as quickSort } from './algorithms/sorting/quicksort'; -export { radixSort as radixSort } from './algorithms/sorting/radix-sort'; -export { selectionSort as selectionSort } from './algorithms/sorting/selection-sort'; -export { shellSort as shellSort } from './algorithms/sorting/shell-sort'; - -export { binarySearch as binarySearch } from './algorithms/search/binary-search'; -export { interpolationSearch as interpolationSearch } from './algorithms/search/interpolation-search'; -export { sequentialSearch as sequentialSearch } from './algorithms/search/sequential-search'; -export { findMaxValue as findMaxValue } from './algorithms/search/min-max-search'; -export { findMinValue as findMinValue } from './algorithms/search/min-max-search'; - -// chapter 14 -export { binarySearch as binarySearchRecursive } from './algorithms/search/binary-search-recursive'; -export { minCoinChange } from './algorithms/dynamic-programing/min-coin-change'; -export { minCoinChange as minCoinChangeGreedy } from './algorithms/greedy/min-coin-change'; -export { knapSack } from './algorithms/dynamic-programing/knapsack'; -export { knapSack as knapSackRecursive } from './algorithms/dynamic-programing/knapsack-recursive'; -export { knapSack as knapSackGreedy } from './algorithms/greedy/knapsack'; -export { lcs } from './algorithms/dynamic-programing/longest-common-subsequence'; -export { lcs as lcsPrint } from './algorithms/dynamic-programing/longest-common-subsequence-print'; -export { lcs as lcsRecursive } from './algorithms/greedy/longest-common-subsequence'; -export { matrixChainOrder } from './algorithms/dynamic-programing/matrix-chain-multiplication'; -export { matrixChainOrder as matrixChainOrderGreedy } from './algorithms/greedy/matrix-chain-multiplication'; -export { ratInAMaze } from './algorithms/backtracking/rat-in-maze'; -export { sudokuSolver } from './algorithms/backtracking/sudoku-solver'; - -// others -export { findDivisors } from './algorithms/math/find-divisors'; -export { gcd } from './algorithms/math/gcd'; -export { lcm } from './algorithms/math/lcm'; -export { greatestDifference } from './algorithms/math/greatest-difference'; -export { isPrime } from './algorithms/math/primality-test'; -export { testPrime } from './algorithms/math/primality-test'; -export { isPrime2 } from './algorithms/math/primality-test'; -export { sieveOfEratosthenes } from './algorithms/math/sieve-eratosthenes'; - - -/* import { hotPotato } from './others/hot-potato'; -import { palindromeChecker } from './others/palindrome-checker'; -import Deque from './data-structures/deque'; -import Queue from './data-structures/queue'; -import { hanoi, hanoiStack } from './others/hanoi'; -import { baseConverter, decimalToBinary } from './others/base-converter'; -import StackArray from './data-structures/stack-array'; -import Stack from './data-structures/stack'; -import { parenthesesChecker } from './others/balanced-symbols'; -import { MinHeap, MaxHeap } from './data-structures/heap'; - - -export { - Stack, - StackArray, - parenthesesChecker, - baseConverter, - decimalToBinary, - hanoi, - hanoiStack, - Queue, - Deque, - hotPotato, - palindromeChecker -}; */ diff --git a/src/ts/others/balanced-symbols.ts b/src/ts/others/balanced-symbols.ts deleted file mode 100644 index f20b5830..00000000 --- a/src/ts/others/balanced-symbols.ts +++ /dev/null @@ -1,29 +0,0 @@ -import Stack from '../data-structures/stack'; - -export function parenthesesChecker(symbols: string) { - const stack = new Stack(); - const opens = '([{'; - const closers = ')]}'; - let balanced = true; - let index = 0; - let symbol: string; - let top: string; - - while (index < symbols.length && balanced) { - symbol = symbols[index]; - if (opens.indexOf(symbol) >= 0) { - stack.push(symbol); - } else { - if (stack.isEmpty()) { - balanced = false; - } else { - top = stack.pop(); - if (!(opens.indexOf(top) === closers.indexOf(symbol))) { - balanced = false; - } - } - } - index++; - } - return balanced && stack.isEmpty(); -} diff --git a/src/ts/others/base-converter.ts b/src/ts/others/base-converter.ts deleted file mode 100644 index d65b27ef..00000000 --- a/src/ts/others/base-converter.ts +++ /dev/null @@ -1,42 +0,0 @@ -import Stack from '../data-structures/stack'; - -export function decimalToBinary(decNumber: number) { - const remStack = new Stack(); - let rem: number; - let binaryString = ''; - - while (decNumber > 0) { - rem = Math.floor(decNumber % 2); - remStack.push(rem); - decNumber = Math.floor(decNumber / 2); - } - - while (!remStack.isEmpty()) { - binaryString += remStack.pop().toString(); - } - - return binaryString; -} - -export function baseConverter(decNumber: number, base: number) { - const remStack = new Stack(); - const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - let rem: number; - let baseString = ''; - - if (!(base >= 2 && base <= 36)) { - return ''; - } - - while (decNumber > 0) { - rem = Math.floor(decNumber % base); - remStack.push(rem); - decNumber = Math.floor(decNumber / base); - } - - while (!remStack.isEmpty()) { - baseString += digits[remStack.pop()]; - } - - return baseString; -} diff --git a/src/ts/others/factorial.ts b/src/ts/others/factorial.ts deleted file mode 100644 index e6e4cea9..00000000 --- a/src/ts/others/factorial.ts +++ /dev/null @@ -1,20 +0,0 @@ -export function factorialIterative(number: number) { - if (number < 0) { - return undefined; - } - let total = 1; - for (let n = number; n > 1; n--) { - total *= n; - } - return total; -} - -export function factorial(n: number): number { - if (n < 0) { - return undefined; - } - if (n === 1 || n === 0) { - return 1; - } - return n * factorial(n - 1); -} diff --git a/src/ts/others/fibonacci.ts b/src/ts/others/fibonacci.ts deleted file mode 100644 index 32d8db4f..00000000 --- a/src/ts/others/fibonacci.ts +++ /dev/null @@ -1,29 +0,0 @@ -export function fibonacci(n: number): number { - if (n < 1) { return 0; } // {1} - if (n <= 2) { return 1; } // {2} - return fibonacci(n - 1) + fibonacci(n - 2); // {3} -} - -export function fibonacciIterative(n: number) { - if (n < 1) { return 0; } - let fibNMinus2 = 0; - let fibNMinus1 = 1; - let fibN = n; - for (let i = 2; i <= n; i++) { - // n >= 2 - fibN = fibNMinus1 + fibNMinus2; // f(n-1) + f(n-2) - fibNMinus2 = fibNMinus1; - fibNMinus1 = fibN; - } - return fibN; -} - -export function fibonacciMemoization(n: number) { - if (n < 1) { return 0; } - const memo = [0, 1]; - const fibonacciMem = (num: number): number => { - if (memo[num] != null) { return memo[num]; } - return (memo[num] = fibonacciMem(num - 1) + fibonacciMem(num - 2)); - }; - return fibonacciMem(n); -} diff --git a/src/ts/others/hanoi.ts b/src/ts/others/hanoi.ts deleted file mode 100644 index fdc166a6..00000000 --- a/src/ts/others/hanoi.ts +++ /dev/null @@ -1,64 +0,0 @@ -import Stack from '../data-structures/stack'; - -function towerOfHanoi( - plates: number, - source: Stack, - helper: Stack, - dest: Stack, - sourceName: string, helperName: string, destName: string, - moves: any[] = [] -) { - if (plates <= 0) { - return moves; - } - if (plates === 1) { - dest.push(source.pop()); - const move: any = {}; - move[sourceName] = source.toString(); - move[helperName] = helper.toString(); - move[destName] = dest.toString(); - moves.push(move); - } else { - towerOfHanoi(plates - 1, source, dest, helper, sourceName, destName, helperName, moves); - dest.push(source.pop()); - const move: any = {}; - move[sourceName] = source.toString(); - move[helperName] = helper.toString(); - move[destName] = dest.toString(); - moves.push(move); - towerOfHanoi(plates - 1, helper, source, dest, helperName, sourceName, destName, moves); - } - return moves; -} - -export function hanoiStack(plates: number) { - const source = new Stack(); - const dest = new Stack(); - const helper = new Stack(); - - for (let i = plates; i > 0; i--) { - source.push(i); - } - - return towerOfHanoi(plates, source, helper, dest, 'source', 'helper', 'dest'); -} - -export function hanoi( - plates: number, - source: string, - helper: string, - dest: string, - moves: string[][] = [] -) { - if (plates <= 0) { - return moves; - } - if (plates === 1) { - moves.push([source, dest]); - } else { - hanoi(plates - 1, source, dest, helper, moves); - moves.push([source, dest]); - hanoi(plates - 1, helper, source, dest, moves); - } - return moves; -} diff --git a/src/ts/others/hot-potato.ts b/src/ts/others/hot-potato.ts deleted file mode 100644 index f6eb8349..00000000 --- a/src/ts/others/hot-potato.ts +++ /dev/null @@ -1,22 +0,0 @@ -import Queue from '../data-structures/queue'; - -export function hotPotato(elementsList: any[], num: number) { - const queue = new Queue(); - const elimitatedList = []; - - for (let i = 0; i < elementsList.length; i++) { - queue.enqueue(elementsList[i]); - } - - while (queue.size() > 1) { - for (let i = 0; i < num; i++) { - queue.enqueue(queue.dequeue()); - } - elimitatedList.push(queue.dequeue()); - } - - return { - elimitated: elimitatedList, - winner: queue.dequeue() - }; -} diff --git a/src/ts/others/palindrome-checker.ts b/src/ts/others/palindrome-checker.ts deleted file mode 100644 index 4742d1cd..00000000 --- a/src/ts/others/palindrome-checker.ts +++ /dev/null @@ -1,27 +0,0 @@ -import Deque from '../data-structures/deque'; - -export function palindromeChecker(aString: string) { - - if (aString === undefined || aString === null || - (aString !== null && aString.length === 0)) { - return false; - } - - const deque = new Deque(); - const lowerString = aString.toLocaleLowerCase().split(' ').join(''); - let firstChar: string, lastChar: string; - - for (let i = 0; i < lowerString.length; i++) { - deque.addBack(lowerString.charAt(i)); - } - - while (deque.size() > 1) { - firstChar = deque.removeFront(); - lastChar = deque.removeBack(); - if (firstChar !== lastChar) { - return false; - } - } - - return true; -} diff --git a/src/ts/util.ts b/src/ts/util.ts deleted file mode 100644 index 8c9f75f0..00000000 --- a/src/ts/util.ts +++ /dev/null @@ -1,60 +0,0 @@ -export type ICompareFunction = (a: T, b: T) => number; - -export type IEqualsFunction = (a: T, b: T) => boolean; - -export type IDiffFunction = (a: T, b: T) => number; - -export const DOES_NOT_EXIST = -1; - -export enum Compare { - LESS_THAN = -1, - BIGGER_THAN = 1, - EQUALS = 0 -} - -export function lesserEquals(a: T, b: T, compareFn: ICompareFunction) { - const comp = compareFn(a, b); - return comp === Compare.LESS_THAN || comp === Compare.EQUALS; -} - -export function biggerEquals(a: T, b: T, compareFn: ICompareFunction) { - const comp = compareFn(a, b); - return comp === Compare.BIGGER_THAN || comp === Compare.EQUALS; -} - -export function defaultCompare(a: T, b: T): number { - if (a === b) { - return Compare.EQUALS; - } - return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN; -} - -export function defaultEquals(a: T, b: T): boolean { - return a === b; -} - -export function defaultToString(item: any): string { - if (item === null) { - return 'NULL'; - } else if (item === undefined) { - return 'UNDEFINED'; - } else if (typeof item === 'string' || item instanceof String) { - return `${item}`; - } - return item.toString(); -} - -export function swap(array: any[], a: number, b: number) { - /* const temp = array[a]; - array[a] = array[b]; - array[b] = temp; */ - [array[a], array[b]] = [array[b], array[a]]; -} - -export function reverseCompare(compareFn: ICompareFunction): ICompareFunction { - return (a, b) => compareFn(b, a); -} - -export function defaultDiff(a: T, b: T): number { - return Number(a) - Number(b); -} diff --git a/test/js/algorithms/backtracking/rat-in-maze.spec.js b/test/js/algorithms/backtracking/rat-in-maze.spec.js deleted file mode 100644 index b88e1d60..00000000 --- a/test/js/algorithms/backtracking/rat-in-maze.spec.js +++ /dev/null @@ -1,21 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { ratInAMaze } from '../../../../src/js/index'; - -describe('Rat in a maze', () => { - it('rat in a maze solver', () => { - const maze = [ - [1, 0, 0, 0], - [1, 1, 1, 1], - [0, 0, 1, 0], - [0, 1, 1, 1] - ]; - const solution = [ - [1, 0, 0, 0], - [1, 1, 1, 0], - [0, 0, 1, 0], - [0, 0, 1, 1] - ]; - expect(ratInAMaze(maze)).to.deep.equal(solution); - }); -}); diff --git a/test/js/algorithms/backtracking/sudoku-solver.spec.js b/test/js/algorithms/backtracking/sudoku-solver.spec.js deleted file mode 100644 index f4d8c216..00000000 --- a/test/js/algorithms/backtracking/sudoku-solver.spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { sudokuSolver } from '../../../../src/js/index'; - -describe('Sudoku Solver', () => { - it('sudoku solver', () => { - const grid = [ - [3, 0, 6, 5, 0, 8, 4, 0, 0], - [5, 2, 0, 0, 0, 0, 0, 0, 0], - [0, 8, 7, 0, 0, 0, 0, 3, 1], - [0, 0, 3, 0, 1, 0, 0, 8, 0], - [9, 0, 0, 8, 6, 3, 0, 0, 5], - [0, 5, 0, 0, 9, 0, 6, 0, 0], - [1, 3, 0, 0, 0, 0, 2, 5, 0], - [0, 0, 0, 0, 0, 0, 0, 7, 4], - [0, 0, 5, 2, 0, 6, 3, 0, 0] - ]; - const solution = [ - [3, 1, 6, 5, 7, 8, 4, 9, 2], - [5, 2, 9, 1, 3, 4, 7, 6, 8], - [4, 8, 7, 6, 2, 9, 5, 3, 1], - [2, 6, 3, 4, 1, 5, 9, 8, 7], - [9, 7, 4, 8, 6, 3, 1, 2, 5], - [8, 5, 1, 7, 9, 2, 6, 4, 3], - [1, 3, 8, 9, 4, 7, 2, 5, 6], - [6, 9, 2, 3, 5, 1, 8, 7, 4], - [7, 4, 5, 2, 8, 6, 3, 1, 9] - ]; - expect(sudokuSolver(grid)).to.deep.equal(solution); - }); - - it('sudoku solver 2', () => { - const grid = [ - [5, 3, 0, 0, 7, 0, 0, 0, 0], - [6, 0, 0, 1, 9, 5, 0, 0, 0], - [0, 9, 8, 0, 0, 0, 0, 6, 0], - [8, 0, 0, 0, 6, 0, 0, 0, 3], - [4, 0, 0, 8, 0, 3, 0, 0, 1], - [7, 0, 0, 0, 2, 0, 0, 0, 6], - [0, 6, 0, 0, 0, 0, 2, 8, 0], - [0, 0, 0, 4, 1, 9, 0, 0, 5], - [0, 0, 0, 0, 8, 0, 0, 7, 9] - ]; - const solution = [ - [5, 3, 4, 6, 7, 8, 9, 1, 2], - [6, 7, 2, 1, 9, 5, 3, 4, 8], - [1, 9, 8, 3, 4, 2, 5, 6, 7], - [8, 5, 9, 7, 6, 1, 4, 2, 3], - [4, 2, 6, 8, 5, 3, 7, 9, 1], - [7, 1, 3, 9, 2, 4, 8, 5, 6], - [9, 6, 1, 5, 3, 7, 2, 8, 4], - [2, 8, 7, 4, 1, 9, 6, 3, 5], - [3, 4, 5, 2, 8, 6, 1, 7, 9] - ]; - expect(sudokuSolver(grid)).to.deep.equal(solution); - }); -}); diff --git a/test/js/algorithms/dynamic-programming/knapsack-recursive.spec.js b/test/js/algorithms/dynamic-programming/knapsack-recursive.spec.js deleted file mode 100644 index 589b8e9d..00000000 --- a/test/js/algorithms/dynamic-programming/knapsack-recursive.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { knapSackRecursive } from '../../../../src/js/index'; - -describe('KnapSack Dynamic Programming - Recursive', () => { - - it('works with recursive approach', () => { - const values = [3, 4, 5]; - const weights = [2, 3, 4]; - const capacity = 5; - const n = values.length; - - expect(knapSackRecursive(capacity, weights, values, n)).to.equal(7); - }); -}); diff --git a/test/js/algorithms/dynamic-programming/knapsack.spec.js b/test/js/algorithms/dynamic-programming/knapsack.spec.js deleted file mode 100644 index 47e2ab37..00000000 --- a/test/js/algorithms/dynamic-programming/knapsack.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { knapSack } from '../../../../src/js/index'; - -describe('KnapSack Dynamic Programming', () => { - - it('works with DP approach', () => { - const values = [3, 4, 5]; - const weights = [2, 3, 4]; - const capacity = 5; - const n = values.length; - - expect(knapSack(capacity, weights, values, n)).to.equal(7); - }); -}); diff --git a/test/js/algorithms/dynamic-programming/longest-common-subsequence-print.spec.js b/test/js/algorithms/dynamic-programming/longest-common-subsequence-print.spec.js deleted file mode 100644 index 8b5ba9fe..00000000 --- a/test/js/algorithms/dynamic-programming/longest-common-subsequence-print.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { lcsPrint } from '../../../../src/js/index'; - -describe('LCS Dynamic Programming with print solution', () => { - - it('works with DP approach with print solution', () => { - const wordX = 'acbaed'; - const wordY = 'abcadf'; - - expect(lcsPrint(wordX, wordY)).to.equal('acad'); - }); -}); diff --git a/test/js/algorithms/dynamic-programming/longest-common-subsequence.spec.js b/test/js/algorithms/dynamic-programming/longest-common-subsequence.spec.js deleted file mode 100644 index 121cf4fa..00000000 --- a/test/js/algorithms/dynamic-programming/longest-common-subsequence.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { lcs } from '../../../../src/js/index'; - -describe('LCS Dynamic Programming', () => { - - it('works with DP approach', () => { - const wordX = 'acbaed'; - const wordY = 'abcadf'; - - expect(lcs(wordX, wordY)).to.equal(4); - }); -}); diff --git a/test/js/algorithms/dynamic-programming/matrix-chain-multiplication.spec.js b/test/js/algorithms/dynamic-programming/matrix-chain-multiplication.spec.js deleted file mode 100644 index db1972e3..00000000 --- a/test/js/algorithms/dynamic-programming/matrix-chain-multiplication.spec.js +++ /dev/null @@ -1,12 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { matrixChainOrder } from '../../../../src/js/index'; - -describe('Matrix Chain Multiplication', () => { - - it('works with DP approach', () => { - const p = [10, 100, 5, 50, 1]; - - expect(matrixChainOrder(p)).to.equal(1750); - }); -}); diff --git a/test/js/algorithms/dynamic-programming/min-coin-change.spec.js b/test/js/algorithms/dynamic-programming/min-coin-change.spec.js deleted file mode 100644 index ecc8be1b..00000000 --- a/test/js/algorithms/dynamic-programming/min-coin-change.spec.js +++ /dev/null @@ -1,30 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { minCoinChange } from '../../../../src/js/index'; - -describe('Dynamic Programming: Min Coin Change', () => { - - it('works with amount 0', () => { - expect(minCoinChange([1, 2, 3], 0)).to.deep.equal([]); - }); - - it('works with amount 1', () => { - expect(minCoinChange([1, 2, 3], 1)).to.deep.equal([1]); - }); - - it('works with amount 2', () => { - expect(minCoinChange([1, 2, 3], 2)).to.deep.equal([2]); - }); - - it('works with amount 3', () => { - expect(minCoinChange([1, 2, 3], 3)).to.deep.equal([3]); - }); - - it('works with amount 4', () => { - expect(minCoinChange([1, 2, 3], 4)).to.deep.equal([1, 3]); - }); - - it('works with amount 6', () => { - expect(minCoinChange([1, 2, 3], 6)).to.deep.equal([3, 3]); - }); -}); diff --git a/test/js/algorithms/graph/breadth-first-search.spec.js b/test/js/algorithms/graph/breadth-first-search.spec.js deleted file mode 100644 index 1d7b5e75..00000000 --- a/test/js/algorithms/graph/breadth-first-search.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { BFS, breadthFirstSearch, Graph } from '../../../../src/js/index'; - -describe('Breadth First Search', () => { - let count; - const vertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; - let graph; - - function assertCallback(value) { - expect(value).to.equal(vertices[count]); - count++; - } - - beforeEach(() => { - count = 0; - graph = new Graph(); - - for (let i = 0; i < vertices.length; i++) { - graph.addVertex(vertices[i]); - } - - graph.addEdge('A', 'B'); - graph.addEdge('A', 'C'); - graph.addEdge('A', 'D'); - graph.addEdge('C', 'D'); - graph.addEdge('C', 'G'); - graph.addEdge('D', 'G'); - graph.addEdge('D', 'H'); - graph.addEdge('B', 'E'); - graph.addEdge('B', 'F'); - graph.addEdge('E', 'I'); - }); - - it('breadthFirstSearch', () => { - breadthFirstSearch(graph, vertices[0], assertCallback); - }); - - it('sorthest path - BFS', () => { - const shortestPathA = BFS(graph, vertices[0]); - - expect(shortestPathA.distances).to.deep.equal({ - A: 0, - B: 1, - C: 1, - D: 1, - E: 2, - F: 2, - G: 2, - H: 2, - I: 3 - }); - expect(shortestPathA.predecessors).to.deep.equal({ - A: null, - B: 'A', - C: 'A', - D: 'A', - E: 'B', - F: 'B', - G: 'C', - H: 'D', - I: 'E' - }); - }); -}); diff --git a/test/js/algorithms/graph/depth-first-search.spec.js b/test/js/algorithms/graph/depth-first-search.spec.js deleted file mode 100644 index e0cbcde9..00000000 --- a/test/js/algorithms/graph/depth-first-search.spec.js +++ /dev/null @@ -1,64 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { DFS, depthFirstSearch, Graph } from '../../../../src/js/index'; - -describe('Depth First Search', () => { - let count; - const vertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; - const dfsCallBack = ['A', 'B', 'E', 'I', 'F', 'C', 'D', 'G', 'H']; - let graph; - - beforeEach(() => { - count = 0; - graph = new Graph(true); - }); - - function assertCallback(value) { - expect(value).to.equal(dfsCallBack[count]); - count++; - } - - it('depthFirstSearch', () => { - for (let i = 0; i < vertices.length; i++) { - graph.addVertex(vertices[i]); - } - - graph.addEdge('A', 'B'); - graph.addEdge('A', 'C'); - graph.addEdge('A', 'D'); - graph.addEdge('C', 'D'); - graph.addEdge('C', 'G'); - graph.addEdge('D', 'G'); - graph.addEdge('D', 'H'); - graph.addEdge('B', 'E'); - graph.addEdge('B', 'F'); - graph.addEdge('E', 'I'); - - depthFirstSearch(graph, assertCallback); - }); - - it('topological sort - DFS', () => { - const myVertices = ['A', 'B', 'C', 'D', 'E', 'F']; - for (let i = 0; i < myVertices.length; i++) { - graph.addVertex(myVertices[i]); - } - graph.addEdge('A', 'C'); - graph.addEdge('A', 'D'); - graph.addEdge('B', 'D'); - graph.addEdge('B', 'E'); - graph.addEdge('C', 'F'); - graph.addEdge('F', 'E'); - - const result = DFS(graph); - - expect(result.discovery).to.deep.equal({ - A: 1, B: 11, C: 2, D: 8, E: 4, F: 3 - }); - expect(result.finished).to.deep.equal({ - A: 10, B: 12, C: 7, D: 9, E: 5, F: 6 - }); - expect(result.predecessors).to.deep.equal({ - A: null, B: null, C: 'A', D: 'A', E: 'F', F: 'C' - }); - }); -}); diff --git a/test/js/algorithms/graph/dijkstra.spec.js b/test/js/algorithms/graph/dijkstra.spec.js deleted file mode 100644 index 7a88f040..00000000 --- a/test/js/algorithms/graph/dijkstra.spec.js +++ /dev/null @@ -1,21 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { dijkstra } from '../../../../src/js/index'; - -describe('Dijkstra\'s Algorithm - Shortest Path', () => { - - it('Shortest Path', () => { - const graph = [ - [0, 2, 4, 0, 0, 0], - [0, 0, 2, 4, 2, 0], - [0, 0, 0, 0, 3, 0], - [0, 0, 0, 0, 0, 2], - [0, 0, 0, 3, 0, 2], - [0, 0, 0, 0, 0, 0] - ]; - - expect(dijkstra(graph, 0)).to.deep.equal([0, 2, 4, 6, 4, 6]); - - }); - -}); diff --git a/test/js/algorithms/graph/floyd-warshall.spec.js b/test/js/algorithms/graph/floyd-warshall.spec.js deleted file mode 100644 index 0f62cb7a..00000000 --- a/test/js/algorithms/graph/floyd-warshall.spec.js +++ /dev/null @@ -1,26 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { floydWarshall } from '../../../../src/js/index'; - -describe('Floyd-Warshall Algorithm - All-Pairs Shortest Path', () => { - it('All-Pairs Shortest Path', () => { - const INF = Infinity; - const graph = [ - [INF, 2, 4, INF, INF, INF], - [INF, INF, 2, 4, 2, INF], - [INF, INF, INF, INF, 3, INF], - [INF, INF, INF, INF, INF, 2], - [INF, INF, INF, 3, INF, 2], - [INF, INF, INF, INF, INF, INF] - ]; - - expect(floydWarshall(graph)).to.deep.equal([ - [0, 2, 4, 6, 4, 6], - [INF, 0, 2, 4, 2, 4], - [INF, INF, 0, 6, 3, 5], - [INF, INF, INF, 0, INF, 2], - [INF, INF, INF, 3, 0, 2], - [INF, INF, INF, INF, INF, 0] - ]); - }); -}); diff --git a/test/js/algorithms/graph/kruskal.spec.js b/test/js/algorithms/graph/kruskal.spec.js deleted file mode 100644 index 38a2132c..00000000 --- a/test/js/algorithms/graph/kruskal.spec.js +++ /dev/null @@ -1,18 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { kruskal } from '../../../../src/js/index'; - -describe('Kruskal Algorithm - Minimum Spanning Tree', () => { - it('Minimum Spanning Tree', () => { - const graph = [ - [0, 2, 4, 0, 0, 0], - [2, 0, 2, 4, 2, 0], - [4, 2, 0, 0, 3, 0], - [0, 4, 0, 0, 3, 2], - [0, 2, 3, 3, 0, 2], - [0, 0, 0, 2, 2, 0] - ]; - - expect(kruskal(graph)).to.deep.equal([ , 0, 1, 1, 1, 3]); - }); -}); diff --git a/test/js/algorithms/graph/prim.spec.js b/test/js/algorithms/graph/prim.spec.js deleted file mode 100644 index 9e0b6b31..00000000 --- a/test/js/algorithms/graph/prim.spec.js +++ /dev/null @@ -1,18 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { prim } from '../../../../src/js/index'; - -describe('Prim\'s Algorithm - Minimum Spanning Tree', () => { - it('Minimum Spanning Tree', () => { - const graph = [ - [0, 2, 4, 0, 0, 0], - [2, 0, 2, 4, 2, 0], - [4, 2, 0, 0, 3, 0], - [0, 4, 0, 0, 3, 2], - [0, 2, 3, 3, 0, 2], - [0, 0, 0, 2, 2, 0] - ]; - - expect(prim(graph)).to.deep.equal([-1, 0, 1, 5, 1, 4]); - }); -}); diff --git a/test/js/algorithms/greedy/knapsack.spec.js b/test/js/algorithms/greedy/knapsack.spec.js deleted file mode 100644 index 39be668a..00000000 --- a/test/js/algorithms/greedy/knapsack.spec.js +++ /dev/null @@ -1,14 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { knapSackGreedy } from '../../../../src/js/index'; - -describe('KnapSack Greedy', () => { - - it('works with greedy approach', () => { - const values = [3, 4, 5]; - const weights = [2, 3, 4]; - const capacity = 5; - - expect(knapSackGreedy(capacity, weights, values)).to.equal(7); - }); -}); diff --git a/test/js/algorithms/greedy/longest-common-subsequence.spec.js b/test/js/algorithms/greedy/longest-common-subsequence.spec.js deleted file mode 100644 index 7be0e4c4..00000000 --- a/test/js/algorithms/greedy/longest-common-subsequence.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { lcsRecursive } from '../../../../src/js/index'; - -describe('LCS Greedy', () => { - - it('works with Greedy approach', () => { - const wordX = 'acbaed'; - const wordY = 'abcadf'; - - expect(lcsRecursive(wordX, wordY)).to.equal(4); - }); -}); diff --git a/test/js/algorithms/greedy/matrix-chain-multiplication.spec.js b/test/js/algorithms/greedy/matrix-chain-multiplication.spec.js deleted file mode 100644 index c9d53888..00000000 --- a/test/js/algorithms/greedy/matrix-chain-multiplication.spec.js +++ /dev/null @@ -1,12 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { matrixChainOrderGreedy } from '../../../../src/js/index'; - -describe('Matrix Chain Multiplication', () => { - - it('works with DP approach', () => { - const p = [10, 100, 5, 50, 1]; - - expect(matrixChainOrderGreedy(p)).to.equal(1750); - }); -}); diff --git a/test/js/algorithms/greedy/min-coin-change.spec.js b/test/js/algorithms/greedy/min-coin-change.spec.js deleted file mode 100644 index ffa0b674..00000000 --- a/test/js/algorithms/greedy/min-coin-change.spec.js +++ /dev/null @@ -1,12 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { minCoinChangeGreedy } from '../../../../src/js/index'; - -describe('Min Coin Change Greedy', () => { - - it('works with greedy approach', () => { - expect(minCoinChangeGreedy([1, 5, 10], 15)).to.deep.equal([10, 5]); - expect(minCoinChangeGreedy([1, 3, 4], 6)).to.deep.equal([4, 1, 1]); - }); - -}); diff --git a/test/js/algorithms/search/binary-search-recursive.spec.js b/test/js/algorithms/search/binary-search-recursive.spec.js deleted file mode 100644 index 8aab4959..00000000 --- a/test/js/algorithms/search/binary-search-recursive.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { binarySearchRecursive } from '../../../../src/js/index'; -import { testSearchAlgorithm } from './search-algorithms-tests'; - -testSearchAlgorithm(binarySearchRecursive, 'Binary Search Recursive'); diff --git a/test/js/algorithms/search/binary-search.spec.js b/test/js/algorithms/search/binary-search.spec.js deleted file mode 100644 index 4e4014ce..00000000 --- a/test/js/algorithms/search/binary-search.spec.js +++ /dev/null @@ -1,20 +0,0 @@ -import { expect } from 'chai'; -import { binarySearch } from '../../../../src/js/index'; -import { testSearchAlgorithm } from './search-algorithms-tests'; - -testSearchAlgorithm(binarySearch, 'Binary Search'); - -describe('binarySearch', () => { - it('search elements in array of numbers', () => { - expect(binarySearch([0, 5, 3], 1)).to.equal(-1); - expect(binarySearch([2, 64, 33, 40, 100], 40)).to.equal(2); - expect(binarySearch([1, 2], 2)).to.equal(1); - expect(binarySearch([10, 20, 15, 40, 65], 40)).to.equal(3); - expect(binarySearch([1, 6, 7, 8, 12, 13, 14, 19, 21, 23, 24, 24, 24, 300], 24)).to.equal(10); - expect(binarySearch([1, 2, 3, 610, 800, 1250, 1360, 1400, 1905], 600)).to.equal(-1); - expect(binarySearch([1, 2, 3, 742, 800, 1250, 1360, 1400, 19550], 2)).to.equal(1); - expect(binarySearch([1, 2, 3, 743, 800, 1000, 1335, 1490, 1800], 743)).to.equal(3); - expect(binarySearch([1, 2, 3, 700, 800, 1233, 1380, 1400, 19678], 800)).to.equal(4); - expect(binarySearch([0, 10, 11, 12, 13, 14, 15], 10)).to.equal(1); - }); -}); diff --git a/test/js/algorithms/search/interpolation-search.spec.js b/test/js/algorithms/search/interpolation-search.spec.js deleted file mode 100644 index 1daff1cc..00000000 --- a/test/js/algorithms/search/interpolation-search.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { interpolationSearch } from '../../../../src/js/index'; -import { testSearchAlgorithm } from './search-algorithms-tests'; - -testSearchAlgorithm(interpolationSearch, 'Interpolation Search', { customEquals: false }); diff --git a/test/js/algorithms/search/min-max-search.spec.js b/test/js/algorithms/search/min-max-search.spec.js deleted file mode 100644 index 0c789a2f..00000000 --- a/test/js/algorithms/search/min-max-search.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { findMinValue, findMaxValue } from '../../../../src/js/index'; - -describe('Min and Max Values Search', () => { - const SIZE = 10; - - function createSortedArray() { - const array = []; - for (let i = 1; i <= SIZE; i++) { - array.push(i); - } - return array; - } - - it('min value - works with empty arrays', () => { - expect(findMinValue([])).to.equal(undefined); - }); - - it('max value - works with empty arrays', () => { - expect(findMaxValue([])).to.equal(undefined); - }); - - it('min value', () => { - expect(findMinValue(createSortedArray())).to.equal(1); - }); - - it('max value', () => { - expect(findMaxValue(createSortedArray())).to.equal(SIZE); - }); -}); diff --git a/test/js/algorithms/search/search-algorithms-tests.js b/test/js/algorithms/search/search-algorithms-tests.js deleted file mode 100644 index f0c698a2..00000000 --- a/test/js/algorithms/search/search-algorithms-tests.js +++ /dev/null @@ -1,51 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; - -const customEquals = (a, b) => a.key === b.key; - -export function testSearchAlgorithm( - searchAlgorithm, - algorithmName, - config = { customEquals: true } -) { - describe(algorithmName, () => { - const SIZE = 10; - - function createSortedArray() { - const array = []; - for (let i = 1; i <= SIZE; i++) { - array.push(i); - } - return array; - } - - it('works with empty arrays', () => { - expect(searchAlgorithm([], 1)).to.equal(-1); - }); - - it('finds value at the first position', () => { - const array = createSortedArray(); - expect(searchAlgorithm(array, 1)).to.equal(0); - }); - - it('finds value at the last position', () => { - const array = createSortedArray(); - expect(searchAlgorithm(array, SIZE)).to.equal(SIZE - 1); - }); - - it('finds value at different positions', () => { - const array = createSortedArray(); - - for (let value = 1; value <= SIZE; value++) { - expect(searchAlgorithm(array, value)).to.equal(value - 1); - } - }); - - if (config.customEquals) { - it('finds value with custom equals function', () => { - const array = [{ key: 1 }, { key: 2 }, { key: 3 }]; - expect(searchAlgorithm(array, { key: 2 }, customEquals)).to.equal(1); - }); - } - }); -} diff --git a/test/js/algorithms/search/sequential-search.spec.js b/test/js/algorithms/search/sequential-search.spec.js deleted file mode 100644 index a308474e..00000000 --- a/test/js/algorithms/search/sequential-search.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { sequentialSearch } from '../../../../src/js/index'; -import { testSearchAlgorithm } from './search-algorithms-tests'; - -testSearchAlgorithm(sequentialSearch, 'Sequential Search'); diff --git "a/test/js/algorithms/shuffle/fisher\342\200\223yates.spec.js" "b/test/js/algorithms/shuffle/fisher\342\200\223yates.spec.js" deleted file mode 100644 index 6e87916c..00000000 --- "a/test/js/algorithms/shuffle/fisher\342\200\223yates.spec.js" +++ /dev/null @@ -1,31 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { shuffle } from '../../../../src/js/index'; - -describe('Fisher-Yates Suffle', () => { - const SIZE = 100; - - function createSortedArray() { - const array = []; - for (let i = 1; i <= SIZE; i++) { - array.push(i); - } - return array; - } - - it('works with empty arrays', () => { - expect(shuffle([])).to.deep.equal([]); - }); - - it('works with arrays with a single value', () => { - const array = [1]; - expect(shuffle(array)).to.deep.equal(array); - }); - - it('works with sorted arrays', () => { - let array = createSortedArray(); - const sortedArray = createSortedArray(); - array = shuffle(array); - expect(array).to.not.deep.equal(sortedArray); - }); -}); diff --git a/test/js/algorithms/sorting/bubble-sort-improved.spec.js b/test/js/algorithms/sorting/bubble-sort-improved.spec.js deleted file mode 100644 index 1ad03b39..00000000 --- a/test/js/algorithms/sorting/bubble-sort-improved.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { modifiedBubbleSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(modifiedBubbleSort, 'Bubble Sort - Improved'); diff --git a/test/js/algorithms/sorting/bubble-sort.spec.js b/test/js/algorithms/sorting/bubble-sort.spec.js deleted file mode 100644 index b903df74..00000000 --- a/test/js/algorithms/sorting/bubble-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { bubbleSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(bubbleSort, 'Bubble Sort'); diff --git a/test/js/algorithms/sorting/bucket-sort.spec.js b/test/js/algorithms/sorting/bucket-sort.spec.js deleted file mode 100644 index 2a00d8db..00000000 --- a/test/js/algorithms/sorting/bucket-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { bucketSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(bucketSort, 'Bucket Sort', { reverseCompare: false }); diff --git a/test/js/algorithms/sorting/counting-sort.spec.js b/test/js/algorithms/sorting/counting-sort.spec.js deleted file mode 100644 index 783a48a5..00000000 --- a/test/js/algorithms/sorting/counting-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { countingSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(countingSort, 'Counting Sort', { reverseCompare: false }); diff --git a/test/js/algorithms/sorting/heap-sort.spec.js b/test/js/algorithms/sorting/heap-sort.spec.js deleted file mode 100644 index ae3816dc..00000000 --- a/test/js/algorithms/sorting/heap-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { heapSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(heapSort, 'Heap Sort'); diff --git a/test/js/algorithms/sorting/insertion-sort.spec.js b/test/js/algorithms/sorting/insertion-sort.spec.js deleted file mode 100644 index c28a69de..00000000 --- a/test/js/algorithms/sorting/insertion-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { insertionSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(insertionSort, 'Insertion Sort'); diff --git a/test/js/algorithms/sorting/merge-sort.spec.js b/test/js/algorithms/sorting/merge-sort.spec.js deleted file mode 100644 index 5b161785..00000000 --- a/test/js/algorithms/sorting/merge-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { mergeSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(mergeSort, 'Merge Sort'); diff --git a/test/js/algorithms/sorting/quicksort.spec.js b/test/js/algorithms/sorting/quicksort.spec.js deleted file mode 100644 index 0cbe027a..00000000 --- a/test/js/algorithms/sorting/quicksort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { quickSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(quickSort, 'Quick Sort'); diff --git a/test/js/algorithms/sorting/radix-sort.spec.js b/test/js/algorithms/sorting/radix-sort.spec.js deleted file mode 100644 index af6a5b07..00000000 --- a/test/js/algorithms/sorting/radix-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { radixSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(radixSort, 'Radix Sort', { reverseCompare: false }); diff --git a/test/js/algorithms/sorting/selection-sort.spec.js b/test/js/algorithms/sorting/selection-sort.spec.js deleted file mode 100644 index 3d6cd3cc..00000000 --- a/test/js/algorithms/sorting/selection-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { selectionSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(selectionSort, 'Selection Sort'); diff --git a/test/js/algorithms/sorting/shell-sort.spec.js b/test/js/algorithms/sorting/shell-sort.spec.js deleted file mode 100644 index 92aa33a5..00000000 --- a/test/js/algorithms/sorting/shell-sort.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { shellSort } from '../../../../src/js/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(shellSort, 'Shell Sort'); diff --git a/test/js/algorithms/sorting/sort-algorithm-tests.js b/test/js/algorithms/sorting/sort-algorithm-tests.js deleted file mode 100644 index 6b883e83..00000000 --- a/test/js/algorithms/sorting/sort-algorithm-tests.js +++ /dev/null @@ -1,69 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { Compare } from '../../../../src/js/util'; - -export function testSortAlgorithm(sortAlgorithm, algorithmName, config = { reverseCompare: true }) { - describe(algorithmName, () => { - const SIZE = 100; - - function createNonSortedArray() { - const array = []; - for (let i = SIZE; i > 0; i--) { - array.push(i); - } - return array; - } - - function createSortedArray() { - const array = []; - for (let i = 1; i <= SIZE; i++) { - array.push(i); - } - return array; - } - - it('works with empty arrays', () => { - expect(sortAlgorithm([])).to.deep.equal([]); - }); - - it('works with sorted arrays', () => { - let array = createSortedArray(); - const sortedArray = createSortedArray(); - array = sortAlgorithm(array); - expect(array).to.deep.equal(sortedArray); - }); - - it('works with non-sorted arrays', () => { - let array = createNonSortedArray(); - const sortedArray = createSortedArray(); - array = sortAlgorithm(array); - - expect(array).to.deep.equal(sortedArray); - - for (let i = 0; i < array.length - 1; i++) { - expect(array[i] <= array[i + 1]).to.equal(true); - } - }); - - function reverseCompare(a, b) { - if (a === b) { - return 0; - } - return a < b ? Compare.BIGGER_THAN : Compare.LESS_THAN; - } - - if (config.reverseCompare) { - it('works with reverse comparator - descending order', () => { - let array = createSortedArray(); - const sortedArray = createNonSortedArray(); - array = sortAlgorithm(array, reverseCompare); - - expect(array).to.deep.equal(sortedArray); - - for (let i = 0; i < array.length - 1; i++) { - expect(array[i] >= array[i + 1]).to.equal(true); - } - }); - } - }); -} diff --git a/test/js/data-structures/avl-tree.spec.js b/test/js/data-structures/avl-tree.spec.js deleted file mode 100644 index f113e561..00000000 --- a/test/js/data-structures/avl-tree.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { AVLTree } from '../../../src/js/index'; - -describe('AVLTree', () => { - let tree; - - beforeEach(() => { - tree = new AVLTree(); - }); - - it('starts empty', () => { - expect(tree.getRoot()).to.equal(null); - }); - - it('inserts elements in the AVLTree', () => { - expect(tree.getRoot()).to.equal(null); - - tree.insert(1); - tree.insert(2); - tree.insert(3); - tree.insert(4); - tree.insert(5); - tree.insert(6); - tree.insert(7); - tree.insert(14); - tree.insert(15); - tree.insert(13); - tree.insert(12); - tree.insert(11); - }); -}); diff --git a/test/js/data-structures/binary-search-tree.spec.js b/test/js/data-structures/binary-search-tree.spec.js deleted file mode 100644 index 8b940818..00000000 --- a/test/js/data-structures/binary-search-tree.spec.js +++ /dev/null @@ -1,108 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { BinarySearchTree } from '../../../src/js/index'; - -describe('BinarySearchTree', () => { - let tree; - - beforeEach(() => { - tree = new BinarySearchTree(); - }); - - it('starts empty', () => { - expect(tree.getRoot()).to.equal(undefined); - }); - - function assertNode(node, key, left, right) { - if (key != null) { - expect(node.key).to.equal(key); - } else { - expect(node).to.equal(key); - return; - } - - if (left != null) { - expect(node.left.key).to.equal(left); - } else { - expect(node.left).to.equal(left); - } - - if (right != null) { - expect(node.right.key).to.equal(right); - } else { - expect(node.right).to.equal(right); - } - } - - it('inserts elements in the BST', () => { - expect(tree.getRoot()).to.equal(undefined); - - tree.insert(11); - tree.insert(7); - tree.insert(15); - tree.insert(5); - tree.insert(3); - tree.insert(9); - tree.insert(8); - tree.insert(10); - tree.insert(13); - tree.insert(12); - tree.insert(14); - tree.insert(20); - tree.insert(18); - tree.insert(25); - - let node = tree.getRoot(); - assertNode(node, 11, 7, 15); - - node = node.left; - assertNode(node, 7, 5, 9); - - node = node.left; - assertNode(node, 5, 3, undefined); - - node = node.left; - assertNode(node, 3, undefined, undefined); - - node = tree.getRoot().left.left.right; - assertNode(node, undefined, undefined, undefined); - - node = tree.getRoot().left.right; - assertNode(node, 9, 8, 10); - - node = node.left; - assertNode(node, 8, undefined, undefined); - - node = tree.getRoot().left.right.right; - assertNode(node, 10, undefined, undefined); - - node = tree.getRoot().right; - assertNode(node, 15, 13, 20); - - node = node.left; - assertNode(node, 13, 12, 14); - - node = node.left; - assertNode(node, 12, undefined, undefined); - - node = tree.getRoot().right.left.right; - assertNode(node, 14, undefined, undefined); - - node = tree.getRoot().right.right; - assertNode(node, 20, 18, 25); - - node = node.left; - assertNode(node, 18, undefined, undefined); - - node = tree.getRoot().right.right.right; - assertNode(node, 25, undefined, undefined); - }); - - it('verifies if element exists', () => { - expect(tree.getRoot()).to.equal(undefined); - }); - - it('removes a leaf', () => { - expect(tree.getRoot()).to.equal(undefined); - }); -}); diff --git a/test/js/data-structures/circular-linked-list.spec.js b/test/js/data-structures/circular-linked-list.spec.js deleted file mode 100644 index aadb02ee..00000000 --- a/test/js/data-structures/circular-linked-list.spec.js +++ /dev/null @@ -1,342 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { CircularLinkedList } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('CircularLinkedList', () => { - let list; - let min; - let max; - - beforeEach(() => { - list = new CircularLinkedList(); - min = 1; - max = 3; - }); - - function pushesElements() { - for (let i = min; i <= max; i++) { - list.push(i); - } - } - - function verifyList() { - let current = list.getHead(); - for (let i = min; i <= max && current; i++) { - expect(current).to.not.be.an('undefined'); - if (current) { - // TS strictNullChecks - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(i); - if (i < max) { - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - // TS strictNullChecks - expect(current.next.element).to.equal(i + 1); - } - } else { - // circular list - expect(current.next).to.not.be.an('undefined'); - expect(current.next).to.equal(list.getHead()); - if (current.next) { - expect(current.next.element).to.equal(min); - } - } - current = current.next; - } - } - } - - it('starts empty', () => { - expect(list.size()).to.equal(0); - expect(list.isEmpty()).to.equal(true); - expect(list.getHead()).to.be.an('undefined'); - }); - - it('pushes elements', () => { - pushesElements(); - verifyList(); - }); - - it('returns element at specific index: invalid position', () => { - // list is empty - expect(list.getElementAt(3)).to.be.an('undefined'); - }); - - it('returns element at specific index', () => { - let node; - - pushesElements(); - - for (let i = min; i <= max; i++) { - node = list.getElementAt(i - 1); - expect(node).to.not.be.an('undefined'); - if (node) { - expect(node.element).to.equal(i); - } - } - }); - - it('inserts elements first position empty list', () => { - const element = 1; - max = element; - expect(list.insert(element, 0)).to.equal(true); - verifyList(); - }); - - it('inserts elements first position not empty list', () => { - max = 2; - expect(list.insert(max, 0)).to.equal(true); - - expect(list.insert(min, 0)).to.equal(true); - - verifyList(); - }); - - it('inserts elements invalid position empty list', () => { - expect(list.insert(1, 1)).to.equal(false); - }); - - it('inserts elements invalid position not empty list', () => { - const element = 1; - expect(list.insert(element, 0)).to.equal(true); - expect(list.insert(element, 2)).to.equal(false); - }); - - it('inserts elements in the middle of list', () => { - expect(list.insert(3, 0)).to.equal(true); - expect(list.insert(1, 0)).to.equal(true); - expect(list.insert(2, 1)).to.equal(true); - verifyList(); - }); - - it('inserts elements at the end of list', () => { - max = 5; - - for (let i = min; i <= max; i++) { - expect(list.insert(i, i - 1)).to.equal(true); - } - - verifyList(); - }); - - it('returns index of elements', () => { - let index; - - pushesElements(); - - for (let i = min; i <= max; i++) { - index = list.indexOf(i); - expect(index).to.equal(i - 1); - } - - expect(list.indexOf(max + 2)).to.equal(-1); - }); - - it('removes valid elements', () => { - let element; - - pushesElements(); - - const minIndex = min; - for (let i = minIndex; i <= max; i++) { - element = list.remove(i); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - min++; - verifyList(); - } - }); - - it('removes invalid elements', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.remove(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position empty list', () => { - let element; - - for (let i = min; i <= max; i++) { - element = list.removeAt(i - 1); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position not empty list', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.removeAt(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes first element list single element', () => { - const value = 1; - list.push(value); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(value); - - expect(list.getHead()).to.be.an('undefined'); - expect(list.isEmpty()).to.equal(true); - }); - - it('removes first element list multiple elements', () => { - pushesElements(); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(min); - - min = 2; - verifyList(); - }); - - it('removes element from middle of list', () => { - pushesElements(); // 1, 2, 3 - - const element = list.removeAt(1); // element 2 - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(2); - - // list needs to be [1, 3] - let current = list.getHead(); - - // element 1 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(min); - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - expect(current.next.element).to.equal(max); - current = current.next; - } - } - - // element 3 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(max); - expect(current.next).to.not.be.an('undefined'); - expect(current.next).to.equal(list.getHead()); - if (current.next) { - expect(current.next.element).to.equal(min); - } - } - }); - - it('removes element from end of list', () => { - let element; - - pushesElements(); - - const maxIndex = max; - for (let i = maxIndex; i >= min; i--) { - element = list.removeAt(i - 1); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - max--; - verifyList(); - } - }); - - it('returns the head of the list', () => { - expect(list.getHead()).to.be.an('undefined'); - - list.push(1); - expect(list.getHead()).to.not.be.an('undefined'); - }); - - it('returns the correct size', () => { - expect(list.size()).to.equal(0); - - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.size()).to.equal(i); - } - - const size = max; - for (let i = min; i <= max; i++) { - list.remove(i); - expect(list.size()).to.equal(size - i); - } - - expect(list.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(list.isEmpty()).to.equal(true); - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.isEmpty()).to.equal(false); - } - - for (let i = min; i < max; i++) { - list.remove(i); - expect(list.isEmpty()).to.equal(false); - } - list.remove(max); - expect(list.isEmpty()).to.equal(true); - - pushesElements(); - expect(list.isEmpty()).to.equal(false); - - list.clear(); - expect(list.isEmpty()).to.equal(true); - }); - - it('clears the list', () => { - expect(list.size()).to.equal(0); - list.clear(); - expect(list.size()).to.equal(0); - pushesElements(); - expect(list.size()).to.greaterThan(0); - list.clear(); - expect(list.size()).to.equal(0); - }); - - it('returns toString primitive types', () => { - expect(list.toString()).to.equal(''); - - list.push(1); - expect(list.toString()).to.equal('1'); - - list.push(2); - expect(list.toString()).to.equal('1,2'); - - list.clear(); - expect(list.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const ds = new CircularLinkedList(); - ds.push('el1'); - expect(ds.toString()).to.equal('el1'); - - ds.push('el2'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const ds = new CircularLinkedList(); - expect(ds.toString()).to.equal(''); - - ds.push(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2'); - - ds.push(new MyObj(3, 4)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/data-structures/deque.spec.js b/test/js/data-structures/deque.spec.js deleted file mode 100644 index 49ab2dfa..00000000 --- a/test/js/data-structures/deque.spec.js +++ /dev/null @@ -1,208 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import Deque from '../../../src/js/data-structures/deque'; - -describe('Deque', () => { - let deque; - - beforeEach(() => { - deque = new Deque(); - }); - - it('starts empty', () => { - expect(deque.size()).to.equal(0); - expect(deque.isEmpty()).to.equal(true); - }); - - it('add elements in the back', () => { - deque.addBack(1); - expect(deque.size()).to.equal(1); - - deque.addBack(2); - expect(deque.size()).to.equal(2); - - deque.addBack(3); - expect(deque.size()).to.equal(3); - }); - - it('add elements in the front', () => { - deque.addFront(1); - expect(deque.size()).to.equal(1); - - deque.addFront(2); - expect(deque.size()).to.equal(2); - - deque.addFront(3); - expect(deque.size()).to.equal(3); - - deque.removeFront(); - deque.addFront(4); - expect(deque.size()).to.equal(3); - }); - - it('remove elements from the back', () => { - deque.addBack(1); - deque.addBack(2); - deque.addBack(3); - deque.addFront(0); - - expect(deque.removeBack()).to.equal(3); - expect(deque.removeBack()).to.equal(2); - expect(deque.removeBack()).to.equal(1); - expect(deque.removeBack()).to.equal(0); - expect(deque.removeBack()).to.equal(undefined); - }); - - it('remove elements from the front', () => { - deque.addFront(1); - deque.addBack(2); - deque.addBack(3); - deque.addFront(0); - deque.addFront(-1); - deque.addFront(-2); - - expect(deque.removeFront()).to.equal(-2); - expect(deque.removeFront()).to.equal(-1); - expect(deque.removeFront()).to.equal(0); - expect(deque.removeFront()).to.equal(1); - expect(deque.removeFront()).to.equal(2); - expect(deque.removeFront()).to.equal(3); - expect(deque.removeFront()).to.equal(undefined); - }); - - it('allows to peek at the front element in the deque without removing it', () => { - expect(deque.peekFront()).to.equal(undefined); - - deque.addFront(1); - expect(deque.peekFront()).to.equal(1); - deque.addBack(2); - expect(deque.peekFront()).to.equal(1); - deque.addBack(3); - expect(deque.peekFront()).to.equal(1); - deque.addFront(0); - expect(deque.peekFront()).to.equal(0); - deque.addFront(-1); - expect(deque.peekFront()).to.equal(-1); - deque.addFront(-2); - expect(deque.peekFront()).to.equal(-2); - }); - - it('allows to peek at the last element in the deque without removing it', () => { - expect(deque.peekBack()).to.equal(undefined); - - deque.addFront(1); - expect(deque.peekBack()).to.equal(1); - deque.addBack(2); - expect(deque.peekBack()).to.equal(2); - deque.addBack(3); - expect(deque.peekBack()).to.equal(3); - deque.addFront(0); - expect(deque.peekBack()).to.equal(3); - deque.addFront(-1); - expect(deque.peekBack()).to.equal(3); - deque.addFront(-2); - expect(deque.peekBack()).to.equal(3); - }); - - it('returns the correct size', () => { - expect(deque.size()).to.equal(0); - - deque.addFront(1); - expect(deque.size()).to.equal(1); - deque.addBack(2); - expect(deque.size()).to.equal(2); - deque.addBack(3); - expect(deque.size()).to.equal(3); - deque.addFront(0); - expect(deque.size()).to.equal(4); - deque.addFront(-1); - expect(deque.size()).to.equal(5); - deque.addFront(-2); - expect(deque.size()).to.equal(6); - - deque.clear(); - expect(deque.size()).to.equal(0); - - deque.addFront(1); - deque.addBack(2); - expect(deque.size()).to.equal(2); - - deque.removeFront(); - deque.removeBack(); - expect(deque.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(deque.isEmpty()).to.equal(true); - - deque.addFront(1); - expect(deque.isEmpty()).to.equal(false); - deque.addBack(2); - expect(deque.isEmpty()).to.equal(false); - - deque.clear(); - expect(deque.isEmpty()).to.equal(true); - - deque.addFront(1); - deque.addBack(2); - expect(deque.isEmpty()).to.equal(false); - - deque.removeFront(); - expect(deque.isEmpty()).to.equal(false); - deque.removeBack(); - expect(deque.isEmpty()).to.equal(true); - }); - - it('clears the queue', () => { - deque.clear(); - expect(deque.isEmpty()).to.equal(true); - - deque.addFront(1); - deque.addBack(2); - expect(deque.isEmpty()).to.equal(false); - - deque.clear(); - expect(deque.isEmpty()).to.equal(true); - }); - - it('returns toString primitive types', () => { - expect(deque.toString()).to.equal(''); - - deque.addFront(1); - expect(deque.toString()).to.equal('1'); - - deque.addBack(2); - expect(deque.toString()).to.equal('1,2'); - - deque.clear(); - expect(deque.toString()).to.equal(''); - - const queueString = new Deque(); - queueString.addFront('el1'); - expect(queueString.toString()).to.equal('el1'); - - queueString.addBack('el2'); - expect(queueString.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - class MyObj { - constructor(el1, el2) { - this.el1 = el1; - this.el2 = el2; - } - - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } - } - const dequeMyObj = new Deque(); - expect(dequeMyObj.toString()).to.equal(''); - - dequeMyObj.addFront(new MyObj(1, 2)); - expect(dequeMyObj.toString()).to.equal('1|2'); - - dequeMyObj.addBack(new MyObj(3, 4)); - expect(dequeMyObj.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/data-structures/dictionary.spec.js b/test/js/data-structures/dictionary.spec.js deleted file mode 100644 index 72e78640..00000000 --- a/test/js/data-structures/dictionary.spec.js +++ /dev/null @@ -1,266 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { Dictionary } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('Dictionary', () => { - let dictionary; - beforeEach(() => { - dictionary = new Dictionary(); - }); - it('starts empty', () => { - expect(dictionary.size()).to.equal(0); - expect(dictionary.isEmpty()).to.equal(true); - }); - it('sets undefined and null keys and values', () => { - const dict = new Dictionary(); - expect(dict.set('undefined', undefined)).to.equal(false); - expect(dict.get('undefined')).to.equal(undefined); - expect(dict.set('undefined', 1)).to.equal(true); - expect(dict.get('undefined')).to.equal(1); - expect(dict.set('null', null)).to.equal(false); - expect(dict.get('null')).to.equal(undefined); - expect(dict.set('null', 1)).to.equal(true); - expect(dict.get('null')).to.equal(1); - dict.clear(); - expect(dict.set(undefined, undefined)).to.equal(false); - expect(dict.get(undefined)).to.equal(undefined); - expect(dict.set(undefined, 1)).to.equal(false); - expect(dict.get(undefined)).to.equal(undefined); - expect(dict.set(null, null)).to.equal(false); - expect(dict.get(null)).to.equal(undefined); - expect(dict.set(null, 1)).to.equal(false); - expect(dict.get(null)).to.equal(undefined); - }); - it('sets values with string key', () => { - const dict = new Dictionary(); - const min = 1; - const max = 5; - const size = (max - min) + 1; - for (let i = min; i <= max; i++) { - expect(dict.set(`${i}`, i)).to.equal(true); - } - expect(dict.size()).to.equal(size); - const keys = dict.keys(); - expect(keys.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal((i + 1).toString(10)); - } - dict.set('a', 1); - expect(dict.get('a')).to.equal(1); - }); - it('sets values with number key', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - for (let i = min; i <= max; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - expect(dictionary.size()).to.equal(size); - const keys = dictionary.keys(); - expect(keys.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal(i + 1); - } - }); - it('sets values with object', () => { - const dict = new Dictionary(); - const min = 0; - const max = 5; - const size = max - min; - const myObjList = []; - for (let i = min; i < max; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - for (let i = min; i < max; i++) { - expect(dict.set(myObjList[i], myObjList[i])).to.equal(true); - } - expect(dict.size()).to.equal(size); - for (let i = min; i < max; i++) { - expect(dict.get(myObjList[i])).to.equal(myObjList[i]); - } - const keys = dict.keys(); - expect(keys.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal(myObjList[i]); - } - const values = dict.values(); - expect(values.length).to.equal(size); - for (let i = 0; i < values.length; i++) { - expect(values[i]).to.equal(myObjList[i]); - } - }); - function customToString(key) { - return `####${key.toString()}`; - } - it('sets values with custom toString function', () => { - const dict = new Dictionary(customToString); - const min = 0; - const max = 5; - const size = max - min; - const myObjList = []; - for (let i = min; i < max; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - for (let i = min; i < max; i++) { - expect(dict.set(myObjList[i], myObjList[i])).to.equal(true); - } - expect(dict.size()).to.equal(size); - for (let i = min; i < max; i++) { - expect(dict.get(myObjList[i])).to.equal(myObjList[i]); - } - const keys = dict.keys(); - expect(keys.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal(myObjList[i]); - } - const values = dict.values(); - expect(values.length).to.equal(size); - for (let i = 0; i < values.length; i++) { - expect(values[i]).to.equal(myObjList[i]); - } - }); - it('removes elements', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - for (let i = min; i <= max; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - expect(dictionary.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(dictionary.remove(i)).to.equal(true); - } - // elements do not exist - for (let i = min; i <= max; i++) { - expect(dictionary.remove(i)).to.equal(false); - } - expect(dictionary.isEmpty()).to.equal(true); - }); - it('returns the correct size', () => { - expect(dictionary.size()).to.equal(0); - const max = 5; - for (let i = 1; i < max; i++) { - dictionary.set(i, i); - expect(dictionary.size()).to.equal(i); - } - for (let i = 1; i < max; i++) { - dictionary.remove(i); - expect(dictionary.size()).to.equal(max - i - 1); - } - expect(dictionary.size()).to.equal(0); - expect(dictionary.isEmpty()).to.equal(true); - }); - it('returns if element exists', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - for (let i = min; i <= max; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - expect(dictionary.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(dictionary.hasKey(i)).to.equal(true); - expect(dictionary.remove(i)).to.equal(true); - expect(dictionary.hasKey(i)).to.equal(false); - } - }); - it('returns if it is empty', () => { - expect(dictionary.isEmpty()).to.equal(true); - for (let i = 1; i < 5; i++) { - dictionary.set(i, i); - expect(dictionary.isEmpty()).to.equal(false); - } - for (let i = 1; i < 5; i++) { - dictionary.remove(i); - expect(dictionary.isEmpty()).to.equal(!(i < 4)); - } - expect(dictionary.size()).to.equal(0); - expect(dictionary.isEmpty()).to.equal(true); - }); - it('clears the dictionary', () => { - dictionary.clear(); - expect(dictionary.isEmpty()).to.equal(true); - dictionary.set(1, 1); - dictionary.set(2, 2); - dictionary.clear(); - expect(dictionary.isEmpty()).to.equal(true); - }); - it('returns values, keys and value pairs', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - for (let i = min; i <= max; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - expect(dictionary.size()).to.equal(size); - const keys = dictionary.keys(); - const values = dictionary.values(); - const valuePairs = dictionary.keyValues(); - expect(keys.length).to.equal(size); - expect(values.length).to.equal(size); - expect(valuePairs.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal(i + 1); - expect(values[i]).to.equal(i + 1); - expect(valuePairs[i].key).to.equal(i + 1); - expect(valuePairs[i].value).to.equal(i + 1); - } - }); - it('allows to iterate with forEach', () => { - for (let i = 1; i <= 5; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - dictionary.forEach((k, v) => { - expect(dictionary.hasKey(k)).to.equal(true); - expect(dictionary.get(k)).to.equal(v); - }); - }); - it('allows to iterate with forEach and interrupt', () => { - for (let i = 1; i <= 5; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - const size = dictionary.keys().length; - let index = 1; - dictionary.forEach((k, v) => { - expect(dictionary.hasKey(k)).to.equal(true); - expect(dictionary.get(k)).to.equal(v); - index++; - }); - expect(index).to.equal(size + 1); - index = 1; - dictionary.forEach((k, v) => { - expect(dictionary.hasKey(k)).to.equal(true); - expect(dictionary.get(k)).to.equal(v); - index++; - return !(k % 3 === 0); - }); - expect(index).to.equal(size - 1); - }); - it('returns toString primitive types', () => { - expect(dictionary.toString()).to.equal(''); - dictionary.set(1, 1); - expect(dictionary.toString()).to.equal('[#1: 1]'); - dictionary.set(2, 2); - expect(dictionary.toString()).to.equal('[#1: 1],[#2: 2]'); - dictionary.clear(); - expect(dictionary.toString()).to.equal(''); - }); - it('returns toString primitive types: string', () => { - const dict = new Dictionary(); - dict.set('el1', 1); - expect(dict.toString()).to.equal('[#el1: 1]'); - dict.set('el2', 2); - expect(dict.toString()).to.equal('[#el1: 1],[#el2: 2]'); - }); - it('returns toString objects', () => { - const dict = new Dictionary(); - expect(dict.toString()).to.equal(''); - let myObj = new MyObj(1, 2); - dict.set(myObj, myObj); - expect(dict.toString()).to.equal('[#1|2: 1|2]'); - myObj = new MyObj(3, 4); - dict.set(myObj, myObj); - expect(dict.toString()).to.equal('[#1|2: 1|2],[#3|4: 3|4]'); - }); -}); diff --git a/test/js/data-structures/doubly-linked-list.spec.js b/test/js/data-structures/doubly-linked-list.spec.js deleted file mode 100644 index 5e7fd6a4..00000000 --- a/test/js/data-structures/doubly-linked-list.spec.js +++ /dev/null @@ -1,406 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { DoublyLinkedList } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('DoublyLinkedList', () => { - let list; - let min; - let max; - - beforeEach(() => { - list = new DoublyLinkedList(); - min = 1; - max = 3; - }); - - function pushesElements() { - for (let i = min; i <= max; i++) { - list.push(i); - } - } - - function verifyNode(current, i) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(i); - - // verify next node - if (i < max) { - expect(current.next).to.not.be.an('undefined'); - // TS strictNullChecks - if (current.next) { - expect(current.next.element).to.equal(i + 1); - } - } else { - expect(current.next).to.be.an('undefined'); - } - - // verify previous node - if (i > min) { - expect(current.prev).to.not.be.an('undefined'); - if (current.prev) { - expect(current.prev.element).to.equal(i - 1); - } - } else { - expect(current.prev).to.be.an('undefined'); - } - } - - function verifyListFromTail() { - let current = list.getTail(); - for (let i = max; i >= min; i--) { - expect(current).to.not.be.an('undefined'); - // TS strictNullChecks - if (current) { - verifyNode(current, i); - current = current.prev; - } - } - } - - function verifyList() { - let current = list.getHead(); - for (let i = min; i <= max; i++) { - expect(current).to.not.be.an('undefined'); - // TS strictNullChecks - if (current) { - verifyNode(current, i); - current = current.next; - } - } - verifyListFromTail(); - } - - it('starts empty', () => { - expect(list.size()).to.equal(0); - expect(list.isEmpty()).to.equal(true); - expect(list.getHead()).to.be.an('undefined'); - expect(list.getTail()).to.be.an('undefined'); - }); - - it('pushes elements', () => { - pushesElements(); - verifyList(); - }); - - it('returns element at specific index: invalid position', () => { - // list is empty - expect(list.getElementAt(3)).to.be.an('undefined'); - }); - - it('returns element at specific index', () => { - let node; - - pushesElements(); - - for (let i = min; i <= max; i++) { - node = list.getElementAt(i - 1); - expect(node).to.not.be.an('undefined'); - if (node) { - expect(node.element).to.equal(i); - } - } - }); - - it('inserts elements first position empty list', () => { - const element = 1; - max = element; - expect(list.insert(element, 0)).to.equal(true); - verifyList(); - }); - - it('inserts elements first position not empty list', () => { - max = 2; - expect(list.insert(max, 0)).to.equal(true); - - expect(list.insert(min, 0)).to.equal(true); - - verifyList(); - }); - - it('inserts elements invalid position empty list', () => { - expect(list.insert(1, 1)).to.equal(false); - }); - - it('inserts elements invalid position not empty list', () => { - const element = 1; - expect(list.insert(element, 0)).to.equal(true); - expect(list.insert(element, 2)).to.equal(false); - }); - - it('inserts elements at the end of list', () => { - max = 5; - - for (let i = min; i <= max; i++) { - expect(list.insert(i, i - 1)).to.equal(true); - } - - verifyList(); - }); - - it('inserts elements in the middle of list', () => { - expect(list.insert(3, 0)).to.equal(true); - expect(list.insert(1, 0)).to.equal(true); - expect(list.insert(2, 1)).to.equal(true); - verifyList(); - }); - - it('returns index of elements', () => { - let index; - - pushesElements(); - - for (let i = min; i <= max; i++) { - index = list.indexOf(i); - expect(index).to.equal(i - 1); - } - - expect(list.indexOf(max + 2)).to.equal(-1); - }); - - it('removes invalid elements', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.remove(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes valid elements', () => { - let element; - - pushesElements(); - - for (let i = min; i <= max; i++) { - element = list.remove(i); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - } - }); - - it('removes element invalid position empty list', () => { - let element; - - for (let i = min; i <= max; i++) { - element = list.removeAt(i - 1); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position not empty list', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.removeAt(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes first element list single element', () => { - const value = 1; - list.push(value); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(value); - - expect(list.getHead()).to.be.an('undefined'); - expect(list.getTail()).to.be.an('undefined'); - expect(list.isEmpty()).to.equal(true); - }); - - it('removes first element list multiple elements', () => { - pushesElements(); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(min); - - min = 2; - verifyList(); - }); - - it('removes element from end of list', () => { - let element; - - pushesElements(); - - const maxIndex = max; - for (let i = maxIndex; i >= min; i--) { - element = list.removeAt(i - 1); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - max--; - verifyList(); - } - }); - - it('removes element from middle of list', () => { - pushesElements(); // 1, 2, 3 - - const element = list.removeAt(1); // element 2 - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(2); - - // list needs to be [1, 3] - let current = list.getHead(); - - // element 1 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(1); - expect(current.prev).to.be.an('undefined'); - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - expect(current.next.element).to.equal(3); - current = current.next; - } - } - - // element 3 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(3); - expect(current.next).to.be.an('undefined'); - expect(current.prev).to.not.be.an('undefined'); - if (current.prev) { - expect(current.prev.element).to.equal(1); - } - } - }); - - it('returns the head of the list', () => { - expect(list.getHead()).to.be.an('undefined'); - - list.push(1); - expect(list.getHead()).to.not.be.an('undefined'); - }); - - it('returns the tail of the list', () => { - expect(list.getTail()).to.be.an('undefined'); - - list.push(1); - expect(list.getTail()).to.not.be.an('undefined'); - }); - - it('returns the correct size', () => { - expect(list.size()).to.equal(0); - - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.size()).to.equal(i); - } - - const size = max; - for (let i = min; i <= max; i++) { - list.remove(i); - expect(list.size()).to.equal(size - i); - } - - expect(list.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(list.isEmpty()).to.equal(true); - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.isEmpty()).to.equal(false); - } - - for (let i = min; i < max; i++) { - list.remove(i); - expect(list.isEmpty()).to.equal(false); - } - list.remove(max); - expect(list.isEmpty()).to.equal(true); - - pushesElements(); - expect(list.isEmpty()).to.equal(false); - - list.clear(); - expect(list.isEmpty()).to.equal(true); - }); - - it('clears the list', () => { - expect(list.size()).to.equal(0); - list.clear(); - expect(list.size()).to.equal(0); - pushesElements(); - expect(list.size()).to.greaterThan(0); - list.clear(); - expect(list.size()).to.equal(0); - }); - - it('returns toString primitive types', () => { - expect(list.toString()).to.equal(''); - - list.push(1); - expect(list.toString()).to.equal('1'); - - list.push(2); - expect(list.toString()).to.equal('1,2'); - - list.clear(); - expect(list.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const ds = new DoublyLinkedList(); - ds.push('el1'); - expect(ds.toString()).to.equal('el1'); - - ds.push('el2'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const ds = new DoublyLinkedList(); - expect(ds.toString()).to.equal(''); - - ds.push(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2'); - - ds.push(new MyObj(3, 4)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); - - it('returns inverseToString primitive types', () => { - expect(list.inverseToString()).to.equal(''); - - list.push(1); - expect(list.inverseToString()).to.equal('1'); - - list.push(2); - expect(list.inverseToString()).to.equal('2,1'); - - list.clear(); - expect(list.inverseToString()).to.equal(''); - }); - - it('returns inverseToString primitive types: string', () => { - const ds = new DoublyLinkedList(); - ds.push('el1'); - expect(ds.inverseToString()).to.equal('el1'); - - ds.push('el2'); - expect(ds.inverseToString()).to.equal('el2,el1'); - }); - - it('returns inverseToString objects', () => { - const ds = new DoublyLinkedList(); - expect(ds.inverseToString()).to.equal(''); - - ds.push(new MyObj(1, 2)); - expect(ds.inverseToString()).to.equal('1|2'); - - ds.push(new MyObj(3, 4)); - expect(ds.inverseToString()).to.equal('3|4,1|2'); - }); -}); diff --git a/test/js/data-structures/hash-table-linear-probing-lazy.spec.js b/test/js/data-structures/hash-table-linear-probing-lazy.spec.js deleted file mode 100644 index f7dd7e06..00000000 --- a/test/js/data-structures/hash-table-linear-probing-lazy.spec.js +++ /dev/null @@ -1,300 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { HashTableLinearProbingLazy } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('HashTableLinearProbingLazy', () => { - const A = 'Jonathan'; - const B = 'Jamie'; - const C = 'Sue'; - it('starts empty', () => { - const hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.size()).to.equal(0); - expect(hashTable.isEmpty()).to.equal(true); - }); - it('generates hashcode', () => { - // numbers - let hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.hashCode(1)).to.equal(1); - expect(hashTable.hashCode(10)).to.equal(10); - expect(hashTable.hashCode(100)).to.equal(100); - expect(hashTable.hashCode(1000)).to.equal(1000); - // strings - hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.hashCode('1')).to.equal(12); - expect(hashTable.hashCode('10')).to.equal(23); - expect(hashTable.hashCode('100')).to.equal(34); - expect(hashTable.hashCode('1000')).to.equal(8); - expect(hashTable.hashCode('a')).to.equal(23); - expect(hashTable.hashCode('A')).to.equal(28); - expect(hashTable.hashCode('Aba')).to.equal(1); - // objects - hashTable = new HashTableLinearProbingLazy(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - expect(hashTable.hashCode(myObjList[0])).to.equal(1); - expect(hashTable.hashCode(myObjList[1])).to.equal(3); - expect(hashTable.hashCode(myObjList[2])).to.equal(5); - expect(hashTable.hashCode(myObjList[3])).to.equal(7); - expect(hashTable.hashCode(myObjList[4])).to.equal(9); - }); - it('puts undefined and null keys and values', () => { - const hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.put('undefined', undefined)).to.equal(false); - expect(hashTable.get('undefined')).to.equal(undefined); - expect(hashTable.put('undefined', 1)).to.equal(true); - expect(hashTable.get('undefined')).to.equal(1); - expect(hashTable.put('null', null)).to.equal(false); - expect(hashTable.get('null')).to.equal(undefined); - expect(hashTable.put('null', 1)).to.equal(true); - expect(hashTable.get('null')).to.equal(1); - hashTable.clear(); - expect(hashTable.put(undefined, undefined)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - expect(hashTable.put(undefined, 1)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - expect(hashTable.put(null, null)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - expect(hashTable.put(null, 1)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - }); - it('puts values with number key without collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableLinearProbingLazy(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - } - }); - it('puts values with string key without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.put('1', 1)).to.equal(true); - expect(hashTable.put('10', 10)).to.equal(true); - expect(hashTable.put('100', 100)).to.equal(true); - expect(hashTable.put('1000', 1000)).to.equal(true); - const table = hashTable.getTable(); - expect(table[12].key).to.equal('1'); - expect(table[12].value).to.equal(1); - expect(table[23].key).to.equal('10'); - expect(table[23].value).to.equal(10); - expect(table[34].key).to.equal('100'); - expect(table[34].value).to.equal(100); - expect(table[8].key).to.equal('1000'); - expect(table[8].value).to.equal(1000); - }); - it('puts values with object key without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - expect(hashTable.put(myObjList[i - 1], myObjList[i - 1])).to.equal(true); - } - const table = hashTable.getTable(); - expect(table[1].key).to.equal(myObjList[0]); - expect(table[1].value).to.equal(myObjList[0]); - expect(table[3].key).to.equal(myObjList[1]); - expect(table[3].value).to.equal(myObjList[1]); - expect(table[5].key).to.equal(myObjList[2]); - expect(table[5].value).to.equal(myObjList[2]); - expect(table[7].key).to.equal(myObjList[3]); - expect(table[7].value).to.equal(myObjList[3]); - expect(table[9].key).to.equal(myObjList[4]); - expect(table[9].value).to.equal(myObjList[4]); - }); - function addValuesCollision() { - const hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.size()).to.equal(3); - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - expect(hashTable.size()).to.equal(3); - return hashTable; - } - it('puts values with collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableLinearProbingLazy(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 10)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 2); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 100)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 3); - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - expect(table[i + size].key).to.equal(i); - expect(table[i + size].value).to.equal(i + 10); - expect(table[i + (size * 2)].key).to.equal(i); - expect(table[i + (size * 2)].value).to.equal(i + 100); - } - addValuesCollision(); - }); - it('removes elements without collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableLinearProbingLazy(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(true); - } - // elements do not exist - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(false); - } - expect(hashTable.isEmpty()).to.equal(true); - }); - function removeWithCollision(a, b, c) { - const hashTable = addValuesCollision(); - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - expect(hashTable.isEmpty()).to.equal(true); - } - it('removes elements with collisions: scenario 1', () => { - // test all possibilities for removal - removeWithCollision(A, B, C); - removeWithCollision(A, C, B); - removeWithCollision(B, A, C); - removeWithCollision(B, C, A); - removeWithCollision(C, A, B); - removeWithCollision(C, B, A); - }); - function addValuesCollision2() { - const hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.put(')', 'parenthesis@email.com')).to.equal(true); - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put('+', 'plus@email.com')).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(',', 'comma@email.com')).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.put('-', 'minus@email.com')).to.equal(true); - expect(hashTable.put('0', 'zero@email.com')).to.equal(true); - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - expect(hashTable.hashCode(')')).to.equal(4); - expect(hashTable.hashCode('+')).to.equal(6); - expect(hashTable.hashCode(',')).to.equal(7); - expect(hashTable.hashCode('-')).to.equal(8); - expect(hashTable.hashCode('0')).to.equal(11); - expect(hashTable.size()).to.equal(8); - const table = hashTable.getTable(); - expect(table[4].key).to.equal(')'); - expect(table[5].key).to.equal(A); - expect(table[6].key).to.equal('+'); - expect(table[7].key).to.equal(B); - expect(table[8].key).to.equal(','); - expect(table[9].key).to.equal(C); - expect(table[10].key).to.equal('-'); - expect(table[11].key).to.equal('0'); - return hashTable; - } - function verifyOtherKeys(hashTable) { - expect(hashTable.get(')')).to.not.equal(undefined); - expect(hashTable.get('+')).to.not.equal(undefined); - expect(hashTable.get(',')).to.not.equal(undefined); - expect(hashTable.get('-')).to.not.equal(undefined); - expect(hashTable.get('0')).to.not.equal(undefined); - } - function removeWithCollision2(a, b, c) { - const hashTable = addValuesCollision2(); - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - verifyOtherKeys(hashTable); - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - verifyOtherKeys(hashTable); - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - verifyOtherKeys(hashTable); - } - it('removes elements with collisions: scenario 2', () => { - // test all possibilities for removal - removeWithCollision2(A, B, C); - removeWithCollision2(A, C, B); - removeWithCollision2(B, A, C); - removeWithCollision2(B, C, A); - removeWithCollision2(C, A, B); - removeWithCollision2(C, B, A); - }); - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.toString()).to.equal(''); - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - hashTable.put('el1', 1); - expect(hashTable.toString()).to.equal('{36 => [#el1: 1]}'); - hashTable.put('el2', 2); - expect(hashTable.toString()).to.equal('{0 => [#el2: 2]},{36 => [#el1: 1]}'); - }); - it('returns toString objects without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - let myObj = new MyObj(1, 2); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]}'); - myObj = new MyObj(3, 4); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]},{5 => [#3|4: 3|4]}'); - }); - it('returns toString with collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.toString()).to.equal(''); - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - hashTable.put(1, 10); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]},{3 => [#1: 10]}'); - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); -}); diff --git a/test/js/data-structures/hash-table-linear-probing.spec.js b/test/js/data-structures/hash-table-linear-probing.spec.js deleted file mode 100644 index bfb519f3..00000000 --- a/test/js/data-structures/hash-table-linear-probing.spec.js +++ /dev/null @@ -1,300 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { HashTableLinearProbing } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('HashTableLinearProbing', () => { - const A = 'Jonathan'; - const B = 'Jamie'; - const C = 'Sue'; - it('starts empty', () => { - const hashTable = new HashTableLinearProbing(); - expect(hashTable.size()).to.equal(0); - expect(hashTable.isEmpty()).to.equal(true); - }); - it('generates hashcode', () => { - // numbers - let hashTable = new HashTableLinearProbing(); - expect(hashTable.hashCode(1)).to.equal(1); - expect(hashTable.hashCode(10)).to.equal(10); - expect(hashTable.hashCode(100)).to.equal(100); - expect(hashTable.hashCode(1000)).to.equal(1000); - // strings - hashTable = new HashTableLinearProbing(); - expect(hashTable.hashCode('1')).to.equal(12); - expect(hashTable.hashCode('10')).to.equal(23); - expect(hashTable.hashCode('100')).to.equal(34); - expect(hashTable.hashCode('1000')).to.equal(8); - expect(hashTable.hashCode('a')).to.equal(23); - expect(hashTable.hashCode('A')).to.equal(28); - expect(hashTable.hashCode('Aba')).to.equal(1); - // objects - hashTable = new HashTableLinearProbing(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - expect(hashTable.hashCode(myObjList[0])).to.equal(1); - expect(hashTable.hashCode(myObjList[1])).to.equal(3); - expect(hashTable.hashCode(myObjList[2])).to.equal(5); - expect(hashTable.hashCode(myObjList[3])).to.equal(7); - expect(hashTable.hashCode(myObjList[4])).to.equal(9); - }); - it('puts undefined and null keys and values', () => { - const hashTable = new HashTableLinearProbing(); - expect(hashTable.put('undefined', undefined)).to.equal(false); - expect(hashTable.get('undefined')).to.equal(undefined); - expect(hashTable.put('undefined', 1)).to.equal(true); - expect(hashTable.get('undefined')).to.equal(1); - expect(hashTable.put('null', null)).to.equal(false); - expect(hashTable.get('null')).to.equal(undefined); - expect(hashTable.put('null', 1)).to.equal(true); - expect(hashTable.get('null')).to.equal(1); - hashTable.clear(); - expect(hashTable.put(undefined, undefined)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - expect(hashTable.put(undefined, 1)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - expect(hashTable.put(null, null)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - expect(hashTable.put(null, 1)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - }); - it('puts values with number key without collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableLinearProbing(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - } - }); - it('puts values with string key without collisions', () => { - const hashTable = new HashTableLinearProbing(); - expect(hashTable.put('1', 1)).to.equal(true); - expect(hashTable.put('10', 10)).to.equal(true); - expect(hashTable.put('100', 100)).to.equal(true); - expect(hashTable.put('1000', 1000)).to.equal(true); - const table = hashTable.getTable(); - expect(table[12].key).to.equal('1'); - expect(table[12].value).to.equal(1); - expect(table[23].key).to.equal('10'); - expect(table[23].value).to.equal(10); - expect(table[34].key).to.equal('100'); - expect(table[34].value).to.equal(100); - expect(table[8].key).to.equal('1000'); - expect(table[8].value).to.equal(1000); - }); - it('puts values with object key without collisions', () => { - const hashTable = new HashTableLinearProbing(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - expect(hashTable.put(myObjList[i - 1], myObjList[i - 1])).to.equal(true); - } - const table = hashTable.getTable(); - expect(table[1].key).to.equal(myObjList[0]); - expect(table[1].value).to.equal(myObjList[0]); - expect(table[3].key).to.equal(myObjList[1]); - expect(table[3].value).to.equal(myObjList[1]); - expect(table[5].key).to.equal(myObjList[2]); - expect(table[5].value).to.equal(myObjList[2]); - expect(table[7].key).to.equal(myObjList[3]); - expect(table[7].value).to.equal(myObjList[3]); - expect(table[9].key).to.equal(myObjList[4]); - expect(table[9].value).to.equal(myObjList[4]); - }); - function addValuesCollision() { - const hashTable = new HashTableLinearProbing(); - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.size()).to.equal(3); - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - expect(hashTable.size()).to.equal(3); - return hashTable; - } - it('puts values with collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableLinearProbing(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 10)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 2); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 100)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 3); - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - expect(table[i + size].key).to.equal(i); - expect(table[i + size].value).to.equal(i + 10); - expect(table[i + (size * 2)].key).to.equal(i); - expect(table[i + (size * 2)].value).to.equal(i + 100); - } - addValuesCollision(); - }); - it('removes elements without collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableLinearProbing(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(true); - } - // elements do not exist - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(false); - } - expect(hashTable.isEmpty()).to.equal(true); - }); - function removeWithCollision(a, b, c) { - const hashTable = addValuesCollision(); - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - expect(hashTable.isEmpty()).to.equal(true); - } - it('removes elements with collisions: scenario 1', () => { - // test all possibilities for removal - removeWithCollision(A, B, C); - removeWithCollision(A, C, B); - removeWithCollision(B, A, C); - removeWithCollision(B, C, A); - removeWithCollision(C, A, B); - removeWithCollision(C, B, A); - }); - function addValuesCollision2() { - const hashTable = new HashTableLinearProbing(); - expect(hashTable.put(')', 'parenthesis@email.com')).to.equal(true); - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put('+', 'plus@email.com')).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(',', 'comma@email.com')).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.put('-', 'minus@email.com')).to.equal(true); - expect(hashTable.put('0', 'zero@email.com')).to.equal(true); - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - expect(hashTable.hashCode(')')).to.equal(4); - expect(hashTable.hashCode('+')).to.equal(6); - expect(hashTable.hashCode(',')).to.equal(7); - expect(hashTable.hashCode('-')).to.equal(8); - expect(hashTable.hashCode('0')).to.equal(11); - expect(hashTable.size()).to.equal(8); - const table = hashTable.getTable(); - expect(table[4].key).to.equal(')'); - expect(table[5].key).to.equal(A); - expect(table[6].key).to.equal('+'); - expect(table[7].key).to.equal(B); - expect(table[8].key).to.equal(','); - expect(table[9].key).to.equal(C); - expect(table[10].key).to.equal('-'); - expect(table[11].key).to.equal('0'); - return hashTable; - } - function verifyOtherKeys(hashTable) { - expect(hashTable.get(')')).to.not.equal(undefined); - expect(hashTable.get('+')).to.not.equal(undefined); - expect(hashTable.get(',')).to.not.equal(undefined); - expect(hashTable.get('-')).to.not.equal(undefined); - expect(hashTable.get('0')).to.not.equal(undefined); - } - function removeWithCollision2(a, b, c) { - const hashTable = addValuesCollision2(); - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - verifyOtherKeys(hashTable); - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - verifyOtherKeys(hashTable); - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - verifyOtherKeys(hashTable); - } - it('removes elements with collisions: scenario 2', () => { - // test all possibilities for removal - removeWithCollision2(A, B, C); - removeWithCollision2(A, C, B); - removeWithCollision2(B, A, C); - removeWithCollision2(B, C, A); - removeWithCollision2(C, A, B); - removeWithCollision2(C, B, A); - }); - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableLinearProbing(); - expect(hashTable.toString()).to.equal(''); - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableLinearProbing(); - hashTable.put('el1', 1); - expect(hashTable.toString()).to.equal('{36 => [#el1: 1]}'); - hashTable.put('el2', 2); - expect(hashTable.toString()).to.equal('{0 => [#el2: 2]},{36 => [#el1: 1]}'); - }); - it('returns toString objects without collisions', () => { - const hashTable = new HashTableLinearProbing(); - let myObj = new MyObj(1, 2); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]}'); - myObj = new MyObj(3, 4); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]},{5 => [#3|4: 3|4]}'); - }); - it('returns toString with collisions', () => { - const hashTable = new HashTableLinearProbing(); - expect(hashTable.toString()).to.equal(''); - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - hashTable.put(1, 10); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]},{3 => [#1: 10]}'); - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); -}); diff --git a/test/js/data-structures/hash-table-separate-chaining.spec.js b/test/js/data-structures/hash-table-separate-chaining.spec.js deleted file mode 100644 index 2066c2d0..00000000 --- a/test/js/data-structures/hash-table-separate-chaining.spec.js +++ /dev/null @@ -1,269 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { HashTableSeparateChaining } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('HashTableSeparateChaining', () => { - const A = 'Jonathan'; - const B = 'Jamie'; - const C = 'Sue'; - it('starts empty', () => { - const hashTable = new HashTableSeparateChaining(); - expect(hashTable.size()).to.equal(0); - expect(hashTable.isEmpty()).to.equal(true); - }); - it('generates hashcode', () => { - // numbers - let hashTable = new HashTableSeparateChaining(); - expect(hashTable.hashCode(1)).to.equal(1); - expect(hashTable.hashCode(10)).to.equal(10); - expect(hashTable.hashCode(100)).to.equal(100); - expect(hashTable.hashCode(1000)).to.equal(1000); - // strings - hashTable = new HashTableSeparateChaining(); - expect(hashTable.hashCode('1')).to.equal(12); - expect(hashTable.hashCode('10')).to.equal(23); - expect(hashTable.hashCode('100')).to.equal(34); - expect(hashTable.hashCode('1000')).to.equal(8); - expect(hashTable.hashCode('a')).to.equal(23); - expect(hashTable.hashCode('A')).to.equal(28); - expect(hashTable.hashCode('Aba')).to.equal(1); - // objects - hashTable = new HashTableSeparateChaining(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - expect(hashTable.hashCode(myObjList[0])).to.equal(1); - expect(hashTable.hashCode(myObjList[1])).to.equal(3); - expect(hashTable.hashCode(myObjList[2])).to.equal(5); - expect(hashTable.hashCode(myObjList[3])).to.equal(7); - expect(hashTable.hashCode(myObjList[4])).to.equal(9); - }); - it('puts undefined and null keys and values', () => { - const hashTable = new HashTableSeparateChaining(); - expect(hashTable.put('undefined', undefined)).to.equal(false); - expect(hashTable.get('undefined')).to.equal(undefined); - expect(hashTable.put('undefined', 1)).to.equal(true); - expect(hashTable.get('undefined')).to.equal(1); - expect(hashTable.put('null', null)).to.equal(false); - expect(hashTable.get('null')).to.equal(undefined); - expect(hashTable.put('null', 1)).to.equal(true); - expect(hashTable.get('null')).to.equal(1); - hashTable.clear(); - expect(hashTable.put(undefined, undefined)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - expect(hashTable.put(undefined, 1)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - expect(hashTable.put(null, null)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - expect(hashTable.put(null, 1)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - }); - it('puts values with number key without collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableSeparateChaining(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - const linkedList = table[i]; - expect(linkedList.size()).to.equal(1); - const valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(i); - expect(valuePair.element.value).to.equal(i); - } - }); - it('puts values with string key without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - expect(hashTable.put('1', 1)).to.equal(true); - expect(hashTable.put('10', 10)).to.equal(true); - expect(hashTable.put('100', 100)).to.equal(true); - expect(hashTable.put('1000', 1000)).to.equal(true); - const table = hashTable.getTable(); - let linkedList = table[12]; - expect(linkedList.size()).to.equal(1); - let valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal('1'); - expect(valuePair.element.value).to.equal(1); - linkedList = table[23]; // eslint-disable-line prefer-destructuring - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal('10'); - expect(valuePair.element.value).to.equal(10); - linkedList = table[34]; // eslint-disable-line prefer-destructuring - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal('100'); - expect(valuePair.element.value).to.equal(100); - linkedList = table[8]; // eslint-disable-line prefer-destructuring - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal('1000'); - expect(valuePair.element.value).to.equal(1000); - }); - it('puts values with object key without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - expect(hashTable.put(myObjList[i - 1], myObjList[i - 1])).to.equal(true); - } - const table = hashTable.getTable(); - let linkedList = table[1]; - expect(linkedList.size()).to.equal(1); - let valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[0]); - expect(valuePair.element.value).to.equal(myObjList[0]); - linkedList = table[3]; // eslint-disable-line prefer-destructuring - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[1]); - expect(valuePair.element.value).to.equal(myObjList[1]); - linkedList = table[5]; // eslint-disable-line prefer-destructuring - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[2]); - expect(valuePair.element.value).to.equal(myObjList[2]); - linkedList = table[7]; // eslint-disable-line prefer-destructuring - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[3]); - expect(valuePair.element.value).to.equal(myObjList[3]); - linkedList = table[9]; // eslint-disable-line prefer-destructuring - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[4]); - expect(valuePair.element.value).to.equal(myObjList[4]); - }); - it('puts values with collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableSeparateChaining(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 10)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 2); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 100)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 3); - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - const linkedList = table[i]; - expect(linkedList.size()).to.equal(3); - let valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(i); - expect(valuePair.element.value).to.equal(i); - valuePair = valuePair.next; - expect(valuePair.element.key).to.equal(i); - expect(valuePair.element.value).to.equal(i + 10); - valuePair = valuePair.next; - expect(valuePair.element.key).to.equal(i); - expect(valuePair.element.value).to.equal(i + 100); - } - }); - it('removes elements without collisions', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTableSeparateChaining(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(true); - } - // elements do not exist - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(false); - } - expect(hashTable.isEmpty()).to.equal(true); - }); - function addValuesCollision() { - const hashTable = new HashTableSeparateChaining(); - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.size()).to.equal(3); - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - expect(hashTable.getTable()[expectedHash].size()).to.equal(3); - return hashTable; - } - function removeWithCollision(a, b, c) { - const hashTable = addValuesCollision(); - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - expect(hashTable.isEmpty()).to.equal(true); - } - it('removes elements with collisions', () => { - // test all possibilities for removal - removeWithCollision(A, B, C); - removeWithCollision(A, C, B); - removeWithCollision(B, A, C); - removeWithCollision(B, C, A); - removeWithCollision(C, A, B); - removeWithCollision(C, B, A); - }); - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - expect(hashTable.toString()).to.equal(''); - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - hashTable.put('el1', 1); - expect(hashTable.toString()).to.equal('{36 => [#el1: 1]}'); - hashTable.put('el2', 2); - expect(hashTable.toString()).to.equal('{0 => [#el2: 2]},{36 => [#el1: 1]}'); - }); - it('returns toString objects without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - let myObj = new MyObj(1, 2); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]}'); - myObj = new MyObj(3, 4); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]},{5 => [#3|4: 3|4]}'); - }); - it('returns toString with collisions', () => { - const hashTable = new HashTableSeparateChaining(); - expect(hashTable.toString()).to.equal(''); - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - hashTable.put(1, 10); - expect(hashTable.toString()).to.equal('{1 => [#1: 1],[#1: 10]},{2 => [#2: 2]}'); - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); -}); diff --git a/test/js/data-structures/hash-table.spec.js b/test/js/data-structures/hash-table.spec.js deleted file mode 100644 index 862c9be0..00000000 --- a/test/js/data-structures/hash-table.spec.js +++ /dev/null @@ -1,161 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { HashTable } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('HashTable', () => { - it('starts empty', () => { - const hashTable = new HashTable(); - expect(hashTable.size()).to.equal(0); - expect(hashTable.isEmpty()).to.equal(true); - }); - it('generates hashcode', () => { - // numbers - let hashTable = new HashTable(); - expect(hashTable.hashCode(1)).to.equal(1); - expect(hashTable.hashCode(10)).to.equal(10); - expect(hashTable.hashCode(100)).to.equal(100); - expect(hashTable.hashCode(1000)).to.equal(1000); - // strings - hashTable = new HashTable(); - expect(hashTable.hashCode('1')).to.equal(12); - expect(hashTable.hashCode('10')).to.equal(23); - expect(hashTable.hashCode('100')).to.equal(34); - expect(hashTable.hashCode('1000')).to.equal(8); - expect(hashTable.hashCode('a')).to.equal(23); - expect(hashTable.hashCode('A')).to.equal(28); - expect(hashTable.hashCode('Aba')).to.equal(1); - // objects - hashTable = new HashTable(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - expect(hashTable.hashCode(myObjList[0])).to.equal(1); - expect(hashTable.hashCode(myObjList[1])).to.equal(3); - expect(hashTable.hashCode(myObjList[2])).to.equal(5); - expect(hashTable.hashCode(myObjList[3])).to.equal(7); - expect(hashTable.hashCode(myObjList[4])).to.equal(9); - }); - it('puts undefined and null keys and values', () => { - const hashTable = new HashTable(); - expect(hashTable.put('undefined', undefined)).to.equal(false); - expect(hashTable.get('undefined')).to.equal(undefined); - expect(hashTable.put('undefined', 1)).to.equal(true); - expect(hashTable.get('undefined')).to.equal(1); - expect(hashTable.put('null', null)).to.equal(false); - expect(hashTable.get('null')).to.equal(undefined); - expect(hashTable.put('null', 1)).to.equal(true); - expect(hashTable.get('null')).to.equal(1); - hashTable.clear(); - expect(hashTable.put(undefined, undefined)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - expect(hashTable.put(undefined, 1)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - expect(hashTable.put(null, null)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - expect(hashTable.put(null, 1)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - }); - it('puts values with number key', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTable(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - } - }); - it('puts values with string key', () => { - const hashTable = new HashTable(); - expect(hashTable.put('1', 1)).to.equal(true); - expect(hashTable.put('10', 10)).to.equal(true); - expect(hashTable.put('100', 100)).to.equal(true); - expect(hashTable.put('1000', 1000)).to.equal(true); - const table = hashTable.getTable(); - expect(table[12].key).to.equal('1'); - expect(table[12].value).to.equal(1); - expect(table[23].key).to.equal('10'); - expect(table[23].value).to.equal(10); - expect(table[34].key).to.equal('100'); - expect(table[34].value).to.equal(100); - expect(table[8].key).to.equal('1000'); - expect(table[8].value).to.equal(1000); - }); - it('puts values with object key', () => { - const hashTable = new HashTable(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - expect(hashTable.put(myObjList[i - 1], myObjList[i - 1])).to.equal(true); - } - const table = hashTable.getTable(); - expect(table[1].key).to.equal(myObjList[0]); - expect(table[1].value).to.equal(myObjList[0]); - expect(table[3].key).to.equal(myObjList[1]); - expect(table[3].value).to.equal(myObjList[1]); - expect(table[5].key).to.equal(myObjList[2]); - expect(table[5].value).to.equal(myObjList[2]); - expect(table[7].key).to.equal(myObjList[3]); - expect(table[7].value).to.equal(myObjList[3]); - expect(table[9].key).to.equal(myObjList[4]); - expect(table[9].value).to.equal(myObjList[4]); - }); - it('does NOT handle collision, replaces values', () => { - const hashTable = new HashTable(); - for (let i = 0; i < 5; i++) { - expect(hashTable.put(1, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(1); - }); - it('removes elements', () => { - const min = 1; - const max = 5; - const size = (max - min) + 1; - const hashTable = new HashTable(); - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(true); - } - // elements do not exist - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(false); - } - expect(hashTable.isEmpty()).to.equal(true); - }); - it('returns toString primitive types', () => { - const hashTable = new HashTable(); - expect(hashTable.toString()).to.equal(''); - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); - it('returns toString primitive types', () => { - const hashTable = new HashTable(); - hashTable.put('el1', 1); - expect(hashTable.toString()).to.equal('{36 => [#el1: 1]}'); - hashTable.put('el2', 2); - expect(hashTable.toString()).to.equal('{0 => [#el2: 2]},{36 => [#el1: 1]}'); - }); - it('returns toString objects', () => { - const hashTable = new HashTable(); - let myObj = new MyObj(1, 2); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]}'); - myObj = new MyObj(3, 4); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]},{5 => [#3|4: 3|4]}'); - }); -}); diff --git a/test/js/data-structures/heap.spec.js b/test/js/data-structures/heap.spec.js deleted file mode 100644 index 15ce1bce..00000000 --- a/test/js/data-structures/heap.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { MinHeap, heapSort } from '../../../src/js/index'; - -describe('Heap', () => { - let heap; - - beforeEach(() => { - heap = new MinHeap(); - }); - - it('starts empty MinHeap', () => { - expect(heap.size()).to.equal(0); - expect(heap.isEmpty()).to.equal(true); - }); - - it('inserts values in the MinHeap', () => { - const resultArray = []; - for (let i = 1; i < 10; i++) { - resultArray.push(i); - heap.insert(i); - expect(heap.getAsArray()).to.deep.equal(resultArray); - } - }); - - it('finds the min value from the MinHeap', () => { - const resultArray = []; - for (let i = 10; i >= 1; i--) { - resultArray.push(i); - heap.insert(i); - expect(heap.findMinimum()).to.equal(i); - } - }); - - it('performs heapify in the MinHeap', () => { - const resultArray = []; - for (let i = 10; i >= 1; i--) { - resultArray.push(i); - } - expect(heap.heapify(resultArray)).to.deep.equal(resultArray); - }); - - it('extracts the min value from the MinHeap', () => { - let resultArray = []; - for (let i = 1; i < 10; i++) { - resultArray.push(i); - heap.insert(i); - expect(heap.getAsArray()).to.deep.equal(resultArray); - } - - resultArray = [ - [], - [2, 4, 3, 8, 5, 6, 7, 9], - [3, 4, 6, 8, 5, 9, 7], - [4, 5, 6, 8, 7, 9], - [5, 7, 6, 8, 9], - [6, 7, 9, 8], - [7, 8, 9], - [8, 9], - [9], - [] - ]; - - for (let i = 1; i < 10; i++) { - expect(heap.extract()).to.equal(i); - expect(heap.getAsArray()).to.deep.equal(resultArray[i]); - } - }); - - it('Heap Sort', () => { - const array = [3, 2, 5, 6, 1, 7, 8, 9]; - - expect(heapSort(array)).to.deep.equal([1, 2, 3, 5, 6, 7, 8, 9]); - }); -}); diff --git a/test/js/data-structures/linked-list.spec.js b/test/js/data-structures/linked-list.spec.js deleted file mode 100644 index 4d9f19c6..00000000 --- a/test/js/data-structures/linked-list.spec.js +++ /dev/null @@ -1,330 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { LinkedList, util } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('LinkedList', () => { - let list; - let min; - let max; - - beforeEach(() => { - list = new LinkedList(util.defaultEquals); - min = 1; - max = 3; - }); - - function pushesElements() { - for (let i = min; i <= max; i++) { - list.push(i); - } - } - - function verifyList() { - let current = list.getHead(); - for (let i = min; i <= max && current; i++) { - expect(current).to.not.be.an('undefined'); - if (current) { - // TS strictNullChecks - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(i); - if (i < max) { - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - // TS strictNullChecks - expect(current.next.element).to.equal(i + 1); - } - } else { - expect(current.next).to.be.an('undefined'); - } - current = current.next; - } - } - } - - it('starts empty', () => { - expect(list.size()).to.equal(0); - expect(list.isEmpty()).to.equal(true); - expect(list.getHead()).to.be.an('undefined'); - }); - - it('pushes elements', () => { - pushesElements(); - verifyList(); - }); - - it('returns element at specific index: invalid position', () => { - // list is empty - expect(list.getElementAt(3)).to.be.an('undefined'); - }); - - it('returns element at specific index', () => { - let node; - - pushesElements(); - - for (let i = min; i <= max; i++) { - node = list.getElementAt(i - 1); - expect(node).to.not.be.an('undefined'); - if (node) { - expect(node.element).to.equal(i); - } - } - }); - - it('inserts elements first position empty list', () => { - const element = 1; - max = element; - expect(list.insert(element, 0)).to.equal(true); - verifyList(); - }); - - it('inserts elements first position not empty list', () => { - max = 2; - expect(list.insert(max, 0)).to.equal(true); - - expect(list.insert(min, 0)).to.equal(true); - - verifyList(); - }); - - it('inserts elements invalid position empty list', () => { - expect(list.insert(1, 1)).to.equal(false); - }); - - it('inserts elements invalid position not empty list', () => { - const element = 1; - expect(list.insert(element, 0)).to.equal(true); - expect(list.insert(element, 2)).to.equal(false); - }); - - it('inserts elements in the middle of list', () => { - expect(list.insert(3, 0)).to.equal(true); - expect(list.insert(1, 0)).to.equal(true); - expect(list.insert(2, 1)).to.equal(true); - verifyList(); - }); - - it('inserts elements at the end of list', () => { - max = 5; - - for (let i = min; i <= max; i++) { - expect(list.insert(i, i - 1)).to.equal(true); - } - - verifyList(); - }); - - it('returns index of elements', () => { - let index; - - pushesElements(); - - for (let i = min; i <= max; i++) { - index = list.indexOf(i); - expect(index).to.equal(i - 1); - } - - expect(list.indexOf(max + 2)).to.equal(-1); - }); - - it('removes valid elements', () => { - let element; - - pushesElements(); - - for (let i = min; i <= max; i++) { - element = list.remove(i); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - } - }); - - it('removes invalid elements', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.remove(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position empty list', () => { - let element; - - for (let i = min; i <= max; i++) { - element = list.removeAt(i - 1); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position not empty list', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.removeAt(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes first element list single element', () => { - const value = 1; - list.push(value); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(value); - - expect(list.getHead()).to.be.an('undefined'); - expect(list.isEmpty()).to.equal(true); - }); - - it('removes first element list multiple elements', () => { - pushesElements(); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(min); - - min = 2; - verifyList(); - }); - - it('removes element from middle of list', () => { - pushesElements(); // 1, 2, 3 - - const element = list.removeAt(1); // element 2 - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(2); - - // list needs to be [1, 3] - let current = list.getHead(); - - // element 1 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(1); - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - expect(current.next.element).to.equal(3); - current = current.next; - } - } - - // element 3 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(3); - expect(current.next).to.be.an('undefined'); - } - }); - - it('removes element from end of list', () => { - let element; - - pushesElements(); - - const maxIndex = max; - for (let i = maxIndex; i >= min; i--) { - element = list.removeAt(i - 1); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - max--; - verifyList(); - } - }); - - it('returns the head of the list', () => { - expect(list.getHead()).to.be.an('undefined'); - - list.push(1); - expect(list.getHead()).to.not.be.an('undefined'); - }); - - it('returns the correct size', () => { - expect(list.size()).to.equal(0); - - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.size()).to.equal(i); - } - - const size = max; - for (let i = min; i <= max; i++) { - list.remove(i); - expect(list.size()).to.equal(size - i); - } - - expect(list.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(list.isEmpty()).to.equal(true); - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.isEmpty()).to.equal(false); - } - - for (let i = min; i < max; i++) { - list.remove(i); - expect(list.isEmpty()).to.equal(false); - } - list.remove(max); - expect(list.isEmpty()).to.equal(true); - - pushesElements(); - expect(list.isEmpty()).to.equal(false); - - list.clear(); - expect(list.isEmpty()).to.equal(true); - }); - - it('clears the list', () => { - expect(list.size()).to.equal(0); - list.clear(); - expect(list.size()).to.equal(0); - pushesElements(); - expect(list.size()).to.greaterThan(0); - list.clear(); - expect(list.size()).to.equal(0); - }); - - it('returns toString primitive types', () => { - expect(list.toString()).to.equal(''); - - list.push(1); - expect(list.toString()).to.equal('1'); - - list.push(2); - expect(list.toString()).to.equal('1,2'); - - list.clear(); - expect(list.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const ds = new LinkedList(); - ds.push('el1'); - expect(ds.toString()).to.equal('el1'); - - ds.push('el2'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const ds = new LinkedList(); - expect(ds.toString()).to.equal(''); - - ds.push(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2'); - - ds.push(new MyObj(3, 4)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/data-structures/my-obj.js b/test/js/data-structures/my-obj.js deleted file mode 100644 index ed407894..00000000 --- a/test/js/data-structures/my-obj.js +++ /dev/null @@ -1,10 +0,0 @@ -export default class MyObj { - constructor(el1, el2) { - this.el1 = el1; - this.el2 = el2; - } - - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } -} diff --git a/test/js/data-structures/queue.spec.js b/test/js/data-structures/queue.spec.js deleted file mode 100644 index 84587bc1..00000000 --- a/test/js/data-structures/queue.spec.js +++ /dev/null @@ -1,172 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import Queue from '../../../src/js/data-structures/queue'; - -describe('Queue', () => { - let queue; - - beforeEach(() => { - queue = new Queue(); - }); - - it('starts empty', () => { - expect(queue.size()).to.equal(0); - expect(queue.isEmpty()).to.equal(true); - }); - - it('enqueues elements', () => { - queue.enqueue(1); - expect(queue.size()).to.equal(1); - queue.enqueue(2); - expect(queue.size()).to.equal(2); - queue.enqueue(3); - expect(queue.size()).to.equal(3); - - expect(queue.isEmpty()).to.equal(false); - }); - - it('dequeue elements', () => { - queue.enqueue(1); - queue.enqueue(2); - queue.enqueue(3); - - expect(queue.dequeue()).to.equal(1); - expect(queue.dequeue()).to.equal(2); - expect(queue.dequeue()).to.equal(3); - expect(queue.dequeue()).to.equal(undefined); - }); - - it('implements FIFO logic', () => { - queue.enqueue(1); - expect(queue.peek()).to.equal(1); - queue.enqueue(2); - expect(queue.peek()).to.equal(1); - queue.enqueue(3); - expect(queue.peek()).to.equal(1); - - expect(queue.dequeue()).to.equal(1); - expect(queue.dequeue()).to.equal(2); - expect(queue.dequeue()).to.equal(3); - expect(queue.dequeue()).to.equal(undefined); - }); - - it('allows to peek at the front element in the queue without dequeuing it', () => { - expect(queue.peek()).to.equal(undefined); - - queue.enqueue(1); - expect(queue.peek()).to.equal(1); - - queue.enqueue(2); - expect(queue.peek()).to.equal(1); - - queue.dequeue(); - expect(queue.peek()).to.equal(2); - }); - - it('returns the correct size', () => { - expect(queue.size()).to.equal(0); - queue.enqueue(1); - expect(queue.size()).to.equal(1); - queue.enqueue(2); - expect(queue.size()).to.equal(2); - queue.enqueue(3); - expect(queue.size()).to.equal(3); - - queue.clear(); - expect(queue.isEmpty()).to.equal(true); - - queue.enqueue(1); - queue.enqueue(2); - queue.enqueue(3); - expect(queue.size()).to.equal(3); - - queue.dequeue(); - expect(queue.size()).to.equal(2); - queue.dequeue(); - expect(queue.size()).to.equal(1); - queue.dequeue(); - expect(queue.size()).to.equal(0); - queue.dequeue(); - expect(queue.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(queue.isEmpty()).to.equal(true); - queue.enqueue(1); - expect(queue.isEmpty()).to.equal(false); - queue.enqueue(2); - expect(queue.isEmpty()).to.equal(false); - queue.enqueue(3); - expect(queue.isEmpty()).to.equal(false); - - queue.clear(); - expect(queue.isEmpty()).to.equal(true); - - queue.enqueue(1); - queue.enqueue(2); - queue.enqueue(3); - expect(queue.isEmpty()).to.equal(false); - - queue.dequeue(); - expect(queue.isEmpty()).to.equal(false); - queue.dequeue(); - expect(queue.isEmpty()).to.equal(false); - queue.dequeue(); - expect(queue.isEmpty()).to.equal(true); - queue.dequeue(); - expect(queue.isEmpty()).to.equal(true); - }); - - it('clears the queue', () => { - queue.clear(); - expect(queue.isEmpty()).to.equal(true); - - queue.enqueue(1); - queue.enqueue(2); - expect(queue.isEmpty()).to.equal(false); - - queue.clear(); - expect(queue.isEmpty()).to.equal(true); - }); - - it('returns toString primitive types', () => { - expect(queue.toString()).to.equal(''); - - queue.enqueue(1); - expect(queue.toString()).to.equal('1'); - - queue.enqueue(2); - expect(queue.toString()).to.equal('1,2'); - - queue.clear(); - expect(queue.toString()).to.equal(''); - - const queueString = new Queue(); - queueString.enqueue('el1'); - expect(queueString.toString()).to.equal('el1'); - - queueString.enqueue('el2'); - expect(queueString.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - class MyObj { - constructor(el1, el2) { - this.el1 = el1; - this.el2 = el2; - } - - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } - } - const queueMyObj = new Queue(); - expect(queueMyObj.toString()).to.equal(''); - - queueMyObj.enqueue(new MyObj(1, 2)); - expect(queueMyObj.toString()).to.equal('1|2'); - - queueMyObj.enqueue(new MyObj(3, 4)); - expect(queueMyObj.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/data-structures/set.spec.js b/test/js/data-structures/set.spec.js deleted file mode 100644 index f8e2bac1..00000000 --- a/test/js/data-structures/set.spec.js +++ /dev/null @@ -1,352 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { Set } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('Set', () => { - let set; - - beforeEach(() => { - set = new Set(); - }); - - it('starts empty', () => { - expect(set.size()).to.equal(0); - expect(set.isEmpty()).to.equal(true); - }); - - it('adds elements', () => { - for (let i = 1; i < 5; i++) { - set.add(i); - expect(set.size()).to.equal(i); - } - - expect(set.isEmpty()).to.equal(false); - }); - - it('does not allow duplicated elements', () => { - let expected = true; - for (let i = 1; i < 5; i++) { - expect(set.add(i)).to.equal(expected); - } - - expected = false; - for (let i = 1; i < 5; i++) { - expect(set.add(i)).to.equal(expected); - } - }); - - it('deletes elements', () => { - for (let i = 1; i < 5; i++) { - set.add(i); - } - - for (let i = 1; i < 5; i++) { - expect(set.delete(i)).to.equal(true); - } - - // elements do not exist - for (let i = 1; i < 5; i++) { - expect(set.delete(i)).to.equal(false); - } - - expect(set.isEmpty()).to.equal(true); - }); - - it('returns if element exists', () => { - for (let i = 1; i < 5; i++) { - set.add(i); - expect(set.has(i)).to.equal(true); - } - - for (let i = 1; i < 5; i++) { - expect(set.delete(i)).to.equal(true); - expect(set.has(i)).to.equal(false); - } - }); - - it('returns the correct size', () => { - expect(set.size()).to.equal(0); - - for (let i = 1; i < 5; i++) { - set.add(i); - expect(set.size()).to.equal(i); - } - - const max = 5; - for (let i = 1; i < max; i++) { - set.delete(i); - expect(set.size()).to.equal(max - i - 1); - } - - expect(set.size()).to.equal(0); - expect(set.isEmpty()).to.equal(true); - }); - - it('returns if it is empty', () => { - expect(set.isEmpty()).to.equal(true); - - for (let i = 1; i < 5; i++) { - set.add(i); - expect(set.isEmpty()).to.equal(false); - } - - for (let i = 1; i < 5; i++) { - set.delete(i); - expect(set.isEmpty()).to.equal(!(i < 4)); - } - - expect(set.size()).to.equal(0); - expect(set.isEmpty()).to.equal(true); - }); - - it('clears the set', () => { - set.clear(); - expect(set.isEmpty()).to.equal(true); - - set.add(1); - set.add(2); - - set.clear(); - expect(set.isEmpty()).to.equal(true); - }); - - function addValues(min, max) { - set = new Set(); - - for (let i = min; i <= max; i++) { - set.add(i); - } - - return set; - } - - it('union between empty sets', () => { - const set1 = new Set(); - const set2 = new Set(); - - let setResult = set1.union(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.union(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('union between equal sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(1, 5); - - let setResult = set1.union(set2); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.union(set1); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('union between different sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(6, 10); - - let setResult = set1.union(set2); - for (let i = 1; i <= 10; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.union(set1); - for (let i = 1; i <= 10; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('union between sets with common values', () => { - const set1 = addValues(1, 5); - const set2 = addValues(3, 6); - - let setResult = set1.union(set2); - for (let i = 1; i <= 6; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.union(set1); - for (let i = 1; i <= 6; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('intersection between empty sets', () => { - const set1 = new Set(); - const set2 = new Set(); - - let setResult = set1.intersection(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.intersection(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('intersection between equal sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(1, 5); - - let setResult = set1.intersection(set2); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.intersection(set1); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('intersection different sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(6, 10); - - let setResult = set1.intersection(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.intersection(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('intersection between sets with common values', () => { - const set1 = addValues(1, 5); - const set2 = addValues(3, 6); - - let setResult = set1.intersection(set2); - for (let i = 3; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.intersection(set1); - for (let i = 3; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('difference between empty sets', () => { - const set1 = new Set(); - const set2 = new Set(); - - let setResult = set1.difference(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.difference(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('difference between equal sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(1, 5); - - let setResult = set1.difference(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.difference(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('difference different sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(6, 10); - - let setResult = set1.difference(set2); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.difference(set1); - for (let i = 6; i <= 10; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('difference between sets with common values', () => { - const set1 = addValues(1, 5); - const set2 = addValues(3, 6); - - let setResult = set1.difference(set2); - for (let i = 1; i <= 2; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.difference(set1); - for (let i = 6; i <= 6; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('isSubsetOf between empty sets', () => { - const set1 = new Set(); - const set2 = new Set(); - - expect(set1.isSubsetOf(set2)).to.equal(true); - expect(set2.isSubsetOf(set1)).to.equal(true); - }); - - it('isSubsetOf between equal sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(1, 5); - - expect(set1.isSubsetOf(set2)).to.equal(true); - expect(set2.isSubsetOf(set1)).to.equal(true); - }); - - it('isSubsetOf different sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(6, 10); - - expect(set1.isSubsetOf(set2)).to.equal(false); - expect(set2.isSubsetOf(set1)).to.equal(false); - }); - - it('isSubsetOf between sets with common values', () => { - const set1 = addValues(1, 8); - const set2 = addValues(3, 6); - expect(set1.isSubsetOf(set2)).to.equal(false); - expect(set2.isSubsetOf(set1)).to.equal(true); - - const set3 = addValues(1, 5); - const set4 = addValues(3, 6); - expect(set3.isSubsetOf(set4)).to.equal(false); - expect(set4.isSubsetOf(set3)).to.equal(false); - }); - - it('returns toString primitive types', () => { - expect(set.toString()).to.equal(''); - - set.add(1); - expect(set.toString()).to.equal('1'); - - set.add(2); - expect(set.toString()).to.equal('1,2'); - - set.clear(); - expect(set.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const ds = new Set(); - ds.add('el1'); - expect(ds.toString()).to.equal('el1'); - - ds.add('el2'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const ds = new Set(); - expect(ds.toString()).to.equal(''); - - ds.add(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2'); - - ds.add(new MyObj(3, 4)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/data-structures/sorted-linked-list.spec.js b/test/js/data-structures/sorted-linked-list.spec.js deleted file mode 100644 index 5ccaaff9..00000000 --- a/test/js/data-structures/sorted-linked-list.spec.js +++ /dev/null @@ -1,340 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { SortedLinkedList, util } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('SortedLinkedList', () => { - let list; - let min; - let max; - - beforeEach(() => { - list = new SortedLinkedList(); - min = 1; - max = 3; - }); - - function pushesElements() { - for (let i = max; i >= min; i--) { - list.push(i); - } - } - - function verifyList() { - let current = list.getHead(); - for (let i = min; i <= max && current; i++) { - expect(current).to.not.be.an('undefined'); - if (current) { - // TS strictNullChecks - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(i); - if (i < max) { - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - // TS strictNullChecks - expect(current.next.element).to.equal(i + 1); - } - } else { - expect(current.next).to.be.an('undefined'); - } - current = current.next; - } - } - } - - it('starts empty', () => { - expect(list.size()).to.equal(0); - expect(list.isEmpty()).to.equal(true); - expect(list.getHead()).to.be.an('undefined'); - }); - - it('pushes elements', () => { - pushesElements(); - verifyList(); - }); - - it('returns element at specific index: invalid position', () => { - // list is empty - expect(list.getElementAt(3)).to.be.an('undefined'); - }); - - it('returns element at specific index', () => { - let node; - - pushesElements(); - - for (let i = min; i <= max; i++) { - node = list.getElementAt(i - 1); - expect(node).to.not.be.an('undefined'); - if (node) { - expect(node.element).to.equal(i); - } - } - }); - - it('inserts elements first position empty list', () => { - const element = 1; - max = element; - expect(list.insert(element, 0)).to.equal(true); - verifyList(); - }); - - it('inserts elements first position not empty list', () => { - max = 2; - expect(list.insert(max)).to.equal(true); - - expect(list.insert(min, 0)).to.equal(true); - - verifyList(); - }); - - it('inserts elements invalid position empty list', () => { - // sorted list will ignore the index position - expect(list.insert(1, 1)).to.equal(true); - }); - - it('inserts elements invalid position not empty list', () => { - // sorted list will ignore the index position - const element = 1; - expect(list.insert(element, 0)).to.equal(true); - expect(list.insert(element, 2)).to.equal(true); - }); - - it('inserts elements in the middle of list', () => { - expect(list.insert(3, 0)).to.equal(true); - expect(list.insert(1, 0)).to.equal(true); - expect(list.insert(2, 1)).to.equal(true); - verifyList(); - }); - - it('inserts elements at the end of list', () => { - max = 5; - - for (let i = min; i <= max; i++) { - expect(list.insert(i, i - 1)).to.equal(true); - } - - verifyList(); - }); - - it('returns index of elements', () => { - let index; - - pushesElements(); - - for (let i = min; i <= max; i++) { - index = list.indexOf(i); - expect(index).to.equal(i - 1); - } - - expect(list.indexOf(max + 2)).to.equal(-1); - }); - - it('removes valid elements', () => { - let element; - - pushesElements(); - - for (let i = min; i <= max; i++) { - element = list.remove(i); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - } - }); - - it('removes invalid elements', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.remove(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position empty list', () => { - let element; - - for (let i = min; i <= max; i++) { - element = list.removeAt(i - 1); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position not empty list', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.removeAt(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes first element list single element', () => { - const value = 1; - list.push(value); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(value); - - expect(list.getHead()).to.be.an('undefined'); - expect(list.isEmpty()).to.equal(true); - }); - - it('removes first element list multiple elements', () => { - pushesElements(); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(min); - - min = 2; - verifyList(); - }); - - it('removes element from middle of list', () => { - pushesElements(); // 1, 2, 3 - - const element = list.removeAt(1); // element 2 - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(2); - - // list needs to be [1, 3] - let current = list.getHead(); - - // element 1 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(1); - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - expect(current.next.element).to.equal(3); - current = current.next; - } - } - - // element 3 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(3); - expect(current.next).to.be.an('undefined'); - } - }); - - it('removes element from end of list', () => { - let element; - - pushesElements(); - - const maxIndex = max; - for (let i = maxIndex; i >= min; i--) { - element = list.removeAt(i - 1); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - max--; - verifyList(); - } - }); - - it('returns the head of the list', () => { - expect(list.getHead()).to.be.an('undefined'); - - list.push(1); - expect(list.getHead()).to.not.be.an('undefined'); - }); - - it('returns the correct size', () => { - expect(list.size()).to.equal(0); - - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.size()).to.equal(i); - } - - const size = max; - for (let i = min; i <= max; i++) { - list.remove(i); - expect(list.size()).to.equal(size - i); - } - - expect(list.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(list.isEmpty()).to.equal(true); - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.isEmpty()).to.equal(false); - } - - for (let i = min; i < max; i++) { - list.remove(i); - expect(list.isEmpty()).to.equal(false); - } - list.remove(max); - expect(list.isEmpty()).to.equal(true); - - pushesElements(); - expect(list.isEmpty()).to.equal(false); - - list.clear(); - expect(list.isEmpty()).to.equal(true); - }); - - it('clears the list', () => { - expect(list.size()).to.equal(0); - list.clear(); - expect(list.size()).to.equal(0); - pushesElements(); - expect(list.size()).to.greaterThan(0); - list.clear(); - expect(list.size()).to.equal(0); - }); - - it('returns toString primitive types', () => { - expect(list.toString()).to.equal(''); - - list.push(1); - expect(list.toString()).to.equal('1'); - - list.push(2); - expect(list.toString()).to.equal('1,2'); - - list.clear(); - expect(list.toString()).to.equal(''); - }); - - function stringCompare(a, b) { - return a.localeCompare(b); - } - - it('returns toString primitive types: string', () => { - const ds = new SortedLinkedList(util.defaultEquals, stringCompare); - ds.push('el2'); - expect(ds.toString()).to.equal('el2'); - - ds.push('el1'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - function myObjCompare(a, b) { - return a.toString().localeCompare(b.toString()); - } - - it('returns toString objects', () => { - const ds = new SortedLinkedList(util.defaultEquals, myObjCompare); - expect(ds.toString()).to.equal(''); - - ds.push(new MyObj(3, 4)); - expect(ds.toString()).to.equal('3|4'); - - ds.push(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/data-structures/stack-array.spec.js b/test/js/data-structures/stack-array.spec.js deleted file mode 100644 index 0f5912ca..00000000 --- a/test/js/data-structures/stack-array.spec.js +++ /dev/null @@ -1,181 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import StackArray from '../../../src/js/data-structures/stack-array'; - -describe('StackArray', () => { - let stack; - - beforeEach(() => { - stack = new StackArray(); - }); - - it('starts empty', () => { - expect(stack.size()).to.equal(0); - expect(stack.isEmpty()).to.equal(true); - }); - - it('pushes elements', () => { - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - expect(stack.isEmpty()).to.equal(false); - }); - - it('pops elements', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('implements LIFO logic', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('allows to peek at the top element in he stack without popping it', () => { - expect(stack.peek()).to.equal(undefined); - - stack.push(1); - expect(stack.peek()).to.equal(1); - - stack.push(2); - expect(stack.peek()).to.equal(2); - - stack.pop(); - expect(stack.peek()).to.equal(1); - }); - - it('returns the correct size', () => { - expect(stack.size()).to.equal(0); - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.size()).to.equal(2); - stack.pop(); - expect(stack.size()).to.equal(1); - stack.pop(); - expect(stack.size()).to.equal(0); - stack.pop(); - expect(stack.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(stack.isEmpty()).to.equal(true); - stack.push(1); - expect(stack.isEmpty()).to.equal(false); - stack.push(2); - expect(stack.isEmpty()).to.equal(false); - stack.push(3); - expect(stack.isEmpty()).to.equal(false); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('clears the stack', () => { - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('returns an Array', () => { - let stackArray = stack.toArray(); - expect(stackArray.length).to.equal(0); - - stack.push(1); - stack.push(2); - - stackArray = stack.toArray(); - expect(stackArray.length).to.equal(2); - - let i = 1; - stackArray.forEach(e => { - expect(e).to.equal(i); - i++; - }); - }); - - it('returns toString primitive types', () => { - expect(stack.toString()).to.equal(''); - - stack.push(1); - expect(stack.toString()).to.equal('1'); - - stack.push(2); - expect(stack.toString()).to.equal('1,2'); - - stack.clear(); - expect(stack.toString()).to.equal(''); - - stack.push('el1'); - expect(stack.toString()).to.equal('el1'); - - stack.push('el2'); - expect(stack.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - class MyObj { - constructor(el1, el2) { - this.el1 = el1; - this.el2 = el2; - } - - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } - } - expect(stack.toString()).to.equal(''); - - stack.push(new MyObj(1, 2)); - expect(stack.toString()).to.equal('1|2'); - - stack.push(new MyObj(3, 4)); - expect(stack.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/data-structures/stack-linked-list.spec.js b/test/js/data-structures/stack-linked-list.spec.js deleted file mode 100644 index 19549713..00000000 --- a/test/js/data-structures/stack-linked-list.spec.js +++ /dev/null @@ -1,157 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { StackLinkedList } from '../../../src/js/index'; -import MyObj from './my-obj'; - -describe('StackLinkedList', () => { - let stack; - - beforeEach(() => { - stack = new StackLinkedList(); - }); - - it('starts empty', () => { - expect(stack.size()).to.equal(0); - expect(stack.isEmpty()).to.equal(true); - }); - - it('pushes elements', () => { - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - expect(stack.isEmpty()).to.equal(false); - }); - - it('pops elements', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('implements LIFO logic', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('allows to peek at the top element in he stack without popping it', () => { - expect(stack.peek()).to.equal(undefined); - - stack.push(1); - expect(stack.peek()).to.equal(1); - - stack.push(2); - expect(stack.peek()).to.equal(2); - - stack.pop(); - expect(stack.peek()).to.equal(1); - }); - - it('returns the correct size', () => { - expect(stack.size()).to.equal(0); - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.size()).to.equal(2); - stack.pop(); - expect(stack.size()).to.equal(1); - stack.pop(); - expect(stack.size()).to.equal(0); - stack.pop(); - expect(stack.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(stack.isEmpty()).to.equal(true); - stack.push(1); - expect(stack.isEmpty()).to.equal(false); - stack.push(2); - expect(stack.isEmpty()).to.equal(false); - stack.push(3); - expect(stack.isEmpty()).to.equal(false); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('clears the stack', () => { - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('returns toString primitive types', () => { - expect(stack.toString()).to.equal(''); - - stack.push(1); - expect(stack.toString()).to.equal('1'); - - stack.push(2); - expect(stack.toString()).to.equal('1,2'); - - stack.clear(); - expect(stack.toString()).to.equal(''); - - const stackString = new StackLinkedList(); - stackString.push('el1'); - expect(stackString.toString()).to.equal('el1'); - - stackString.push('el2'); - expect(stackString.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const stackMyObj = new StackLinkedList(); - expect(stackMyObj.toString()).to.equal(''); - - stackMyObj.push(new MyObj(1, 2)); - expect(stackMyObj.toString()).to.equal('1|2'); - - stackMyObj.push(new MyObj(3, 4)); - expect(stackMyObj.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/data-structures/stack.spec.js b/test/js/data-structures/stack.spec.js deleted file mode 100644 index 55361a8a..00000000 --- a/test/js/data-structures/stack.spec.js +++ /dev/null @@ -1,164 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import Stack from '../../../src/js/data-structures/stack'; - -describe('Stack', () => { - let stack; - - beforeEach(() => { - stack = new Stack(); - }); - - it('starts empty', () => { - expect(stack.size()).to.equal(0); - expect(stack.isEmpty()).to.equal(true); - }); - - it('pushes elements', () => { - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - expect(stack.isEmpty()).to.equal(false); - }); - - it('pops elements', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('implements LIFO logic', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('allows to peek at the top element in he stack without popping it', () => { - expect(stack.peek()).to.equal(undefined); - - stack.push(1); - expect(stack.peek()).to.equal(1); - - stack.push(2); - expect(stack.peek()).to.equal(2); - - stack.pop(); - expect(stack.peek()).to.equal(1); - }); - - it('returns the correct size', () => { - expect(stack.size()).to.equal(0); - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.size()).to.equal(2); - stack.pop(); - expect(stack.size()).to.equal(1); - stack.pop(); - expect(stack.size()).to.equal(0); - stack.pop(); - expect(stack.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(stack.isEmpty()).to.equal(true); - stack.push(1); - expect(stack.isEmpty()).to.equal(false); - stack.push(2); - expect(stack.isEmpty()).to.equal(false); - stack.push(3); - expect(stack.isEmpty()).to.equal(false); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('clears the stack', () => { - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('returns toString primitive types', () => { - expect(stack.toString()).to.equal(''); - - stack.push(1); - expect(stack.toString()).to.equal('1'); - - stack.push(2); - expect(stack.toString()).to.equal('1,2'); - - stack.clear(); - expect(stack.toString()).to.equal(''); - - stack.push('el1'); - expect(stack.toString()).to.equal('el1'); - - stack.push('el2'); - expect(stack.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - class MyObj { - constructor(el1, el2) { - this.el1 = el1; - this.el2 = el2; - } - - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } - } - expect(stack.toString()).to.equal(''); - - stack.push(new MyObj(1, 2)); - expect(stack.toString()).to.equal('1|2'); - - stack.push(new MyObj(3, 4)); - expect(stack.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/js/others/balanced-symbols.spec.js b/test/js/others/balanced-symbols.spec.js deleted file mode 100644 index 6a2ce6e4..00000000 --- a/test/js/others/balanced-symbols.spec.js +++ /dev/null @@ -1,41 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { parenthesesChecker } from '../../../src/js/others/balanced-symbols'; - -describe('Balanced Symbols', () => { - it('empty to be falsy', () => { - expect(parenthesesChecker('')).to.equal(true); - }); - - it('{ to be falsy', () => { - expect(parenthesesChecker('{')).to.equal(false); - }); - - it('} to be falsy', () => { - expect(parenthesesChecker('}')).to.equal(false); - }); - - it('11 to be falsy', () => { - expect(parenthesesChecker('11')).to.equal(false); - }); - - it('{11 to be falsy', () => { - expect(parenthesesChecker('{11')).to.equal(false); - }); - - it('{([1])} to be falsy', () => { - expect(parenthesesChecker('{([1])}')).to.equal(false); - }); - - it('{([])} to be truthy', () => { - expect(parenthesesChecker('{([])}')).to.equal(true); - }); - - it('{{([][])}()} to be truthy', () => { - expect(parenthesesChecker('{{([][])}()}')).to.equal(true); - }); - - it('[{()] to be falsy', () => { - expect(parenthesesChecker('[{()]')).to.equal(false); - }); -}); diff --git a/test/js/others/base-converter.spec.js b/test/js/others/base-converter.spec.js deleted file mode 100644 index ed93a0dc..00000000 --- a/test/js/others/base-converter.spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { baseConverter, decimalToBinary } from '../../../src/js/others/base-converter'; - -describe('Base Converter', () => { - it('decimalToBinary 1 -> 1', () => { - expect(decimalToBinary(1)).to.equal('1'); - }); - - it('decimalToBinary 2 -> 11', () => { - expect(decimalToBinary(2)).to.equal('10'); - }); - - it('decimalToBinary 233 -> 11101001', () => { - expect(decimalToBinary(233)).to.equal('11101001'); - }); - - it('decimalToBinary 10 -> 1010', () => { - expect(decimalToBinary(10)).to.equal('1010'); - }); - - it('decimalToBinary 1000 -> 1111101000', () => { - expect(decimalToBinary(1000)).to.equal('1111101000'); - }); - - it('baseConverter 100345, 2 -> 11000011111111001', () => { - expect(baseConverter(100345, 2)).to.equal('11000011111111001'); - }); - - it('baseConverter 100345, 8 -> 303771', () => { - expect(baseConverter(100345, 8)).to.equal('303771'); - }); - - it('baseConverter 100345, 16 -> 187F9', () => { - expect(baseConverter(100345, 16)).to.equal('187F9'); - }); - - it('baseConverter 100345, 7 -> 565360', () => { - expect(baseConverter(100345, 7)).to.equal('565360'); - }); - - it('baseConverter 100345, 20 -> CAH5', () => { - expect(baseConverter(100345, 20)).to.equal('CAH5'); - }); - - it('baseConverter 100345, 35 -> 2BW0', () => { - expect(baseConverter(100345, 35)).to.equal('2BW0'); - }); - - it('baseConverter 100345, 36 -> 25FD', () => { - expect(baseConverter(100345, 36)).to.equal('25FD'); - }); - - it('baseConverter 100345, 37 -> ', () => { - expect(baseConverter(100345, 37)).to.equal(''); - }); -}); diff --git a/test/js/others/factorial.spec.js b/test/js/others/factorial.spec.js deleted file mode 100644 index 69341a7a..00000000 --- a/test/js/others/factorial.spec.js +++ /dev/null @@ -1,25 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { factorialIterative, factorial } from '../../../src/js/others/factorial'; - -describe('Factorial', () => { - it('Iterative Factorial', () => { - expect(factorialIterative(-1)).to.equal(undefined); - expect(factorialIterative(0)).to.equal(1); - expect(factorialIterative(1)).to.equal(1); - expect(factorialIterative(2)).to.equal(2); - expect(factorialIterative(3)).to.equal(6); - expect(factorialIterative(4)).to.equal(24); - expect(factorialIterative(5)).to.equal(120); - }); - - it('Recursive Factorial', () => { - expect(factorial(-1)).to.equal(undefined); - expect(factorial(0)).to.equal(1); - expect(factorial(1)).to.equal(1); - expect(factorial(2)).to.equal(2); - expect(factorial(3)).to.equal(6); - expect(factorial(4)).to.equal(24); - expect(factorial(5)).to.equal(120); - }); -}); diff --git a/test/js/others/fibonacci.spec.js b/test/js/others/fibonacci.spec.js deleted file mode 100644 index 5eea4888..00000000 --- a/test/js/others/fibonacci.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { - fibonacci, - fibonacciIterative, - fibonacciMemoization -} from '../../../src/js/others/fibonacci'; - -describe('Fibonacci', () => { - it('Fibonacci Recursive', () => { - expect(fibonacci(-1)).to.equal(0); - expect(fibonacci(0)).to.equal(0); - expect(fibonacci(1)).to.equal(1); - expect(fibonacci(2)).to.equal(1); - expect(fibonacci(3)).to.equal(2); - expect(fibonacci(4)).to.equal(3); - }); - - it('Fibonacci Iterative', () => { - expect(fibonacciIterative(-1)).to.equal(0); - expect(fibonacciIterative(0)).to.equal(0); - expect(fibonacciIterative(1)).to.equal(1); - expect(fibonacciIterative(2)).to.equal(1); - expect(fibonacciIterative(3)).to.equal(2); - expect(fibonacciIterative(4)).to.equal(3); - }); - - it('Fibonacci with Memoization', () => { - expect(fibonacciMemoization(-1)).to.equal(0); - expect(fibonacciMemoization(0)).to.equal(0); - expect(fibonacciMemoization(1)).to.equal(1); - expect(fibonacciMemoization(2)).to.equal(1); - expect(fibonacciMemoization(3)).to.equal(2); - expect(fibonacciMemoization(4)).to.equal(3); - }); -}); diff --git a/test/js/others/hanoi.spec.js b/test/js/others/hanoi.spec.js deleted file mode 100644 index cca28431..00000000 --- a/test/js/others/hanoi.spec.js +++ /dev/null @@ -1,19 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { hanoi, hanoiStack } from '../../../src/js/others/hanoi'; - -describe('Tower of Hanoi', () => { - it('Hanoi', () => { - for (let i = 0; i < 10; i++) { - const result = hanoi(i, 'a', 'b', 'c'); - expect(result.length).to.equal((2 ** i) - 1); - } - }); - - it('Hanoi with Stack', () => { - for (let i = 0; i < 10; i++) { - const result = hanoiStack(i); - expect(result.length).to.equal((2 ** i) - 1); - } - }); -}); diff --git a/test/js/others/hot-potato.spec.js b/test/js/others/hot-potato.spec.js deleted file mode 100644 index dfbb2751..00000000 --- a/test/js/others/hot-potato.spec.js +++ /dev/null @@ -1,14 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { hotPotato } from '../../../src/js/others/hot-potato'; - -describe('Hot Potato with Queue', () => { - it('Hot potato game', () => { - const names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl']; - expect(hotPotato(names, 6).winner).to.equal('Ingrid'); - expect(hotPotato(names, 7).winner).to.equal('John'); - expect(hotPotato(names, 8).winner).to.equal('Jack'); - expect(hotPotato(names, 9).winner).to.equal('Ingrid'); - expect(hotPotato(names, 10).winner).to.equal('Carl'); - }); -}); diff --git a/test/js/others/palindrome-checker.spec.js b/test/js/others/palindrome-checker.spec.js deleted file mode 100644 index c5664a31..00000000 --- a/test/js/others/palindrome-checker.spec.js +++ /dev/null @@ -1,19 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { palindromeChecker } from '../../../src/js/others/palindrome-checker'; - -describe('Palindrome', () => { - it('Palindrome Checker', () => { - expect(palindromeChecker('')).to.equal(false); - expect(palindromeChecker('a')).to.equal(true); - expect(palindromeChecker('aa')).to.equal(true); - expect(palindromeChecker('aba')).to.equal(true); - expect(palindromeChecker('ab')).to.equal(false); - expect(palindromeChecker('kayak')).to.equal(true); - expect(palindromeChecker('radar')).to.equal(true); - expect(palindromeChecker('level')).to.equal(true); - expect(palindromeChecker('Was it a car or a cat I saw')).to.equal(true); - expect(palindromeChecker('Step on no pets')).to.equal(true); - expect(palindromeChecker('Able was I ere I saw Elba')).to.equal(true); - }); -}); diff --git a/test/ts/algorithms/backtracking/rat-in-maze.spec.ts b/test/ts/algorithms/backtracking/rat-in-maze.spec.ts deleted file mode 100644 index 0a292984..00000000 --- a/test/ts/algorithms/backtracking/rat-in-maze.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { ratInAMaze } from '../../../../src/ts/index'; - -describe('Rat in a maze', () => { - it('rat in a maze solver', () => { - const maze = [ - [1, 0, 0, 0], - [1, 1, 1, 1], - [0, 0, 1, 0], - [0, 1, 1, 1] - ]; - const solution = [ - [1, 0, 0, 0], - [1, 1, 1, 0], - [0, 0, 1, 0], - [0, 0, 1, 1] - ]; - expect(ratInAMaze(maze)).to.deep.equal(solution); - }); -}); diff --git a/test/ts/algorithms/backtracking/sudoku-solver.spec.ts b/test/ts/algorithms/backtracking/sudoku-solver.spec.ts deleted file mode 100644 index e747683b..00000000 --- a/test/ts/algorithms/backtracking/sudoku-solver.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { sudokuSolver } from '../../../../src/ts/index'; - -describe('Sudoku Solver', () => { - it('sudoku solver', () => { - const grid = [ - [3, 0, 6, 5, 0, 8, 4, 0, 0], - [5, 2, 0, 0, 0, 0, 0, 0, 0], - [0, 8, 7, 0, 0, 0, 0, 3, 1], - [0, 0, 3, 0, 1, 0, 0, 8, 0], - [9, 0, 0, 8, 6, 3, 0, 0, 5], - [0, 5, 0, 0, 9, 0, 6, 0, 0], - [1, 3, 0, 0, 0, 0, 2, 5, 0], - [0, 0, 0, 0, 0, 0, 0, 7, 4], - [0, 0, 5, 2, 0, 6, 3, 0, 0] - ]; - const solution = [ - [3, 1, 6, 5, 7, 8, 4, 9, 2], - [5, 2, 9, 1, 3, 4, 7, 6, 8], - [4, 8, 7, 6, 2, 9, 5, 3, 1], - [2, 6, 3, 4, 1, 5, 9, 8, 7], - [9, 7, 4, 8, 6, 3, 1, 2, 5], - [8, 5, 1, 7, 9, 2, 6, 4, 3], - [1, 3, 8, 9, 4, 7, 2, 5, 6], - [6, 9, 2, 3, 5, 1, 8, 7, 4], - [7, 4, 5, 2, 8, 6, 3, 1, 9] - ]; - expect(sudokuSolver(grid)).to.deep.equal(solution); - }); - - it('sudoku solver 2', () => { - const grid = [ - [5, 3, 0, 0, 7, 0, 0, 0, 0], - [6, 0, 0, 1, 9, 5, 0, 0, 0], - [0, 9, 8, 0, 0, 0, 0, 6, 0], - [8, 0, 0, 0, 6, 0, 0, 0, 3], - [4, 0, 0, 8, 0, 3, 0, 0, 1], - [7, 0, 0, 0, 2, 0, 0, 0, 6], - [0, 6, 0, 0, 0, 0, 2, 8, 0], - [0, 0, 0, 4, 1, 9, 0, 0, 5], - [0, 0, 0, 0, 8, 0, 0, 7, 9] - ]; - const solution = [ - [5, 3, 4, 6, 7, 8, 9, 1, 2], - [6, 7, 2, 1, 9, 5, 3, 4, 8], - [1, 9, 8, 3, 4, 2, 5, 6, 7], - [8, 5, 9, 7, 6, 1, 4, 2, 3], - [4, 2, 6, 8, 5, 3, 7, 9, 1], - [7, 1, 3, 9, 2, 4, 8, 5, 6], - [9, 6, 1, 5, 3, 7, 2, 8, 4], - [2, 8, 7, 4, 1, 9, 6, 3, 5], - [3, 4, 5, 2, 8, 6, 1, 7, 9] - ]; - expect(sudokuSolver(grid)).to.deep.equal(solution); - }); -}); diff --git a/test/ts/algorithms/dynamic-programming/knapsack-recursive.spec.ts b/test/ts/algorithms/dynamic-programming/knapsack-recursive.spec.ts deleted file mode 100644 index 944cd655..00000000 --- a/test/ts/algorithms/dynamic-programming/knapsack-recursive.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { knapSackRecursive } from '../../../../src/ts/index'; - -describe('KnapSack Dynamic Programming - Recursive', () => { - - it('works with recursive approach', () => { - const values = [3, 4, 5]; - const weights = [2, 3, 4]; - const capacity = 5; - const n = values.length; - - expect(knapSackRecursive(capacity, weights, values, n)).to.equal(7); - }); -}); diff --git a/test/ts/algorithms/dynamic-programming/knapsack.spec.ts b/test/ts/algorithms/dynamic-programming/knapsack.spec.ts deleted file mode 100644 index 113f9182..00000000 --- a/test/ts/algorithms/dynamic-programming/knapsack.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { knapSack } from '../../../../src/ts/index'; - -describe('KnapSack Dynamic Programming', () => { - - it('works with DP approach', () => { - const values = [3, 4, 5]; - const weights = [2, 3, 4]; - const capacity = 5; - const n = values.length; - - expect(knapSack(capacity, weights, values, n)).to.equal(7); - }); -}); diff --git a/test/ts/algorithms/dynamic-programming/longest-common-subsequence-print.spec.ts b/test/ts/algorithms/dynamic-programming/longest-common-subsequence-print.spec.ts deleted file mode 100644 index 4626c593..00000000 --- a/test/ts/algorithms/dynamic-programming/longest-common-subsequence-print.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { lcsPrint } from '../../../../src/ts/index'; - -describe('LCS Dynamic Programming with print solution', () => { - - it('works with DP approach with print solution', () => { - const wordX = 'acbaed'; - const wordY = 'abcadf'; - - expect(lcsPrint(wordX, wordY)).to.equal('acad'); - }); -}); diff --git a/test/ts/algorithms/dynamic-programming/longest-common-subsequence.spec.ts b/test/ts/algorithms/dynamic-programming/longest-common-subsequence.spec.ts deleted file mode 100644 index 3da8abcd..00000000 --- a/test/ts/algorithms/dynamic-programming/longest-common-subsequence.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { lcs } from '../../../../src/ts/index'; - -describe('LCS Dynamic Programming', () => { - - it('works with DP approach', () => { - const wordX = 'acbaed'; - const wordY = 'abcadf'; - - expect(lcs(wordX, wordY)).to.equal(4); - }); -}); diff --git a/test/ts/algorithms/dynamic-programming/matrix-chain-multiplication.spec.ts b/test/ts/algorithms/dynamic-programming/matrix-chain-multiplication.spec.ts deleted file mode 100644 index 09b58d2d..00000000 --- a/test/ts/algorithms/dynamic-programming/matrix-chain-multiplication.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { matrixChainOrder } from '../../../../src/ts/index'; - -describe('Matrix Chain Multiplication', () => { - - it('works with DP approach', () => { - const p = [10, 100, 5, 50, 1]; - - expect(matrixChainOrder(p)).to.equal(1750); - }); -}); diff --git a/test/ts/algorithms/dynamic-programming/min-coin-change.spec.ts b/test/ts/algorithms/dynamic-programming/min-coin-change.spec.ts deleted file mode 100644 index 26821b06..00000000 --- a/test/ts/algorithms/dynamic-programming/min-coin-change.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { minCoinChange } from '../../../../src/ts/index'; - -describe('Dynamic Programming: Min Coin Change', () => { - - it('works with amount 0', () => { - expect(minCoinChange([1, 2, 3], 0)).to.deep.equal([]); - }); - - it('works with amount 1', () => { - expect(minCoinChange([1, 2, 3], 1)).to.deep.equal([1]); - }); - - it('works with amount 2', () => { - expect(minCoinChange([1, 2, 3], 2)).to.deep.equal([2]); - }); - - it('works with amount 3', () => { - expect(minCoinChange([1, 2, 3], 3)).to.deep.equal([3]); - }); - - it('works with amount 4', () => { - expect(minCoinChange([1, 2, 3], 4)).to.deep.equal([1, 3]); - }); - - it('works with amount 6', () => { - expect(minCoinChange([1, 2, 3], 6)).to.deep.equal([3, 3]); - }); -}); diff --git a/test/ts/algorithms/graph/breadth-first-search.spec.ts b/test/ts/algorithms/graph/breadth-first-search.spec.ts deleted file mode 100644 index db5f929f..00000000 --- a/test/ts/algorithms/graph/breadth-first-search.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { BFS, breadthFirstSearch, Graph } from '../../../../src/ts'; - -describe('Breadth First Search', () => { - - let count: number; - const vertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; - let graph: Graph; - - beforeEach(() => { - count = 0; - graph = new Graph(); - - for (let i = 0; i < vertices.length; i++) { - graph.addVertex(vertices[i]); - } - - graph.addEdge('A', 'B'); - graph.addEdge('A', 'C'); - graph.addEdge('A', 'D'); - graph.addEdge('C', 'D'); - graph.addEdge('C', 'G'); - graph.addEdge('D', 'G'); - graph.addEdge('D', 'H'); - graph.addEdge('B', 'E'); - graph.addEdge('B', 'F'); - graph.addEdge('E', 'I'); - }); - - it('breadthFirstSearch', () => { - breadthFirstSearch(graph, vertices[0], assertCallback); - }); - - function assertCallback(value: string) { - expect(value).to.equal(vertices[count]); - count++; - } - - it('sorthest path - BFS', () => { - const shortestPathA = BFS(graph, vertices[0]); - - expect(shortestPathA.distances).to.deep.equal({A: 0, B: 1, C: 1, D: 1, E: 2,  F: 2, G: 2, H: 2, I: 3}); - expect(shortestPathA.predecessors).to.deep.equal({A: null, B: 'A', C: 'A', D: 'A', E: 'B',  F: 'B', G: 'C', H: 'D', I: 'E'}); - }); - -}); diff --git a/test/ts/algorithms/graph/depth-first-search.spec.ts b/test/ts/algorithms/graph/depth-first-search.spec.ts deleted file mode 100644 index 763284a7..00000000 --- a/test/ts/algorithms/graph/depth-first-search.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { DFS, depthFirstSearch, Graph } from '../../../../src/ts/index'; - -describe('Depth First Search', () => { - let count: number; - const vertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; - const dfsCallBack = ['A', 'B', 'E', 'I', 'F', 'C', 'D', 'G', 'H']; - let graph: Graph; - - beforeEach(() => { - count = 0; - graph = new Graph(true); - }); - - it('depthFirstSearch', () => { - for (let i = 0; i < vertices.length; i++) { - graph.addVertex(vertices[i]); - } - - graph.addEdge('A', 'B'); - graph.addEdge('A', 'C'); - graph.addEdge('A', 'D'); - graph.addEdge('C', 'D'); - graph.addEdge('C', 'G'); - graph.addEdge('D', 'G'); - graph.addEdge('D', 'H'); - graph.addEdge('B', 'E'); - graph.addEdge('B', 'F'); - graph.addEdge('E', 'I'); - - depthFirstSearch(graph, assertCallback); - }); - - function assertCallback(value: string) { - expect(value).to.equal(dfsCallBack[count]); - count++; - } - - it('topological sort - DFS', () => { - const myVertices = ['A', 'B', 'C', 'D', 'E', 'F']; - for (let i = 0; i < myVertices.length; i++) { - graph.addVertex(myVertices[i]); - } - graph.addEdge('A', 'C'); - graph.addEdge('A', 'D'); - graph.addEdge('B', 'D'); - graph.addEdge('B', 'E'); - graph.addEdge('C', 'F'); - graph.addEdge('F', 'E'); - - const result = DFS(graph); - - expect(result.discovery).to.deep.equal({A: 1, B: 11, C: 2, D: 8, E: 4, F: 3}); - expect(result.finished).to.deep.equal({A: 10, B: 12, C: 7, D: 9, E: 5, F: 6}); - expect(result.predecessors).to.deep.equal({A: null, B: null, C: 'A', D: 'A', E: 'F', F: 'C'}); - }); -}); diff --git a/test/ts/algorithms/graph/dijkstra.spec.ts b/test/ts/algorithms/graph/dijkstra.spec.ts deleted file mode 100644 index 05b2e2f9..00000000 --- a/test/ts/algorithms/graph/dijkstra.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { dijkstra } from '../../../../src/ts/index'; - -describe('Dijkstra\'s Algorithm - Shortest Path', () => { - - it('Shortest Path', () => { - const graph = [ - [0, 2, 4, 0, 0, 0], - [0, 0, 2, 4, 2, 0], - [0, 0, 0, 0, 3, 0], - [0, 0, 0, 0, 0, 2], - [0, 0, 0, 3, 0, 2], - [0, 0, 0, 0, 0, 0] - ]; - - expect(dijkstra(graph, 0)).to.deep.equal([0, 2, 4, 6, 4, 6]); - - }); - -}); diff --git a/test/ts/algorithms/graph/floyd-warshall.spec.ts b/test/ts/algorithms/graph/floyd-warshall.spec.ts deleted file mode 100644 index cf0adae2..00000000 --- a/test/ts/algorithms/graph/floyd-warshall.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { floydWarshall } from '../../../../src/ts/index'; - -describe('Floyd-Warshall Algorithm - All-Pairs Shortest Path', () => { - it('All-Pairs Shortest Path', () => { - const INF = Infinity; - const graph = [ - [INF, 2, 4, INF, INF, INF], - [INF, INF, 2, 4, 2, INF], - [INF, INF, INF, INF, 3, INF], - [INF, INF, INF, INF, INF, 2], - [INF, INF, INF, 3, INF, 2], - [INF, INF, INF, INF, INF, INF] - ]; - - expect(floydWarshall(graph)).to.deep.equal([ - [0, 2, 4, 6, 4, 6], - [INF, 0, 2, 4, 2, 4], - [INF, INF, 0, 6, 3, 5], - [INF, INF, INF, 0, INF, 2], - [INF, INF, INF, 3, 0, 2], - [INF, INF, INF, INF, INF, 0] - ]); - }); -}); diff --git a/test/ts/algorithms/graph/kruskal.spec.ts b/test/ts/algorithms/graph/kruskal.spec.ts deleted file mode 100644 index 838c643e..00000000 --- a/test/ts/algorithms/graph/kruskal.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { kruskal } from '../../../../src/ts/index'; - -describe('Kruskal Algorithm - Minimum Spanning Tree', () => { - it('Minimum Spanning Tree', () => { - const graph = [ - [0, 2, 4, 0, 0, 0], - [2, 0, 2, 4, 2, 0], - [4, 2, 0, 0, 3, 0], - [0, 4, 0, 0, 3, 2], - [0, 2, 3, 3, 0, 2], - [0, 0, 0, 2, 2, 0] - ]; - - expect(kruskal(graph)).to.deep.equal([ , 0, 1, 1, 1, 3]); - }); -}); diff --git a/test/ts/algorithms/graph/prim.spec.ts b/test/ts/algorithms/graph/prim.spec.ts deleted file mode 100644 index 18224d71..00000000 --- a/test/ts/algorithms/graph/prim.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { prim } from '../../../../src/ts/index'; - -describe('Prim\'s Algorithm - Minimum Spanning Tree', () => { - it('Minimum Spanning Tree', () => { - const graph = [ - [0, 2, 4, 0, 0, 0], - [2, 0, 2, 4, 2, 0], - [4, 2, 0, 0, 3, 0], - [0, 4, 0, 0, 3, 2], - [0, 2, 3, 3, 0, 2], - [0, 0, 0, 2, 2, 0] - ]; - - expect(prim(graph)).to.deep.equal([-1, 0, 1, 5, 1, 4]); - }); -}); diff --git a/test/ts/algorithms/greedy/knapsack.spec.ts b/test/ts/algorithms/greedy/knapsack.spec.ts deleted file mode 100644 index de73ff47..00000000 --- a/test/ts/algorithms/greedy/knapsack.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { knapSackGreedy } from '../../../../src/ts/index'; - -describe('KnapSack Greedy', () => { - - it('works with greedy approach', () => { - const values = [3, 4, 5]; - const weights = [2, 3, 4]; - const capacity = 5; - - expect(knapSackGreedy(capacity, weights, values)).to.equal(7); - }); -}); diff --git a/test/ts/algorithms/greedy/longest-common-subsequence.spec.ts b/test/ts/algorithms/greedy/longest-common-subsequence.spec.ts deleted file mode 100644 index 82d4000a..00000000 --- a/test/ts/algorithms/greedy/longest-common-subsequence.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { lcsRecursive } from '../../../../src/ts/index'; - -describe('LCS Greedy', () => { - - it('works with Greedy approach', () => { - const wordX = 'acbaed'; - const wordY = 'abcadf'; - - expect(lcsRecursive(wordX, wordY)).to.equal(4); - }); -}); diff --git a/test/ts/algorithms/greedy/matrix-chain-multiplication.spec.ts b/test/ts/algorithms/greedy/matrix-chain-multiplication.spec.ts deleted file mode 100644 index d6655752..00000000 --- a/test/ts/algorithms/greedy/matrix-chain-multiplication.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { matrixChainOrderGreedy } from '../../../../src/ts/index'; - -describe('Matrix Chain Multiplication', () => { - - it('works with DP approach', () => { - const p = [10, 100, 5, 50, 1]; - - expect(matrixChainOrderGreedy(p)).to.equal(1750); - }); -}); diff --git a/test/ts/algorithms/greedy/min-coin-change.spec.ts b/test/ts/algorithms/greedy/min-coin-change.spec.ts deleted file mode 100644 index 946d19ff..00000000 --- a/test/ts/algorithms/greedy/min-coin-change.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { minCoinChangeGreedy } from '../../../../src/ts/index'; - -describe('Min Coin Change Greedy', () => { - - it('works with greedy approach', () => { - expect(minCoinChangeGreedy([1, 5, 10], 15)).to.deep.equal([10, 5]); - expect(minCoinChangeGreedy([1, 3, 4], 6)).to.deep.equal([4, 1, 1]); - }); - -}); diff --git a/test/ts/algorithms/math/find-divisors.spec.ts b/test/ts/algorithms/math/find-divisors.spec.ts deleted file mode 100644 index b4223378..00000000 --- a/test/ts/algorithms/math/find-divisors.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { findDivisors } from '../../../../src/ts/index'; - -describe('Find Divisors', () => { - - it('returns the divisors of the number', () => { - - expect(findDivisors(-1)).to.deep.equal([]); - expect(findDivisors(0)).to.deep.equal([]); - expect(findDivisors(1)).to.deep.equal([1]); - expect(findDivisors(2)).to.deep.equal([1, 2]); - expect(findDivisors(3)).to.deep.equal([1, 3]); - expect(findDivisors(4)).to.deep.equal([1, 2, 4]); - expect(findDivisors(100)).to.deep.equal([1, 2, 4, 5, 10, 20, 25, 50, 100 ]); - }); -}); diff --git a/test/ts/algorithms/math/gcd.spec.ts b/test/ts/algorithms/math/gcd.spec.ts deleted file mode 100644 index 75a66ae6..00000000 --- a/test/ts/algorithms/math/gcd.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { gcd } from '../../../../src/ts/index'; - -describe('GCD', () => { - it('returns the correct GCD for positive numbers', () => { - expect(gcd(8, 12)).to.equal(4); - expect(gcd(15, 25)).to.equal(5); - expect(gcd(21, 28)).to.equal(7); - }); - - it('returns the correct GCD for negative numbers', () => { - expect(gcd(-8, 12)).to.equal(4); - expect(gcd(15, -25)).to.equal(5); - expect(gcd(-21, -28)).to.equal(7); - }); - - it('returns the correct GCD when one of the numbers is 0', () => { - expect(gcd(0, -12)).to.equal(12); - expect(gcd(15, 0)).to.equal(15); - }); - - it('returns 1 for co-prime numbers', () => { - expect(gcd(7, 22)).to.equal(1); - expect(gcd(11, 28)).to.equal(1); - expect(gcd(9, 16)).to.equal(1); - }); -}); diff --git a/test/ts/algorithms/math/greatest-difference.spec.ts b/test/ts/algorithms/math/greatest-difference.spec.ts deleted file mode 100644 index 889e4ef6..00000000 --- a/test/ts/algorithms/math/greatest-difference.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { greatestDifference } from '../../../../src/ts/index'; - -describe('Greatest Difference', () => { - - it('returns the gcd between two numbers', () => { - - expect(greatestDifference([5, 6, 7, 2, 10])).to.equal(8); - expect(greatestDifference([1, 2, 4])).to.equal(3); - expect(greatestDifference([1, 3])).to.equal(2); - - }); -}); diff --git a/test/ts/algorithms/math/lcm.spec.ts b/test/ts/algorithms/math/lcm.spec.ts deleted file mode 100644 index 2262161c..00000000 --- a/test/ts/algorithms/math/lcm.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { lcm } from '../../../../src/ts/index'; - -describe('LCM', () => { - - it('returns the lcm between two numbers', () => { - - expect(lcm(0, 0)).to.equal(0); - expect(lcm(1, 1)).to.equal(1); - expect(lcm(1, 2)).to.equal(2); - expect(lcm(2, 4)).to.equal(4); - expect(lcm(2, 3)).to.equal(6); - - }); -}); diff --git a/test/ts/algorithms/math/primality-test.spec.ts b/test/ts/algorithms/math/primality-test.spec.ts deleted file mode 100644 index 36680623..00000000 --- a/test/ts/algorithms/math/primality-test.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { isPrime, testPrime, isPrime2 } from '../../../../src/ts/index'; - -describe('Primality Tests', () => { - - it('returns if the number is prime or not - isPrime', () => { - testIsPrime(isPrime); - }); - - it('returns if the number is prime or not - testPrime', () => { - testIsPrime(testPrime); - }); - - it('returns if the number is prime or not - isPrime2', () => { - testIsPrime(isPrime2); - }); - - function testIsPrime(primeFunction: Function) { - expect(primeFunction(-1)).to.equal(false); - expect(primeFunction(0)).to.equal(false); - expect(primeFunction(1)).to.equal(false); - expect(primeFunction(2)).to.equal(true); - expect(primeFunction(3)).to.equal(true); - expect(primeFunction(4)).to.equal(false); - expect(primeFunction(5)).to.equal(true); - expect(primeFunction(10)).to.equal(false); - expect(primeFunction(113)).to.equal(true); - } -}); diff --git a/test/ts/algorithms/math/sieve-eratosthenes.spec.ts b/test/ts/algorithms/math/sieve-eratosthenes.spec.ts deleted file mode 100644 index 1cd31c2d..00000000 --- a/test/ts/algorithms/math/sieve-eratosthenes.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { sieveOfEratosthenes } from '../../../../src/ts/index'; - -describe('Sieve Of Eratosthene', () => { - - it('returns the prime numbers', () => { - - expect(sieveOfEratosthenes(0)).to.deep.equal([]); - expect(sieveOfEratosthenes(1)).to.deep.equal([]); - expect(sieveOfEratosthenes(2)).to.deep.equal([2]); - expect(sieveOfEratosthenes(3)).to.deep.equal([2, 3]); - expect(sieveOfEratosthenes(4)).to.deep.equal([2, 3]); - expect(sieveOfEratosthenes(5)).to.deep.equal([2, 3, 5]); - - }); -}); diff --git a/test/ts/algorithms/search/binary-search-recursive.spec.ts b/test/ts/algorithms/search/binary-search-recursive.spec.ts deleted file mode 100644 index b06ce773..00000000 --- a/test/ts/algorithms/search/binary-search-recursive.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { binarySearchRecursive } from '../../../../src/ts/index'; -import { testSearchAlgorithm } from './search-algorithms-tests'; - -testSearchAlgorithm(binarySearchRecursive, 'Binary Search Recursive'); - diff --git a/test/ts/algorithms/search/binary-search.spec.ts b/test/ts/algorithms/search/binary-search.spec.ts deleted file mode 100644 index f62d0e96..00000000 --- a/test/ts/algorithms/search/binary-search.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { binarySearch } from '../../../../src/ts/index'; -import { testSearchAlgorithm } from './search-algorithms-tests'; - -testSearchAlgorithm(binarySearch, 'Binary Search'); - diff --git a/test/ts/algorithms/search/interpolation-search.spec.ts b/test/ts/algorithms/search/interpolation-search.spec.ts deleted file mode 100644 index 287351f2..00000000 --- a/test/ts/algorithms/search/interpolation-search.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { interpolationSearch } from '../../../../src/ts/index'; -import { testSearchAlgorithm } from './search-algorithms-tests'; - -testSearchAlgorithm(interpolationSearch, 'Interpolation Search', { customEquals: false }); - diff --git a/test/ts/algorithms/search/min-max-search.spec.ts b/test/ts/algorithms/search/min-max-search.spec.ts deleted file mode 100644 index d0dd76c3..00000000 --- a/test/ts/algorithms/search/min-max-search.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { findMinValue, findMaxValue } from '../../../../src/ts/index'; - -describe('Min and Max Values Search', () => { - - const SIZE = 10; - - function createSortedArray() { - const array: number[] = []; - for (let i = 1; i <= SIZE; i++) { - array.push(i); - } - return array; - } - - it('min value - works with empty arrays', () => { - expect(findMinValue([])).to.equal(undefined); - }); - - it('max value - works with empty arrays', () => { - expect(findMaxValue([])).to.equal(undefined); - }); - - it('min value', () => { - expect(findMinValue(createSortedArray())).to.equal(1); - }); - - it('max value', () => { - expect(findMaxValue(createSortedArray())).to.equal(SIZE); - }); -}); diff --git a/test/ts/algorithms/search/search-algorithms-tests.ts b/test/ts/algorithms/search/search-algorithms-tests.ts deleted file mode 100644 index dd590f5d..00000000 --- a/test/ts/algorithms/search/search-algorithms-tests.ts +++ /dev/null @@ -1,57 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { IEqualsFunction } from '../../../../src/ts/util'; - -interface CustomObject { - key: number; -} - -const customEquals: IEqualsFunction = (a: CustomObject, b: CustomObject) => - a.key === b.key; - -export function testSearchAlgorithm( - searchAlgorithm: Function, - algorithmName: string, - config = { customEquals: true } -) { - describe(algorithmName, () => { - const SIZE = 10; - - function createSortedArray() { - const array: number[] = []; - for (let i = 1; i <= SIZE; i++) { - array.push(i); - } - return array; - } - - it('works with empty arrays', () => { - expect(searchAlgorithm([], 1)).to.equal(-1); - }); - - it('finds value at the first position', () => { - const array = createSortedArray(); - expect(searchAlgorithm(array, 1)).to.equal(0); - }); - - it('finds value at the last position', () => { - const array = createSortedArray(); - expect(searchAlgorithm(array, SIZE)).to.equal(SIZE - 1); - }); - - it('finds value at different positions', () => { - const array = createSortedArray(); - - for (let value = 1; value <= SIZE; value++) { - expect(searchAlgorithm(array, value)).to.equal(value - 1); - } - }); - - if (config.customEquals) { - it('finds value with custom equals function', () => { - const array = [{ key: 1 }, { key: 2 }, { key: 3 }]; - expect(searchAlgorithm(array, { key: 2 }, customEquals)).to.equal(1); - }); - } - }); -} diff --git a/test/ts/algorithms/search/sequential-search.spec.ts b/test/ts/algorithms/search/sequential-search.spec.ts deleted file mode 100644 index 94ddf885..00000000 --- a/test/ts/algorithms/search/sequential-search.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { sequentialSearch } from '../../../../src/ts/index'; -import { testSearchAlgorithm } from './search-algorithms-tests'; - -testSearchAlgorithm(sequentialSearch, 'Sequential Search'); - diff --git "a/test/ts/algorithms/shuffle/fisher\342\200\223yates.spec.ts" "b/test/ts/algorithms/shuffle/fisher\342\200\223yates.spec.ts" deleted file mode 100644 index da450f41..00000000 --- "a/test/ts/algorithms/shuffle/fisher\342\200\223yates.spec.ts" +++ /dev/null @@ -1,33 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { shuffle } from '../../../../src/ts/index'; - -describe('Fisher-Yates Suffle', () => { - - const SIZE = 100; - - function createSortedArray() { - const array: number[] = []; - for (let i = 1; i <= SIZE; i++) { - array.push(i); - } - return array; - } - - it('works with empty arrays', () => { - expect(shuffle([])).to.deep.equal([]); - }); - - it('works with arrays with a single value', () => { - const array = [1]; - expect(shuffle(array)).to.deep.equal(array); - }); - - it('works with sorted arrays', () => { - let array = createSortedArray(); - const sortedArray = createSortedArray(); - array = shuffle(array); - expect(array).to.not.deep.equal(sortedArray); - }); - -}); diff --git a/test/ts/algorithms/sorting/bubble-sort-improved.spec.ts b/test/ts/algorithms/sorting/bubble-sort-improved.spec.ts deleted file mode 100644 index 7686a5fd..00000000 --- a/test/ts/algorithms/sorting/bubble-sort-improved.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { modifiedBubbleSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(modifiedBubbleSort, 'Bubble Sort - Improved'); - diff --git a/test/ts/algorithms/sorting/bubble-sort.spec.ts b/test/ts/algorithms/sorting/bubble-sort.spec.ts deleted file mode 100644 index 2804fe9c..00000000 --- a/test/ts/algorithms/sorting/bubble-sort.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bubbleSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(bubbleSort, 'Bubble Sort'); - diff --git a/test/ts/algorithms/sorting/bucket-sort.spec.ts b/test/ts/algorithms/sorting/bucket-sort.spec.ts deleted file mode 100644 index 1a4ec458..00000000 --- a/test/ts/algorithms/sorting/bucket-sort.spec.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bucketSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(bucketSort, 'Bucket Sort', {reverseCompare: false}); diff --git a/test/ts/algorithms/sorting/counting-sort.spec.ts b/test/ts/algorithms/sorting/counting-sort.spec.ts deleted file mode 100644 index c3fee9a5..00000000 --- a/test/ts/algorithms/sorting/counting-sort.spec.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { countingSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(countingSort, 'Counting Sort', {reverseCompare: false}); diff --git a/test/ts/algorithms/sorting/heap-sort.spec.ts b/test/ts/algorithms/sorting/heap-sort.spec.ts deleted file mode 100644 index b0b95da9..00000000 --- a/test/ts/algorithms/sorting/heap-sort.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { heapSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(heapSort, 'Heap Sort'); - diff --git a/test/ts/algorithms/sorting/insertion-sort.spec.ts b/test/ts/algorithms/sorting/insertion-sort.spec.ts deleted file mode 100644 index 86beb941..00000000 --- a/test/ts/algorithms/sorting/insertion-sort.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { insertionSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(insertionSort, 'Insertion Sort'); - diff --git a/test/ts/algorithms/sorting/merge-sort.spec.ts b/test/ts/algorithms/sorting/merge-sort.spec.ts deleted file mode 100644 index cf4a7418..00000000 --- a/test/ts/algorithms/sorting/merge-sort.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { mergeSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(mergeSort, 'Merge Sort'); - diff --git a/test/ts/algorithms/sorting/quicksort.spec.ts b/test/ts/algorithms/sorting/quicksort.spec.ts deleted file mode 100644 index 348c58f4..00000000 --- a/test/ts/algorithms/sorting/quicksort.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { quickSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(quickSort, 'Quick Sort'); - diff --git a/test/ts/algorithms/sorting/radix-sort.spec.ts b/test/ts/algorithms/sorting/radix-sort.spec.ts deleted file mode 100644 index 36f909ce..00000000 --- a/test/ts/algorithms/sorting/radix-sort.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { radixSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(radixSort, 'Radix Sort', {reverseCompare: false}); - diff --git a/test/ts/algorithms/sorting/selection-sort.spec.ts b/test/ts/algorithms/sorting/selection-sort.spec.ts deleted file mode 100644 index a1359074..00000000 --- a/test/ts/algorithms/sorting/selection-sort.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { selectionSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(selectionSort, 'Selection Sort'); - diff --git a/test/ts/algorithms/sorting/shell-sort.spec.ts b/test/ts/algorithms/sorting/shell-sort.spec.ts deleted file mode 100644 index 4683a70c..00000000 --- a/test/ts/algorithms/sorting/shell-sort.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { shellSort } from '../../../../src/ts/index'; -import { testSortAlgorithm } from './sort-algorithm-tests'; - -testSortAlgorithm(shellSort, 'Shell Sort'); - diff --git a/test/ts/algorithms/sorting/sort-algorithm-tests.ts b/test/ts/algorithms/sorting/sort-algorithm-tests.ts deleted file mode 100644 index c1bacf3d..00000000 --- a/test/ts/algorithms/sorting/sort-algorithm-tests.ts +++ /dev/null @@ -1,73 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { Compare } from '../../../../src/ts/util'; - -export function testSortAlgorithm( - sortAlgorithm: Function, - algorithmName: string, - config = { reverseCompare: true } -) { - describe(algorithmName, () => { - const SIZE = 100; - - function createNonSortedArray() { - const array: number[] = []; - for (let i = SIZE; i > 0; i--) { - array.push(i); - } - return array; - } - - function createSortedArray() { - const array: number[] = []; - for (let i = 1; i <= SIZE; i++) { - array.push(i); - } - return array; - } - - it('works with empty arrays', () => { - expect(sortAlgorithm([])).to.deep.equal([]); - }); - - it('works with sorted arrays', () => { - let array = createSortedArray(); - const sortedArray = createSortedArray(); - array = sortAlgorithm(array); - expect(array).to.deep.equal(sortedArray); - }); - - it('works with non-sorted arrays', () => { - let array = createNonSortedArray(); - const sortedArray = createSortedArray(); - array = sortAlgorithm(array); - - expect(array).to.deep.equal(sortedArray); - - for (let i = 0; i < array.length - 1; i++) { - expect(array[i] <= array[i + 1]).to.equal(true); - } - }); - - function reverseCompare(a: T, b: T): number { - if (a === b) { - return 0; - } - return a < b ? Compare.BIGGER_THAN : Compare.LESS_THAN; - } - - if (config.reverseCompare) { - it('works with reverse comparator - descending order', () => { - let array = createSortedArray(); - const sortedArray = createNonSortedArray(); - array = sortAlgorithm(array, reverseCompare); - - expect(array).to.deep.equal(sortedArray); - - for (let i = 0; i < array.length - 1; i++) { - expect(array[i] >= array[i + 1]).to.equal(true); - } - }); - } - }); -} diff --git a/test/ts/data-structures/avl-tree.spec.ts b/test/ts/data-structures/avl-tree.spec.ts deleted file mode 100644 index 95562b95..00000000 --- a/test/ts/data-structures/avl-tree.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { AVLTree } from '../../../src/ts/index'; - -describe('AVLTree', () => { - let tree: AVLTree; - - beforeEach(() => { - tree = new AVLTree(); - }); - - it('starts empty', () => { - expect(tree.getRoot()).to.equal(undefined); - }); - - it('inserts elements in the AVLTree', () => { - expect(tree.getRoot()).to.equal(undefined); - - tree.insert(1); - tree.insert(2); - tree.insert(3); - tree.insert(4); - tree.insert(5); - tree.insert(6); - tree.insert(7); - tree.insert(14); - tree.insert(15); - tree.insert(13); - tree.insert(12); - tree.insert(11); - }); -}); diff --git a/test/ts/data-structures/binary-search-tree.spec.ts b/test/ts/data-structures/binary-search-tree.spec.ts deleted file mode 100644 index 419f8e10..00000000 --- a/test/ts/data-structures/binary-search-tree.spec.ts +++ /dev/null @@ -1,109 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { BinarySearchTree } from '../../../src/ts/index'; - -describe('BinarySearchTree', () => { - let tree: BinarySearchTree; - - beforeEach(() => { - tree = new BinarySearchTree(); - }); - - it('starts empty', () => { - expect(tree.getRoot()).to.equal(undefined); - }); - - function assertNode(node: any, key: number, left: number, right: number) { - - if (key != null) { - expect(node.key).to.equal(key); - } else { - expect(node).to.equal(key); - return; - } - - if (left != null) { - expect(node.left.key).to.equal(left); - } else { - expect(node.left).to.equal(left); - } - - if (right != null) { - expect(node.right.key).to.equal(right); - } else { - expect(node.right).to.equal(right); - } - } - - it('inserts elements in the BST', () => { - expect(tree.getRoot()).to.equal(undefined); - - tree.insert(11); - tree.insert(7); - tree.insert(15); - tree.insert(5); - tree.insert(3); - tree.insert(9); - tree.insert(8); - tree.insert(10); - tree.insert(13); - tree.insert(12); - tree.insert(14); - tree.insert(20); - tree.insert(18); - tree.insert(25); - - let node = tree.getRoot(); - assertNode(node, 11, 7, 15); - - node = node.left; - assertNode(node, 7, 5, 9); - - node = node.left; - assertNode(node, 5, 3, undefined); - - node = node.left; - assertNode(node, 3, undefined, undefined); - - node = tree.getRoot().left.left.right; - assertNode(node, undefined, undefined, undefined); - - node = tree.getRoot().left.right; - assertNode(node, 9, 8, 10); - - node = node.left; - assertNode(node, 8, undefined, undefined); - - node = tree.getRoot().left.right.right; - assertNode(node, 10, undefined, undefined); - - node = tree.getRoot().right; - assertNode(node, 15, 13, 20); - - node = node.left; - assertNode(node, 13, 12, 14); - - node = node.left; - assertNode(node, 12, undefined, undefined); - - node = tree.getRoot().right.left.right; - assertNode(node, 14, undefined, undefined); - - node = tree.getRoot().right.right; - assertNode(node, 20, 18, 25); - - node = node.left; - assertNode(node, 18, undefined, undefined); - - node = tree.getRoot().right.right.right; - assertNode(node, 25, undefined, undefined); - }); - - it('verifies if element exists', () => { - expect(tree.getRoot()).to.equal(undefined); - }); - - it('removes a leaf', () => { - expect(tree.getRoot()).to.equal(undefined); - }); -}); diff --git a/test/ts/data-structures/circular-linked-list.spec.ts b/test/ts/data-structures/circular-linked-list.spec.ts deleted file mode 100644 index 78312614..00000000 --- a/test/ts/data-structures/circular-linked-list.spec.ts +++ /dev/null @@ -1,342 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { CircularLinkedList } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('CircularLinkedList', () => { - let list: CircularLinkedList; - let min: number; - let max: number; - - beforeEach(() => { - list = new CircularLinkedList(); - min = 1; - max = 3; - }); - - function pushesElements() { - for (let i = min; i <= max; i++) { - list.push(i); - } - } - - function verifyList() { - let current = list.getHead(); - for (let i = min; i <= max && current; i++) { - expect(current).to.not.be.an('undefined'); - if (current) { - // TS strictNullChecks - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(i); - if (i < max) { - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - // TS strictNullChecks - expect(current.next.element).to.equal(i + 1); - } - } else { - // circular list - expect(current.next).to.not.be.an('undefined'); - expect(current.next).to.equal(list.getHead()); - if (current.next) { - expect(current.next.element).to.equal(min); - } - } - current = current.next; - } - } - } - - it('starts empty', () => { - expect(list.size()).to.equal(0); - expect(list.isEmpty()).to.equal(true); - expect(list.getHead()).to.be.an('undefined'); - }); - - it('pushes elements', () => { - pushesElements(); - verifyList(); - }); - - it('returns element at specific index: invalid position', () => { - // list is empty - expect(list.getElementAt(3)).to.be.an('undefined'); - }); - - it('returns element at specific index', () => { - let node; - - pushesElements(); - - for (let i = min; i <= max; i++) { - node = list.getElementAt(i - 1); - expect(node).to.not.be.an('undefined'); - if (node) { - expect(node.element).to.equal(i); - } - } - }); - - it('inserts elements first position empty list', () => { - const element = 1; - max = element; - expect(list.insert(element, 0)).to.equal(true); - verifyList(); - }); - - it('inserts elements first position not empty list', () => { - max = 2; - expect(list.insert(max, 0)).to.equal(true); - - expect(list.insert(min, 0)).to.equal(true); - - verifyList(); - }); - - it('inserts elements invalid position empty list', () => { - expect(list.insert(1, 1)).to.equal(false); - }); - - it('inserts elements invalid position not empty list', () => { - const element = 1; - expect(list.insert(element, 0)).to.equal(true); - expect(list.insert(element, 2)).to.equal(false); - }); - - it('inserts elements in the middle of list', () => { - expect(list.insert(3, 0)).to.equal(true); - expect(list.insert(1, 0)).to.equal(true); - expect(list.insert(2, 1)).to.equal(true); - verifyList(); - }); - - it('inserts elements at the end of list', () => { - max = 5; - - for (let i = min; i <= max; i++) { - expect(list.insert(i , i - 1)).to.equal(true); - } - - verifyList(); - }); - - it('returns index of elements', () => { - let index; - - pushesElements(); - - for (let i = min; i <= max; i++) { - index = list.indexOf(i); - expect(index).to.equal(i - 1); - } - - expect(list.indexOf(max + 2)).to.equal(-1); - }); - - it('removes valid elements', () => { - let element; - - pushesElements(); - - const minIndex = min; - for (let i = minIndex; i <= max; i++) { - element = list.remove(i); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - min++; - verifyList(); - } - }); - - it('removes invalid elements', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.remove(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position empty list', () => { - let element; - - for (let i = min; i <= max; i++) { - element = list.removeAt(i - 1); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position not empty list', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.removeAt(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes first element list single element', () => { - const value = 1; - list.push(value); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(value); - - expect(list.getHead()).to.be.an('undefined'); - expect(list.isEmpty()).to.equal(true); - }); - - it('removes first element list multiple elements', () => { - pushesElements(); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(min); - - min = 2; - verifyList(); - }); - - it('removes element from middle of list', () => { - pushesElements(); // 1, 2, 3 - - const element = list.removeAt(1); // element 2 - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(2); - - // list needs to be [1, 3] - let current = list.getHead(); - - // element 1 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(min); - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - expect(current.next.element).to.equal(max); - current = current.next; - } - } - - // element 3 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(max); - expect(current.next).to.not.be.an('undefined'); - expect(current.next).to.equal(list.getHead()); - if (current.next) { - expect(current.next.element).to.equal(min); - } - } - }); - - it('removes element from end of list', () => { - let element; - - pushesElements(); - - const maxIndex = max; - for (let i = maxIndex; i >= min; i--) { - element = list.removeAt(i - 1); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - max--; - verifyList(); - } - }); - - it('returns the head of the list', () => { - expect(list.getHead()).to.be.an('undefined'); - - list.push(1); - expect(list.getHead()).to.not.be.an('undefined'); - }); - - it('returns the correct size', () => { - expect(list.size()).to.equal(0); - - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.size()).to.equal(i); - } - - const size = max; - for (let i = min; i <= max; i++) { - list.remove(i); - expect(list.size()).to.equal(size - i); - } - - expect(list.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(list.isEmpty()).to.equal(true); - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.isEmpty()).to.equal(false); - } - - for (let i = min; i < max; i++) { - list.remove(i); - expect(list.isEmpty()).to.equal(false); - } - list.remove(max); - expect(list.isEmpty()).to.equal(true); - - pushesElements(); - expect(list.isEmpty()).to.equal(false); - - list.clear(); - expect(list.isEmpty()).to.equal(true); - }); - - it('clears the list', () => { - expect(list.size()).to.equal(0); - list.clear(); - expect(list.size()).to.equal(0); - pushesElements(); - expect(list.size()).to.greaterThan(0); - list.clear(); - expect(list.size()).to.equal(0); - }); - - it('returns toString primitive types', () => { - expect(list.toString()).to.equal(''); - - list.push(1); - expect(list.toString()).to.equal('1'); - - list.push(2); - expect(list.toString()).to.equal('1,2'); - - list.clear(); - expect(list.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const ds = new CircularLinkedList(); - ds.push('el1'); - expect(ds.toString()).to.equal('el1'); - - ds.push('el2'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const ds = new CircularLinkedList(); - expect(ds.toString()).to.equal(''); - - ds.push(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2'); - - ds.push(new MyObj(3, 4)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/data-structures/deque.spec.ts b/test/ts/data-structures/deque.spec.ts deleted file mode 100644 index 7dcb4c8a..00000000 --- a/test/ts/data-structures/deque.spec.ts +++ /dev/null @@ -1,204 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import Deque from '../../../src/ts/data-structures/deque'; - -describe('Deque', () => { - let deque: Deque; - - beforeEach(() => { - deque = new Deque(); - }); - - it('starts empty', () => { - expect(deque.size()).to.equal(0); - expect(deque.isEmpty()).to.equal(true); - }); - - it('add elements in the back', () => { - deque.addBack(1); - expect(deque.size()).to.equal(1); - - deque.addBack(2); - expect(deque.size()).to.equal(2); - - deque.addBack(3); - expect(deque.size()).to.equal(3); - }); - - it('add elements in the front', () => { - deque.addFront(1); - expect(deque.size()).to.equal(1); - - deque.addFront(2); - expect(deque.size()).to.equal(2); - - deque.addFront(3); - expect(deque.size()).to.equal(3); - - deque.removeFront(); - deque.addFront(4); - expect(deque.size()).to.equal(3); - }); - - it('remove elements from the back', () => { - deque.addBack(1); - deque.addBack(2); - deque.addBack(3); - deque.addFront(0); - - expect(deque.removeBack()).to.equal(3); - expect(deque.removeBack()).to.equal(2); - expect(deque.removeBack()).to.equal(1); - expect(deque.removeBack()).to.equal(0); - expect(deque.removeBack()).to.equal(undefined); - }); - - it('remove elements from the front', () => { - deque.addFront(1); - deque.addBack(2); - deque.addBack(3); - deque.addFront(0); - deque.addFront(-1); - deque.addFront(-2); - - expect(deque.removeFront()).to.equal(-2); - expect(deque.removeFront()).to.equal(-1); - expect(deque.removeFront()).to.equal(0); - expect(deque.removeFront()).to.equal(1); - expect(deque.removeFront()).to.equal(2); - expect(deque.removeFront()).to.equal(3); - expect(deque.removeFront()).to.equal(undefined); - }); - - it('allows to peek at the front element in the deque without removing it', () => { - expect(deque.peekFront()).to.equal(undefined); - - deque.addFront(1); - expect(deque.peekFront()).to.equal(1); - deque.addBack(2); - expect(deque.peekFront()).to.equal(1); - deque.addBack(3); - expect(deque.peekFront()).to.equal(1); - deque.addFront(0); - expect(deque.peekFront()).to.equal(0); - deque.addFront(-1); - expect(deque.peekFront()).to.equal(-1); - deque.addFront(-2); - expect(deque.peekFront()).to.equal(-2); - }); - - it('allows to peek at the last element in the deque without removing it', () => { - expect(deque.peekBack()).to.equal(undefined); - - deque.addFront(1); - expect(deque.peekBack()).to.equal(1); - deque.addBack(2); - expect(deque.peekBack()).to.equal(2); - deque.addBack(3); - expect(deque.peekBack()).to.equal(3); - deque.addFront(0); - expect(deque.peekBack()).to.equal(3); - deque.addFront(-1); - expect(deque.peekBack()).to.equal(3); - deque.addFront(-2); - expect(deque.peekBack()).to.equal(3); - }); - - it('returns the correct size', () => { - expect(deque.size()).to.equal(0); - - deque.addFront(1); - expect(deque.size()).to.equal(1); - deque.addBack(2); - expect(deque.size()).to.equal(2); - deque.addBack(3); - expect(deque.size()).to.equal(3); - deque.addFront(0); - expect(deque.size()).to.equal(4); - deque.addFront(-1); - expect(deque.size()).to.equal(5); - deque.addFront(-2); - expect(deque.size()).to.equal(6); - - deque.clear(); - expect(deque.size()).to.equal(0); - - deque.addFront(1); - deque.addBack(2); - expect(deque.size()).to.equal(2); - - deque.removeFront(); - deque.removeBack(); - expect(deque.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(deque.isEmpty()).to.equal(true); - - deque.addFront(1); - expect(deque.isEmpty()).to.equal(false); - deque.addBack(2); - expect(deque.isEmpty()).to.equal(false); - - deque.clear(); - expect(deque.isEmpty()).to.equal(true); - - deque.addFront(1); - deque.addBack(2); - expect(deque.isEmpty()).to.equal(false); - - deque.removeFront(); - expect(deque.isEmpty()).to.equal(false); - deque.removeBack(); - expect(deque.isEmpty()).to.equal(true); - }); - - it('clears the queue', () => { - deque.clear(); - expect(deque.isEmpty()).to.equal(true); - - deque.addFront(1); - deque.addBack(2); - expect(deque.isEmpty()).to.equal(false); - - deque.clear(); - expect(deque.isEmpty()).to.equal(true); - }); - - it('returns toString primitive types', () => { - expect(deque.toString()).to.equal(''); - - deque.addFront(1); - expect(deque.toString()).to.equal('1'); - - deque.addBack(2); - expect(deque.toString()).to.equal('1,2'); - - deque.clear(); - expect(deque.toString()).to.equal(''); - - const queueString = new Deque(); - queueString.addFront('el1'); - expect(queueString.toString()).to.equal('el1'); - - queueString.addBack('el2'); - expect(queueString.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - class MyObj { - constructor(public el1: any, public el2: any) {} - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } - } - const dequeMyObj = new Deque(); - expect(dequeMyObj.toString()).to.equal(''); - - dequeMyObj.addFront(new MyObj(1, 2)); - expect(dequeMyObj.toString()).to.equal('1|2'); - - dequeMyObj.addBack(new MyObj(3, 4)); - expect(dequeMyObj.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/data-structures/dictionary.spec.ts b/test/ts/data-structures/dictionary.spec.ts deleted file mode 100644 index 28bf6615..00000000 --- a/test/ts/data-structures/dictionary.spec.ts +++ /dev/null @@ -1,335 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { Dictionary } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('Dictionary', () => { - let dictionary: Dictionary; - - beforeEach(() => { - dictionary = new Dictionary(); - }); - - it('starts empty', () => { - expect(dictionary.size()).to.equal(0); - expect(dictionary.isEmpty()).to.equal(true); - }); - - it('sets undefined and null keys and values', () => { - const dict = new Dictionary(); - - expect(dict.set('undefined', undefined)).to.equal(false); - expect(dict.get('undefined')).to.equal(undefined); - - expect(dict.set('undefined', 1)).to.equal(true); - expect(dict.get('undefined')).to.equal(1); - - expect(dict.set('null', null)).to.equal(false); - expect(dict.get('null')).to.equal(undefined); - - expect(dict.set('null', 1)).to.equal(true); - expect(dict.get('null')).to.equal(1); - - dict.clear(); - expect(dict.set(undefined, undefined)).to.equal(false); - expect(dict.get(undefined)).to.equal(undefined); - - expect(dict.set(undefined, 1)).to.equal(false); - expect(dict.get(undefined)).to.equal(undefined); - - expect(dict.set(null, null)).to.equal(false); - expect(dict.get(null)).to.equal(undefined); - - expect(dict.set(null, 1)).to.equal(false); - expect(dict.get(null)).to.equal(undefined); - }); - - it('sets values with string key', () => { - const dict = new Dictionary(); - const min = 1; - const max = 5; - const size = max - min + 1; - - for (let i = min; i <= max; i++) { - expect(dict.set(`${i}`, i)).to.equal(true); - } - expect(dict.size()).to.equal(size); - - const keys = dict.keys(); - expect(keys.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal((i + 1).toString(10)); - } - - dict.set('a', 1); - expect(dict.get('a')).to.equal(1); - }); - - it('sets values with number key', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - - for (let i = min; i <= max; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - expect(dictionary.size()).to.equal(size); - - const keys = dictionary.keys(); - expect(keys.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal((i + 1)); - } - }); - - it('sets values with object', () => { - const dict = new Dictionary(); - const min = 0; - const max = 5; - const size = max - min; - const myObjList = []; - - for (let i = min; i < max; i++) { - myObjList.push(new MyObj(i, (i + 1))); - } - - for (let i = min; i < max; i++) { - expect(dict.set(myObjList[i], myObjList[i])).to.equal(true); - } - expect(dict.size()).to.equal(size); - - for (let i = min; i < max; i++) { - expect(dict.get(myObjList[i])).to.equal(myObjList[i]); - } - - const keys = dict.keys(); - expect(keys.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal(myObjList[i]); - } - - const values = dict.values(); - expect(values.length).to.equal(size); - for (let i = 0; i < values.length; i++) { - expect(values[i]).to.equal(myObjList[i]); - } - }); - - function customToString(key: MyObj) { - return `####${key.toString()}`; - } - - it('sets values with custom toString function', () => { - const dict = new Dictionary(customToString); - const min = 0; - const max = 5; - const size = max - min; - const myObjList = []; - - for (let i = min; i < max; i++) { - myObjList.push(new MyObj(i, (i + 1))); - } - - for (let i = min; i < max; i++) { - expect(dict.set(myObjList[i], myObjList[i])).to.equal(true); - } - expect(dict.size()).to.equal(size); - - for (let i = min; i < max; i++) { - expect(dict.get(myObjList[i])).to.equal(myObjList[i]); - } - - const keys = dict.keys(); - expect(keys.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal(myObjList[i]); - } - - const values = dict.values(); - expect(values.length).to.equal(size); - for (let i = 0; i < values.length; i++) { - expect(values[i]).to.equal(myObjList[i]); - } - }); - - it('removes elements', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - - for (let i = min; i <= max; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - expect(dictionary.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(dictionary.remove(i)).to.equal(true); - } - - // elements do not exist - for (let i = min; i <= max; i++) { - expect(dictionary.remove(i)).to.equal(false); - } - - expect(dictionary.isEmpty()).to.equal(true); - }); - - it('returns the correct size', () => { - expect(dictionary.size()).to.equal(0); - - const max = 5; - - for (let i = 1; i < max; i++) { - dictionary.set(i, i); - expect(dictionary.size()).to.equal(i); - } - for (let i = 1; i < max; i++) { - dictionary.remove(i); - expect(dictionary.size()).to.equal(max - i - 1); - } - - expect(dictionary.size()).to.equal(0); - expect(dictionary.isEmpty()).to.equal(true); - }); - - it('returns if element exists', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - - for (let i = min; i <= max; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - expect(dictionary.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(dictionary.hasKey(i)).to.equal(true); - expect(dictionary.remove(i)).to.equal(true); - expect(dictionary.hasKey(i)).to.equal(false); - } - }); - - it('returns if it is empty', () => { - expect(dictionary.isEmpty()).to.equal(true); - - for (let i = 1; i < 5; i++) { - dictionary.set(i, i); - expect(dictionary.isEmpty()).to.equal(false); - } - - for (let i = 1; i < 5; i++) { - dictionary.remove(i); - expect(dictionary.isEmpty()).to.equal(!(i < 4)); - } - - expect(dictionary.size()).to.equal(0); - expect(dictionary.isEmpty()).to.equal(true); - }); - - it('clears the dictionary', () => { - dictionary.clear(); - expect(dictionary.isEmpty()).to.equal(true); - - dictionary.set(1, 1); - dictionary.set(2, 2); - - dictionary.clear(); - expect(dictionary.isEmpty()).to.equal(true); - }); - - it('returns values, keys and value pairs', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - - for (let i = min; i <= max; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - expect(dictionary.size()).to.equal(size); - - const keys = dictionary.keys(); - const values = dictionary.values(); - const valuePairs = dictionary.keyValues(); - expect(keys.length).to.equal(size); - expect(values.length).to.equal(size); - expect(valuePairs.length).to.equal(size); - for (let i = 0; i < keys.length; i++) { - expect(keys[i]).to.equal((i + 1)); - expect(values[i]).to.equal((i + 1)); - expect(valuePairs[i].key).to.equal((i + 1)); - expect(valuePairs[i].value).to.equal((i + 1)); - } - }); - - it('allows to iterate with forEach', () => { - for (let i = 1; i <= 5; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - - dictionary.forEach((k, v) => { - expect(dictionary.hasKey(k)).to.equal(true); - expect(dictionary.get(k)).to.equal(v); - }); - }); - - it('allows to iterate with forEach and interrupt', () => { - for (let i = 1; i <= 5; i++) { - expect(dictionary.set(i, i)).to.equal(true); - } - - const size = dictionary.keys().length; - - let index = 1; - dictionary.forEach((k, v) => { - expect(dictionary.hasKey(k)).to.equal(true); - expect(dictionary.get(k)).to.equal(v); - index++; - }); - expect(index).to.equal(size + 1); - - index = 1; - dictionary.forEach((k, v) => { - expect(dictionary.hasKey(k)).to.equal(true); - expect(dictionary.get(k)).to.equal(v); - index++; - return !(k % 3 === 0); - }); - expect(index).to.equal(size - 1); - }); - - it('returns toString primitive types', () => { - expect(dictionary.toString()).to.equal(''); - - dictionary.set(1, 1); - expect(dictionary.toString()).to.equal('[#1: 1]'); - - dictionary.set(2, 2); - expect(dictionary.toString()).to.equal('[#1: 1],[#2: 2]'); - - dictionary.clear(); - expect(dictionary.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const dict = new Dictionary(); - dict.set('el1', 1); - expect(dict.toString()).to.equal('[#el1: 1]'); - - dict.set('el2', 2); - expect(dict.toString()).to.equal('[#el1: 1],[#el2: 2]'); - }); - - it('returns toString objects', () => { - const dict = new Dictionary(); - expect(dict.toString()).to.equal(''); - - let myObj = new MyObj(1, 2); - dict.set(myObj, myObj); - expect(dict.toString()).to.equal('[#1|2: 1|2]'); - - myObj = new MyObj(3, 4); - dict.set(myObj, myObj); - expect(dict.toString()).to.equal('[#1|2: 1|2],[#3|4: 3|4]'); - }); - -}); diff --git a/test/ts/data-structures/doubly-linked-list.spec.ts b/test/ts/data-structures/doubly-linked-list.spec.ts deleted file mode 100644 index 76abb29a..00000000 --- a/test/ts/data-structures/doubly-linked-list.spec.ts +++ /dev/null @@ -1,406 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { DoublyLinkedList } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('DoublyLinkedList', () => { - let list: DoublyLinkedList; - let min: number; - let max: number; - - beforeEach(() => { - list = new DoublyLinkedList(); - min = 1; - max = 3; - }); - - function pushesElements() { - for (let i = min; i <= max; i++) { - list.push(i); - } - } - - function verifyNode(current: any, i: number) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(i); - - // verify next node - if (i < max) { - expect(current.next).to.not.be.an('undefined'); - // TS strictNullChecks - if (current.next) { - expect(current.next.element).to.equal(i + 1); - } - } else { - expect(current.next).to.be.an('undefined'); - } - - // verify previous node - if (i > min) { - expect(current.prev).to.not.be.an('undefined'); - if (current.prev) { - expect(current.prev.element).to.equal(i - 1); - } - } else { - expect(current.prev).to.be.an('undefined'); - } - } - - function verifyList() { - let current = list.getHead(); - for (let i = min; i <= max; i++) { - expect(current).to.not.be.an('undefined'); - // TS strictNullChecks - if (current) { - verifyNode(current, i); - current = current.next; - } - } - verifyListFromTail(); - } - - function verifyListFromTail() { - let current = list.getTail(); - for (let i = max; i >= min; i--) { - expect(current).to.not.be.an('undefined'); - // TS strictNullChecks - if (current) { - verifyNode(current, i); - current = current.prev; - } - } - } - - it('starts empty', () => { - expect(list.size()).to.equal(0); - expect(list.isEmpty()).to.equal(true); - expect(list.getHead()).to.be.an('undefined'); - expect(list.getTail()).to.be.an('undefined'); - }); - - it('pushes elements', () => { - pushesElements(); - verifyList(); - }); - - it('returns element at specific index: invalid position', () => { - // list is empty - expect(list.getElementAt(3)).to.be.an('undefined'); - }); - - it('returns element at specific index', () => { - let node; - - pushesElements(); - - for (let i = min; i <= max; i++) { - node = list.getElementAt(i - 1); - expect(node).to.not.be.an('undefined'); - if (node) { - expect(node.element).to.equal(i); - } - } - }); - - it('inserts elements first position empty list', () => { - const element = 1; - max = element; - expect(list.insert(element, 0)).to.equal(true); - verifyList(); - }); - - it('inserts elements first position not empty list', () => { - max = 2; - expect(list.insert(max, 0)).to.equal(true); - - expect(list.insert(min, 0)).to.equal(true); - - verifyList(); - }); - - it('inserts elements invalid position empty list', () => { - expect(list.insert(1, 1)).to.equal(false); - }); - - it('inserts elements invalid position not empty list', () => { - const element = 1; - expect(list.insert(element, 0)).to.equal(true); - expect(list.insert(element, 2)).to.equal(false); - }); - - it('inserts elements at the end of list', () => { - max = 5; - - for (let i = min; i <= max; i++) { - expect(list.insert(i , i - 1)).to.equal(true); - } - - verifyList(); - }); - - it('inserts elements in the middle of list', () => { - expect(list.insert(3, 0)).to.equal(true); - expect(list.insert(1, 0)).to.equal(true); - expect(list.insert(2, 1)).to.equal(true); - verifyList(); - }); - - it('returns index of elements', () => { - let index; - - pushesElements(); - - for (let i = min; i <= max; i++) { - index = list.indexOf(i); - expect(index).to.equal(i - 1); - } - - expect(list.indexOf(max + 2)).to.equal(-1); - }); - - it('removes invalid elements', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.remove(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes valid elements', () => { - let element; - - pushesElements(); - - for (let i = min; i <= max; i++) { - element = list.remove(i); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - } - }); - - it('removes element invalid position empty list', () => { - let element; - - for (let i = min; i <= max; i++) { - element = list.removeAt(i - 1); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position not empty list', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.removeAt(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes first element list single element', () => { - const value = 1; - list.push(value); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(value); - - expect(list.getHead()).to.be.an('undefined'); - expect(list.getTail()).to.be.an('undefined'); - expect(list.isEmpty()).to.equal(true); - }); - - it('removes first element list multiple elements', () => { - pushesElements(); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(min); - - min = 2; - verifyList(); - }); - - it('removes element from end of list', () => { - let element; - - pushesElements(); - - const maxIndex = max; - for (let i = maxIndex; i >= min; i--) { - element = list.removeAt(i - 1); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - max--; - verifyList(); - } - }); - - it('removes element from middle of list', () => { - pushesElements(); // 1, 2, 3 - - const element = list.removeAt(1); // element 2 - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(2); - - // list needs to be [1, 3] - let current = list.getHead(); - - // element 1 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(1); - expect(current.prev).to.be.an('undefined'); - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - expect(current.next.element).to.equal(3); - current = current.next; - } - } - - // element 3 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(3); - expect(current.next).to.be.an('undefined'); - expect(current.prev).to.not.be.an('undefined'); - if (current.prev) { - expect(current.prev.element).to.equal(1); - } - } - }); - - it('returns the head of the list', () => { - expect(list.getHead()).to.be.an('undefined'); - - list.push(1); - expect(list.getHead()).to.not.be.an('undefined'); - }); - - it('returns the tail of the list', () => { - expect(list.getTail()).to.be.an('undefined'); - - list.push(1); - expect(list.getTail()).to.not.be.an('undefined'); - }); - - it('returns the correct size', () => { - expect(list.size()).to.equal(0); - - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.size()).to.equal(i); - } - - const size = max; - for (let i = min; i <= max; i++) { - list.remove(i); - expect(list.size()).to.equal(size - i); - } - - expect(list.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(list.isEmpty()).to.equal(true); - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.isEmpty()).to.equal(false); - } - - for (let i = min; i < max; i++) { - list.remove(i); - expect(list.isEmpty()).to.equal(false); - } - list.remove(max); - expect(list.isEmpty()).to.equal(true); - - pushesElements(); - expect(list.isEmpty()).to.equal(false); - - list.clear(); - expect(list.isEmpty()).to.equal(true); - }); - - it('clears the list', () => { - expect(list.size()).to.equal(0); - list.clear(); - expect(list.size()).to.equal(0); - pushesElements(); - expect(list.size()).to.greaterThan(0); - list.clear(); - expect(list.size()).to.equal(0); - }); - - it('returns toString primitive types', () => { - expect(list.toString()).to.equal(''); - - list.push(1); - expect(list.toString()).to.equal('1'); - - list.push(2); - expect(list.toString()).to.equal('1,2'); - - list.clear(); - expect(list.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const ds = new DoublyLinkedList(); - ds.push('el1'); - expect(ds.toString()).to.equal('el1'); - - ds.push('el2'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const ds = new DoublyLinkedList(); - expect(ds.toString()).to.equal(''); - - ds.push(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2'); - - ds.push(new MyObj(3, 4)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); - - it('returns inverseToString primitive types', () => { - expect(list.inverseToString()).to.equal(''); - - list.push(1); - expect(list.inverseToString()).to.equal('1'); - - list.push(2); - expect(list.inverseToString()).to.equal('2,1'); - - list.clear(); - expect(list.inverseToString()).to.equal(''); - }); - - it('returns inverseToString primitive types: string', () => { - const ds = new DoublyLinkedList(); - ds.push('el1'); - expect(ds.inverseToString()).to.equal('el1'); - - ds.push('el2'); - expect(ds.inverseToString()).to.equal('el2,el1'); - }); - - it('returns inverseToString objects', () => { - const ds = new DoublyLinkedList(); - expect(ds.inverseToString()).to.equal(''); - - ds.push(new MyObj(1, 2)); - expect(ds.inverseToString()).to.equal('1|2'); - - ds.push(new MyObj(3, 4)); - expect(ds.inverseToString()).to.equal('3|4,1|2'); - }); -}); diff --git a/test/ts/data-structures/hash-table-linear-probing-lazy.spec.ts b/test/ts/data-structures/hash-table-linear-probing-lazy.spec.ts deleted file mode 100644 index 7d004349..00000000 --- a/test/ts/data-structures/hash-table-linear-probing-lazy.spec.ts +++ /dev/null @@ -1,388 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { HashTableLinearProbingLazy } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('HashTableLinearProbingLazy', () => { - const A = 'Jonathan'; - const B = 'Jamie'; - const C = 'Sue'; - - it('starts empty', () => { - const hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.size()).to.equal(0); - expect(hashTable.isEmpty()).to.equal(true); - }); - - it('generates hashcode', () => { - // numbers - let hashTable: any = new HashTableLinearProbingLazy(); - expect(hashTable.hashCode(1)).to.equal(1); - expect(hashTable.hashCode(10)).to.equal(10); - expect(hashTable.hashCode(100)).to.equal(100); - expect(hashTable.hashCode(1000)).to.equal(1000); - - // strings - hashTable = new HashTableLinearProbingLazy(); - expect(hashTable.hashCode('1')).to.equal(12); - expect(hashTable.hashCode('10')).to.equal(23); - expect(hashTable.hashCode('100')).to.equal(34); - expect(hashTable.hashCode('1000')).to.equal(8); - expect(hashTable.hashCode('a')).to.equal(23); - expect(hashTable.hashCode('A')).to.equal(28); - expect(hashTable.hashCode('Aba')).to.equal(1); - - // objects - hashTable = new HashTableLinearProbingLazy(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - expect(hashTable.hashCode(myObjList[0])).to.equal(1); - expect(hashTable.hashCode(myObjList[1])).to.equal(3); - expect(hashTable.hashCode(myObjList[2])).to.equal(5); - expect(hashTable.hashCode(myObjList[3])).to.equal(7); - expect(hashTable.hashCode(myObjList[4])).to.equal(9); - }); - - it('puts undefined and null keys and values', () => { - const hashTable = new HashTableLinearProbingLazy(); - - expect(hashTable.put('undefined', undefined)).to.equal(false); - expect(hashTable.get('undefined')).to.equal(undefined); - - expect(hashTable.put('undefined', 1)).to.equal(true); - expect(hashTable.get('undefined')).to.equal(1); - - expect(hashTable.put('null', null)).to.equal(false); - expect(hashTable.get('null')).to.equal(undefined); - - expect(hashTable.put('null', 1)).to.equal(true); - expect(hashTable.get('null')).to.equal(1); - - hashTable.clear(); - expect(hashTable.put(undefined, undefined)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - - expect(hashTable.put(undefined, 1)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - - expect(hashTable.put(null, null)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - - expect(hashTable.put(null, 1)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - }); - - it('puts values with number key without collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableLinearProbingLazy(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - } - }); - - it('puts values with string key without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - - expect(hashTable.put('1', 1)).to.equal(true); - expect(hashTable.put('10', 10)).to.equal(true); - expect(hashTable.put('100', 100)).to.equal(true); - expect(hashTable.put('1000', 1000)).to.equal(true); - - const table = hashTable.getTable(); - - expect(table[12].key).to.equal('1'); - expect(table[12].value).to.equal(1); - - expect(table[23].key).to.equal('10'); - expect(table[23].value).to.equal(10); - - expect(table[34].key).to.equal('100'); - expect(table[34].value).to.equal(100); - - expect(table[8].key).to.equal('1000'); - expect(table[8].value).to.equal(1000); - }); - - it('puts values with object key without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - expect(hashTable.put(myObjList[i - 1], myObjList[i - 1])).to.equal(true); - } - - const table = hashTable.getTable(); - - expect(table[1].key).to.equal(myObjList[0]); - expect(table[1].value).to.equal(myObjList[0]); - - expect(table[3].key).to.equal(myObjList[1]); - expect(table[3].value).to.equal(myObjList[1]); - - expect(table[5].key).to.equal(myObjList[2]); - expect(table[5].value).to.equal(myObjList[2]); - - expect(table[7].key).to.equal(myObjList[3]); - expect(table[7].value).to.equal(myObjList[3]); - - expect(table[9].key).to.equal(myObjList[4]); - expect(table[9].value).to.equal(myObjList[4]); - }); - - function addValuesCollision() { - const hashTable = new HashTableLinearProbingLazy(); - - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.size()).to.equal(3); - - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - - expect(hashTable.size()).to.equal(3); - - return hashTable; - } - - it('puts values with collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableLinearProbingLazy(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 10)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 2); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 100)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 3); - - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - - expect(table[i + size].key).to.equal(i); - expect(table[i + size].value).to.equal(i + 10); - - expect(table[i + size * 2].key).to.equal(i); - expect(table[i + size * 2].value).to.equal(i + 100); - } - - addValuesCollision(); - }); - - it('removes elements without collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableLinearProbingLazy(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(true); - } - - // elements do not exist - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(false); - } - - expect(hashTable.isEmpty()).to.equal(true); - }); - - function removeWithCollision(a: string, b: string, c: string) { - const hashTable = addValuesCollision(); - - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - - expect(hashTable.isEmpty()).to.equal(true); - } - - it('removes elements with collisions: scenario 1', () => { - // test all possibilities for removal - removeWithCollision(A, B, C); - removeWithCollision(A, C, B); - removeWithCollision(B, A, C); - removeWithCollision(B, C, A); - removeWithCollision(C, A, B); - removeWithCollision(C, B, A); - }); - - function addValuesCollision2() { - const hashTable = new HashTableLinearProbingLazy(); - - expect(hashTable.put(')', `parenthesis@email.com`)).to.equal(true); - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put('+', `plus@email.com`)).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(',', `comma@email.com`)).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.put('-', `minus@email.com`)).to.equal(true); - expect(hashTable.put('0', `zero@email.com`)).to.equal(true); - - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - expect(hashTable.hashCode(')')).to.equal(4); - expect(hashTable.hashCode('+')).to.equal(6); - expect(hashTable.hashCode(',')).to.equal(7); - expect(hashTable.hashCode('-')).to.equal(8); - expect(hashTable.hashCode('0')).to.equal(11); - - expect(hashTable.size()).to.equal(8); - - const table = hashTable.getTable(); - expect(table[4].key).to.equal(')'); - expect(table[5].key).to.equal(A); - expect(table[6].key).to.equal('+'); - expect(table[7].key).to.equal(B); - expect(table[8].key).to.equal(','); - expect(table[9].key).to.equal(C); - expect(table[10].key).to.equal('-'); - expect(table[11].key).to.equal('0'); - - return hashTable; - } - - function verifyOtherKeys(hashTable: HashTableLinearProbingLazy) { - expect(hashTable.get(')')).to.not.equal(undefined); - expect(hashTable.get('+')).to.not.equal(undefined); - expect(hashTable.get(',')).to.not.equal(undefined); - expect(hashTable.get('-')).to.not.equal(undefined); - expect(hashTable.get('0')).to.not.equal(undefined); - } - - function removeWithCollision2(a: string, b: string, c: string) { - const hashTable = addValuesCollision2(); - - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - verifyOtherKeys(hashTable); - - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - verifyOtherKeys(hashTable); - - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - verifyOtherKeys(hashTable); - } - - it('removes elements with collisions: scenario 2', () => { - // test all possibilities for removal - removeWithCollision2(A, B, C); - removeWithCollision2(A, C, B); - removeWithCollision2(B, A, C); - removeWithCollision2(B, C, A); - removeWithCollision2(C, A, B); - removeWithCollision2(C, B, A); - }); - - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - - expect(hashTable.toString()).to.equal(''); - - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); - - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - - hashTable.put('el1', 1); - expect(hashTable.toString()).to.equal('{36 => [#el1: 1]}'); - - hashTable.put('el2', 2); - expect(hashTable.toString()).to.equal('{0 => [#el2: 2]},{36 => [#el1: 1]}'); - }); - - it('returns toString objects without collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - - let myObj = new MyObj(1, 2); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]}'); - - myObj = new MyObj(3, 4); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal( - '{1 => [#1|2: 1|2]},{5 => [#3|4: 3|4]}' - ); - }); - - it('returns toString with collisions', () => { - const hashTable = new HashTableLinearProbingLazy(); - - expect(hashTable.toString()).to.equal(''); - - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - - hashTable.put(1, 10); - expect(hashTable.toString()).to.equal( - '{1 => [#1: 1]},{2 => [#2: 2]},{3 => [#1: 10]}' - ); - - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); -}); diff --git a/test/ts/data-structures/hash-table-linear-probing.spec.ts b/test/ts/data-structures/hash-table-linear-probing.spec.ts deleted file mode 100644 index 77ed340f..00000000 --- a/test/ts/data-structures/hash-table-linear-probing.spec.ts +++ /dev/null @@ -1,388 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { HashTableLinearProbing } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('HashTableLinearProbing', () => { - const A = 'Jonathan'; - const B = 'Jamie'; - const C = 'Sue'; - - it('starts empty', () => { - const hashTable = new HashTableLinearProbing(); - expect(hashTable.size()).to.equal(0); - expect(hashTable.isEmpty()).to.equal(true); - }); - - it('generates hashcode', () => { - // numbers - let hashTable: any = new HashTableLinearProbing(); - expect(hashTable.hashCode(1)).to.equal(1); - expect(hashTable.hashCode(10)).to.equal(10); - expect(hashTable.hashCode(100)).to.equal(100); - expect(hashTable.hashCode(1000)).to.equal(1000); - - // strings - hashTable = new HashTableLinearProbing(); - expect(hashTable.hashCode('1')).to.equal(12); - expect(hashTable.hashCode('10')).to.equal(23); - expect(hashTable.hashCode('100')).to.equal(34); - expect(hashTable.hashCode('1000')).to.equal(8); - expect(hashTable.hashCode('a')).to.equal(23); - expect(hashTable.hashCode('A')).to.equal(28); - expect(hashTable.hashCode('Aba')).to.equal(1); - - // objects - hashTable = new HashTableLinearProbing(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - expect(hashTable.hashCode(myObjList[0])).to.equal(1); - expect(hashTable.hashCode(myObjList[1])).to.equal(3); - expect(hashTable.hashCode(myObjList[2])).to.equal(5); - expect(hashTable.hashCode(myObjList[3])).to.equal(7); - expect(hashTable.hashCode(myObjList[4])).to.equal(9); - }); - - it('puts undefined and null keys and values', () => { - const hashTable = new HashTableLinearProbing(); - - expect(hashTable.put('undefined', undefined)).to.equal(false); - expect(hashTable.get('undefined')).to.equal(undefined); - - expect(hashTable.put('undefined', 1)).to.equal(true); - expect(hashTable.get('undefined')).to.equal(1); - - expect(hashTable.put('null', null)).to.equal(false); - expect(hashTable.get('null')).to.equal(undefined); - - expect(hashTable.put('null', 1)).to.equal(true); - expect(hashTable.get('null')).to.equal(1); - - hashTable.clear(); - expect(hashTable.put(undefined, undefined)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - - expect(hashTable.put(undefined, 1)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - - expect(hashTable.put(null, null)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - - expect(hashTable.put(null, 1)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - }); - - it('puts values with number key without collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableLinearProbing(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - } - }); - - it('puts values with string key without collisions', () => { - const hashTable = new HashTableLinearProbing(); - - expect(hashTable.put('1', 1)).to.equal(true); - expect(hashTable.put('10', 10)).to.equal(true); - expect(hashTable.put('100', 100)).to.equal(true); - expect(hashTable.put('1000', 1000)).to.equal(true); - - const table = hashTable.getTable(); - - expect(table[12].key).to.equal('1'); - expect(table[12].value).to.equal(1); - - expect(table[23].key).to.equal('10'); - expect(table[23].value).to.equal(10); - - expect(table[34].key).to.equal('100'); - expect(table[34].value).to.equal(100); - - expect(table[8].key).to.equal('1000'); - expect(table[8].value).to.equal(1000); - }); - - it('puts values with object key without collisions', () => { - const hashTable = new HashTableLinearProbing(); - - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - expect(hashTable.put(myObjList[i - 1], myObjList[i - 1])).to.equal(true); - } - - const table = hashTable.getTable(); - - expect(table[1].key).to.equal(myObjList[0]); - expect(table[1].value).to.equal(myObjList[0]); - - expect(table[3].key).to.equal(myObjList[1]); - expect(table[3].value).to.equal(myObjList[1]); - - expect(table[5].key).to.equal(myObjList[2]); - expect(table[5].value).to.equal(myObjList[2]); - - expect(table[7].key).to.equal(myObjList[3]); - expect(table[7].value).to.equal(myObjList[3]); - - expect(table[9].key).to.equal(myObjList[4]); - expect(table[9].value).to.equal(myObjList[4]); - }); - - function addValuesCollision() { - const hashTable = new HashTableLinearProbing(); - - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.size()).to.equal(3); - - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - - expect(hashTable.size()).to.equal(3); - - return hashTable; - } - - it('puts values with collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableLinearProbing(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 10)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 2); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 100)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 3); - - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - - expect(table[i + size].key).to.equal(i); - expect(table[i + size].value).to.equal(i + 10); - - expect(table[i + size * 2].key).to.equal(i); - expect(table[i + size * 2].value).to.equal(i + 100); - } - - addValuesCollision(); - }); - - it('removes elements without collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableLinearProbing(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(true); - } - - // elements do not exist - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(false); - } - - expect(hashTable.isEmpty()).to.equal(true); - }); - - function removeWithCollision(a: string, b: string, c: string) { - const hashTable = addValuesCollision(); - - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - - expect(hashTable.isEmpty()).to.equal(true); - } - - it('removes elements with collisions: scenario 1', () => { - // test all possibilities for removal - removeWithCollision(A, B, C); - removeWithCollision(A, C, B); - removeWithCollision(B, A, C); - removeWithCollision(B, C, A); - removeWithCollision(C, A, B); - removeWithCollision(C, B, A); - }); - - function addValuesCollision2() { - const hashTable = new HashTableLinearProbing(); - - expect(hashTable.put(')', `parenthesis@email.com`)).to.equal(true); - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put('+', `plus@email.com`)).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(',', `comma@email.com`)).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.put('-', `minus@email.com`)).to.equal(true); - expect(hashTable.put('0', `zero@email.com`)).to.equal(true); - - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - expect(hashTable.hashCode(')')).to.equal(4); - expect(hashTable.hashCode('+')).to.equal(6); - expect(hashTable.hashCode(',')).to.equal(7); - expect(hashTable.hashCode('-')).to.equal(8); - expect(hashTable.hashCode('0')).to.equal(11); - - expect(hashTable.size()).to.equal(8); - - const table = hashTable.getTable(); - expect(table[4].key).to.equal(')'); - expect(table[5].key).to.equal(A); - expect(table[6].key).to.equal('+'); - expect(table[7].key).to.equal(B); - expect(table[8].key).to.equal(','); - expect(table[9].key).to.equal(C); - expect(table[10].key).to.equal('-'); - expect(table[11].key).to.equal('0'); - - return hashTable; - } - - function verifyOtherKeys(hashTable: HashTableLinearProbing) { - expect(hashTable.get(')')).to.not.equal(undefined); - expect(hashTable.get('+')).to.not.equal(undefined); - expect(hashTable.get(',')).to.not.equal(undefined); - expect(hashTable.get('-')).to.not.equal(undefined); - expect(hashTable.get('0')).to.not.equal(undefined); - } - - function removeWithCollision2(a: string, b: string, c: string) { - const hashTable = addValuesCollision2(); - - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - verifyOtherKeys(hashTable); - - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - verifyOtherKeys(hashTable); - - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - verifyOtherKeys(hashTable); - } - - it('removes elements with collisions: scenario 2', () => { - // test all possibilities for removal - removeWithCollision2(A, B, C); - removeWithCollision2(A, C, B); - removeWithCollision2(B, A, C); - removeWithCollision2(B, C, A); - removeWithCollision2(C, A, B); - removeWithCollision2(C, B, A); - }); - - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableLinearProbing(); - - expect(hashTable.toString()).to.equal(''); - - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); - - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableLinearProbing(); - - hashTable.put('el1', 1); - expect(hashTable.toString()).to.equal('{36 => [#el1: 1]}'); - - hashTable.put('el2', 2); - expect(hashTable.toString()).to.equal('{0 => [#el2: 2]},{36 => [#el1: 1]}'); - }); - - it('returns toString objects without collisions', () => { - const hashTable = new HashTableLinearProbing(); - - let myObj = new MyObj(1, 2); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]}'); - - myObj = new MyObj(3, 4); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal( - '{1 => [#1|2: 1|2]},{5 => [#3|4: 3|4]}' - ); - }); - - it('returns toString with collisions', () => { - const hashTable = new HashTableLinearProbing(); - - expect(hashTable.toString()).to.equal(''); - - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - - hashTable.put(1, 10); - expect(hashTable.toString()).to.equal( - '{1 => [#1: 1]},{2 => [#2: 2]},{3 => [#1: 10]}' - ); - - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); -}); diff --git a/test/ts/data-structures/hash-table-separate-chaining.spec.ts b/test/ts/data-structures/hash-table-separate-chaining.spec.ts deleted file mode 100644 index b7f72524..00000000 --- a/test/ts/data-structures/hash-table-separate-chaining.spec.ts +++ /dev/null @@ -1,343 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { HashTableSeparateChaining } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('HashTableSeparateChaining', () => { - const A = 'Jonathan'; - const B = 'Jamie'; - const C = 'Sue'; - - it('starts empty', () => { - const hashTable = new HashTableSeparateChaining(); - expect(hashTable.size()).to.equal(0); - expect(hashTable.isEmpty()).to.equal(true); - }); - - it('generates hashcode', () => { - // numbers - let hashTable: any = new HashTableSeparateChaining(); - expect(hashTable.hashCode(1)).to.equal(1); - expect(hashTable.hashCode(10)).to.equal(10); - expect(hashTable.hashCode(100)).to.equal(100); - expect(hashTable.hashCode(1000)).to.equal(1000); - - // strings - hashTable = new HashTableSeparateChaining(); - expect(hashTable.hashCode('1')).to.equal(12); - expect(hashTable.hashCode('10')).to.equal(23); - expect(hashTable.hashCode('100')).to.equal(34); - expect(hashTable.hashCode('1000')).to.equal(8); - expect(hashTable.hashCode('a')).to.equal(23); - expect(hashTable.hashCode('A')).to.equal(28); - expect(hashTable.hashCode('Aba')).to.equal(1); - - // objects - hashTable = new HashTableSeparateChaining(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - expect(hashTable.hashCode(myObjList[0])).to.equal(1); - expect(hashTable.hashCode(myObjList[1])).to.equal(3); - expect(hashTable.hashCode(myObjList[2])).to.equal(5); - expect(hashTable.hashCode(myObjList[3])).to.equal(7); - expect(hashTable.hashCode(myObjList[4])).to.equal(9); - }); - - it('puts undefined and null keys and values', () => { - const hashTable = new HashTableSeparateChaining(); - - expect(hashTable.put('undefined', undefined)).to.equal(false); - expect(hashTable.get('undefined')).to.equal(undefined); - - expect(hashTable.put('undefined', 1)).to.equal(true); - expect(hashTable.get('undefined')).to.equal(1); - - expect(hashTable.put('null', null)).to.equal(false); - expect(hashTable.get('null')).to.equal(undefined); - - expect(hashTable.put('null', 1)).to.equal(true); - expect(hashTable.get('null')).to.equal(1); - - hashTable.clear(); - expect(hashTable.put(undefined, undefined)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - - expect(hashTable.put(undefined, 1)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - - expect(hashTable.put(null, null)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - - expect(hashTable.put(null, 1)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - }); - - it('puts values with number key without collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableSeparateChaining(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - const linkedList = table[i]; - expect(linkedList.size()).to.equal(1); - const valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(i); - expect(valuePair.element.value).to.equal(i); - } - }); - - it('puts values with string key without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - - expect(hashTable.put('1', 1)).to.equal(true); - expect(hashTable.put('10', 10)).to.equal(true); - expect(hashTable.put('100', 100)).to.equal(true); - expect(hashTable.put('1000', 1000)).to.equal(true); - - const table = hashTable.getTable(); - - let linkedList = table[12]; - expect(linkedList.size()).to.equal(1); - let valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal('1'); - expect(valuePair.element.value).to.equal(1); - - linkedList = table[23]; - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal('10'); - expect(valuePair.element.value).to.equal(10); - - linkedList = table[34]; - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal('100'); - expect(valuePair.element.value).to.equal(100); - - linkedList = table[8]; - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal('1000'); - expect(valuePair.element.value).to.equal(1000); - }); - - it('puts values with object key without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - expect(hashTable.put(myObjList[i - 1], myObjList[i - 1])).to.equal(true); - } - - const table = hashTable.getTable(); - - let linkedList = table[1]; - expect(linkedList.size()).to.equal(1); - let valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[0]); - expect(valuePair.element.value).to.equal(myObjList[0]); - - linkedList = table[3]; - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[1]); - expect(valuePair.element.value).to.equal(myObjList[1]); - - linkedList = table[5]; - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[2]); - expect(valuePair.element.value).to.equal(myObjList[2]); - - linkedList = table[7]; - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[3]); - expect(valuePair.element.value).to.equal(myObjList[3]); - - linkedList = table[9]; - expect(linkedList.size()).to.equal(1); - valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(myObjList[4]); - expect(valuePair.element.value).to.equal(myObjList[4]); - }); - - it('puts values with collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableSeparateChaining(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 10)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 2); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i + 100)).to.equal(true); - } - expect(hashTable.size()).to.equal(size * 3); - - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - const linkedList = table[i]; - expect(linkedList.size()).to.equal(3); - - let valuePair = linkedList.getHead(); - expect(valuePair.element.key).to.equal(i); - expect(valuePair.element.value).to.equal(i); - - valuePair = valuePair.next; - expect(valuePair.element.key).to.equal(i); - expect(valuePair.element.value).to.equal(i + 10); - - valuePair = valuePair.next; - expect(valuePair.element.key).to.equal(i); - expect(valuePair.element.value).to.equal(i + 100); - } - }); - - it('removes elements without collisions', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTableSeparateChaining(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(true); - } - - // elements do not exist - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(false); - } - - expect(hashTable.isEmpty()).to.equal(true); - }); - - function addValuesCollision() { - const hashTable = new HashTableSeparateChaining(); - - expect(hashTable.put(A, `${A}@email.com`)).to.equal(true); - expect(hashTable.put(B, `${B}@email.com`)).to.equal(true); - expect(hashTable.put(C, `${C}@email.com`)).to.equal(true); - expect(hashTable.size()).to.equal(3); - - const expectedHash = 5; - expect(hashTable.hashCode(A)).to.equal(expectedHash); - expect(hashTable.hashCode(B)).to.equal(expectedHash); - expect(hashTable.hashCode(C)).to.equal(expectedHash); - - expect(hashTable.getTable()[expectedHash].size()).to.equal(3); - - return hashTable; - } - - function removeWithCollision(a: string, b: string, c: string) { - const hashTable = addValuesCollision(); - - expect(hashTable.remove(a)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.not.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - - expect(hashTable.remove(b)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.not.equal(undefined); - - expect(hashTable.remove(c)).to.equal(true); - expect(hashTable.get(a)).to.equal(undefined); - expect(hashTable.get(b)).to.equal(undefined); - expect(hashTable.get(c)).to.equal(undefined); - - expect(hashTable.isEmpty()).to.equal(true); - } - - it('removes elements with collisions', () => { - // test all possibilities for removal - removeWithCollision(A, B, C); - removeWithCollision(A, C, B); - removeWithCollision(B, A, C); - removeWithCollision(B, C, A); - removeWithCollision(C, A, B); - removeWithCollision(C, B, A); - }); - - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - - expect(hashTable.toString()).to.equal(''); - - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); - - it('returns toString primitive types without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - - hashTable.put('el1', 1); - expect(hashTable.toString()).to.equal('{36 => [#el1: 1]}'); - - hashTable.put('el2', 2); - expect(hashTable.toString()).to.equal('{0 => [#el2: 2]},{36 => [#el1: 1]}'); - }); - - it('returns toString objects without collisions', () => { - const hashTable = new HashTableSeparateChaining(); - - let myObj = new MyObj(1, 2); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]}'); - - myObj = new MyObj(3, 4); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal( - '{1 => [#1|2: 1|2]},{5 => [#3|4: 3|4]}' - ); - }); - - it('returns toString with collisions', () => { - const hashTable = new HashTableSeparateChaining(); - - expect(hashTable.toString()).to.equal(''); - - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - - hashTable.put(1, 10); - expect(hashTable.toString()).to.equal('{1 => [#1: 1],[#1: 10]},{2 => [#2: 2]}'); - - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); -}); diff --git a/test/ts/data-structures/hash-table.spec.ts b/test/ts/data-structures/hash-table.spec.ts deleted file mode 100644 index 2dd56a3f..00000000 --- a/test/ts/data-structures/hash-table.spec.ts +++ /dev/null @@ -1,211 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { HashTable } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('HashTable', () => { - it('starts empty', () => { - const hashTable = new HashTable(); - expect(hashTable.size()).to.equal(0); - expect(hashTable.isEmpty()).to.equal(true); - }); - - it('generates hashcode', () => { - // numbers - let hashTable: any = new HashTable(); - expect(hashTable.hashCode(1)).to.equal(1); - expect(hashTable.hashCode(10)).to.equal(10); - expect(hashTable.hashCode(100)).to.equal(100); - expect(hashTable.hashCode(1000)).to.equal(1000); - - // strings - hashTable = new HashTable(); - expect(hashTable.hashCode('1')).to.equal(12); - expect(hashTable.hashCode('10')).to.equal(23); - expect(hashTable.hashCode('100')).to.equal(34); - expect(hashTable.hashCode('1000')).to.equal(8); - expect(hashTable.hashCode('a')).to.equal(23); - expect(hashTable.hashCode('A')).to.equal(28); - expect(hashTable.hashCode('Aba')).to.equal(1); - - // objects - hashTable = new HashTable(); - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - } - expect(hashTable.hashCode(myObjList[0])).to.equal(1); - expect(hashTable.hashCode(myObjList[1])).to.equal(3); - expect(hashTable.hashCode(myObjList[2])).to.equal(5); - expect(hashTable.hashCode(myObjList[3])).to.equal(7); - expect(hashTable.hashCode(myObjList[4])).to.equal(9); - }); - - it('puts undefined and null keys and values', () => { - const hashTable = new HashTable(); - - expect(hashTable.put('undefined', undefined)).to.equal(false); - expect(hashTable.get('undefined')).to.equal(undefined); - - expect(hashTable.put('undefined', 1)).to.equal(true); - expect(hashTable.get('undefined')).to.equal(1); - - expect(hashTable.put('null', null)).to.equal(false); - expect(hashTable.get('null')).to.equal(undefined); - - expect(hashTable.put('null', 1)).to.equal(true); - expect(hashTable.get('null')).to.equal(1); - - hashTable.clear(); - expect(hashTable.put(undefined, undefined)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - - expect(hashTable.put(undefined, 1)).to.equal(false); - expect(hashTable.get(undefined)).to.equal(undefined); - - expect(hashTable.put(null, null)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - - expect(hashTable.put(null, 1)).to.equal(false); - expect(hashTable.get(null)).to.equal(undefined); - }); - - it('puts values with number key', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTable(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - const table = hashTable.getTable(); - for (let i = min; i <= max; i++) { - expect(table[i].key).to.equal(i); - expect(table[i].value).to.equal(i); - } - }); - - it('puts values with string key', () => { - const hashTable = new HashTable(); - - expect(hashTable.put('1', 1)).to.equal(true); - expect(hashTable.put('10', 10)).to.equal(true); - expect(hashTable.put('100', 100)).to.equal(true); - expect(hashTable.put('1000', 1000)).to.equal(true); - - const table = hashTable.getTable(); - - expect(table[12].key).to.equal('1'); - expect(table[12].value).to.equal(1); - - expect(table[23].key).to.equal('10'); - expect(table[23].value).to.equal(10); - - expect(table[34].key).to.equal('100'); - expect(table[34].value).to.equal(100); - - expect(table[8].key).to.equal('1000'); - expect(table[8].value).to.equal(1000); - }); - - it('puts values with object key', () => { - const hashTable = new HashTable(); - - const myObjList = []; - for (let i = 1; i <= 5; i++) { - myObjList.push(new MyObj(i, i + 1)); - expect(hashTable.put(myObjList[i - 1], myObjList[i - 1])).to.equal(true); - } - - const table = hashTable.getTable(); - - expect(table[1].key).to.equal(myObjList[0]); - expect(table[1].value).to.equal(myObjList[0]); - - expect(table[3].key).to.equal(myObjList[1]); - expect(table[3].value).to.equal(myObjList[1]); - - expect(table[5].key).to.equal(myObjList[2]); - expect(table[5].value).to.equal(myObjList[2]); - - expect(table[7].key).to.equal(myObjList[3]); - expect(table[7].value).to.equal(myObjList[3]); - - expect(table[9].key).to.equal(myObjList[4]); - expect(table[9].value).to.equal(myObjList[4]); - }); - - it('does NOT handle collision, replaces values', () => { - const hashTable = new HashTable(); - - for (let i = 0; i < 5; i++) { - expect(hashTable.put(1, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(1); - }); - - it('removes elements', () => { - const min = 1; - const max = 5; - const size = max - min + 1; - const hashTable = new HashTable(); - - for (let i = min; i <= max; i++) { - expect(hashTable.put(i, i)).to.equal(true); - } - expect(hashTable.size()).to.equal(size); - - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(true); - } - - // elements do not exist - for (let i = min; i <= max; i++) { - expect(hashTable.remove(i)).to.equal(false); - } - - expect(hashTable.isEmpty()).to.equal(true); - }); - - it('returns toString primitive types', () => { - const hashTable = new HashTable(); - - expect(hashTable.toString()).to.equal(''); - - hashTable.put(1, 1); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]}'); - - hashTable.put(2, 2); - expect(hashTable.toString()).to.equal('{1 => [#1: 1]},{2 => [#2: 2]}'); - - hashTable.clear(); - expect(hashTable.toString()).to.equal(''); - }); - - it('returns toString primitive types', () => { - const hashTable = new HashTable(); - - hashTable.put('el1', 1); - expect(hashTable.toString()).to.equal('{36 => [#el1: 1]}'); - - hashTable.put('el2', 2); - expect(hashTable.toString()).to.equal('{0 => [#el2: 2]},{36 => [#el1: 1]}'); - }); - - it('returns toString objects', () => { - const hashTable = new HashTable(); - - let myObj = new MyObj(1, 2); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal('{1 => [#1|2: 1|2]}'); - - myObj = new MyObj(3, 4); - hashTable.put(myObj, myObj); - expect(hashTable.toString()).to.equal( - '{1 => [#1|2: 1|2]},{5 => [#3|4: 3|4]}' - ); - }); -}); diff --git a/test/ts/data-structures/heap.spec.ts b/test/ts/data-structures/heap.spec.ts deleted file mode 100644 index 6a543fcd..00000000 --- a/test/ts/data-structures/heap.spec.ts +++ /dev/null @@ -1,75 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { MinHeap, heapSort } from '../../../src/ts/index'; - -describe('Heap', () => { - let heap: MinHeap; - - beforeEach(() => { - heap = new MinHeap(); - }); - - it('starts empty MinHeap', () => { - expect(heap.size()).to.equal(0); - expect(heap.isEmpty()).to.equal(true); - }); - - it('inserts values in the MinHeap', () => { - const resultArray = []; - for (let i = 1; i < 10; i++) { - resultArray.push(i); - heap.insert(i); - expect(heap.getAsArray()).to.deep.equal(resultArray); - } - }); - - it('finds the min value from the MinHeap', () => { - const resultArray = []; - for (let i = 10; i >= 1; i--) { - resultArray.push(i); - heap.insert(i); - expect(heap.findMinimum()).to.equal(i); - } - }); - - it('performs heapify in the MinHeap', () => { - const resultArray = []; - for (let i = 10; i >= 1; i--) { - resultArray.push(i); - } - expect(heap.heapify(resultArray)).to.deep.equal(resultArray); - }); - - it('extracts the min value from the MinHeap', () => { - let resultArray = []; - for (let i = 1; i < 10; i++) { - resultArray.push(i); - heap.insert(i); - expect(heap.getAsArray()).to.deep.equal(resultArray); - } - - resultArray = [ - [], - [2, 4, 3, 8, 5, 6, 7, 9], - [3, 4, 6, 8, 5, 9, 7], - [4, 5, 6, 8, 7, 9], - [5, 7, 6, 8, 9], - [6, 7, 9, 8], - [7, 8, 9], - [8, 9], - [9], - [] - ]; - - for (let i = 1; i < 10; i++) { - expect(heap.extract()).to.equal(i); - expect(heap.getAsArray()).to.deep.equal(resultArray[i]); - } - }); - - it('Heap Sort', () => { - const array = [3, 2, 5, 6, 1, 7, 8, 9]; - - expect(heapSort(array)).to.deep.equal([1, 2, 3, 5, 6, 7, 8, 9]); - }); -}); diff --git a/test/ts/data-structures/linked-list.spec.ts b/test/ts/data-structures/linked-list.spec.ts deleted file mode 100644 index 116abbd9..00000000 --- a/test/ts/data-structures/linked-list.spec.ts +++ /dev/null @@ -1,330 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { LinkedList, util } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('LinkedList', () => { - let list: LinkedList; - let min: number; - let max: number; - - beforeEach(() => { - list = new LinkedList(util.defaultEquals); - min = 1; - max = 3; - }); - - function pushesElements() { - for (let i = min; i <= max; i++) { - list.push(i); - } - } - - function verifyList() { - let current = list.getHead(); - for (let i = min; i <= max && current; i++) { - expect(current).to.not.be.an('undefined'); - if (current) { - // TS strictNullChecks - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(i); - if (i < max) { - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - // TS strictNullChecks - expect(current.next.element).to.equal(i + 1); - } - } else { - expect(current.next).to.be.an('undefined'); - } - current = current.next; - } - } - } - - it('starts empty', () => { - expect(list.size()).to.equal(0); - expect(list.isEmpty()).to.equal(true); - expect(list.getHead()).to.be.an('undefined'); - }); - - it('pushes elements', () => { - pushesElements(); - verifyList(); - }); - - it('returns element at specific index: invalid position', () => { - // list is empty - expect(list.getElementAt(3)).to.be.an('undefined'); - }); - - it('returns element at specific index', () => { - let node; - - pushesElements(); - - for (let i = min; i <= max; i++) { - node = list.getElementAt(i - 1); - expect(node).to.not.be.an('undefined'); - if (node) { - expect(node.element).to.equal(i); - } - } - }); - - it('inserts elements first position empty list', () => { - const element = 1; - max = element; - expect(list.insert(element, 0)).to.equal(true); - verifyList(); - }); - - it('inserts elements first position not empty list', () => { - max = 2; - expect(list.insert(max, 0)).to.equal(true); - - expect(list.insert(min, 0)).to.equal(true); - - verifyList(); - }); - - it('inserts elements invalid position empty list', () => { - expect(list.insert(1, 1)).to.equal(false); - }); - - it('inserts elements invalid position not empty list', () => { - const element = 1; - expect(list.insert(element, 0)).to.equal(true); - expect(list.insert(element, 2)).to.equal(false); - }); - - it('inserts elements in the middle of list', () => { - expect(list.insert(3, 0)).to.equal(true); - expect(list.insert(1, 0)).to.equal(true); - expect(list.insert(2, 1)).to.equal(true); - verifyList(); - }); - - it('inserts elements at the end of list', () => { - max = 5; - - for (let i = min; i <= max; i++) { - expect(list.insert(i , i - 1)).to.equal(true); - } - - verifyList(); - }); - - it('returns index of elements', () => { - let index; - - pushesElements(); - - for (let i = min; i <= max; i++) { - index = list.indexOf(i); - expect(index).to.equal(i - 1); - } - - expect(list.indexOf(max + 2)).to.equal(-1); - }); - - it('removes valid elements', () => { - let element; - - pushesElements(); - - for (let i = min; i <= max; i++) { - element = list.remove(i); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - } - }); - - it('removes invalid elements', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.remove(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position empty list', () => { - let element; - - for (let i = min; i <= max; i++) { - element = list.removeAt(i - 1); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position not empty list', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.removeAt(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes first element list single element', () => { - const value = 1; - list.push(value); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(value); - - expect(list.getHead()).to.be.an('undefined'); - expect(list.isEmpty()).to.equal(true); - }); - - it('removes first element list multiple elements', () => { - pushesElements(); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(min); - - min = 2; - verifyList(); - }); - - it('removes element from middle of list', () => { - pushesElements(); // 1, 2, 3 - - const element = list.removeAt(1); // element 2 - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(2); - - // list needs to be [1, 3] - let current = list.getHead(); - - // element 1 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(1); - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - expect(current.next.element).to.equal(3); - current = current.next; - } - } - - // element 3 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(3); - expect(current.next).to.be.an('undefined'); - } - }); - - it('removes element from end of list', () => { - let element; - - pushesElements(); - - const maxIndex = max; - for (let i = maxIndex; i >= min; i--) { - element = list.removeAt(i - 1); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - max--; - verifyList(); - } - }); - - it('returns the head of the list', () => { - expect(list.getHead()).to.be.an('undefined'); - - list.push(1); - expect(list.getHead()).to.not.be.an('undefined'); - }); - - it('returns the correct size', () => { - expect(list.size()).to.equal(0); - - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.size()).to.equal(i); - } - - const size = max; - for (let i = min; i <= max; i++) { - list.remove(i); - expect(list.size()).to.equal(size - i); - } - - expect(list.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(list.isEmpty()).to.equal(true); - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.isEmpty()).to.equal(false); - } - - for (let i = min; i < max; i++) { - list.remove(i); - expect(list.isEmpty()).to.equal(false); - } - list.remove(max); - expect(list.isEmpty()).to.equal(true); - - pushesElements(); - expect(list.isEmpty()).to.equal(false); - - list.clear(); - expect(list.isEmpty()).to.equal(true); - }); - - it('clears the list', () => { - expect(list.size()).to.equal(0); - list.clear(); - expect(list.size()).to.equal(0); - pushesElements(); - expect(list.size()).to.greaterThan(0); - list.clear(); - expect(list.size()).to.equal(0); - }); - - it('returns toString primitive types', () => { - expect(list.toString()).to.equal(''); - - list.push(1); - expect(list.toString()).to.equal('1'); - - list.push(2); - expect(list.toString()).to.equal('1,2'); - - list.clear(); - expect(list.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const ds = new LinkedList(); - ds.push('el1'); - expect(ds.toString()).to.equal('el1'); - - ds.push('el2'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const ds = new LinkedList(); - expect(ds.toString()).to.equal(''); - - ds.push(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2'); - - ds.push(new MyObj(3, 4)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/data-structures/my-obj.ts b/test/ts/data-structures/my-obj.ts deleted file mode 100644 index ff633f2b..00000000 --- a/test/ts/data-structures/my-obj.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default class MyObj { - constructor(public el1: any, public el2: any) { } - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } -} - diff --git a/test/ts/data-structures/queue.spec.ts b/test/ts/data-structures/queue.spec.ts deleted file mode 100644 index 132f7280..00000000 --- a/test/ts/data-structures/queue.spec.ts +++ /dev/null @@ -1,168 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import Queue from '../../../src/ts/data-structures/queue'; - -describe('Queue', () => { - let queue: Queue; - - beforeEach(() => { - queue = new Queue(); - }); - - it('starts empty', () => { - expect(queue.size()).to.equal(0); - expect(queue.isEmpty()).to.equal(true); - }); - - it('enqueues elements', () => { - queue.enqueue(1); - expect(queue.size()).to.equal(1); - queue.enqueue(2); - expect(queue.size()).to.equal(2); - queue.enqueue(3); - expect(queue.size()).to.equal(3); - - expect(queue.isEmpty()).to.equal(false); - }); - - it('dequeue elements', () => { - queue.enqueue(1); - queue.enqueue(2); - queue.enqueue(3); - - expect(queue.dequeue()).to.equal(1); - expect(queue.dequeue()).to.equal(2); - expect(queue.dequeue()).to.equal(3); - expect(queue.dequeue()).to.equal(undefined); - }); - - it('implements FIFO logic', () => { - queue.enqueue(1); - expect(queue.peek()).to.equal(1); - queue.enqueue(2); - expect(queue.peek()).to.equal(1); - queue.enqueue(3); - expect(queue.peek()).to.equal(1); - - expect(queue.dequeue()).to.equal(1); - expect(queue.dequeue()).to.equal(2); - expect(queue.dequeue()).to.equal(3); - expect(queue.dequeue()).to.equal(undefined); - }); - - it('allows to peek at the front element in the queue without dequeuing it', () => { - expect(queue.peek()).to.equal(undefined); - - queue.enqueue(1); - expect(queue.peek()).to.equal(1); - - queue.enqueue(2); - expect(queue.peek()).to.equal(1); - - queue.dequeue(); - expect(queue.peek()).to.equal(2); - }); - - it('returns the correct size', () => { - expect(queue.size()).to.equal(0); - queue.enqueue(1); - expect(queue.size()).to.equal(1); - queue.enqueue(2); - expect(queue.size()).to.equal(2); - queue.enqueue(3); - expect(queue.size()).to.equal(3); - - queue.clear(); - expect(queue.isEmpty()).to.equal(true); - - queue.enqueue(1); - queue.enqueue(2); - queue.enqueue(3); - expect(queue.size()).to.equal(3); - - queue.dequeue(); - expect(queue.size()).to.equal(2); - queue.dequeue(); - expect(queue.size()).to.equal(1); - queue.dequeue(); - expect(queue.size()).to.equal(0); - queue.dequeue(); - expect(queue.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(queue.isEmpty()).to.equal(true); - queue.enqueue(1); - expect(queue.isEmpty()).to.equal(false); - queue.enqueue(2); - expect(queue.isEmpty()).to.equal(false); - queue.enqueue(3); - expect(queue.isEmpty()).to.equal(false); - - queue.clear(); - expect(queue.isEmpty()).to.equal(true); - - queue.enqueue(1); - queue.enqueue(2); - queue.enqueue(3); - expect(queue.isEmpty()).to.equal(false); - - queue.dequeue(); - expect(queue.isEmpty()).to.equal(false); - queue.dequeue(); - expect(queue.isEmpty()).to.equal(false); - queue.dequeue(); - expect(queue.isEmpty()).to.equal(true); - queue.dequeue(); - expect(queue.isEmpty()).to.equal(true); - }); - - it('clears the queue', () => { - queue.clear(); - expect(queue.isEmpty()).to.equal(true); - - queue.enqueue(1); - queue.enqueue(2); - expect(queue.isEmpty()).to.equal(false); - - queue.clear(); - expect(queue.isEmpty()).to.equal(true); - }); - - it('returns toString primitive types', () => { - expect(queue.toString()).to.equal(''); - - queue.enqueue(1); - expect(queue.toString()).to.equal('1'); - - queue.enqueue(2); - expect(queue.toString()).to.equal('1,2'); - - queue.clear(); - expect(queue.toString()).to.equal(''); - - const queueString = new Queue(); - queueString.enqueue('el1'); - expect(queueString.toString()).to.equal('el1'); - - queueString.enqueue('el2'); - expect(queueString.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - class MyObj { - constructor(public el1: any, public el2: any) {} - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } - } - const queueMyObj = new Queue(); - expect(queueMyObj.toString()).to.equal(''); - - queueMyObj.enqueue(new MyObj(1, 2)); - expect(queueMyObj.toString()).to.equal('1|2'); - - queueMyObj.enqueue(new MyObj(3, 4)); - expect(queueMyObj.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/data-structures/red-black-tree.spec.ts b/test/ts/data-structures/red-black-tree.spec.ts deleted file mode 100644 index d5091f86..00000000 --- a/test/ts/data-structures/red-black-tree.spec.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Colors } from './../../../src/ts/data-structures/models/red-black-node'; -import 'mocha'; -import { expect } from 'chai'; -import { RedBlackTree } from '../../../src/ts/index'; -import { RedBlackNode } from '../../../src/ts/data-structures/models/red-black-node'; - -describe('RedBlackTree', () => { - let tree: RedBlackTree; - - beforeEach(() => { - tree = new RedBlackTree(); - }); - - it('starts empty', () => { - expect(tree.getRoot()).to.equal(undefined); - }); - - it('inserts elements in the RedBlackTree', () => { - expect(tree.getRoot()).to.equal(undefined); - - let node; - - tree.insert(1); - assertNode(tree.getRoot(), 1, Colors.BLACK); - - tree.insert(2); - assertNode(tree.getRoot(), 1, Colors.BLACK); - assertNode(tree.getRoot().right, 2, Colors.RED); - - tree.insert(3); - assertNode(tree.getRoot(), 2, Colors.BLACK); - assertNode(tree.getRoot().right, 3, Colors.RED); - assertNode(tree.getRoot().left, 1, Colors.RED); - - tree.insert(4); - assertNode(tree.getRoot(), 2, Colors.BLACK); - assertNode(tree.getRoot().left, 1, Colors.BLACK); - assertNode(tree.getRoot().right, 3, Colors.BLACK); - assertNode(tree.getRoot().right.right, 4, Colors.RED); - - tree.insert(5); - assertNode(tree.getRoot(), 2, Colors.BLACK); - assertNode(tree.getRoot().left, 1, Colors.BLACK); - node = tree.getRoot().right; - assertNode(node, 4, Colors.BLACK); - assertNode(node.left, 3, Colors.RED); - assertNode(node.right, 5, Colors.RED); - - tree.insert(6); - assertNode(tree.getRoot(), 2, Colors.BLACK); - assertNode(tree.getRoot().left, 1, Colors.BLACK); - node = tree.getRoot().right; - assertNode(node, 4, Colors.RED); - assertNode(node.left, 3, Colors.BLACK); - assertNode(node.right, 5, Colors.BLACK); - assertNode(node.right.right, 6, Colors.RED); - - tree.insert(7); - assertNode(tree.getRoot(), 2, Colors.BLACK); - assertNode(tree.getRoot().left, 1, Colors.BLACK); - node = tree.getRoot().right; - assertNode(node, 4, Colors.RED); - assertNode(node.left, 3, Colors.BLACK); - assertNode(node.right, 6, Colors.BLACK); - assertNode(node.right.right, 7, Colors.RED); - assertNode(node.right.left, 5, Colors.RED); - - tree.insert(8); - assertNode(tree.getRoot(), 4, Colors.BLACK); - node = tree.getRoot().left; - assertNode(node, 2, Colors.RED); - assertNode(node.left, 1, Colors.BLACK); - assertNode(node.right, 3, Colors.BLACK); - node = tree.getRoot().right; - assertNode(node, 6, Colors.RED); - assertNode(node.left, 5, Colors.BLACK); - assertNode(node.right, 7, Colors.BLACK); - assertNode(node.right.right, 8, Colors.RED); - - tree.insert(9); - assertNode(tree.getRoot(), 4, Colors.BLACK); - node = tree.getRoot().left; - assertNode(node, 2, Colors.RED); - assertNode(node.left, 1, Colors.BLACK); - assertNode(node.right, 3, Colors.BLACK); - node = tree.getRoot().right; - assertNode(node, 6, Colors.RED); - assertNode(node.left, 5, Colors.BLACK); - assertNode(node.right, 8, Colors.BLACK); - assertNode(node.right.left, 7, Colors.RED); - assertNode(node.right.right, 9, Colors.RED); - - tree.insert(10); - assertNode(tree.getRoot(), 4, Colors.BLACK); - node = tree.getRoot().left; - assertNode(node, 2, Colors.BLACK); - assertNode(node.left, 1, Colors.BLACK); - assertNode(node.right, 3, Colors.BLACK); - node = tree.getRoot().right; - assertNode(node, 6, Colors.BLACK); - assertNode(node.left, 5, Colors.BLACK); - assertNode(node.right, 8, Colors.RED); - assertNode(node.right.left, 7, Colors.BLACK); - assertNode(node.right.right, 9, Colors.BLACK); - assertNode(node.right.right.right, 10, Colors.RED); - - }); - - function assertNode(node: RedBlackNode, key: number, color: Colors) { - expect(node.color).to.equal(color); - expect(node.key).to.equal(key); - } -}); diff --git a/test/ts/data-structures/set.spec.ts b/test/ts/data-structures/set.spec.ts deleted file mode 100644 index 7320cdfc..00000000 --- a/test/ts/data-structures/set.spec.ts +++ /dev/null @@ -1,352 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { Set } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('Set', () => { - let set: Set; - - beforeEach(() => { - set = new Set(); - }); - - it('starts empty', () => { - expect(set.size()).to.equal(0); - expect(set.isEmpty()).to.equal(true); - }); - - it('adds elements', () => { - for (let i = 1; i < 5; i++) { - set.add(i); - expect(set.size()).to.equal(i); - } - - expect(set.isEmpty()).to.equal(false); - }); - - it('does not allow duplicated elements', () => { - let expected = true; - for (let i = 1; i < 5; i++) { - expect(set.add(i)).to.equal(expected); - } - - expected = false; - for (let i = 1; i < 5; i++) { - expect(set.add(i)).to.equal(expected); - } - }); - - it('deletes elements', () => { - for (let i = 1; i < 5; i++) { - set.add(i); - } - - for (let i = 1; i < 5; i++) { - expect(set.delete(i)).to.equal(true); - } - - // elements do not exist - for (let i = 1; i < 5; i++) { - expect(set.delete(i)).to.equal(false); - } - - expect(set.isEmpty()).to.equal(true); - }); - - it('returns if element exists', () => { - for (let i = 1; i < 5; i++) { - set.add(i); - expect(set.has(i)).to.equal(true); - } - - for (let i = 1; i < 5; i++) { - expect(set.delete(i)).to.equal(true); - expect(set.has(i)).to.equal(false); - } - }); - - it('returns the correct size', () => { - expect(set.size()).to.equal(0); - - for (let i = 1; i < 5; i++) { - set.add(i); - expect(set.size()).to.equal(i); - } - - const max = 5; - for (let i = 1; i < max; i++) { - set.delete(i); - expect(set.size()).to.equal(max - i - 1); - } - - expect(set.size()).to.equal(0); - expect(set.isEmpty()).to.equal(true); - }); - - it('returns if it is empty', () => { - expect(set.isEmpty()).to.equal(true); - - for (let i = 1; i < 5; i++) { - set.add(i); - expect(set.isEmpty()).to.equal(false); - } - - for (let i = 1; i < 5; i++) { - set.delete(i); - expect(set.isEmpty()).to.equal(!(i < 4)); - } - - expect(set.size()).to.equal(0); - expect(set.isEmpty()).to.equal(true); - }); - - it('clears the set', () => { - set.clear(); - expect(set.isEmpty()).to.equal(true); - - set.add(1); - set.add(2); - - set.clear(); - expect(set.isEmpty()).to.equal(true); - }); - - function addValues(min: number, max: number) { - set = new Set(); - - for (let i = min; i <= max; i++) { - set.add(i); - } - - return set; - } - - it('union between empty sets', () => { - const set1 = new Set(); - const set2 = new Set(); - - let setResult = set1.union(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.union(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('union between equal sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(1, 5); - - let setResult = set1.union(set2); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.union(set1); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('union between different sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(6, 10); - - let setResult = set1.union(set2); - for (let i = 1; i <= 10; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.union(set1); - for (let i = 1; i <= 10; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('union between sets with common values', () => { - const set1 = addValues(1, 5); - const set2 = addValues(3, 6); - - let setResult = set1.union(set2); - for (let i = 1; i <= 6; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.union(set1); - for (let i = 1; i <= 6; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('intersection between empty sets', () => { - const set1 = new Set(); - const set2 = new Set(); - - let setResult = set1.intersection(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.intersection(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('intersection between equal sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(1, 5); - - let setResult = set1.intersection(set2); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.intersection(set1); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('intersection different sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(6, 10); - - let setResult = set1.intersection(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.intersection(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('intersection between sets with common values', () => { - const set1 = addValues(1, 5); - const set2 = addValues(3, 6); - - let setResult = set1.intersection(set2); - for (let i = 3; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.intersection(set1); - for (let i = 3; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('difference between empty sets', () => { - const set1 = new Set(); - const set2 = new Set(); - - let setResult = set1.difference(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.difference(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('difference between equal sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(1, 5); - - let setResult = set1.difference(set2); - expect(setResult.isEmpty()).to.equal(true); - - setResult = set2.difference(set1); - expect(setResult.isEmpty()).to.equal(true); - }); - - it('difference different sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(6, 10); - - let setResult = set1.difference(set2); - for (let i = 1; i <= 5; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.difference(set1); - for (let i = 6; i <= 10; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('difference between sets with common values', () => { - const set1 = addValues(1, 5); - const set2 = addValues(3, 6); - - let setResult = set1.difference(set2); - for (let i = 1; i <= 2; i++) { - expect(setResult.has(i)).to.equal(true); - } - - setResult = set2.difference(set1); - for (let i = 6; i <= 6; i++) { - expect(setResult.has(i)).to.equal(true); - } - }); - - it('isSubsetOf between empty sets', () => { - const set1 = new Set(); - const set2 = new Set(); - - expect(set1.isSubsetOf(set2)).to.equal(true); - expect(set2.isSubsetOf(set1)).to.equal(true); - }); - - it('isSubsetOf between equal sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(1, 5); - - expect(set1.isSubsetOf(set2)).to.equal(true); - expect(set2.isSubsetOf(set1)).to.equal(true); - }); - - it('isSubsetOf different sets', () => { - const set1 = addValues(1, 5); - const set2 = addValues(6, 10); - - expect(set1.isSubsetOf(set2)).to.equal(false); - expect(set2.isSubsetOf(set1)).to.equal(false); - }); - - it('isSubsetOf between sets with common values', () => { - const set1 = addValues(1, 8); - const set2 = addValues(3, 6); - expect(set1.isSubsetOf(set2)).to.equal(false); - expect(set2.isSubsetOf(set1)).to.equal(true); - - const set3 = addValues(1, 5); - const set4 = addValues(3, 6); - expect(set3.isSubsetOf(set4)).to.equal(false); - expect(set4.isSubsetOf(set3)).to.equal(false); - }); - - it('returns toString primitive types', () => { - expect(set.toString()).to.equal(''); - - set.add(1); - expect(set.toString()).to.equal('1'); - - set.add(2); - expect(set.toString()).to.equal('1,2'); - - set.clear(); - expect(set.toString()).to.equal(''); - }); - - it('returns toString primitive types: string', () => { - const ds = new Set(); - ds.add('el1'); - expect(ds.toString()).to.equal('el1'); - - ds.add('el2'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - const ds = new Set(); - expect(ds.toString()).to.equal(''); - - ds.add(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2'); - - ds.add(new MyObj(3, 4)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/data-structures/sorted-linked-list.spec.ts b/test/ts/data-structures/sorted-linked-list.spec.ts deleted file mode 100644 index 02634f72..00000000 --- a/test/ts/data-structures/sorted-linked-list.spec.ts +++ /dev/null @@ -1,341 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { SortedLinkedList, util } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('SortedLinkedList', () => { - let list: SortedLinkedList; - let min: number; - let max: number; - - beforeEach(() => { - list = new SortedLinkedList(); - min = 1; - max = 3; - }); - - function pushesElements() { - for (let i = max; i >= min; i--) { - list.push(i); - } - } - - function verifyList() { - let current = list.getHead(); - for (let i = min; i <= max && current; i++) { - expect(current).to.not.be.an('undefined'); - if (current) { - // TS strictNullChecks - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(i); - if (i < max) { - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - // TS strictNullChecks - expect(current.next.element).to.equal(i + 1); - } - } else { - expect(current.next).to.be.an('undefined'); - } - current = current.next; - } - } - } - - it('starts empty', () => { - expect(list.size()).to.equal(0); - expect(list.isEmpty()).to.equal(true); - expect(list.getHead()).to.be.an('undefined'); - }); - - it('pushes elements', () => { - pushesElements(); - verifyList(); - }); - - it('returns element at specific index: invalid position', () => { - // list is empty - expect(list.getElementAt(3)).to.be.an('undefined'); - }); - - it('returns element at specific index', () => { - let node; - - pushesElements(); - - for (let i = min; i <= max; i++) { - node = list.getElementAt(i - 1); - expect(node).to.not.be.an('undefined'); - if (node) { - expect(node.element).to.equal(i); - } - } - }); - - it('inserts elements first position empty list', () => { - const element = 1; - max = element; - expect(list.insert(element, 0)).to.equal(true); - verifyList(); - }); - - it('inserts elements first position not empty list', () => { - max = 2; - expect(list.insert(max)).to.equal(true); - - expect(list.insert(min, 0)).to.equal(true); - - verifyList(); - }); - - it('inserts elements invalid position empty list', () => { - // sorted list will ignore the index position - expect(list.insert(1, 1)).to.equal(true); - }); - - it('inserts elements invalid position not empty list', () => { - // sorted list will ignore the index position - const element = 1; - expect(list.insert(element, 0)).to.equal(true); - expect(list.insert(element, 2)).to.equal(true); - }); - - it('inserts elements in the middle of list', () => { - expect(list.insert(3, 0)).to.equal(true); - expect(list.insert(1, 0)).to.equal(true); - expect(list.insert(2, 1)).to.equal(true); - verifyList(); - }); - - it('inserts elements at the end of list', () => { - max = 5; - - for (let i = min; i <= max; i++) { - expect(list.insert(i , i - 1)).to.equal(true); - } - - verifyList(); - }); - - it('returns index of elements', () => { - let index; - - pushesElements(); - - for (let i = min; i <= max; i++) { - index = list.indexOf(i); - expect(index).to.equal(i - 1); - } - - expect(list.indexOf(max + 2)).to.equal(-1); - }); - - it('removes valid elements', () => { - let element; - - pushesElements(); - - for (let i = min; i <= max; i++) { - element = list.remove(i); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - } - }); - - it('removes invalid elements', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.remove(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position empty list', () => { - let element; - - for (let i = min; i <= max; i++) { - element = list.removeAt(i - 1); - expect(element).to.be.an('undefined'); - } - }); - - it('removes element invalid position not empty list', () => { - let element; - - pushesElements(); - - for (let i = max + 2; i <= max + 4; i++) { - element = list.removeAt(i); - expect(element).to.be.an('undefined'); - } - }); - - it('removes first element list single element', () => { - const value = 1; - list.push(value); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(value); - - expect(list.getHead()).to.be.an('undefined'); - expect(list.isEmpty()).to.equal(true); - }); - - it('removes first element list multiple elements', () => { - pushesElements(); - - const element = list.removeAt(0); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(min); - - min = 2; - verifyList(); - }); - - it('removes element from middle of list', () => { - pushesElements(); // 1, 2, 3 - - const element = list.removeAt(1); // element 2 - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(2); - - // list needs to be [1, 3] - let current = list.getHead(); - - // element 1 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(1); - expect(current.next).to.not.be.an('undefined'); - if (current.next) { - expect(current.next.element).to.equal(3); - current = current.next; - } - } - - // element 3 - expect(current).to.not.be.an('undefined'); - if (current) { - expect(current.element).to.not.be.an('undefined'); - expect(current.element).to.equal(3); - expect(current.next).to.be.an('undefined'); - } - }); - - it('removes element from end of list', () => { - let element; - - pushesElements(); - - const maxIndex = max; - for (let i = maxIndex; i >= min; i--) { - element = list.removeAt(i - 1); - expect(element).to.not.be.an('undefined'); - expect(element).to.equal(i); - max--; - verifyList(); - } - }); - - it('returns the head of the list', () => { - expect(list.getHead()).to.be.an('undefined'); - - list.push(1); - expect(list.getHead()).to.not.be.an('undefined'); - }); - - it('returns the correct size', () => { - expect(list.size()).to.equal(0); - - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.size()).to.equal(i); - } - - const size = max; - for (let i = min; i <= max; i++) { - list.remove(i); - expect(list.size()).to.equal(size - i); - } - - expect(list.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(list.isEmpty()).to.equal(true); - for (let i = min; i <= max; i++) { - list.push(i); - expect(list.isEmpty()).to.equal(false); - } - - for (let i = min; i < max; i++) { - list.remove(i); - expect(list.isEmpty()).to.equal(false); - } - list.remove(max); - expect(list.isEmpty()).to.equal(true); - - pushesElements(); - expect(list.isEmpty()).to.equal(false); - - list.clear(); - expect(list.isEmpty()).to.equal(true); - }); - - it('clears the list', () => { - expect(list.size()).to.equal(0); - list.clear(); - expect(list.size()).to.equal(0); - pushesElements(); - expect(list.size()).to.greaterThan(0); - list.clear(); - expect(list.size()).to.equal(0); - }); - - it('returns toString primitive types', () => { - expect(list.toString()).to.equal(''); - - list.push(1); - expect(list.toString()).to.equal('1'); - - list.push(2); - expect(list.toString()).to.equal('1,2'); - - list.clear(); - expect(list.toString()).to.equal(''); - }); - - function stringCompare(a: string, b: string): number { - return a.localeCompare(b); - } - - it('returns toString primitive types: string', () => { - - const ds = new SortedLinkedList(util.defaultEquals, stringCompare); - ds.push('el2'); - expect(ds.toString()).to.equal('el2'); - - ds.push('el1'); - expect(ds.toString()).to.equal('el1,el2'); - }); - - function myObjCompare(a: MyObj, b: MyObj): number { - return a.toString().localeCompare(b.toString()); - } - - it('returns toString objects', () => { - const ds = new SortedLinkedList(util.defaultEquals, myObjCompare); - expect(ds.toString()).to.equal(''); - - ds.push(new MyObj(3, 4)); - expect(ds.toString()).to.equal('3|4'); - - ds.push(new MyObj(1, 2)); - expect(ds.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/data-structures/stack-array.spec.ts b/test/ts/data-structures/stack-array.spec.ts deleted file mode 100644 index 0894d7de..00000000 --- a/test/ts/data-structures/stack-array.spec.ts +++ /dev/null @@ -1,180 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import StackArray from '../../../src/ts/data-structures/stack-array'; - -describe('StackArray', () => { - let stack: StackArray; - - beforeEach(() => { - stack = new StackArray(); - }); - - it('starts empty', () => { - expect(stack.size()).to.equal(0); - expect(stack.isEmpty()).to.equal(true); - }); - - it('pushes elements', () => { - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - expect(stack.isEmpty()).to.equal(false); - }); - - it('pops elements', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('implements LIFO logic', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('allows to peek at the top element in he stack without popping it', () => { - expect(stack.peek()).to.equal(undefined); - - stack.push(1); - expect(stack.peek()).to.equal(1); - - stack.push(2); - expect(stack.peek()).to.equal(2); - - stack.pop(); - expect(stack.peek()).to.equal(1); - }); - - it('returns the correct size', () => { - expect(stack.size()).to.equal(0); - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.size()).to.equal(2); - stack.pop(); - expect(stack.size()).to.equal(1); - stack.pop(); - expect(stack.size()).to.equal(0); - stack.pop(); - expect(stack.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(stack.isEmpty()).to.equal(true); - stack.push(1); - expect(stack.isEmpty()).to.equal(false); - stack.push(2); - expect(stack.isEmpty()).to.equal(false); - stack.push(3); - expect(stack.isEmpty()).to.equal(false); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('clears the stack', () => { - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('returns an Array', () => { - let stackArray = stack.toArray(); - expect(stackArray.length).to.equal(0); - - stack.push(1); - stack.push(2); - - stackArray = stack.toArray(); - expect(stackArray.length).to.equal(2); - - let i = 1; - stackArray.forEach(e => { - expect(e).to.equal(i); - i++; - }); - }); - - it('returns toString primitive types', () => { - expect(stack.toString()).to.equal(''); - - stack.push(1); - expect(stack.toString()).to.equal('1'); - - stack.push(2); - expect(stack.toString()).to.equal('1,2'); - - stack.clear(); - expect(stack.toString()).to.equal(''); - - const stackString = new StackArray(); - stackString.push('el1'); - expect(stackString.toString()).to.equal('el1'); - - stackString.push('el2'); - expect(stackString.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - - class MyObj { - constructor(public el1: any, public el2: any) { } - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } - } - const stackMyObj = new StackArray(); - expect(stackMyObj.toString()).to.equal(''); - - stackMyObj.push(new MyObj(1, 2)); - expect(stackMyObj.toString()).to.equal('1|2'); - - stackMyObj.push(new MyObj(3, 4)); - expect(stackMyObj.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/data-structures/stack-linked-list.spec.ts b/test/ts/data-structures/stack-linked-list.spec.ts deleted file mode 100644 index 9889fb17..00000000 --- a/test/ts/data-structures/stack-linked-list.spec.ts +++ /dev/null @@ -1,159 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { StackLinkedList } from '../../../src/ts/index'; -import MyObj from './my-obj'; - -describe('StackLinkedList', () => { - let stack: StackLinkedList; - - beforeEach(() => { - stack = new StackLinkedList(); - }); - - it('starts empty', () => { - expect(stack.size()).to.equal(0); - expect(stack.isEmpty()).to.equal(true); - }); - - it('pushes elements', () => { - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - expect(stack.isEmpty()).to.equal(false); - }); - - it('pops elements', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('implements LIFO logic', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('allows to peek at the top element in he stack without popping it', () => { - expect(stack.peek()).to.equal(undefined); - - stack.push(1); - expect(stack.peek()).to.equal(1); - - stack.push(2); - expect(stack.peek()).to.equal(2); - - stack.pop(); - expect(stack.peek()).to.equal(1); - }); - - it('returns the correct size', () => { - expect(stack.size()).to.equal(0); - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.size()).to.equal(2); - stack.pop(); - expect(stack.size()).to.equal(1); - stack.pop(); - expect(stack.size()).to.equal(0); - stack.pop(); - expect(stack.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(stack.isEmpty()).to.equal(true); - stack.push(1); - expect(stack.isEmpty()).to.equal(false); - stack.push(2); - expect(stack.isEmpty()).to.equal(false); - stack.push(3); - expect(stack.isEmpty()).to.equal(false); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('clears the stack', () => { - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - }); - - - it('returns toString primitive types', () => { - expect(stack.toString()).to.equal(''); - - stack.push(1); - expect(stack.toString()).to.equal('1'); - - stack.push(2); - expect(stack.toString()).to.equal('1,2'); - - stack.clear(); - expect(stack.toString()).to.equal(''); - - const stackString = new StackLinkedList(); - stackString.push('el1'); - expect(stackString.toString()).to.equal('el1'); - - stackString.push('el2'); - expect(stackString.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - - const stackMyObj = new StackLinkedList(); - expect(stackMyObj.toString()).to.equal(''); - - stackMyObj.push(new MyObj(1, 2)); - expect(stackMyObj.toString()).to.equal('1|2'); - - stackMyObj.push(new MyObj(3, 4)); - expect(stackMyObj.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/data-structures/stack.spec.ts b/test/ts/data-structures/stack.spec.ts deleted file mode 100644 index 731e586c..00000000 --- a/test/ts/data-structures/stack.spec.ts +++ /dev/null @@ -1,163 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import Stack from '../../../src/ts/data-structures/stack'; - -describe('Stack', () => { - let stack: Stack; - - beforeEach(() => { - stack = new Stack(); - }); - - it('starts empty', () => { - expect(stack.size()).to.equal(0); - expect(stack.isEmpty()).to.equal(true); - }); - - it('pushes elements', () => { - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - expect(stack.isEmpty()).to.equal(false); - }); - - it('pops elements', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('implements LIFO logic', () => { - stack.push(1); - stack.push(2); - stack.push(3); - - expect(stack.pop()).to.equal(3); - expect(stack.pop()).to.equal(2); - expect(stack.pop()).to.equal(1); - expect(stack.pop()).to.equal(undefined); - }); - - it('allows to peek at the top element in the stack without popping it', () => { - expect(stack.peek()).to.equal(undefined); - - stack.push(1); - expect(stack.peek()).to.equal(1); - - stack.push(2); - expect(stack.peek()).to.equal(2); - - stack.pop(); - expect(stack.peek()).to.equal(1); - }); - - it('returns the correct size', () => { - expect(stack.size()).to.equal(0); - stack.push(1); - expect(stack.size()).to.equal(1); - stack.push(2); - expect(stack.size()).to.equal(2); - stack.push(3); - expect(stack.size()).to.equal(3); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.size()).to.equal(2); - stack.pop(); - expect(stack.size()).to.equal(1); - stack.pop(); - expect(stack.size()).to.equal(0); - stack.pop(); - expect(stack.size()).to.equal(0); - }); - - it('returns if it is empty', () => { - expect(stack.isEmpty()).to.equal(true); - stack.push(1); - expect(stack.isEmpty()).to.equal(false); - stack.push(2); - expect(stack.isEmpty()).to.equal(false); - stack.push(3); - expect(stack.isEmpty()).to.equal(false); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - stack.push(3); - - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(false); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - stack.pop(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('clears the stack', () => { - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - - stack.push(1); - stack.push(2); - - stack.clear(); - expect(stack.isEmpty()).to.equal(true); - }); - - it('returns toString primitive types', () => { - expect(stack.toString()).to.equal(''); - - stack.push(1); - expect(stack.toString()).to.equal('1'); - - stack.push(2); - expect(stack.toString()).to.equal('1,2'); - - stack.clear(); - expect(stack.toString()).to.equal(''); - - const stackString = new Stack(); - stackString.push('el1'); - expect(stackString.toString()).to.equal('el1'); - - stackString.push('el2'); - expect(stackString.toString()).to.equal('el1,el2'); - }); - - it('returns toString objects', () => { - - class MyObj { - constructor(public el1: any, public el2: any) { } - toString() { - return `${this.el1.toString()}|${this.el2.toString()}`; - } - } - const stackMyObj = new Stack(); - expect(stackMyObj.toString()).to.equal(''); - - stackMyObj.push(new MyObj(1, 2)); - expect(stackMyObj.toString()).to.equal('1|2'); - - stackMyObj.push(new MyObj(3, 4)); - expect(stackMyObj.toString()).to.equal('1|2,3|4'); - }); -}); diff --git a/test/ts/others/balanced-symbols.spec.ts b/test/ts/others/balanced-symbols.spec.ts deleted file mode 100644 index 576432dd..00000000 --- a/test/ts/others/balanced-symbols.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { parenthesesChecker } from '../../../src/ts/others/balanced-symbols'; - -describe('Balanced Symbols', () => { - - it('empty to be falsy', () => { - expect(parenthesesChecker('')).to.equal(true); - }); - - it('{ to be falsy', () => { - expect(parenthesesChecker('{')).to.equal(false); - }); - - it('} to be falsy', () => { - expect(parenthesesChecker('}')).to.equal(false); - }); - - it('11 to be falsy', () => { - expect(parenthesesChecker('11')).to.equal(false); - }); - - it('{11 to be falsy', () => { - expect(parenthesesChecker('{11')).to.equal(false); - }); - - it('{([1])} to be falsy', () => { - expect(parenthesesChecker('{([1])}')).to.equal(false); - }); - - it('{([])} to be truthy', () => { - expect(parenthesesChecker('{([])}')).to.equal(true); - }); - - it('{{([][])}()} to be truthy', () => { - expect(parenthesesChecker('{{([][])}()}')).to.equal(true); - }); - - it('[{()] to be falsy', () => { - expect(parenthesesChecker('[{()]')).to.equal(false); - }); -}); diff --git a/test/ts/others/base-converter.spec.ts b/test/ts/others/base-converter.spec.ts deleted file mode 100644 index cec16bbe..00000000 --- a/test/ts/others/base-converter.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { baseConverter, decimalToBinary } from '../../../src/ts/others/base-converter'; - -describe('Base Converter', () => { - it('decimalToBinary 1 -> 1', () => { - expect(decimalToBinary(1)).to.equal('1'); - }); - - it('decimalToBinary 2 -> 11', () => { - expect(decimalToBinary(2)).to.equal('10'); - }); - - it('decimalToBinary 233 -> 11101001', () => { - expect(decimalToBinary(233)).to.equal('11101001'); - }); - - it('decimalToBinary 10 -> 1010', () => { - expect(decimalToBinary(10)).to.equal('1010'); - }); - - it('decimalToBinary 1000 -> 1111101000', () => { - expect(decimalToBinary(1000)).to.equal('1111101000'); - }); - - it('baseConverter 100345, 2 -> 11000011111111001', () => { - expect(baseConverter(100345, 2)).to.equal('11000011111111001'); - }); - - it('baseConverter 100345, 8 -> 303771', () => { - expect(baseConverter(100345, 8)).to.equal('303771'); - }); - - it('baseConverter 100345, 16 -> 187F9', () => { - expect(baseConverter(100345, 16)).to.equal('187F9'); - }); - - it('baseConverter 100345, 7 -> 565360', () => { - expect(baseConverter(100345, 7)).to.equal('565360'); - }); - - it('baseConverter 100345, 20 -> CAH5', () => { - expect(baseConverter(100345, 20)).to.equal('CAH5'); - }); - - it('baseConverter 100345, 35 -> 2BW0', () => { - expect(baseConverter(100345, 35)).to.equal('2BW0'); - }); - - it('baseConverter 100345, 36 -> 25FD', () => { - expect(baseConverter(100345, 36)).to.equal('25FD'); - }); - - it('baseConverter 100345, 37 -> ', () => { - expect(baseConverter(100345, 37)).to.equal(''); - }); -}); diff --git a/test/ts/others/factorial.spec.ts b/test/ts/others/factorial.spec.ts deleted file mode 100644 index d785d11c..00000000 --- a/test/ts/others/factorial.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { factorialIterative, factorial } from '../../../src/ts/index'; - -describe('Factorial', () => { - - it('Iterative Factorial', () => { - expect(factorialIterative(-1)).to.equal(undefined); - expect(factorialIterative(0)).to.equal(1); - expect(factorialIterative(1)).to.equal(1); - expect(factorialIterative(2)).to.equal(2); - expect(factorialIterative(3)).to.equal(6); - expect(factorialIterative(4)).to.equal(24); - expect(factorialIterative(5)).to.equal(120); - }); - - it('Recursive Factorial', () => { - expect(factorial(-1)).to.equal(undefined); - expect(factorial(0)).to.equal(1); - expect(factorial(1)).to.equal(1); - expect(factorial(2)).to.equal(2); - expect(factorial(3)).to.equal(6); - expect(factorial(4)).to.equal(24); - expect(factorial(5)).to.equal(120); - }); -}); diff --git a/test/ts/others/fibonacci.spec.ts b/test/ts/others/fibonacci.spec.ts deleted file mode 100644 index 27ad81f0..00000000 --- a/test/ts/others/fibonacci.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { fibonacci, fibonacciIterative, fibonacciMemoization } from '../../../src/ts/index'; - -describe('Fibonacci', () => { - - it('Fibonacci Recursive', () => { - expect(fibonacci(-1)).to.equal(0); - expect(fibonacci(0)).to.equal(0); - expect(fibonacci(1)).to.equal(1); - expect(fibonacci(2)).to.equal(1); - expect(fibonacci(3)).to.equal(2); - expect(fibonacci(4)).to.equal(3); - }); - - it('Fibonacci Iterative', () => { - expect(fibonacciIterative(-1)).to.equal(0); - expect(fibonacciIterative(0)).to.equal(0); - expect(fibonacciIterative(1)).to.equal(1); - expect(fibonacciIterative(2)).to.equal(1); - expect(fibonacciIterative(3)).to.equal(2); - expect(fibonacciIterative(4)).to.equal(3); - }); - - it('Fibonacci with Memoization', () => { - expect(fibonacciMemoization(-1)).to.equal(0); - expect(fibonacciMemoization(0)).to.equal(0); - expect(fibonacciMemoization(1)).to.equal(1); - expect(fibonacciMemoization(2)).to.equal(1); - expect(fibonacciMemoization(3)).to.equal(2); - expect(fibonacciMemoization(4)).to.equal(3); - }); - -}); diff --git a/test/ts/others/hanoi.spec.ts b/test/ts/others/hanoi.spec.ts deleted file mode 100644 index 70f43fcd..00000000 --- a/test/ts/others/hanoi.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { hanoi, hanoiStack } from '../../../src/ts/others/hanoi'; - -describe('Tower of Hanoi', () => { - - it('Hanoi', () => { - for (let i = 0; i < 10; i++) { - const result = hanoi(i, 'a', 'b', 'c'); - expect(result.length).to.equal(2 ** i - 1); - } - }); - - it('Hanoi with Stack', () => { - for (let i = 0; i < 10; i++) { - const result = hanoiStack(i); - expect(result.length).to.equal(2 ** i - 1); - } - }); -}); diff --git a/test/ts/others/hot-potato.spec.ts b/test/ts/others/hot-potato.spec.ts deleted file mode 100644 index 7ac9b827..00000000 --- a/test/ts/others/hot-potato.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { hotPotato } from '../../../src/ts/others/hot-potato'; -import 'mocha'; -import { expect } from 'chai'; - -describe('Hot Potato with Queue', () => { - - it('Hot potato game', () => { - const names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl']; - expect(hotPotato(names, 6).winner).to.equal('Ingrid'); - expect(hotPotato(names, 7).winner).to.equal('John'); - expect(hotPotato(names, 8).winner).to.equal('Jack'); - expect(hotPotato(names, 9).winner).to.equal('Ingrid'); - expect(hotPotato(names, 10).winner).to.equal('Carl'); - }); - -}); diff --git a/test/ts/others/palindrome-checker.spec.ts b/test/ts/others/palindrome-checker.spec.ts deleted file mode 100644 index 82451113..00000000 --- a/test/ts/others/palindrome-checker.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import 'mocha'; -import { expect } from 'chai'; -import { palindromeChecker } from '../../../src/ts/others/palindrome-checker'; - -describe('Palindrome', () => { - - it('Palindrome Checker', () => { - expect(palindromeChecker('')).to.equal(false); - expect(palindromeChecker('a')).to.equal(true); - expect(palindromeChecker('aa')).to.equal(true); - expect(palindromeChecker('aba')).to.equal(true); - expect(palindromeChecker('ab')).to.equal(false); - expect(palindromeChecker('kayak')).to.equal(true); - expect(palindromeChecker('radar')).to.equal(true); - expect(palindromeChecker('level')).to.equal(true); - expect(palindromeChecker('Was it a car or a cat I saw')).to.equal(true); - expect(palindromeChecker('Step on no pets')).to.equal(true); - expect(palindromeChecker('Able was I ere I saw Elba')).to.equal(true); - }); -}); diff --git a/tsconfig.json b/tsconfig.json index 0acebfa5..3cafd3f4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,57 +1,16 @@ { - "compilerOptions": { - /* Basic Options */ - "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "module": "es2015", /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["es2017"], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/ts", /* Redirect output structure to the directory. */ - // "rootDir": "./src/ts", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - // "strict": true /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - "noUnusedLocals": true, /* Report errors on unused locals. */ - "noUnusedParameters": true, /* Report errors on unused parameters. */ - "noImplicitReturns": true /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - - /* Source Map Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - }, - "exclude": ["node_modules", "dist"], - "include": ["src/ts/**/*"] -} + "compilerOptions": { + "target": "ESNext", + "module": "CommonJS", + "lib": ["ESNext"], + //"outDir": "dist", + "rootDir": "src", + // "strict": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + }, + "include": ["src/**/*"], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 449d62a0..00000000 --- a/tslint.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "rules": { - "arrow-return-shorthand": true, - "callable-types": true, - "class-name": true, - "comment-format": [ - true, - "check-space" - ], - "curly": true, - "eofline": true, - "forin": true, - "import-blacklist": [ - true, - "rxjs" - ], - "import-spacing": true, - "indent": [ - true, - "spaces" - ], - "interface-over-type-literal": true, - "label-position": true, - "max-line-length": [ - true, - 140 - ], - "member-access": false, - "member-ordering": [ - true, - { - "order": [ - "static-field", - "instance-field", - "static-method", - "instance-method" - ] - } - ], - "no-arg": true, - "no-bitwise": true, - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], - "no-construct": true, - "no-debugger": true, - "no-duplicate-super": true, - "no-empty": false, - "no-empty-interface": true, - "no-eval": true, - "no-inferrable-types": [ - true, - "ignore-params" - ], - "no-misused-new": true, - "no-non-null-assertion": true, - "no-shadowed-variable": true, - "no-string-literal": false, - "no-string-throw": true, - "no-switch-case-fall-through": true, - "no-trailing-whitespace": true, - "no-unnecessary-initializer": true, - "no-unused-expression": true, - "no-use-before-declare": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, - "one-line": [ - true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" - ], - "prefer-const": true, - "quotemark": [ - true, - "single" - ], - "radix": true, - "semicolon": [ - true, - "always" - ], - "triple-equals": [ - true, - "allow-null-check" - ], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - } - ], - "typeof-compare": true, - "unified-signatures": true, - "variable-name": false, - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ] - } -} diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 6d033ef4..00000000 --- a/webpack.config.js +++ /dev/null @@ -1,56 +0,0 @@ -// @ts-check -/* eslint-disable */ -const webpack = require('webpack'); -const UglifyJsPlugin = require('uglifyjs-webpack-plugin');; -const path = require('path'); -const env = require('yargs').argv.env; - -let libraryName = 'PacktDataStructuresAlgorithms'; - -let plugins = [], - outputFile; - -if (env === 'build') { - // plugins.push(new UglifyJsPlugin({ minimize: true })); - outputFile = libraryName + '.min.js'; -} else { - outputFile = libraryName + '.js'; -} - -const config = { - entry: __dirname + '/src/js/index.js', - devtool: 'source-map', - output: { - path: __dirname + '/examples', - filename: outputFile, - library: libraryName, - libraryTarget: 'umd', - umdNamedDefine: true - }, - module: { - rules: [ - { - test: /(\.jsx|\.js)$/, - loader: 'babel-loader', - exclude: /(node_modules|bower_components)/ - } - ] - }, - resolve: { - modules: [path.resolve('./node_modules'), path.resolve('./src/js')], - extensions: ['.json', '.js'] - }, - optimization: { - minimizer: [ - // we specify a custom UglifyJsPlugin here to get source maps in production - new UglifyJsPlugin({ - cache: true, - parallel: true, - sourceMap: true - }) - ] - } - // plugins: plugins -}; - -module.exports = config;