├── .eslintrc.json
├── .gitignore
├── .travis.yml
├── .vscode
├── extensions.json
├── launch.json
├── settings.json
└── tasks.json
├── .vscodeignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── coverconfig.json
├── doc
├── navigation.gif
├── sample.gif
└── table-mode-status.png
├── e2e
└── e2e.code-workspace
├── icons
└── icon.png
├── package-lock.json
├── package.json
├── src
├── commands.ts
├── configuration.ts
├── context.ts
├── extension.ts
├── ttMarkdown.ts
├── ttOrg.ts
├── ttTable.ts
└── utils.ts
├── test
├── commands.test.ts
├── index.ts
├── runTest.ts
├── table-navigator.test.ts
├── ttMarkdown.test.ts
├── ttOrg.test.ts
└── ttTable.test.ts
└── tsconfig.json
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "parser": "@typescript-eslint/parser",
4 | "parserOptions": {
5 | "ecmaVersion": 6,
6 | "sourceType": "module"
7 | },
8 | "plugins": [
9 | "@typescript-eslint"
10 | ],
11 | "rules": {
12 | "@typescript-eslint/class-name-casing": "warn",
13 | "@typescript-eslint/semi": "warn",
14 | "brace-style": "error",
15 | "curly": ["error", "all"],
16 | "eqeqeq": "warn",
17 | "no-throw-literal": "warn",
18 | "quotes": ["error", "single"],
19 | "semi": "error"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | node_modules
3 | .vscode-test/
4 | *.vsix
5 |
6 | .DS_Store
7 | coverage/
8 | e2e/*
9 | !e2e/e2e.code-workspace
10 |
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | os:
3 | - osx
4 | - linux
5 | node_js: 10
6 |
7 | install:
8 | - |
9 | if [ $TRAVIS_OS_NAME == "linux" ]; then
10 | export DISPLAY=':99.0'
11 | /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
12 | fi
13 |
14 | script:
15 | - npm install
16 | - npm run vscode:prepublish
17 | - npm run lint
18 | - npm test --silent
19 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See http://go.microsoft.com/fwlink/?LinkId=827846
3 | // for the documentation about the extensions.json format
4 | "recommendations": [
5 | "eg2.tslint"
6 | ]
7 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | // A launch configuration that compiles the extension and then opens it inside a new window
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | {
6 | "version": "0.2.0",
7 | "configurations": [
8 | {
9 | "name": "Extension",
10 | "type": "extensionHost",
11 | "request": "launch",
12 | "runtimeExecutable": "${execPath}",
13 | "args": [
14 | "--extensionDevelopmentPath=${workspaceFolder}"
15 | ],
16 | "outFiles": [
17 | "${workspaceFolder}/out/**/*.js"
18 | ],
19 | "preLaunchTask": "npm: watch"
20 | },
21 | {
22 | "name": "Extension Tests",
23 | "type": "extensionHost",
24 | "request": "launch",
25 | "runtimeExecutable": "${execPath}",
26 | "args": [
27 | "--extensionDevelopmentPath=${workspaceFolder}",
28 | "--extensionTestsPath=${workspaceFolder}/out/test"
29 | ],
30 | "outFiles": [
31 | "${workspaceFolder}/out/test/**/*.js"
32 | ],
33 | "preLaunchTask": "npm: watch"
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "out": false // set this to true to hide the "out" folder with the compiled JS files
5 | },
6 | "search.exclude": {
7 | "out": true // set this to false to include "out" folder in search results
8 | },
9 | "markdownlint.config": {
10 | "MD013": false,
11 | "MD024": false
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | // See https://go.microsoft.com/fwlink/?LinkId=733558
2 | // for the documentation about the tasks.json format
3 | {
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "type": "npm",
8 | "script": "watch",
9 | "problemMatcher": "$tsc-watch",
10 | "isBackground": true,
11 | "presentation": {
12 | "reveal": "never"
13 | },
14 | "group": {
15 | "kind": "build",
16 | "isDefault": true
17 | }
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .vscode/**
2 | .vscode-test/**
3 | out/test/**
4 | out/**/*.map
5 | src/**
6 | .gitignore
7 | tsconfig.json
8 | vsc-extension-quickstart.md
9 | tslint.json
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7 |
8 | ## [Unreleased]
9 |
10 | ### Changed
11 |
12 | - Fixed tests when run from command line.
13 |
14 | ## [0.1.5] - 2018-05-03
15 |
16 | ### Added
17 |
18 | - Command `text-tables.nextRow` (`Text Tables: Next row` in command pallete) for jumping on next row and creating new rows if needed.
19 |
20 | ### Changed
21 |
22 | - Command `text-tables.gotoNextCell` (`Text Tables: Go to next cell` in command pallete) inserts new row when applied in last data cell of table.
23 | - Fixed markdown parser for tables with separator row where separator row has less columns than other row (#33).
24 |
25 | ## [0.1.0] - 2018-04-16
26 |
27 | ### Changed
28 |
29 | - Codebase refactor.
30 | - Preview status removed from extension.
31 |
32 | ## [0.0.9] - 2018-04-14
33 |
34 | ### Added
35 |
36 | - Command `Move row down` to move row down in table mode.
37 | - Command `Move row up` to move row up in table mode.
38 | - Command `Move column right` to move column right in table mode.
39 | - Command `Move column left` to move column left in table mode.
40 |
41 | ## [0.0.8] - 2018-04-14
42 |
43 | ### Changed
44 |
45 | - Fixed `Create table` command for markdown (#24).
46 |
47 | ## [0.0.7] - 2018-04-13
48 |
49 | ### Changed
50 |
51 | - Table mode made local to editor (#22).
52 |
53 | ## [0.0.6] - 2018-04-12
54 |
55 | ### Changed
56 |
57 | - Shortcuts readme update
58 |
59 | ## [0.0.5] - 2018-04-12
60 |
61 | ### Added
62 |
63 | - Command `text-tables.enable` (`Text Tables: Enable` in command pallete) for activating extension in any file.
64 | - Command `text-tables.clearCell` (`Text Tables: Clear cell` in command pallete) for clearing cell under cursor.
65 |
66 | ## [0.0.4] - 2018-04-11
67 |
68 | ### Added
69 |
70 | - Setting `text-tables.showStatus` to control whether status item for mode should be visible.
71 |
72 | ## [0.0.3] - 2018-04-07
73 |
74 | ### Changed
75 |
76 | - Navigation now via `Tab` and `Shift`+`Tab` skips separator rows
77 |
78 | ## [0.0.2] - 2018-04-05
79 |
80 | ### Added
81 |
82 | - `Create table` command.
83 |
84 | ### Changed
85 |
86 | - Linting settings.
87 | - Readme file updated with additional badges.
88 |
89 | ## [0.0.1] - 2018-03-24
90 |
91 | - Initial release
92 |
93 | [Unreleased]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.1.5...HEAD
94 | [0.1.5]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.1.0...v0.1.5
95 | [0.1.0]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.9...v0.1.0
96 | [0.0.9]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.8...v0.0.9
97 | [0.0.8]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.7...v0.0.8
98 | [0.0.7]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.6...v0.0.7
99 | [0.0.6]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.5...v0.0.6
100 | [0.0.5]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.4...v0.0.5
101 | [0.0.4]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.3...v0.0.4
102 | [0.0.3]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.2...v0.0.3
103 | [0.0.2]: https://github.com/rpeshkov/vscode-text-tables/compare/v0.0.1...v0.0.2
104 | [0.0.1]: https://github.com/rpeshkov/vscode-text-tables/releases/tag/v0.0.1
105 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at peshkovroman@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute to Text Tables
2 |
3 | ## Reporting issues
4 |
5 | In case if you want to report about some issue in functionality of extension or propose new feature, please follow this simple rules:
6 |
7 | * **Ensure that the issue was not raised before** by searching on GitHub in [Issues][issues]. If you found already existing issue, make relevant comments or add your reaction to the issue.
8 |
9 | * **Provide clear information about the issue** by filling following fields:
10 |
11 | * VSCode version
12 | * Text tables extension version
13 | * Information about other extensions installed
14 | * Reproducible steps that cause the issue
15 | * What you expected to see and what you saw instead
16 |
17 | ## Providing patches
18 |
19 | * In case if you want to fix specific issue, **be sure that the issue was assigned to you**. In that case there won't be confusions that 2 or more different people were working on the issue.
20 |
21 | * **Don't provide cosmetic patches** without opening an issue prior to this. If there won't be referenced issue, pull request will be rejected.
22 |
23 | **Thank you!**
24 |
25 | [issues]: https://github.com/rpeshkov/text-tables/issues/
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Roman Peshkov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Text Tables
2 |
3 | [![version][version-badge]][CHANGELOG]
4 | [![license][license-badge]][LICENSE]
5 | [](https://travis-ci.org/rpeshkov/vscode-text-tables)
6 |
7 | 
8 |
9 | VSCode extension that brings the power of Emacs table editing.
10 |
11 | 
12 |
13 | ## Features
14 |
15 | - Tables reformat
16 | - Easy table cells navigation
17 | - Support for [org](https://orgmode.org/manual/Built_002din-table-editor.html#Built_002din-table-editor) and [markdown](https://help.github.com/articles/organizing-information-with-tables/) tables
18 |
19 | ## Activation
20 |
21 | Extension is automatically activated when you open markdown or org file. If you want to use this extension in any other file, just trigger `Text Tables: Enable` command in command pallete.
22 |
23 | ## Commands
24 |
25 | Extension provides several commands that are available in the Command Palette:
26 |
27 | - `Text Tables: Enable` - enable extension.
28 | - `Text Tables: Create table` - create new table in cursor position.
29 | - `Text Tables: Format under cursor` - reformat the table under cursor.
30 | - `Text Tables: Enter table mode` - enter [table mode](#table-mode).
31 | - `Text Tables: Exit table mode` - exit [table mode](#table-mode).
32 | - `Text Tables: Go to next cell` - switch to next cell in current table.
33 | - `Text Tables: Go to previous cell` - switch to previous cell in current table.
34 | - `Text Tables: Clear cell` - clear cell under cursor.
35 |
36 | You can access all of the above commands from the command pallete (Ctrl+Shift+p or Cmd+Shift+p)
37 |
38 | ## Table mode
39 |
40 | Table mode is the mode where some of the default keybindings have another action assigned.
41 |
42 | To enter table mode you may execute command `Text Tables: Enter table mode` from command palette or press Ctrl+q Ctrl+q shortcut to toggle mode. To control whether you're in table mode or not, see the icon in the status bar of Visual Studio Code:
43 |
44 | 
45 |
46 | When in table mode, Tab and Shift+Tab keybindings will navigate next/previous cell accordingly.
47 |
48 | 
49 |
50 | ## Keybindings
51 |
52 | - Ctrl+q f - format table under cursor.
53 | - Ctrl+q space - clear cell under cursor.
54 | - Ctrl+q Ctrl+q - toggle table mode.
55 |
56 | ### In table mode
57 |
58 | - Tab - navigate to the next cell in table.
59 | - Shift+Tab - navigate to the previous cell in table.
60 |
61 | ### Custom keybindings
62 |
63 | Extension introduces additional `tableMode` when-clause that you may use to define your own keybindings when in table mode.
64 |
65 | Sample keybinding:
66 |
67 | ```json
68 | {
69 | "key": "tab",
70 | "command": "text-tables.gotoNextCell",
71 | "when": "tableMode"
72 | }
73 | ```
74 |
75 | ## Settings
76 |
77 | This extension introduces some settings that you may setup in your user settings or workspace settings.
78 |
79 | Available settings:
80 |
81 | - `text-tables.mode` - sets the type of tables. Valid values are: `org` and `markdown`.
82 | - `text-tables.showStatus` - controls whether to show or not status item for table mode.
83 |
84 | ## Contribution
85 |
86 | All contributions are welcome.
87 |
88 | If you found a bug or want to propose new feature for the extension, feel free to create an issue.
89 |
90 | [CHANGELOG]: ./CHANGELOG.md
91 | [LICENSE]: ./LICENSE
92 | [version-badge]: https://img.shields.io/badge/version-0.1.5-blue.svg
93 | [license-badge]: https://img.shields.io/badge/license-MIT-blue.svg
94 |
--------------------------------------------------------------------------------
/coverconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": true,
3 | "relativeSourcePath": "../src",
4 | "relativeCoverageDir": "../../coverage",
5 | "ignorePatterns": [
6 | "**/node_modules/**"
7 | ],
8 | "includePid": false,
9 | "reports": [
10 | "html",
11 | "lcov",
12 | "text-summary"
13 | ],
14 | "verbose": false
15 | }
16 |
--------------------------------------------------------------------------------
/doc/navigation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rpeshkov/vscode-text-tables/e6502bfc5765286a7a8819ffbb5cf819be23b32f/doc/navigation.gif
--------------------------------------------------------------------------------
/doc/sample.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rpeshkov/vscode-text-tables/e6502bfc5765286a7a8819ffbb5cf819be23b32f/doc/sample.gif
--------------------------------------------------------------------------------
/doc/table-mode-status.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rpeshkov/vscode-text-tables/e6502bfc5765286a7a8819ffbb5cf819be23b32f/doc/table-mode-status.png
--------------------------------------------------------------------------------
/e2e/e2e.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": "."
5 | }
6 | ],
7 | "settings": {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rpeshkov/vscode-text-tables/e6502bfc5765286a7a8819ffbb5cf819be23b32f/icons/icon.png
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vscode-text-tables",
3 | "version": "0.1.5",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@babel/code-frame": {
8 | "version": "7.8.3",
9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
10 | "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
11 | "dev": true,
12 | "requires": {
13 | "@babel/highlight": "^7.8.3"
14 | }
15 | },
16 | "@babel/helper-validator-identifier": {
17 | "version": "7.9.5",
18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
19 | "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
20 | "dev": true
21 | },
22 | "@babel/highlight": {
23 | "version": "7.9.0",
24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
25 | "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
26 | "dev": true,
27 | "requires": {
28 | "@babel/helper-validator-identifier": "^7.9.0",
29 | "chalk": "^2.0.0",
30 | "js-tokens": "^4.0.0"
31 | }
32 | },
33 | "@types/color-name": {
34 | "version": "1.1.1",
35 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
36 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
37 | "dev": true
38 | },
39 | "@types/eslint-visitor-keys": {
40 | "version": "1.0.0",
41 | "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
42 | "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
43 | "dev": true
44 | },
45 | "@types/events": {
46 | "version": "3.0.0",
47 | "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
48 | "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
49 | "dev": true
50 | },
51 | "@types/glob": {
52 | "version": "7.1.1",
53 | "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
54 | "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
55 | "dev": true,
56 | "requires": {
57 | "@types/events": "*",
58 | "@types/minimatch": "*",
59 | "@types/node": "*"
60 | }
61 | },
62 | "@types/json-schema": {
63 | "version": "7.0.4",
64 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz",
65 | "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==",
66 | "dev": true
67 | },
68 | "@types/minimatch": {
69 | "version": "3.0.3",
70 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
71 | "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
72 | "dev": true
73 | },
74 | "@types/mocha": {
75 | "version": "7.0.2",
76 | "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz",
77 | "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==",
78 | "dev": true
79 | },
80 | "@types/node": {
81 | "version": "7.10.11",
82 | "resolved": "https://registry.npmjs.org/@types/node/-/node-7.10.11.tgz",
83 | "integrity": "sha512-uEqP1HlJFhsgD8DOBFdC72/5selvor0mzdQY97zlyo8Q6qPl849cFBWkNpgTXw3jIvb7iNyWsId51/A8HYKzbQ==",
84 | "dev": true
85 | },
86 | "@types/vscode": {
87 | "version": "1.45.1",
88 | "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.45.1.tgz",
89 | "integrity": "sha512-0NO9qrrEJBO8FsqHCrFMgR2suKnwCsKBWvRSb2OzH5gs4i3QO5AhEMQYrSzDbU/wLPt7N617/rN9lPY213gmwg==",
90 | "dev": true
91 | },
92 | "@typescript-eslint/eslint-plugin": {
93 | "version": "2.34.0",
94 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz",
95 | "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==",
96 | "dev": true,
97 | "requires": {
98 | "@typescript-eslint/experimental-utils": "2.34.0",
99 | "functional-red-black-tree": "^1.0.1",
100 | "regexpp": "^3.0.0",
101 | "tsutils": "^3.17.1"
102 | }
103 | },
104 | "@typescript-eslint/experimental-utils": {
105 | "version": "2.34.0",
106 | "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz",
107 | "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==",
108 | "dev": true,
109 | "requires": {
110 | "@types/json-schema": "^7.0.3",
111 | "@typescript-eslint/typescript-estree": "2.34.0",
112 | "eslint-scope": "^5.0.0",
113 | "eslint-utils": "^2.0.0"
114 | }
115 | },
116 | "@typescript-eslint/parser": {
117 | "version": "2.34.0",
118 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz",
119 | "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==",
120 | "dev": true,
121 | "requires": {
122 | "@types/eslint-visitor-keys": "^1.0.0",
123 | "@typescript-eslint/experimental-utils": "2.34.0",
124 | "@typescript-eslint/typescript-estree": "2.34.0",
125 | "eslint-visitor-keys": "^1.1.0"
126 | }
127 | },
128 | "@typescript-eslint/typescript-estree": {
129 | "version": "2.34.0",
130 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz",
131 | "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==",
132 | "dev": true,
133 | "requires": {
134 | "debug": "^4.1.1",
135 | "eslint-visitor-keys": "^1.1.0",
136 | "glob": "^7.1.6",
137 | "is-glob": "^4.0.1",
138 | "lodash": "^4.17.15",
139 | "semver": "^7.3.2",
140 | "tsutils": "^3.17.1"
141 | },
142 | "dependencies": {
143 | "debug": {
144 | "version": "4.1.1",
145 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
146 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
147 | "dev": true,
148 | "requires": {
149 | "ms": "^2.1.1"
150 | }
151 | },
152 | "ms": {
153 | "version": "2.1.2",
154 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
155 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
156 | "dev": true
157 | }
158 | }
159 | },
160 | "acorn": {
161 | "version": "7.2.0",
162 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
163 | "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
164 | "dev": true
165 | },
166 | "acorn-jsx": {
167 | "version": "5.2.0",
168 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
169 | "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
170 | "dev": true
171 | },
172 | "agent-base": {
173 | "version": "4.3.0",
174 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
175 | "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
176 | "dev": true,
177 | "requires": {
178 | "es6-promisify": "^5.0.0"
179 | }
180 | },
181 | "ajv": {
182 | "version": "6.12.2",
183 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
184 | "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
185 | "dev": true,
186 | "requires": {
187 | "fast-deep-equal": "^3.1.1",
188 | "fast-json-stable-stringify": "^2.0.0",
189 | "json-schema-traverse": "^0.4.1",
190 | "uri-js": "^4.2.2"
191 | }
192 | },
193 | "ansi-escapes": {
194 | "version": "4.3.1",
195 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
196 | "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
197 | "dev": true,
198 | "requires": {
199 | "type-fest": "^0.11.0"
200 | },
201 | "dependencies": {
202 | "type-fest": {
203 | "version": "0.11.0",
204 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
205 | "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
206 | "dev": true
207 | }
208 | }
209 | },
210 | "ansi-regex": {
211 | "version": "5.0.0",
212 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
213 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
214 | "dev": true
215 | },
216 | "ansi-styles": {
217 | "version": "3.2.1",
218 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
219 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
220 | "dev": true,
221 | "requires": {
222 | "color-convert": "^1.9.0"
223 | }
224 | },
225 | "anymatch": {
226 | "version": "3.1.1",
227 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
228 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
229 | "dev": true,
230 | "requires": {
231 | "normalize-path": "^3.0.0",
232 | "picomatch": "^2.0.4"
233 | }
234 | },
235 | "argparse": {
236 | "version": "1.0.10",
237 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
238 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
239 | "dev": true,
240 | "requires": {
241 | "sprintf-js": "~1.0.2"
242 | }
243 | },
244 | "astral-regex": {
245 | "version": "1.0.0",
246 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
247 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
248 | "dev": true
249 | },
250 | "balanced-match": {
251 | "version": "1.0.0",
252 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
253 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
254 | "dev": true
255 | },
256 | "binary-extensions": {
257 | "version": "2.0.0",
258 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
259 | "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
260 | "dev": true
261 | },
262 | "brace-expansion": {
263 | "version": "1.1.11",
264 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
265 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
266 | "dev": true,
267 | "requires": {
268 | "balanced-match": "^1.0.0",
269 | "concat-map": "0.0.1"
270 | }
271 | },
272 | "braces": {
273 | "version": "3.0.2",
274 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
275 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
276 | "dev": true,
277 | "requires": {
278 | "fill-range": "^7.0.1"
279 | }
280 | },
281 | "browser-stdout": {
282 | "version": "1.3.1",
283 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
284 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
285 | "dev": true
286 | },
287 | "callsite": {
288 | "version": "1.0.0",
289 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
290 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
291 | "dev": true
292 | },
293 | "callsites": {
294 | "version": "3.1.0",
295 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
296 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
297 | "dev": true
298 | },
299 | "camelcase": {
300 | "version": "5.3.1",
301 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
302 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
303 | "dev": true
304 | },
305 | "chalk": {
306 | "version": "2.4.2",
307 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
308 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
309 | "dev": true,
310 | "requires": {
311 | "ansi-styles": "^3.2.1",
312 | "escape-string-regexp": "^1.0.5",
313 | "supports-color": "^5.3.0"
314 | }
315 | },
316 | "chardet": {
317 | "version": "0.7.0",
318 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
319 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
320 | "dev": true
321 | },
322 | "chokidar": {
323 | "version": "3.3.0",
324 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
325 | "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
326 | "dev": true,
327 | "requires": {
328 | "anymatch": "~3.1.1",
329 | "braces": "~3.0.2",
330 | "fsevents": "~2.1.1",
331 | "glob-parent": "~5.1.0",
332 | "is-binary-path": "~2.1.0",
333 | "is-glob": "~4.0.1",
334 | "normalize-path": "~3.0.0",
335 | "readdirp": "~3.2.0"
336 | }
337 | },
338 | "cli-cursor": {
339 | "version": "3.1.0",
340 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
341 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
342 | "dev": true,
343 | "requires": {
344 | "restore-cursor": "^3.1.0"
345 | }
346 | },
347 | "cli-width": {
348 | "version": "2.2.1",
349 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
350 | "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
351 | "dev": true
352 | },
353 | "cliui": {
354 | "version": "5.0.0",
355 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
356 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
357 | "dev": true,
358 | "requires": {
359 | "string-width": "^3.1.0",
360 | "strip-ansi": "^5.2.0",
361 | "wrap-ansi": "^5.1.0"
362 | },
363 | "dependencies": {
364 | "emoji-regex": {
365 | "version": "7.0.3",
366 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
367 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
368 | "dev": true
369 | },
370 | "is-fullwidth-code-point": {
371 | "version": "2.0.0",
372 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
373 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
374 | "dev": true
375 | },
376 | "string-width": {
377 | "version": "3.1.0",
378 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
379 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
380 | "dev": true,
381 | "requires": {
382 | "emoji-regex": "^7.0.1",
383 | "is-fullwidth-code-point": "^2.0.0",
384 | "strip-ansi": "^5.1.0"
385 | }
386 | },
387 | "wrap-ansi": {
388 | "version": "5.1.0",
389 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
390 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
391 | "dev": true,
392 | "requires": {
393 | "ansi-styles": "^3.2.0",
394 | "string-width": "^3.0.0",
395 | "strip-ansi": "^5.0.0"
396 | }
397 | }
398 | }
399 | },
400 | "color-convert": {
401 | "version": "1.9.3",
402 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
403 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
404 | "dev": true,
405 | "requires": {
406 | "color-name": "1.1.3"
407 | }
408 | },
409 | "color-name": {
410 | "version": "1.1.3",
411 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
412 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
413 | "dev": true
414 | },
415 | "concat-map": {
416 | "version": "0.0.1",
417 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
418 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
419 | "dev": true
420 | },
421 | "cross-spawn": {
422 | "version": "6.0.5",
423 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
424 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
425 | "dev": true,
426 | "requires": {
427 | "nice-try": "^1.0.4",
428 | "path-key": "^2.0.1",
429 | "semver": "^5.5.0",
430 | "shebang-command": "^1.2.0",
431 | "which": "^1.2.9"
432 | },
433 | "dependencies": {
434 | "semver": {
435 | "version": "5.7.1",
436 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
437 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
438 | "dev": true
439 | }
440 | }
441 | },
442 | "debug": {
443 | "version": "3.1.0",
444 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
445 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
446 | "dev": true,
447 | "requires": {
448 | "ms": "2.0.0"
449 | }
450 | },
451 | "decache": {
452 | "version": "4.6.0",
453 | "resolved": "https://registry.npmjs.org/decache/-/decache-4.6.0.tgz",
454 | "integrity": "sha512-PppOuLiz+DFeaUvFXEYZjLxAkKiMYH/do/b/MxpDe/8AgKBi5GhZxridoVIbBq72GDbL36e4p0Ce2jTGUwwU+w==",
455 | "dev": true,
456 | "requires": {
457 | "callsite": "^1.0.0"
458 | }
459 | },
460 | "decamelize": {
461 | "version": "1.2.0",
462 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
463 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
464 | "dev": true
465 | },
466 | "deep-is": {
467 | "version": "0.1.3",
468 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
469 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
470 | "dev": true
471 | },
472 | "define-properties": {
473 | "version": "1.1.3",
474 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
475 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
476 | "dev": true,
477 | "requires": {
478 | "object-keys": "^1.0.12"
479 | }
480 | },
481 | "diff": {
482 | "version": "3.5.0",
483 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
484 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
485 | "dev": true
486 | },
487 | "doctrine": {
488 | "version": "3.0.0",
489 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
490 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
491 | "dev": true,
492 | "requires": {
493 | "esutils": "^2.0.2"
494 | }
495 | },
496 | "emoji-regex": {
497 | "version": "8.0.0",
498 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
499 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
500 | "dev": true
501 | },
502 | "es-abstract": {
503 | "version": "1.17.5",
504 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
505 | "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
506 | "dev": true,
507 | "requires": {
508 | "es-to-primitive": "^1.2.1",
509 | "function-bind": "^1.1.1",
510 | "has": "^1.0.3",
511 | "has-symbols": "^1.0.1",
512 | "is-callable": "^1.1.5",
513 | "is-regex": "^1.0.5",
514 | "object-inspect": "^1.7.0",
515 | "object-keys": "^1.1.1",
516 | "object.assign": "^4.1.0",
517 | "string.prototype.trimleft": "^2.1.1",
518 | "string.prototype.trimright": "^2.1.1"
519 | }
520 | },
521 | "es-to-primitive": {
522 | "version": "1.2.1",
523 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
524 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
525 | "dev": true,
526 | "requires": {
527 | "is-callable": "^1.1.4",
528 | "is-date-object": "^1.0.1",
529 | "is-symbol": "^1.0.2"
530 | }
531 | },
532 | "es6-promise": {
533 | "version": "4.2.8",
534 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
535 | "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
536 | "dev": true
537 | },
538 | "es6-promisify": {
539 | "version": "5.0.0",
540 | "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
541 | "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
542 | "dev": true,
543 | "requires": {
544 | "es6-promise": "^4.0.3"
545 | }
546 | },
547 | "escape-string-regexp": {
548 | "version": "1.0.5",
549 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
550 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
551 | "dev": true
552 | },
553 | "eslint": {
554 | "version": "6.8.0",
555 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
556 | "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
557 | "dev": true,
558 | "requires": {
559 | "@babel/code-frame": "^7.0.0",
560 | "ajv": "^6.10.0",
561 | "chalk": "^2.1.0",
562 | "cross-spawn": "^6.0.5",
563 | "debug": "^4.0.1",
564 | "doctrine": "^3.0.0",
565 | "eslint-scope": "^5.0.0",
566 | "eslint-utils": "^1.4.3",
567 | "eslint-visitor-keys": "^1.1.0",
568 | "espree": "^6.1.2",
569 | "esquery": "^1.0.1",
570 | "esutils": "^2.0.2",
571 | "file-entry-cache": "^5.0.1",
572 | "functional-red-black-tree": "^1.0.1",
573 | "glob-parent": "^5.0.0",
574 | "globals": "^12.1.0",
575 | "ignore": "^4.0.6",
576 | "import-fresh": "^3.0.0",
577 | "imurmurhash": "^0.1.4",
578 | "inquirer": "^7.0.0",
579 | "is-glob": "^4.0.0",
580 | "js-yaml": "^3.13.1",
581 | "json-stable-stringify-without-jsonify": "^1.0.1",
582 | "levn": "^0.3.0",
583 | "lodash": "^4.17.14",
584 | "minimatch": "^3.0.4",
585 | "mkdirp": "^0.5.1",
586 | "natural-compare": "^1.4.0",
587 | "optionator": "^0.8.3",
588 | "progress": "^2.0.0",
589 | "regexpp": "^2.0.1",
590 | "semver": "^6.1.2",
591 | "strip-ansi": "^5.2.0",
592 | "strip-json-comments": "^3.0.1",
593 | "table": "^5.2.3",
594 | "text-table": "^0.2.0",
595 | "v8-compile-cache": "^2.0.3"
596 | },
597 | "dependencies": {
598 | "debug": {
599 | "version": "4.1.1",
600 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
601 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
602 | "dev": true,
603 | "requires": {
604 | "ms": "^2.1.1"
605 | }
606 | },
607 | "eslint-utils": {
608 | "version": "1.4.3",
609 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
610 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
611 | "dev": true,
612 | "requires": {
613 | "eslint-visitor-keys": "^1.1.0"
614 | }
615 | },
616 | "ms": {
617 | "version": "2.1.2",
618 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
619 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
620 | "dev": true
621 | },
622 | "optionator": {
623 | "version": "0.8.3",
624 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
625 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
626 | "dev": true,
627 | "requires": {
628 | "deep-is": "~0.1.3",
629 | "fast-levenshtein": "~2.0.6",
630 | "levn": "~0.3.0",
631 | "prelude-ls": "~1.1.2",
632 | "type-check": "~0.3.2",
633 | "word-wrap": "~1.2.3"
634 | }
635 | },
636 | "regexpp": {
637 | "version": "2.0.1",
638 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
639 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
640 | "dev": true
641 | },
642 | "semver": {
643 | "version": "6.3.0",
644 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
645 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
646 | "dev": true
647 | }
648 | }
649 | },
650 | "eslint-scope": {
651 | "version": "5.0.0",
652 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
653 | "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
654 | "dev": true,
655 | "requires": {
656 | "esrecurse": "^4.1.0",
657 | "estraverse": "^4.1.1"
658 | },
659 | "dependencies": {
660 | "estraverse": {
661 | "version": "4.3.0",
662 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
663 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
664 | "dev": true
665 | }
666 | }
667 | },
668 | "eslint-utils": {
669 | "version": "2.0.0",
670 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
671 | "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
672 | "dev": true,
673 | "requires": {
674 | "eslint-visitor-keys": "^1.1.0"
675 | }
676 | },
677 | "eslint-visitor-keys": {
678 | "version": "1.1.0",
679 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
680 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
681 | "dev": true
682 | },
683 | "espree": {
684 | "version": "6.2.1",
685 | "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
686 | "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
687 | "dev": true,
688 | "requires": {
689 | "acorn": "^7.1.1",
690 | "acorn-jsx": "^5.2.0",
691 | "eslint-visitor-keys": "^1.1.0"
692 | }
693 | },
694 | "esprima": {
695 | "version": "4.0.0",
696 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
697 | "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
698 | "dev": true
699 | },
700 | "esquery": {
701 | "version": "1.3.1",
702 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
703 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
704 | "dev": true,
705 | "requires": {
706 | "estraverse": "^5.1.0"
707 | },
708 | "dependencies": {
709 | "estraverse": {
710 | "version": "5.1.0",
711 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
712 | "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==",
713 | "dev": true
714 | }
715 | }
716 | },
717 | "esrecurse": {
718 | "version": "4.2.1",
719 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
720 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
721 | "dev": true,
722 | "requires": {
723 | "estraverse": "^4.1.0"
724 | },
725 | "dependencies": {
726 | "estraverse": {
727 | "version": "4.3.0",
728 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
729 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
730 | "dev": true
731 | }
732 | }
733 | },
734 | "esutils": {
735 | "version": "2.0.2",
736 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
737 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
738 | "dev": true
739 | },
740 | "external-editor": {
741 | "version": "3.1.0",
742 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
743 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
744 | "dev": true,
745 | "requires": {
746 | "chardet": "^0.7.0",
747 | "iconv-lite": "^0.4.24",
748 | "tmp": "^0.0.33"
749 | }
750 | },
751 | "fast-deep-equal": {
752 | "version": "3.1.1",
753 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
754 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
755 | "dev": true
756 | },
757 | "fast-json-stable-stringify": {
758 | "version": "2.1.0",
759 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
760 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
761 | "dev": true
762 | },
763 | "fast-levenshtein": {
764 | "version": "2.0.6",
765 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
766 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
767 | "dev": true
768 | },
769 | "figures": {
770 | "version": "3.2.0",
771 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
772 | "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
773 | "dev": true,
774 | "requires": {
775 | "escape-string-regexp": "^1.0.5"
776 | }
777 | },
778 | "file-entry-cache": {
779 | "version": "5.0.1",
780 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
781 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
782 | "dev": true,
783 | "requires": {
784 | "flat-cache": "^2.0.1"
785 | }
786 | },
787 | "fill-range": {
788 | "version": "7.0.1",
789 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
790 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
791 | "dev": true,
792 | "requires": {
793 | "to-regex-range": "^5.0.1"
794 | }
795 | },
796 | "flat": {
797 | "version": "4.1.0",
798 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
799 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
800 | "dev": true,
801 | "requires": {
802 | "is-buffer": "~2.0.3"
803 | }
804 | },
805 | "flat-cache": {
806 | "version": "2.0.1",
807 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
808 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
809 | "dev": true,
810 | "requires": {
811 | "flatted": "^2.0.0",
812 | "rimraf": "2.6.3",
813 | "write": "1.0.3"
814 | },
815 | "dependencies": {
816 | "rimraf": {
817 | "version": "2.6.3",
818 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
819 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
820 | "dev": true,
821 | "requires": {
822 | "glob": "^7.1.3"
823 | }
824 | }
825 | }
826 | },
827 | "flatted": {
828 | "version": "2.0.2",
829 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
830 | "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
831 | "dev": true
832 | },
833 | "fs.realpath": {
834 | "version": "1.0.0",
835 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
836 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
837 | "dev": true
838 | },
839 | "fsevents": {
840 | "version": "2.1.3",
841 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
842 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
843 | "dev": true,
844 | "optional": true
845 | },
846 | "function-bind": {
847 | "version": "1.1.1",
848 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
849 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
850 | "dev": true
851 | },
852 | "functional-red-black-tree": {
853 | "version": "1.0.1",
854 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
855 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
856 | "dev": true
857 | },
858 | "get-caller-file": {
859 | "version": "2.0.5",
860 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
861 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
862 | "dev": true
863 | },
864 | "glob": {
865 | "version": "7.1.6",
866 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
867 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
868 | "dev": true,
869 | "requires": {
870 | "fs.realpath": "^1.0.0",
871 | "inflight": "^1.0.4",
872 | "inherits": "2",
873 | "minimatch": "^3.0.4",
874 | "once": "^1.3.0",
875 | "path-is-absolute": "^1.0.0"
876 | }
877 | },
878 | "glob-parent": {
879 | "version": "5.1.1",
880 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
881 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
882 | "dev": true,
883 | "requires": {
884 | "is-glob": "^4.0.1"
885 | }
886 | },
887 | "globals": {
888 | "version": "12.4.0",
889 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
890 | "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
891 | "dev": true,
892 | "requires": {
893 | "type-fest": "^0.8.1"
894 | }
895 | },
896 | "growl": {
897 | "version": "1.10.5",
898 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
899 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
900 | "dev": true
901 | },
902 | "has": {
903 | "version": "1.0.3",
904 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
905 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
906 | "dev": true,
907 | "requires": {
908 | "function-bind": "^1.1.1"
909 | }
910 | },
911 | "has-flag": {
912 | "version": "3.0.0",
913 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
914 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
915 | "dev": true
916 | },
917 | "has-symbols": {
918 | "version": "1.0.1",
919 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
920 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
921 | "dev": true
922 | },
923 | "he": {
924 | "version": "1.2.0",
925 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
926 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
927 | "dev": true
928 | },
929 | "http-proxy-agent": {
930 | "version": "2.1.0",
931 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
932 | "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
933 | "dev": true,
934 | "requires": {
935 | "agent-base": "4",
936 | "debug": "3.1.0"
937 | }
938 | },
939 | "https-proxy-agent": {
940 | "version": "2.2.4",
941 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
942 | "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
943 | "dev": true,
944 | "requires": {
945 | "agent-base": "^4.3.0",
946 | "debug": "^3.1.0"
947 | }
948 | },
949 | "iconv-lite": {
950 | "version": "0.4.24",
951 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
952 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
953 | "dev": true,
954 | "requires": {
955 | "safer-buffer": ">= 2.1.2 < 3"
956 | }
957 | },
958 | "ignore": {
959 | "version": "4.0.6",
960 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
961 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
962 | "dev": true
963 | },
964 | "import-fresh": {
965 | "version": "3.2.1",
966 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
967 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
968 | "dev": true,
969 | "requires": {
970 | "parent-module": "^1.0.0",
971 | "resolve-from": "^4.0.0"
972 | }
973 | },
974 | "imurmurhash": {
975 | "version": "0.1.4",
976 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
977 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
978 | "dev": true
979 | },
980 | "inflight": {
981 | "version": "1.0.6",
982 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
983 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
984 | "dev": true,
985 | "requires": {
986 | "once": "^1.3.0",
987 | "wrappy": "1"
988 | }
989 | },
990 | "inherits": {
991 | "version": "2.0.3",
992 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
993 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
994 | "dev": true
995 | },
996 | "inquirer": {
997 | "version": "7.1.0",
998 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz",
999 | "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==",
1000 | "dev": true,
1001 | "requires": {
1002 | "ansi-escapes": "^4.2.1",
1003 | "chalk": "^3.0.0",
1004 | "cli-cursor": "^3.1.0",
1005 | "cli-width": "^2.0.0",
1006 | "external-editor": "^3.0.3",
1007 | "figures": "^3.0.0",
1008 | "lodash": "^4.17.15",
1009 | "mute-stream": "0.0.8",
1010 | "run-async": "^2.4.0",
1011 | "rxjs": "^6.5.3",
1012 | "string-width": "^4.1.0",
1013 | "strip-ansi": "^6.0.0",
1014 | "through": "^2.3.6"
1015 | },
1016 | "dependencies": {
1017 | "ansi-styles": {
1018 | "version": "4.2.1",
1019 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
1020 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
1021 | "dev": true,
1022 | "requires": {
1023 | "@types/color-name": "^1.1.1",
1024 | "color-convert": "^2.0.1"
1025 | }
1026 | },
1027 | "chalk": {
1028 | "version": "3.0.0",
1029 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
1030 | "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
1031 | "dev": true,
1032 | "requires": {
1033 | "ansi-styles": "^4.1.0",
1034 | "supports-color": "^7.1.0"
1035 | }
1036 | },
1037 | "color-convert": {
1038 | "version": "2.0.1",
1039 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1040 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1041 | "dev": true,
1042 | "requires": {
1043 | "color-name": "~1.1.4"
1044 | }
1045 | },
1046 | "color-name": {
1047 | "version": "1.1.4",
1048 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1049 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1050 | "dev": true
1051 | },
1052 | "has-flag": {
1053 | "version": "4.0.0",
1054 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1055 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1056 | "dev": true
1057 | },
1058 | "strip-ansi": {
1059 | "version": "6.0.0",
1060 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
1061 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
1062 | "dev": true,
1063 | "requires": {
1064 | "ansi-regex": "^5.0.0"
1065 | }
1066 | },
1067 | "supports-color": {
1068 | "version": "7.1.0",
1069 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
1070 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
1071 | "dev": true,
1072 | "requires": {
1073 | "has-flag": "^4.0.0"
1074 | }
1075 | }
1076 | }
1077 | },
1078 | "is-binary-path": {
1079 | "version": "2.1.0",
1080 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1081 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1082 | "dev": true,
1083 | "requires": {
1084 | "binary-extensions": "^2.0.0"
1085 | }
1086 | },
1087 | "is-buffer": {
1088 | "version": "2.0.4",
1089 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
1090 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
1091 | "dev": true
1092 | },
1093 | "is-callable": {
1094 | "version": "1.1.5",
1095 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
1096 | "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
1097 | "dev": true
1098 | },
1099 | "is-date-object": {
1100 | "version": "1.0.2",
1101 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
1102 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
1103 | "dev": true
1104 | },
1105 | "is-extglob": {
1106 | "version": "2.1.1",
1107 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1108 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
1109 | "dev": true
1110 | },
1111 | "is-fullwidth-code-point": {
1112 | "version": "3.0.0",
1113 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1114 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1115 | "dev": true
1116 | },
1117 | "is-glob": {
1118 | "version": "4.0.1",
1119 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
1120 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
1121 | "dev": true,
1122 | "requires": {
1123 | "is-extglob": "^2.1.1"
1124 | }
1125 | },
1126 | "is-number": {
1127 | "version": "7.0.0",
1128 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1129 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1130 | "dev": true
1131 | },
1132 | "is-regex": {
1133 | "version": "1.0.5",
1134 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
1135 | "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
1136 | "dev": true,
1137 | "requires": {
1138 | "has": "^1.0.3"
1139 | }
1140 | },
1141 | "is-symbol": {
1142 | "version": "1.0.3",
1143 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
1144 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
1145 | "dev": true,
1146 | "requires": {
1147 | "has-symbols": "^1.0.1"
1148 | }
1149 | },
1150 | "isexe": {
1151 | "version": "2.0.0",
1152 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1153 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
1154 | "dev": true
1155 | },
1156 | "js-tokens": {
1157 | "version": "4.0.0",
1158 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1159 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1160 | "dev": true
1161 | },
1162 | "js-yaml": {
1163 | "version": "3.13.1",
1164 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
1165 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
1166 | "dev": true,
1167 | "requires": {
1168 | "argparse": "^1.0.7",
1169 | "esprima": "^4.0.0"
1170 | }
1171 | },
1172 | "json-schema-traverse": {
1173 | "version": "0.4.1",
1174 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
1175 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
1176 | "dev": true
1177 | },
1178 | "json-stable-stringify-without-jsonify": {
1179 | "version": "1.0.1",
1180 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
1181 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
1182 | "dev": true
1183 | },
1184 | "levn": {
1185 | "version": "0.3.0",
1186 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
1187 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
1188 | "dev": true,
1189 | "requires": {
1190 | "prelude-ls": "~1.1.2",
1191 | "type-check": "~0.3.2"
1192 | }
1193 | },
1194 | "lodash": {
1195 | "version": "4.17.15",
1196 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
1197 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
1198 | "dev": true
1199 | },
1200 | "log-symbols": {
1201 | "version": "3.0.0",
1202 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
1203 | "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
1204 | "dev": true,
1205 | "requires": {
1206 | "chalk": "^2.4.2"
1207 | }
1208 | },
1209 | "mimic-fn": {
1210 | "version": "2.1.0",
1211 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
1212 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
1213 | "dev": true
1214 | },
1215 | "minimatch": {
1216 | "version": "3.0.4",
1217 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1218 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1219 | "dev": true,
1220 | "requires": {
1221 | "brace-expansion": "^1.1.7"
1222 | }
1223 | },
1224 | "mkdirp": {
1225 | "version": "0.5.5",
1226 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
1227 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
1228 | "dev": true,
1229 | "requires": {
1230 | "minimist": "^1.2.5"
1231 | },
1232 | "dependencies": {
1233 | "minimist": {
1234 | "version": "1.2.5",
1235 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
1236 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
1237 | "dev": true
1238 | }
1239 | }
1240 | },
1241 | "mocha": {
1242 | "version": "7.2.0",
1243 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
1244 | "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
1245 | "dev": true,
1246 | "requires": {
1247 | "ansi-colors": "3.2.3",
1248 | "browser-stdout": "1.3.1",
1249 | "chokidar": "3.3.0",
1250 | "debug": "3.2.6",
1251 | "diff": "3.5.0",
1252 | "escape-string-regexp": "1.0.5",
1253 | "find-up": "3.0.0",
1254 | "glob": "7.1.3",
1255 | "growl": "1.10.5",
1256 | "he": "1.2.0",
1257 | "js-yaml": "3.13.1",
1258 | "log-symbols": "3.0.0",
1259 | "minimatch": "3.0.4",
1260 | "mkdirp": "0.5.5",
1261 | "ms": "2.1.1",
1262 | "node-environment-flags": "1.0.6",
1263 | "object.assign": "4.1.0",
1264 | "strip-json-comments": "2.0.1",
1265 | "supports-color": "6.0.0",
1266 | "which": "1.3.1",
1267 | "wide-align": "1.1.3",
1268 | "yargs": "13.3.2",
1269 | "yargs-parser": "13.1.2",
1270 | "yargs-unparser": "1.6.0"
1271 | },
1272 | "dependencies": {
1273 | "ansi-colors": {
1274 | "version": "3.2.3",
1275 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
1276 | "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
1277 | "dev": true
1278 | },
1279 | "debug": {
1280 | "version": "3.2.6",
1281 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
1282 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
1283 | "dev": true,
1284 | "requires": {
1285 | "ms": "^2.1.1"
1286 | }
1287 | },
1288 | "find-up": {
1289 | "version": "3.0.0",
1290 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
1291 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
1292 | "dev": true,
1293 | "requires": {
1294 | "locate-path": "^3.0.0"
1295 | }
1296 | },
1297 | "glob": {
1298 | "version": "7.1.3",
1299 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
1300 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
1301 | "dev": true,
1302 | "requires": {
1303 | "fs.realpath": "^1.0.0",
1304 | "inflight": "^1.0.4",
1305 | "inherits": "2",
1306 | "minimatch": "^3.0.4",
1307 | "once": "^1.3.0",
1308 | "path-is-absolute": "^1.0.0"
1309 | }
1310 | },
1311 | "locate-path": {
1312 | "version": "3.0.0",
1313 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
1314 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
1315 | "dev": true,
1316 | "requires": {
1317 | "p-locate": "^3.0.0",
1318 | "path-exists": "^3.0.0"
1319 | }
1320 | },
1321 | "ms": {
1322 | "version": "2.1.1",
1323 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
1324 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
1325 | "dev": true
1326 | },
1327 | "p-locate": {
1328 | "version": "3.0.0",
1329 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
1330 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
1331 | "dev": true,
1332 | "requires": {
1333 | "p-limit": "^2.0.0"
1334 | }
1335 | },
1336 | "path-exists": {
1337 | "version": "3.0.0",
1338 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
1339 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
1340 | "dev": true
1341 | },
1342 | "strip-json-comments": {
1343 | "version": "2.0.1",
1344 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
1345 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
1346 | "dev": true
1347 | },
1348 | "supports-color": {
1349 | "version": "6.0.0",
1350 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
1351 | "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
1352 | "dev": true,
1353 | "requires": {
1354 | "has-flag": "^3.0.0"
1355 | }
1356 | },
1357 | "which": {
1358 | "version": "1.3.1",
1359 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1360 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1361 | "dev": true,
1362 | "requires": {
1363 | "isexe": "^2.0.0"
1364 | }
1365 | },
1366 | "yargs-parser": {
1367 | "version": "13.1.2",
1368 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
1369 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
1370 | "dev": true,
1371 | "requires": {
1372 | "camelcase": "^5.0.0",
1373 | "decamelize": "^1.2.0"
1374 | }
1375 | }
1376 | }
1377 | },
1378 | "ms": {
1379 | "version": "2.0.0",
1380 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1381 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
1382 | "dev": true
1383 | },
1384 | "mute-stream": {
1385 | "version": "0.0.8",
1386 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
1387 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
1388 | "dev": true
1389 | },
1390 | "natural-compare": {
1391 | "version": "1.4.0",
1392 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
1393 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
1394 | "dev": true
1395 | },
1396 | "nice-try": {
1397 | "version": "1.0.5",
1398 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
1399 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
1400 | "dev": true
1401 | },
1402 | "node-environment-flags": {
1403 | "version": "1.0.6",
1404 | "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
1405 | "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
1406 | "dev": true,
1407 | "requires": {
1408 | "object.getownpropertydescriptors": "^2.0.3",
1409 | "semver": "^5.7.0"
1410 | },
1411 | "dependencies": {
1412 | "semver": {
1413 | "version": "5.7.1",
1414 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1415 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
1416 | "dev": true
1417 | }
1418 | }
1419 | },
1420 | "normalize-path": {
1421 | "version": "3.0.0",
1422 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1423 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1424 | "dev": true
1425 | },
1426 | "object-inspect": {
1427 | "version": "1.7.0",
1428 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
1429 | "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
1430 | "dev": true
1431 | },
1432 | "object-keys": {
1433 | "version": "1.1.1",
1434 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
1435 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
1436 | "dev": true
1437 | },
1438 | "object.assign": {
1439 | "version": "4.1.0",
1440 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
1441 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
1442 | "dev": true,
1443 | "requires": {
1444 | "define-properties": "^1.1.2",
1445 | "function-bind": "^1.1.1",
1446 | "has-symbols": "^1.0.0",
1447 | "object-keys": "^1.0.11"
1448 | }
1449 | },
1450 | "object.getownpropertydescriptors": {
1451 | "version": "2.1.0",
1452 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
1453 | "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
1454 | "dev": true,
1455 | "requires": {
1456 | "define-properties": "^1.1.3",
1457 | "es-abstract": "^1.17.0-next.1"
1458 | }
1459 | },
1460 | "once": {
1461 | "version": "1.4.0",
1462 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1463 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1464 | "dev": true,
1465 | "requires": {
1466 | "wrappy": "1"
1467 | }
1468 | },
1469 | "onetime": {
1470 | "version": "5.1.0",
1471 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
1472 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
1473 | "dev": true,
1474 | "requires": {
1475 | "mimic-fn": "^2.1.0"
1476 | }
1477 | },
1478 | "os-tmpdir": {
1479 | "version": "1.0.2",
1480 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
1481 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
1482 | "dev": true
1483 | },
1484 | "p-limit": {
1485 | "version": "2.3.0",
1486 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
1487 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
1488 | "dev": true,
1489 | "requires": {
1490 | "p-try": "^2.0.0"
1491 | }
1492 | },
1493 | "p-try": {
1494 | "version": "2.2.0",
1495 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
1496 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
1497 | "dev": true
1498 | },
1499 | "parent-module": {
1500 | "version": "1.0.1",
1501 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
1502 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
1503 | "dev": true,
1504 | "requires": {
1505 | "callsites": "^3.0.0"
1506 | }
1507 | },
1508 | "path-is-absolute": {
1509 | "version": "1.0.1",
1510 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1511 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
1512 | "dev": true
1513 | },
1514 | "path-key": {
1515 | "version": "2.0.1",
1516 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
1517 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
1518 | "dev": true
1519 | },
1520 | "picomatch": {
1521 | "version": "2.2.2",
1522 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
1523 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
1524 | "dev": true
1525 | },
1526 | "prelude-ls": {
1527 | "version": "1.1.2",
1528 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
1529 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
1530 | "dev": true
1531 | },
1532 | "progress": {
1533 | "version": "2.0.3",
1534 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
1535 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
1536 | "dev": true
1537 | },
1538 | "punycode": {
1539 | "version": "2.1.1",
1540 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
1541 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
1542 | "dev": true
1543 | },
1544 | "readdirp": {
1545 | "version": "3.2.0",
1546 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
1547 | "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
1548 | "dev": true,
1549 | "requires": {
1550 | "picomatch": "^2.0.4"
1551 | }
1552 | },
1553 | "regexpp": {
1554 | "version": "3.1.0",
1555 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
1556 | "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
1557 | "dev": true
1558 | },
1559 | "require-directory": {
1560 | "version": "2.1.1",
1561 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1562 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
1563 | "dev": true
1564 | },
1565 | "require-main-filename": {
1566 | "version": "2.0.0",
1567 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
1568 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
1569 | "dev": true
1570 | },
1571 | "resolve-from": {
1572 | "version": "4.0.0",
1573 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
1574 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
1575 | "dev": true
1576 | },
1577 | "restore-cursor": {
1578 | "version": "3.1.0",
1579 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
1580 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
1581 | "dev": true,
1582 | "requires": {
1583 | "onetime": "^5.1.0",
1584 | "signal-exit": "^3.0.2"
1585 | }
1586 | },
1587 | "rimraf": {
1588 | "version": "2.7.1",
1589 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
1590 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
1591 | "dev": true,
1592 | "requires": {
1593 | "glob": "^7.1.3"
1594 | }
1595 | },
1596 | "run-async": {
1597 | "version": "2.4.1",
1598 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
1599 | "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
1600 | "dev": true
1601 | },
1602 | "rxjs": {
1603 | "version": "6.5.5",
1604 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
1605 | "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
1606 | "dev": true,
1607 | "requires": {
1608 | "tslib": "^1.9.0"
1609 | }
1610 | },
1611 | "safer-buffer": {
1612 | "version": "2.1.2",
1613 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1614 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1615 | "dev": true
1616 | },
1617 | "semver": {
1618 | "version": "7.3.2",
1619 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
1620 | "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
1621 | "dev": true
1622 | },
1623 | "set-blocking": {
1624 | "version": "2.0.0",
1625 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
1626 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
1627 | "dev": true
1628 | },
1629 | "shebang-command": {
1630 | "version": "1.2.0",
1631 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
1632 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
1633 | "dev": true,
1634 | "requires": {
1635 | "shebang-regex": "^1.0.0"
1636 | }
1637 | },
1638 | "shebang-regex": {
1639 | "version": "1.0.0",
1640 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
1641 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
1642 | "dev": true
1643 | },
1644 | "signal-exit": {
1645 | "version": "3.0.3",
1646 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
1647 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
1648 | "dev": true
1649 | },
1650 | "slice-ansi": {
1651 | "version": "2.1.0",
1652 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
1653 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
1654 | "dev": true,
1655 | "requires": {
1656 | "ansi-styles": "^3.2.0",
1657 | "astral-regex": "^1.0.0",
1658 | "is-fullwidth-code-point": "^2.0.0"
1659 | },
1660 | "dependencies": {
1661 | "is-fullwidth-code-point": {
1662 | "version": "2.0.0",
1663 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
1664 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
1665 | "dev": true
1666 | }
1667 | }
1668 | },
1669 | "sprintf-js": {
1670 | "version": "1.0.3",
1671 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
1672 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
1673 | "dev": true
1674 | },
1675 | "string-width": {
1676 | "version": "4.2.0",
1677 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
1678 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
1679 | "dev": true,
1680 | "requires": {
1681 | "emoji-regex": "^8.0.0",
1682 | "is-fullwidth-code-point": "^3.0.0",
1683 | "strip-ansi": "^6.0.0"
1684 | },
1685 | "dependencies": {
1686 | "strip-ansi": {
1687 | "version": "6.0.0",
1688 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
1689 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
1690 | "dev": true,
1691 | "requires": {
1692 | "ansi-regex": "^5.0.0"
1693 | }
1694 | }
1695 | }
1696 | },
1697 | "string.prototype.trimend": {
1698 | "version": "1.0.1",
1699 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
1700 | "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
1701 | "dev": true,
1702 | "requires": {
1703 | "define-properties": "^1.1.3",
1704 | "es-abstract": "^1.17.5"
1705 | }
1706 | },
1707 | "string.prototype.trimleft": {
1708 | "version": "2.1.2",
1709 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
1710 | "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
1711 | "dev": true,
1712 | "requires": {
1713 | "define-properties": "^1.1.3",
1714 | "es-abstract": "^1.17.5",
1715 | "string.prototype.trimstart": "^1.0.0"
1716 | }
1717 | },
1718 | "string.prototype.trimright": {
1719 | "version": "2.1.2",
1720 | "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
1721 | "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
1722 | "dev": true,
1723 | "requires": {
1724 | "define-properties": "^1.1.3",
1725 | "es-abstract": "^1.17.5",
1726 | "string.prototype.trimend": "^1.0.0"
1727 | }
1728 | },
1729 | "string.prototype.trimstart": {
1730 | "version": "1.0.1",
1731 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
1732 | "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
1733 | "dev": true,
1734 | "requires": {
1735 | "define-properties": "^1.1.3",
1736 | "es-abstract": "^1.17.5"
1737 | }
1738 | },
1739 | "strip-ansi": {
1740 | "version": "5.2.0",
1741 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
1742 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
1743 | "dev": true,
1744 | "requires": {
1745 | "ansi-regex": "^4.1.0"
1746 | },
1747 | "dependencies": {
1748 | "ansi-regex": {
1749 | "version": "4.1.0",
1750 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
1751 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
1752 | "dev": true
1753 | }
1754 | }
1755 | },
1756 | "strip-json-comments": {
1757 | "version": "3.1.0",
1758 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
1759 | "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
1760 | "dev": true
1761 | },
1762 | "supports-color": {
1763 | "version": "5.5.0",
1764 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1765 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1766 | "dev": true,
1767 | "requires": {
1768 | "has-flag": "^3.0.0"
1769 | }
1770 | },
1771 | "table": {
1772 | "version": "5.4.6",
1773 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
1774 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
1775 | "dev": true,
1776 | "requires": {
1777 | "ajv": "^6.10.2",
1778 | "lodash": "^4.17.14",
1779 | "slice-ansi": "^2.1.0",
1780 | "string-width": "^3.0.0"
1781 | },
1782 | "dependencies": {
1783 | "emoji-regex": {
1784 | "version": "7.0.3",
1785 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
1786 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
1787 | "dev": true
1788 | },
1789 | "is-fullwidth-code-point": {
1790 | "version": "2.0.0",
1791 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
1792 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
1793 | "dev": true
1794 | },
1795 | "string-width": {
1796 | "version": "3.1.0",
1797 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
1798 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
1799 | "dev": true,
1800 | "requires": {
1801 | "emoji-regex": "^7.0.1",
1802 | "is-fullwidth-code-point": "^2.0.0",
1803 | "strip-ansi": "^5.1.0"
1804 | }
1805 | }
1806 | }
1807 | },
1808 | "text-table": {
1809 | "version": "0.2.0",
1810 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
1811 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
1812 | "dev": true
1813 | },
1814 | "through": {
1815 | "version": "2.3.8",
1816 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
1817 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
1818 | "dev": true
1819 | },
1820 | "tmp": {
1821 | "version": "0.0.33",
1822 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
1823 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
1824 | "dev": true,
1825 | "requires": {
1826 | "os-tmpdir": "~1.0.2"
1827 | }
1828 | },
1829 | "to-regex-range": {
1830 | "version": "5.0.1",
1831 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1832 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1833 | "dev": true,
1834 | "requires": {
1835 | "is-number": "^7.0.0"
1836 | }
1837 | },
1838 | "tslib": {
1839 | "version": "1.13.0",
1840 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
1841 | "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
1842 | "dev": true
1843 | },
1844 | "tsutils": {
1845 | "version": "3.17.1",
1846 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
1847 | "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
1848 | "dev": true,
1849 | "requires": {
1850 | "tslib": "^1.8.1"
1851 | }
1852 | },
1853 | "type-check": {
1854 | "version": "0.3.2",
1855 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
1856 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
1857 | "dev": true,
1858 | "requires": {
1859 | "prelude-ls": "~1.1.2"
1860 | }
1861 | },
1862 | "type-fest": {
1863 | "version": "0.8.1",
1864 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
1865 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
1866 | "dev": true
1867 | },
1868 | "typescript": {
1869 | "version": "3.9.3",
1870 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz",
1871 | "integrity": "sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==",
1872 | "dev": true
1873 | },
1874 | "uri-js": {
1875 | "version": "4.2.2",
1876 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
1877 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
1878 | "dev": true,
1879 | "requires": {
1880 | "punycode": "^2.1.0"
1881 | }
1882 | },
1883 | "v8-compile-cache": {
1884 | "version": "2.1.0",
1885 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
1886 | "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
1887 | "dev": true
1888 | },
1889 | "vscode-test": {
1890 | "version": "1.3.0",
1891 | "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.3.0.tgz",
1892 | "integrity": "sha512-LddukcBiSU2FVTDr3c1D8lwkiOvwlJdDL2hqVbn6gIz+rpTqUCkMZSKYm94Y1v0WXlHSDQBsXyY+tchWQgGVsw==",
1893 | "dev": true,
1894 | "requires": {
1895 | "http-proxy-agent": "^2.1.0",
1896 | "https-proxy-agent": "^2.2.4",
1897 | "rimraf": "^2.6.3"
1898 | }
1899 | },
1900 | "which": {
1901 | "version": "1.3.0",
1902 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
1903 | "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
1904 | "dev": true,
1905 | "requires": {
1906 | "isexe": "^2.0.0"
1907 | }
1908 | },
1909 | "which-module": {
1910 | "version": "2.0.0",
1911 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
1912 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
1913 | "dev": true
1914 | },
1915 | "wide-align": {
1916 | "version": "1.1.3",
1917 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
1918 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
1919 | "dev": true,
1920 | "requires": {
1921 | "string-width": "^1.0.2 || 2"
1922 | },
1923 | "dependencies": {
1924 | "ansi-regex": {
1925 | "version": "3.0.0",
1926 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
1927 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
1928 | "dev": true
1929 | },
1930 | "is-fullwidth-code-point": {
1931 | "version": "2.0.0",
1932 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
1933 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
1934 | "dev": true
1935 | },
1936 | "string-width": {
1937 | "version": "2.1.1",
1938 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
1939 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
1940 | "dev": true,
1941 | "requires": {
1942 | "is-fullwidth-code-point": "^2.0.0",
1943 | "strip-ansi": "^4.0.0"
1944 | }
1945 | },
1946 | "strip-ansi": {
1947 | "version": "4.0.0",
1948 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
1949 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
1950 | "dev": true,
1951 | "requires": {
1952 | "ansi-regex": "^3.0.0"
1953 | }
1954 | }
1955 | }
1956 | },
1957 | "word-wrap": {
1958 | "version": "1.2.3",
1959 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
1960 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
1961 | "dev": true
1962 | },
1963 | "wrappy": {
1964 | "version": "1.0.2",
1965 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1966 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1967 | "dev": true
1968 | },
1969 | "write": {
1970 | "version": "1.0.3",
1971 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
1972 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
1973 | "dev": true,
1974 | "requires": {
1975 | "mkdirp": "^0.5.1"
1976 | }
1977 | },
1978 | "y18n": {
1979 | "version": "4.0.0",
1980 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
1981 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
1982 | "dev": true
1983 | },
1984 | "yargs": {
1985 | "version": "13.3.2",
1986 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
1987 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
1988 | "dev": true,
1989 | "requires": {
1990 | "cliui": "^5.0.0",
1991 | "find-up": "^3.0.0",
1992 | "get-caller-file": "^2.0.1",
1993 | "require-directory": "^2.1.1",
1994 | "require-main-filename": "^2.0.0",
1995 | "set-blocking": "^2.0.0",
1996 | "string-width": "^3.0.0",
1997 | "which-module": "^2.0.0",
1998 | "y18n": "^4.0.0",
1999 | "yargs-parser": "^13.1.2"
2000 | },
2001 | "dependencies": {
2002 | "emoji-regex": {
2003 | "version": "7.0.3",
2004 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
2005 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
2006 | "dev": true
2007 | },
2008 | "find-up": {
2009 | "version": "3.0.0",
2010 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
2011 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
2012 | "dev": true,
2013 | "requires": {
2014 | "locate-path": "^3.0.0"
2015 | }
2016 | },
2017 | "is-fullwidth-code-point": {
2018 | "version": "2.0.0",
2019 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
2020 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
2021 | "dev": true
2022 | },
2023 | "locate-path": {
2024 | "version": "3.0.0",
2025 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
2026 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
2027 | "dev": true,
2028 | "requires": {
2029 | "p-locate": "^3.0.0",
2030 | "path-exists": "^3.0.0"
2031 | }
2032 | },
2033 | "p-locate": {
2034 | "version": "3.0.0",
2035 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
2036 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
2037 | "dev": true,
2038 | "requires": {
2039 | "p-limit": "^2.0.0"
2040 | }
2041 | },
2042 | "path-exists": {
2043 | "version": "3.0.0",
2044 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
2045 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
2046 | "dev": true
2047 | },
2048 | "string-width": {
2049 | "version": "3.1.0",
2050 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
2051 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
2052 | "dev": true,
2053 | "requires": {
2054 | "emoji-regex": "^7.0.1",
2055 | "is-fullwidth-code-point": "^2.0.0",
2056 | "strip-ansi": "^5.1.0"
2057 | }
2058 | },
2059 | "yargs-parser": {
2060 | "version": "13.1.2",
2061 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
2062 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
2063 | "dev": true,
2064 | "requires": {
2065 | "camelcase": "^5.0.0",
2066 | "decamelize": "^1.2.0"
2067 | }
2068 | }
2069 | }
2070 | },
2071 | "yargs-unparser": {
2072 | "version": "1.6.0",
2073 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
2074 | "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
2075 | "dev": true,
2076 | "requires": {
2077 | "flat": "^4.1.0",
2078 | "lodash": "^4.17.15",
2079 | "yargs": "^13.3.0"
2080 | }
2081 | }
2082 | }
2083 | }
2084 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vscode-text-tables",
3 | "displayName": "Text Tables",
4 | "description": "Work with text tables without pain",
5 | "version": "0.1.5",
6 | "icon": "icons/icon.png",
7 | "preview": false,
8 | "publisher": "RomanPeshkov",
9 | "license": "SEE LICENSE IN LICENSE",
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/rpeshkov/vscode-text-tables"
13 | },
14 | "engines": {
15 | "vscode": "^1.45.0"
16 | },
17 | "categories": [
18 | "Formatters",
19 | "Other"
20 | ],
21 | "keywords": [
22 | "org-mode",
23 | "org",
24 | "tables",
25 | "markdown"
26 | ],
27 | "activationEvents": [
28 | "onLanguage:markdown",
29 | "onLanguage:org",
30 | "onCommand:text-tables.enable"
31 | ],
32 | "main": "./out/src/extension",
33 | "contributes": {
34 | "commands": [
35 | {
36 | "command": "text-tables.enable",
37 | "title": "Text Tables: Enable"
38 | },
39 | {
40 | "command": "text-tables.formatUnderCursor",
41 | "title": "Text Tables: Format under cursor"
42 | },
43 | {
44 | "command": "text-tables.tableModeOn",
45 | "title": "Text Tables: Enter table mode"
46 | },
47 | {
48 | "command": "text-tables.tableModeOff",
49 | "title": "Text Tables: Exit table mode"
50 | },
51 | {
52 | "command": "text-tables.gotoNextCell",
53 | "title": "Text Tables: Go to next cell"
54 | },
55 | {
56 | "command": "text-tables.gotoPreviousCell",
57 | "title": "Text Tables: Go to previous cell"
58 | },
59 | {
60 | "command": "text-tables.createTable",
61 | "title": "Text Tables: Create table"
62 | },
63 | {
64 | "command": "text-tables.clearCell",
65 | "title": "Text Tables: Clear cell"
66 | },
67 | {
68 | "command": "text-tables.moveRowDown",
69 | "title": "Move row down",
70 | "category": "Text Tables"
71 | },
72 | {
73 | "command": "text-tables.moveRowUp",
74 | "title": "Move row up",
75 | "category": "Text Tables"
76 | },
77 | {
78 | "command": "text-tables.moveColRight",
79 | "title": "Move column right",
80 | "category": "Text Tables"
81 | },
82 | {
83 | "command": "text-tables.moveColLeft",
84 | "title": "Move column left",
85 | "category": "Text Tables"
86 | },
87 | {
88 | "command": "text-tables.nextRow",
89 | "title": "Next row",
90 | "category": "Text Tables"
91 | }
92 | ],
93 | "configuration": {
94 | "type": "object",
95 | "title": "Text Tables configuration",
96 | "properties": {
97 | "text-tables.mode": {
98 | "type": "string",
99 | "enum": [
100 | "markdown",
101 | "org"
102 | ],
103 | "default": "markdown",
104 | "description": "Sets the mode in which extension should work",
105 | "scope": "window"
106 | },
107 | "text-tables.showStatus": {
108 | "type": "boolean",
109 | "default": true,
110 | "description": "Show table mode status bar item",
111 | "scope": "window"
112 | }
113 | }
114 | },
115 | "keybindings": [
116 | {
117 | "command": "text-tables.formatUnderCursor",
118 | "key": "ctrl+q ctrl+f"
119 | },
120 | {
121 | "command": "text-tables.clearCell",
122 | "key": "ctrl+q space"
123 | },
124 | {
125 | "command": "text-tables.tableModeOn",
126 | "key": "ctrl+q ctrl+q",
127 | "when": "editorFocus && !tableMode"
128 | },
129 | {
130 | "command": "text-tables.tableModeOff",
131 | "key": "ctrl+q ctrl+q",
132 | "when": "editorFocus && tableMode"
133 | },
134 | {
135 | "command": "text-tables.gotoNextCell",
136 | "key": "tab",
137 | "when": "tableMode"
138 | },
139 | {
140 | "command": "text-tables.gotoPreviousCell",
141 | "key": "shift+tab",
142 | "when": "tableMode"
143 | },
144 | {
145 | "command": "text-tables.moveRowUp",
146 | "key": "alt+up",
147 | "when": "tableMode"
148 | },
149 | {
150 | "command": "text-tables.moveRowDown",
151 | "key": "alt+down",
152 | "when": "tableMode"
153 | },
154 | {
155 | "command": "text-tables.moveColRight",
156 | "key": "alt+right",
157 | "when": "tableMode"
158 | },
159 | {
160 | "command": "text-tables.moveColLeft",
161 | "key": "alt+left",
162 | "when": "tableMode"
163 | },
164 | {
165 | "command": "text-tables.nextRow",
166 | "key": "enter",
167 | "when": "tableMode"
168 | }
169 | ]
170 | },
171 | "scripts": {
172 | "vscode:prepublish": "npm run compile",
173 | "compile": "tsc -p ./",
174 | "watch": "tsc -watch -p ./",
175 | "pretest": "npm run compile && npm run lint",
176 | "test": "node ./out/test/runTest.js",
177 | "lint": "eslint src --ext ts"
178 | },
179 | "devDependencies": {
180 | "@types/glob": "^7.1.1",
181 | "@types/mocha": "^7.0.2",
182 | "@types/node": "^7.10.11",
183 | "@types/vscode": "^1.45.1",
184 | "@typescript-eslint/eslint-plugin": "^2.30.0",
185 | "@typescript-eslint/parser": "^2.30.0",
186 | "decache": "^4.6.0",
187 | "eslint": "^6.8.0",
188 | "glob": "^7.1.6",
189 | "mocha": "^7.2.0",
190 | "typescript": "^3.8.3",
191 | "vscode-test": "^1.3.0"
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/src/commands.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 | import { Table, RowType, Stringifier, TableNavigator, Parser } from './ttTable';
3 |
4 | /**
5 | * Create new table with specified rows and columns count in position of cursor
6 | */
7 | export async function createTable(rowsCount: number, colsCount: number, editor: vscode.TextEditor, stringifier: Stringifier) {
8 | const table = new Table();
9 | for (let i = 0; i < rowsCount + 1; i++) {
10 | table.addRow(RowType.Data, new Array(colsCount).fill(''));
11 | }
12 | table.rows[1].type = RowType.Separator;
13 |
14 | const currentPosition = editor.selection.start;
15 | await editor.edit(b => b.insert(currentPosition, stringifier.stringify(table)));
16 | editor.selection = new vscode.Selection(currentPosition, currentPosition);
17 | }
18 |
19 | /**
20 | * Swap row under cursor with row below
21 | */
22 | export async function moveRowDown(editor: vscode.TextEditor, _range: vscode.Range, table: Table) {
23 | const rowNum = editor.selection.end.line - table.startLine;
24 | if (rowNum >= table.rows.length - 1) {
25 | vscode.window.showWarningMessage('Cannot move row further');
26 | return;
27 | }
28 | await vscode.commands.executeCommand('editor.action.moveLinesDownAction');
29 | }
30 |
31 | /**
32 | * Swap row under cursor with row above
33 | */
34 | export async function moveRowUp(editor: vscode.TextEditor, _range: vscode.Range, table: Table) {
35 | const rowNum = editor.selection.start.line - table.startLine;
36 | if (rowNum <= 0) {
37 | vscode.window.showWarningMessage('Cannot move row further');
38 | return;
39 | }
40 | await vscode.commands.executeCommand('editor.action.moveLinesUpAction');
41 | }
42 |
43 | /**
44 | * Move cursor to the next cell of table
45 | */
46 | export async function gotoNextCell(editor: vscode.TextEditor, range: vscode.Range, table: Table,
47 | stringifier: Stringifier) {
48 |
49 | const nav = new TableNavigator(table);
50 | const newPos = nav.nextCell(editor.selection.start);
51 | if (newPos) {
52 | await formatUnderCursor(editor, range, table, stringifier);
53 | editor.selection = new vscode.Selection(newPos, newPos);
54 | } else {
55 | table.addRow(RowType.Data, new Array(table.cols.length).fill(''));
56 | await gotoNextCell(editor, range, table, stringifier);
57 | }
58 | }
59 |
60 | /**
61 | * Move cursor to the previous cell of table
62 | */
63 | export async function gotoPreviousCell(editor: vscode.TextEditor, _range: vscode.Range, table: Table) {
64 | const nav = new TableNavigator(table);
65 | const newPos = nav.previousCell(editor.selection.start);
66 | if (newPos) {
67 | editor.selection = new vscode.Selection(newPos, newPos);
68 | }
69 | }
70 |
71 | /**
72 | * Format table under cursor
73 | */
74 | export async function formatUnderCursor(editor: vscode.TextEditor, range: vscode.Range, table: Table, stringifier: Stringifier) {
75 | const newText = stringifier.stringify(table);
76 | const prevSel = editor.selection.start;
77 |
78 | await editor.edit(e => e.replace(range, newText));
79 | editor.selection = new vscode.Selection(prevSel, prevSel);
80 | }
81 |
82 | /**
83 | * Swap column under cursor with column on the right
84 | */
85 | export async function moveColRight(editor: vscode.TextEditor, range: vscode.Range, table: Table, stringifier: Stringifier) {
86 | const rowCol = rowColFromPosition(table, editor.selection.start);
87 | if (rowCol.col < 0) {
88 | vscode.window.showWarningMessage('Not in table data field');
89 | return;
90 | }
91 |
92 | if (rowCol.col >= table.cols.length - 1 ) {
93 | vscode.window.showWarningMessage('Cannot move column further right');
94 | return;
95 | }
96 |
97 | [table.cols[rowCol.col], table.cols[rowCol.col + 1]] = [table.cols[rowCol.col + 1], table.cols[rowCol.col]];
98 |
99 | table.rows.forEach((_, i) => {
100 | const v1 = table.getAt(i, rowCol.col);
101 | const v2 = table.getAt(i, rowCol.col + 1);
102 | table.setAt(i, rowCol.col + 1, v1);
103 | table.setAt(i, rowCol.col, v2);
104 | });
105 |
106 | const newText = stringifier.stringify(table);
107 | await editor.edit(e => e.replace(range, newText));
108 | await gotoNextCell(editor, range, table, stringifier);
109 | }
110 |
111 | /**
112 | * Swap column under cursor with column on the left
113 | */
114 | export async function moveColLeft(editor: vscode.TextEditor, range: vscode.Range, table: Table, stringifier: Stringifier) {
115 | const rowCol = rowColFromPosition(table, editor.selection.start);
116 | if (rowCol.col < 0) {
117 | vscode.window.showWarningMessage('Not in table data field');
118 | return;
119 | }
120 |
121 | if (rowCol.col === 0) {
122 | vscode.window.showWarningMessage('Cannot move column further left');
123 | return;
124 | }
125 |
126 | [table.cols[rowCol.col], table.cols[rowCol.col - 1]] = [table.cols[rowCol.col - 1], table.cols[rowCol.col]];
127 |
128 | table.rows.forEach((_, i) => {
129 | const v1 = table.getAt(i, rowCol.col);
130 | const v2 = table.getAt(i, rowCol.col - 1);
131 | table.setAt(i, rowCol.col - 1, v1);
132 | table.setAt(i, rowCol.col, v2);
133 | });
134 |
135 | const newText = stringifier.stringify(table);
136 | await editor.edit(e => e.replace(range, newText));
137 | await gotoPreviousCell(editor, range, table);
138 | }
139 |
140 | /**
141 | * Clear cell under cursor
142 | */
143 | export function clearCell(editor: vscode.TextEditor, edit: vscode.TextEditorEdit, parser: Parser) {
144 | const document = editor.document;
145 | const currentLineNumber = editor.selection.start.line;
146 | const currentLine = document.lineAt(currentLineNumber);
147 |
148 | if (parser.isSeparatorRow(currentLine.text)) {
149 | vscode.window.showInformationMessage('Not in table data field');
150 | return;
151 | }
152 |
153 | const leftSepPosition = currentLine.text.lastIndexOf('|', editor.selection.start.character - 1);
154 | let rightSepPosition = currentLine.text.indexOf('|', editor.selection.start.character);
155 | if (rightSepPosition < 0) {
156 | rightSepPosition = currentLine.range.end.character;
157 | }
158 |
159 | if (leftSepPosition === rightSepPosition) {
160 | vscode.window.showInformationMessage('Not in table data field');
161 | return;
162 | }
163 |
164 | const r = new vscode.Range(currentLineNumber, leftSepPosition + 1, currentLineNumber, rightSepPosition);
165 | edit.replace(r, ' '.repeat(rightSepPosition - leftSepPosition - 1));
166 | const newPos = new vscode.Position(currentLineNumber, leftSepPosition + 2);
167 | editor.selection = new vscode.Selection(newPos, newPos);
168 | }
169 |
170 | /**
171 | * Moves cursor to the next row. If cursor is in the last row of table, create new row
172 | */
173 | export async function nextRow(editor: vscode.TextEditor, range: vscode.Range, table: Table, stringifier: Stringifier) {
174 | const inLastRow = range.end.line === editor.selection.start.line;
175 |
176 | if (inLastRow) {
177 | table.addRow(RowType.Data, new Array(table.cols.length).fill(''));
178 | }
179 |
180 | await editor.edit(b => b.replace(range, stringifier.stringify(table)));
181 |
182 | const nav = new TableNavigator(table);
183 | const nextRowPos = nav.nextRow(editor.selection.start);
184 | if (nextRowPos) {
185 | editor.selection = new vscode.Selection(nextRowPos, nextRowPos);
186 | }
187 | }
188 |
189 | function rowColFromPosition(table: Table, position: vscode.Position): { row: number, col: number } {
190 | const result = { row: -1, col: -1 };
191 |
192 | result.row = position.line - table.startLine;
193 | let counter = 1;
194 | for (let i = 0; i < table.cols.length; ++i) {
195 | const col = table.cols[i];
196 | if (position.character >= counter && position.character < counter + col.width + 3) {
197 | result.col = i;
198 | break;
199 | }
200 |
201 | counter += col.width + 3;
202 | }
203 |
204 | return result;
205 | }
206 |
--------------------------------------------------------------------------------
/src/configuration.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 |
3 | export const section = 'text-tables';
4 |
5 | export const modeKey = 'mode';
6 | export const showStatusKey = 'showStatus';
7 |
8 | export enum Mode {
9 | Org = 'org',
10 | Markdown = 'markdown'
11 | }
12 |
13 | export interface Configuration {
14 | mode: Mode;
15 | showStatus: boolean;
16 | }
17 |
18 | export function build(): Configuration {
19 | const c = vscode.workspace.getConfiguration(section);
20 |
21 | return {
22 | mode: c.get(modeKey, Mode.Markdown),
23 | showStatus: c.get(showStatusKey, true)
24 | };
25 | }
26 |
27 | export async function override(overrides: any) {
28 | const c = vscode.workspace.getConfiguration(section);
29 | for (const k of Object.keys(overrides)) {
30 | await c.update(k, overrides[k], false);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/context.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 |
3 | export enum ContextType {
4 | TableMode = 'tableMode'
5 | }
6 |
7 | const contexts: Map = new Map();
8 | const state: Map = new Map();
9 |
10 | export function registerContext(type: ContextType, title: string, statusItem?: vscode.StatusBarItem) {
11 | const ctx = new Context(type, title, statusItem);
12 | contexts.set(type, ctx);
13 | ctx.setState(false);
14 | }
15 |
16 | export function enterContext(editor: vscode.TextEditor, type: ContextType) {
17 | const ctx = contexts.get(type);
18 | if (ctx) {
19 | ctx.setState(true);
20 |
21 | const editorState = state.get(editor.document.fileName) || [];
22 | state.set(editor.document.fileName, editorState.concat(type));
23 | }
24 | }
25 |
26 | export function exitContext(editor: vscode.TextEditor, type: ContextType) {
27 | const ctx = contexts.get(type);
28 | if (ctx) {
29 | ctx.setState(false);
30 |
31 | const editorState = state.get(editor.document.fileName) || [];
32 | state.set(editor.document.fileName, editorState.filter(x => x !== type));
33 | }
34 | }
35 |
36 | export function restoreContext(editor: vscode.TextEditor) {
37 | let toEnter: ContextType[] = [];
38 | // @ts-ignore
39 | let toExit: ContextType[] = Object.keys(ContextType).map((x: any) => ContextType[x] as ContextType);
40 |
41 | if (state.has(editor.document.fileName)) {
42 | toEnter = state.get(editor.document.fileName)!;
43 | toExit = toExit.filter(x => toEnter.indexOf(x) < 0);
44 | }
45 |
46 | toEnter.forEach(x => enterContext(editor, x));
47 | toExit.forEach(x => exitContext(editor, x));
48 | }
49 |
50 | class Context {
51 | constructor(private type: ContextType, private title: string, private statusItem?: vscode.StatusBarItem) {
52 |
53 | }
54 |
55 | setState(isEnabled: boolean) {
56 | vscode.commands.executeCommand('setContext', this.type, isEnabled);
57 | if (this.statusItem) {
58 | const stateText = isEnabled ? 'On' : 'Off';
59 | this.statusItem.text = `${this.title}: ${stateText}`;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as utils from './utils';
5 | import * as cmd from './commands';
6 | import { OrgLocator, OrgParser, OrgStringifier } from './ttOrg';
7 | import { Locator, Parser, Stringifier, Table } from './ttTable';
8 | import { MarkdownLocator, MarkdownParser, MarkdownStringifier } from './ttMarkdown';
9 | import { isUndefined } from 'util';
10 | import { registerContext, ContextType, enterContext, exitContext, restoreContext } from './context';
11 | import * as cfg from './configuration';
12 |
13 | let locator: Locator;
14 | let parser: Parser;
15 | let stringifier: Stringifier;
16 | let configuration: cfg.Configuration;
17 |
18 | function loadConfiguration() {
19 | configuration = cfg.build();
20 |
21 | if (configuration.mode === cfg.Mode.Org) {
22 | locator = new OrgLocator();
23 | parser = new OrgParser();
24 | stringifier = new OrgStringifier();
25 | } else {
26 | locator = new MarkdownLocator();
27 | parser = new MarkdownParser();
28 | stringifier = new MarkdownStringifier();
29 | }
30 | }
31 |
32 | export function activate(ctx: vscode.ExtensionContext) {
33 | loadConfiguration();
34 |
35 | const statusItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
36 | registerContext(ContextType.TableMode, '$(book) Table Mode', statusItem);
37 |
38 | if (configuration.showStatus) {
39 | statusItem.show();
40 | }
41 |
42 | vscode.workspace.onDidChangeConfiguration(() => {
43 | loadConfiguration();
44 |
45 | if (configuration.showStatus) {
46 | statusItem.show();
47 | } else {
48 | statusItem.hide();
49 | }
50 | });
51 |
52 | vscode.window.onDidChangeActiveTextEditor(e => {
53 | if (e) {
54 | restoreContext(e);
55 | }
56 | });
57 |
58 | ctx.subscriptions.push(vscode.commands.registerCommand('text-tables.enable', () => {
59 | vscode.window.showInformationMessage('Text tables enabled!');
60 | }));
61 |
62 | ctx.subscriptions.push(vscode.commands.registerTextEditorCommand('text-tables.tableModeOn',
63 | (e) => enterContext(e, ContextType.TableMode)));
64 | ctx.subscriptions.push(vscode.commands.registerTextEditorCommand('text-tables.tableModeOff',
65 | (e) => exitContext(e, ContextType.TableMode)));
66 |
67 | ctx.subscriptions.push(registerTableCommand('text-tables.moveRowDown', cmd.moveRowDown, {format: true}));
68 | ctx.subscriptions.push(registerTableCommand('text-tables.moveRowUp', cmd.moveRowUp, {format: true}));
69 | ctx.subscriptions.push(registerTableCommand('text-tables.moveColRight', async (editor, range, table) => {
70 | await cmd.moveColRight(editor, range, table, stringifier);
71 | }));
72 | ctx.subscriptions.push(registerTableCommand('text-tables.moveColLeft', async (editor, range, table) => {
73 | await cmd.moveColLeft(editor, range, table, stringifier);
74 | }));
75 |
76 | ctx.subscriptions.push(vscode.commands.registerTextEditorCommand('text-tables.clearCell',
77 | (e, ed) => cmd.clearCell(e, ed, parser)));
78 |
79 | ctx.subscriptions.push(registerTableCommand('text-tables.gotoNextCell', async (editor, range, table) => {
80 | await cmd.gotoNextCell(editor, range, table, stringifier);
81 | }));
82 |
83 | ctx.subscriptions.push(registerTableCommand('text-tables.gotoPreviousCell', cmd.gotoPreviousCell, {format: true}));
84 | ctx.subscriptions.push(registerTableCommand('text-tables.nextRow', async (editor, range, table) => {
85 | await cmd.nextRow(editor, range, table, stringifier);
86 | }));
87 |
88 | // Format table under cursor
89 | ctx.subscriptions.push(registerTableCommand('text-tables.formatUnderCursor',
90 | (editor, range, table) => cmd.formatUnderCursor(editor, range, table, stringifier)));
91 |
92 | ctx.subscriptions.push(vscode.commands.registerTextEditorCommand('text-tables.createTable', async editor => {
93 | const opts: vscode.InputBoxOptions = {
94 | value: '5x2',
95 | prompt: 'Table size Columns x Rows (e.g. 5x2)',
96 | validateInput: (value: string) => {
97 | if (!utils.tableSizeRe.test(value)) {
98 | return 'Provided value is invalid. Please provide the value in format Columns x Rows (e.g. 5x2)';
99 | }
100 | return;
101 | }
102 | };
103 |
104 | const size = await vscode.window.showInputBox(opts);
105 | if (size) {
106 | const match = size.match(utils.tableSizeRe);
107 | if (match) {
108 | const cols = +match[1] || 1;
109 | const rows = +match[2] || 2;
110 | cmd.createTable(rows, cols, editor, stringifier);
111 | }
112 | }
113 | }));
114 | }
115 |
116 | export function deactivate() {
117 | }
118 |
119 | type TableCommandCallback = (editor: vscode.TextEditor, tableLocation: vscode.Range, table: Table) => Thenable;
120 |
121 | function registerTableCommand(command: string, callback: TableCommandCallback, options?: {format: boolean}) {
122 | return vscode.commands.registerCommand(command, async () => {
123 | const editor = vscode.window.activeTextEditor;
124 |
125 | if (isUndefined(editor)) {
126 | return;
127 | }
128 |
129 | const tableRange = locator.locate(editor.document, editor.selection.start.line);
130 | if (isUndefined(tableRange)) {
131 | return;
132 | }
133 | const selectedText = editor.document.getText(tableRange);
134 | const table = parser.parse(selectedText);
135 |
136 | if (isUndefined(table)) {
137 | return;
138 | }
139 |
140 | table.startLine = tableRange.start.line;
141 |
142 | if (options && options.format) {
143 | await cmd.formatUnderCursor(editor, tableRange, table, stringifier);
144 | }
145 |
146 | await callback(editor, tableRange, table);
147 | });
148 | }
149 |
--------------------------------------------------------------------------------
/src/ttMarkdown.ts:
--------------------------------------------------------------------------------
1 | import * as tt from './ttTable';
2 | import * as vscode from 'vscode';
3 | import { RowType } from './ttTable';
4 |
5 | const verticalSeparator = '|';
6 | const horizontalSeparator = '-';
7 |
8 | type StringReducer = (previous: string, current: string, index: number) => string;
9 |
10 | export class MarkdownParser implements tt.Parser {
11 | parse(text: string): tt.Table | undefined {
12 | if (!text || text.length === 0) {
13 | return undefined;
14 | }
15 |
16 | const result = new tt.Table();
17 | const strings = text.split('\n').map(x => x.trim()).filter(x => x.startsWith(verticalSeparator));
18 |
19 | for (const s of strings) {
20 | const cleanedString = s.replace(/\s+/g, '');
21 |
22 | if (this.isSeparatorRow(cleanedString)) {
23 | result.addRow(tt.RowType.Separator, []);
24 | const startIndex = cleanedString.startsWith(verticalSeparator) ? 1 : 0;
25 | const endIndex = cleanedString.length - (cleanedString.endsWith(verticalSeparator) ? 1 : 0);
26 | const rowParts = cleanedString.slice(startIndex, endIndex).split('|');
27 |
28 | rowParts.forEach((part, i) => {
29 | if (part.length < 3) {
30 | return;
31 | }
32 | const trimmed = part.trim();
33 | let align = tt.Alignment.Left;
34 | if (trimmed[trimmed.length - 1] === ':') {
35 | if (trimmed[0] === ':') {
36 | align = tt.Alignment.Center;
37 | } else {
38 | align = tt.Alignment.Right;
39 | }
40 | }
41 | const col = result.cols[i];
42 | if (col) {
43 | col.alignment = align;
44 | } else {
45 | result.cols.push({ alignment: align, width: 3 });
46 | }
47 | });
48 |
49 | continue;
50 | }
51 |
52 | const lastIndex = s.length - (s.endsWith(verticalSeparator) ? 1 : 0);
53 |
54 | const values = s
55 | .slice(1, lastIndex)
56 | .split(verticalSeparator)
57 | .map(x => x.trim());
58 |
59 | result.addRow(tt.RowType.Data, values);
60 | }
61 |
62 | if (result.rows.some(x => x.type === RowType.Separator)) {
63 | result.cols.forEach(x => x.width = Math.max(x.width, 3));
64 | }
65 |
66 | return result;
67 | }
68 |
69 | isSeparatorRow(text: string): boolean {
70 | const cleaned = text.replace(/\s+/g, '');
71 | return cleaned.startsWith('|-') || cleaned.startsWith('|:-');
72 | }
73 | }
74 |
75 | export class MarkdownStringifier implements tt.Stringifier {
76 | private reducers = new Map([
77 | [tt.RowType.Data, this.dataRowReducer],
78 | [tt.RowType.Separator, this.separatorReducer],
79 | ]);
80 |
81 | stringify(table: tt.Table): string {
82 | const result = [];
83 |
84 | if (table.rows.some(x => x.type === RowType.Separator)) {
85 | table.cols.forEach(x => x.width = Math.max(x.width, 3));
86 | }
87 |
88 | for (let i = 0; i < table.rows.length; ++i) {
89 | let rowString = '';
90 | const rowData = table.getRow(i);
91 | const reducer = this.reducers.get(table.rows[i].type);
92 | if (reducer) {
93 | rowString = rowData.reduce(reducer(table.cols), verticalSeparator);
94 | }
95 | result.push(rowString);
96 | }
97 |
98 | return result.join('\n');
99 | }
100 |
101 | private dataRowReducer(cols: tt.ColDef[]): StringReducer {
102 | return (prev, cur, idx) => {
103 | const pad = ' '.repeat(cols[idx].width - cur.length + 1);
104 | return prev + ' ' + cur + pad + verticalSeparator;
105 | };
106 | }
107 |
108 | private separatorReducer(cols: tt.ColDef[]): StringReducer {
109 | return (prev, _, idx) => {
110 | const begin = cols[idx].alignment === tt.Alignment.Center
111 | ? ' :'
112 | : ' -';
113 | const ending = cols[idx].alignment !== tt.Alignment.Left
114 | ? ': ' + verticalSeparator
115 | : '- ' + verticalSeparator;
116 |
117 | const middle = horizontalSeparator.repeat(cols[idx].width - 2);
118 |
119 | return prev + begin + middle + ending;
120 | };
121 | }
122 | }
123 |
124 | export class MarkdownLocator implements tt.Locator {
125 | locate(reader: tt.LineReader, lineNr: number): vscode.Range | undefined {
126 | const isTableLikeString = (ln: number) => {
127 | if (ln < 0 || ln >= reader.lineCount) {
128 | return false;
129 | }
130 | const firstCharIdx = reader.lineAt(ln).firstNonWhitespaceCharacterIndex;
131 | const firstChar = reader.lineAt(ln).text[firstCharIdx];
132 | return firstChar === '|';
133 | };
134 |
135 | let start = lineNr;
136 | while (isTableLikeString(start)) {
137 | start--;
138 | }
139 |
140 | let end = lineNr;
141 | while (isTableLikeString(end)) {
142 | end++;
143 | }
144 |
145 | if (start === end) {
146 | return undefined;
147 | }
148 |
149 | const startPos = reader.lineAt(start + 1).range.start;
150 | const endPos = reader.lineAt(end - 1).range.end;
151 |
152 | return new vscode.Range(startPos, endPos);
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/ttOrg.ts:
--------------------------------------------------------------------------------
1 | import * as tt from './ttTable';
2 | import * as vscode from 'vscode';
3 |
4 | const verticalSeparator = '|';
5 | const horizontalSeparator = '-';
6 | const intersection = '+';
7 |
8 | type StringReducer = (previous: string, current: string, index: number) => string;
9 |
10 | export class OrgParser implements tt.Parser {
11 | parse(text: string): tt.Table | undefined {
12 | if (!text || text.length === 0) {
13 | return undefined;
14 | }
15 |
16 | const result = new tt.Table();
17 | const strings = text.split('\n').map(x => x.trim()).filter(x => x.startsWith(verticalSeparator));
18 |
19 | for (const s of strings) {
20 | if (this.isSeparatorRow(s)) {
21 | result.addRow(tt.RowType.Separator, []);
22 | continue;
23 | }
24 |
25 | const lastIndex = s.length - (s.endsWith(verticalSeparator) ? 1 : 0);
26 | const values = s
27 | .slice(1, lastIndex)
28 | .split(verticalSeparator)
29 | .map(x => x.trim());
30 |
31 | result.addRow(tt.RowType.Data, values);
32 | }
33 |
34 | return result;
35 | }
36 |
37 | isSeparatorRow(text: string): boolean {
38 | return text.length > 1 && text[1] === horizontalSeparator;
39 | }
40 | }
41 |
42 | export class OrgStringifier implements tt.Stringifier {
43 | private reducers = new Map([
44 | [tt.RowType.Data, this.dataRowReducer],
45 | [tt.RowType.Separator, this.separatorReducer],
46 | ]);
47 |
48 | stringify(table: tt.Table): string {
49 | const result = [];
50 |
51 | for (let i = 0; i < table.rows.length; ++i) {
52 | let rowString = '';
53 | const rowData = table.getRow(i);
54 | const reducer = this.reducers.get(table.rows[i].type);
55 | if (reducer) {
56 | rowString = rowData.reduce(reducer(table.cols), verticalSeparator);
57 | }
58 |
59 | result.push(rowString);
60 | }
61 |
62 | return result.join('\n');
63 | }
64 |
65 | private dataRowReducer(cols: tt.ColDef[]): StringReducer {
66 | return (prev, cur, idx) => {
67 | const pad = ' '.repeat(cols[idx].width - cur.length + 1);
68 | return prev + ' ' + cur + pad + verticalSeparator;
69 | };
70 | }
71 |
72 | private separatorReducer(cols: tt.ColDef[]): (p: string, c: string, i: number) => string {
73 | return (prev, _, idx) => {
74 | // Intersections for each cell are '+', except the last one, where it should be '|'
75 | const ending = (idx === cols.length - 1)
76 | ? verticalSeparator
77 | : intersection;
78 |
79 | return prev + horizontalSeparator.repeat(cols[idx].width + 2) + ending;
80 | };
81 | }
82 | }
83 |
84 | export class OrgLocator implements tt.Locator {
85 | /**
86 | * Locate start and end of Org table in text from line number.
87 | *
88 | * @param reader Reader that is able to read line by line
89 | * @param lineNr Current line number
90 | * @returns vscode.Range if table was located. undefined if it failed
91 | */
92 | locate(reader: tt.LineReader, lineNr: number): vscode.Range | undefined {
93 |
94 | // Checks that line starts with vertical bar
95 | const isTableLikeString = (ln: number) => {
96 | if (ln < 0 || ln >= reader.lineCount) {
97 | return false;
98 | }
99 | const line = reader.lineAt(ln);
100 | const firstCharIdx = line.firstNonWhitespaceCharacterIndex;
101 | const firstChar = line.text[firstCharIdx];
102 | return firstChar === '|';
103 | };
104 |
105 | let start = lineNr;
106 | while (isTableLikeString(start)) {
107 | start--;
108 | }
109 |
110 | let end = lineNr;
111 | while (isTableLikeString(end)) {
112 | end++;
113 | }
114 |
115 | if (start === end) {
116 | return undefined;
117 | }
118 |
119 | const startPos = reader.lineAt(start + 1).range.start;
120 | const endPos = reader.lineAt(end - 1).range.end;
121 |
122 | return new vscode.Range(startPos, endPos);
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/ttTable.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 |
3 | export enum RowType {
4 | Unknown,
5 | Separator,
6 | Data
7 | }
8 |
9 | export enum Alignment {
10 | Left,
11 | Center,
12 | Right
13 | }
14 |
15 | export interface RowDef {
16 | type: RowType;
17 | }
18 |
19 | export interface ColDef {
20 | alignment: Alignment;
21 | width: number;
22 | }
23 |
24 | export class Table {
25 | /**
26 | * Line where the table starts
27 | */
28 | startLine = 0;
29 |
30 | rows: RowDef[] = [];
31 | cols: ColDef[] = [];
32 |
33 | private data: string[][] = [];
34 |
35 | addRow(type: RowType, values: string[]) {
36 | let adjustCount = values.length - this.cols.length;
37 | while (adjustCount-- > 0) {
38 | this.cols.push({ alignment: Alignment.Left, width: 0 });
39 | }
40 |
41 | for (const row of this.data) {
42 | const adjustee = row.length < values.length ? row : values;
43 | adjustCount = Math.abs(row.length - values.length);
44 |
45 | while (adjustCount-- > 0) {
46 | adjustee.push('');
47 | }
48 | }
49 |
50 | this.cols.forEach((col, i) => col.width = Math.max(col.width, values[i].length));
51 |
52 | this.rows.push({ type });
53 | this.data.push(values);
54 | }
55 |
56 | getAt(row: number, col: number): string {
57 | return this.data[row][col];
58 | }
59 |
60 | getRow(row: number): string[] {
61 | return this.data[row];
62 | }
63 |
64 | setAt(row: number, col: number, value: string) {
65 | if (this.cols[col].width < value.length) {
66 | this.cols[col].width = value.length;
67 | }
68 |
69 | this.data[row][col] = value;
70 | }
71 | }
72 |
73 | export interface Parser {
74 | parse(text: string): Table | undefined;
75 | isSeparatorRow(text: string): boolean;
76 | }
77 |
78 | export interface Stringifier {
79 | stringify(table: Table): string;
80 | }
81 |
82 | export interface Locator {
83 | locate(reader: LineReader, lineNr: number): vscode.Range | undefined;
84 | }
85 |
86 | export interface LineReader {
87 | lineAt(line: number): vscode.TextLine;
88 | lineCount: number;
89 | }
90 |
91 | class JumpPosition {
92 | constructor(start: vscode.Position, end: vscode.Position, public isSeparator: boolean, prev?: JumpPosition) {
93 | this.range = new vscode.Range(start, end);
94 |
95 | if (prev) {
96 | prev.next = this;
97 | this.prev = prev;
98 | }
99 | }
100 |
101 | range: vscode.Range;
102 | next?: JumpPosition;
103 | prev?: JumpPosition;
104 | }
105 |
106 | export class TableNavigator {
107 | private jumpPositions: JumpPosition[] = [];
108 |
109 | constructor(public table: Table) {
110 | this.jumpPositions = this.buildJumpPositions();
111 | }
112 |
113 | nextCell(cursorPosition: vscode.Position): vscode.Position | undefined {
114 | return this.jump(cursorPosition, x => x.next!);
115 | }
116 |
117 | previousCell(cursorPosition: vscode.Position): vscode.Position | undefined {
118 | return this.jump(cursorPosition, x => x.prev!);
119 | }
120 |
121 | nextRow(cursorPosition: vscode.Position): vscode.Position | undefined {
122 | const nextRowJump = this.jumpPositions.find(x => x.range.contains(cursorPosition.translate(1)));
123 | if (!nextRowJump) {
124 | return undefined;
125 | }
126 |
127 | return nextRowJump.range.start.translate(0, 1);
128 | }
129 |
130 | private jump(currentPosition: vscode.Position, accessor: (x: JumpPosition) => JumpPosition): vscode.Position | undefined {
131 | let jmp = this.jumpPositions.find(x => x.range.contains(currentPosition));
132 | if (jmp) {
133 | jmp = accessor(jmp);
134 | if (jmp) {
135 | if (jmp.isSeparator) {
136 | if (!accessor(jmp)) {
137 | return undefined;
138 | }
139 | jmp = accessor(jmp);
140 | }
141 | return jmp.range.start.translate(0, 1);
142 | }
143 | }
144 |
145 | // Maybe we're just outside left part of table? Let's move cursor a bit...
146 | if (currentPosition.character === 0) {
147 | return currentPosition.translate(0, 2);
148 | } else {
149 | return undefined;
150 | }
151 | }
152 |
153 | private buildJumpPositions(): JumpPosition[] {
154 | const result: JumpPosition[] = [];
155 |
156 | const cellPadding = 2;
157 | let lastAnchor = 0;
158 | const anchors = this.table.cols.reduce((accum, col) => {
159 | lastAnchor += col.width + cellPadding + 1;
160 | accum.push(lastAnchor);
161 | return accum;
162 | }, [lastAnchor]);
163 | // extend last point to "infinity"
164 | anchors[anchors.length - 1] = 999;
165 |
166 | for (let i = 0; i < this.table.rows.length; ++i) {
167 | const row = this.table.rows[i];
168 | const rowLine = this.table.startLine + i;
169 |
170 | if (row.type === RowType.Separator) {
171 | const prevJmpPos = result[result.length - 1];
172 | // Extend last range to whole separator line or start from beginning of line
173 | const start = prevJmpPos
174 | ? prevJmpPos.range.end
175 | : new vscode.Position(rowLine, 0);
176 | const end = start.translate(1);
177 | const jmpPos = new JumpPosition(start, end, true, prevJmpPos);
178 | result.push(jmpPos);
179 | } else {
180 | for (let j = 0; j < anchors.length - 1; ++j) {
181 | const prevJmpPos = result[result.length - 1];
182 | const start = new vscode.Position(rowLine, anchors[j] + 1);
183 | const end = new vscode.Position(rowLine, anchors[j + 1]);
184 | const jmpPos = new JumpPosition(start, end, false, prevJmpPos);
185 | result.push(jmpPos);
186 | }
187 | }
188 | }
189 | return result;
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | export const tableSizeRe = /^(\d+)x(\d+)$/u;
2 |
--------------------------------------------------------------------------------
/test/commands.test.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 | import * as assert from 'assert';
3 | import * as cfg from '../src/configuration';
4 |
5 | import * as cmd from '../src/commands';
6 | import { MarkdownStringifier } from '../src/ttMarkdown';
7 | import { OrgStringifier } from '../src/ttOrg';
8 |
9 | async function inTextEditor(options: { language?: string; content?: string; },
10 | cb: (editor: vscode.TextEditor, document: vscode.TextDocument) => void) {
11 | const d = await vscode.workspace.openTextDocument(options);
12 | await vscode.window.showTextDocument(d);
13 | await cb(vscode.window.activeTextEditor!, d);
14 | }
15 |
16 | function move(editor: vscode.TextEditor, line: number, col: number) {
17 | const pos = new vscode.Position(line, col);
18 | editor.selection = new vscode.Selection(pos, pos);
19 | }
20 |
21 | suite('Commands', () => {
22 | test('Test "Create table" for markdown', async () => {
23 | const expectedResult = `| | |
24 | | --- | --- |
25 | | | |`;
26 |
27 | await inTextEditor({language: 'markdown'}, async (editor, document) => {
28 | await cfg.override({'mode': cfg.Mode.Markdown});
29 | await cmd.createTable(2, 2, editor, new MarkdownStringifier());
30 | assert.equal(document.getText(), expectedResult);
31 | });
32 | }).timeout(10000);
33 |
34 | test('Test "Create table" for org', async () => {
35 | const expectedResult = `| | |
36 | |--+--|
37 | | | |`;
38 |
39 | await inTextEditor({language: 'org'}, async (editor, document) => {
40 | await cfg.override({'mode': cfg.Mode.Org});
41 | await cmd.createTable(2, 2, editor, new OrgStringifier());
42 | assert.equal(document.getText(), expectedResult);
43 | });
44 | });
45 |
46 | test('Test "Clear cell"', async () => {
47 | const testCase =
48 | `| Hello | World | Some other text
49 | | ----- | ----- |`;
50 | const expectedResult =
51 | `| | World | \n` +
52 | `| ----- | ----- |`;
53 |
54 | await inTextEditor({language: 'markdown', content: testCase}, async (editor, document) => {
55 | await cfg.override({mode: 'markdown'});
56 | await vscode.commands.executeCommand('text-tables.clearCell');
57 | move(editor, 0, 2);
58 | await vscode.commands.executeCommand('text-tables.clearCell');
59 | move(editor, 0, 17);
60 | await vscode.commands.executeCommand('text-tables.clearCell');
61 | move(editor, 1, 2);
62 | await vscode.commands.executeCommand('text-tables.clearCell');
63 | assert.equal(document.getText(), expectedResult);
64 | });
65 | });
66 |
67 | test('Test "Go to next cell"', async () => {
68 | const input = `| | |
69 | |--+--|
70 | | | |`;
71 | const expected = `| | |
72 | |--+--|
73 | | | |
74 | | | |`;
75 |
76 | const testCases = [
77 | new vscode.Position(0, 2),
78 | new vscode.Position(0, 5),
79 | new vscode.Position(2, 2),
80 | new vscode.Position(2, 5),
81 | new vscode.Position(3, 2),
82 | new vscode.Position(3, 5),
83 | ];
84 |
85 | await inTextEditor({language: 'markdown', content: input}, async (editor, document) => {
86 | await cfg.override({mode: 'org'});
87 | for (const t of testCases) {
88 | await vscode.commands.executeCommand('text-tables.gotoNextCell');
89 | assert.deepEqual(editor.selection.start, t);
90 | }
91 |
92 | assert.equal(document.getText(), expected);
93 | });
94 | });
95 |
96 | test('Test "Go to previous cell"', async () => {
97 | const input = `| | |
98 | |--+--|
99 | | | |`;
100 |
101 | const testCases = [
102 | new vscode.Position(2, 2),
103 | new vscode.Position(0, 5),
104 | new vscode.Position(0, 2),
105 | // Repeated intentionally to check that it won't jump outside
106 | new vscode.Position(0, 2),
107 | ];
108 |
109 | await inTextEditor({language: 'markdown', content: input}, async (editor, _) => {
110 | await cfg.override({mode: 'org'});
111 | move(editor, 2, 5);
112 | for (const t of testCases) {
113 | await vscode.commands.executeCommand('text-tables.gotoPreviousCell');
114 | assert.deepEqual(editor.selection.start, t);
115 | }
116 | });
117 | });
118 |
119 | test('Test "Move row down"', async () => {
120 | const input = `| 1 | 2 |
121 | |---+---|
122 | | 3 | 4 |`;
123 |
124 | const steps = [
125 | `|---+---|
126 | | 1 | 2 |
127 | | 3 | 4 |`
128 | ,
129 | `|---+---|
130 | | 3 | 4 |
131 | | 1 | 2 |`,
132 | `|---+---|
133 | | 3 | 4 |
134 | | 1 | 2 |`
135 | ];
136 |
137 | await inTextEditor({language: 'org', content: input}, async (_, document) => {
138 | await cfg.override({mode: 'org'});
139 |
140 | for (const expected of steps) {
141 | await vscode.commands.executeCommand('text-tables.moveRowDown');
142 | assert.equal(document.getText(), expected);
143 | }
144 | });
145 | });
146 |
147 | test('Test "Move row up"', async () => {
148 | const input =
149 | `|---+---|
150 | | 3 | 4 |
151 | | 1 | 2 |`;
152 |
153 | const steps = [
154 | `|---+---|
155 | | 1 | 2 |
156 | | 3 | 4 |`
157 | ,
158 | `| 1 | 2 |
159 | |---+---|
160 | | 3 | 4 |`
161 | ,
162 | `| 1 | 2 |
163 | |---+---|
164 | | 3 | 4 |`
165 |
166 | ];
167 |
168 | await inTextEditor({language: 'org', content: input}, async (editor, document) => {
169 | await cfg.override({mode: 'org'});
170 | move(editor, 2, 0);
171 | for (const expected of steps) {
172 | await vscode.commands.executeCommand('text-tables.moveRowUp');
173 | assert.equal(document.getText(), expected);
174 | }
175 | });
176 | });
177 |
178 | test('Test "Move col right"', async () => {
179 | const input =
180 | `| 1 | 2 | 3 |
181 | | 4 | 5 | 6 |`;
182 |
183 | const steps = [
184 | `| 2 | 1 | 3 |
185 | | 5 | 4 | 6 |`
186 | ,
187 | `| 2 | 3 | 1 |
188 | | 5 | 6 | 4 |`
189 | ,
190 | `| 2 | 3 | 1 |
191 | | 5 | 6 | 4 |`
192 |
193 | ];
194 |
195 | await inTextEditor({language: 'org', content: input}, async (editor, document) => {
196 | await cfg.override({mode: 'org'});
197 | move(editor, 0, 2);
198 | for (const expected of steps) {
199 | await vscode.commands.executeCommand('text-tables.moveColRight');
200 | assert.equal(document.getText(), expected);
201 | }
202 | });
203 | });
204 |
205 | test('Test "Move col left"', async () => {
206 | const input =
207 | `| 1 | 2 | 3 |
208 | | 4 | 5 | 6 |`;
209 |
210 | const steps = [
211 | `| 1 | 3 | 2 |
212 | | 4 | 6 | 5 |`
213 | ,
214 | `| 3 | 1 | 2 |
215 | | 6 | 4 | 5 |`
216 | ,
217 | `| 3 | 1 | 2 |
218 | | 6 | 4 | 5 |`
219 | ];
220 |
221 | await inTextEditor({language: 'org', content: input}, async (editor, document) => {
222 | await cfg.override({mode: 'org'});
223 | move(editor, 0, 10);
224 | for (const expected of steps) {
225 | await vscode.commands.executeCommand('text-tables.moveColLeft');
226 | assert.equal(document.getText(), expected);
227 | }
228 | });
229 | });
230 |
231 | test('Test "Format under cursor"', async () => {
232 | const input =
233 | `| 1 | 2 | 3 |
234 | | 4 | 5 | 6 |`;
235 |
236 | const expected =
237 | `| 1 | 2 | 3 |
238 | | 4 | 5 | 6 |`;
239 |
240 | await inTextEditor({language: 'org', content: input}, async (_, document) => {
241 | await cfg.override({mode: 'org'});
242 |
243 | await vscode.commands.executeCommand('text-tables.formatUnderCursor');
244 | assert.equal(document.getText(), expected);
245 | });
246 | });
247 |
248 | test('Test "Format under cursor" for markdown', async () => {
249 | const input =
250 | `| 1 | 2 |
251 | | --- |
252 | | 4 | 5 | 6 |`;
253 |
254 | const expected =
255 | `| 1 | 2 | |
256 | | --- | --- | --- |
257 | | 4 | 5 | 6 |`;
258 |
259 | await inTextEditor({language: 'markdown', content: input}, async (_, document) => {
260 | await cfg.override({mode: 'markdown'});
261 |
262 | await vscode.commands.executeCommand('text-tables.formatUnderCursor');
263 | assert.equal(document.getText(), expected);
264 | });
265 | });
266 |
267 | test('Test "Next Row"', async () => {
268 | const input =
269 | `| Row |
270 | | Row2 |`;
271 |
272 | const steps = [
273 | `| Row |
274 | | Row2 |`
275 | ,
276 | `| Row |
277 | | Row2 |
278 | | |`
279 | ,
280 | `| Row |
281 | | Row2 |
282 | | |
283 | | |`
284 | ];
285 |
286 | await inTextEditor({language: 'org', content: input}, async (editor, document) => {
287 | await cfg.override({mode: 'org'});
288 | move(editor, 0, 2);
289 | for (const expected of steps) {
290 | await vscode.commands.executeCommand('text-tables.nextRow');
291 | assert.equal(document.getText(), expected);
292 | }
293 | });
294 | });
295 | });
296 |
--------------------------------------------------------------------------------
/test/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as Mocha from 'mocha';
3 | import * as glob from 'glob';
4 |
5 | export function run(): Promise {
6 | // Create the mocha test
7 | const mocha = new Mocha({
8 | ui: 'tdd',
9 | color: true
10 | });
11 |
12 | const testsRoot = path.resolve(__dirname, '..');
13 |
14 | return new Promise((c, e) => {
15 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
16 | if (err) {
17 | return e(err);
18 | }
19 |
20 | // Add files to the test suite
21 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
22 |
23 | try {
24 | // Run the mocha test
25 | mocha.run(failures => {
26 | if (failures > 0) {
27 | e(new Error(`${failures} tests failed.`));
28 | } else {
29 | c();
30 | }
31 | });
32 | } catch (err) {
33 | console.error(err);
34 | e(err);
35 | }
36 | });
37 | });
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/test/runTest.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 |
3 | import { runTests } from 'vscode-test';
4 |
5 | async function main() {
6 | try {
7 | // The folder containing the Extension Manifest package.json
8 | // Passed to `--extensionDevelopmentPath`
9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../');
10 |
11 | // The path to test runner
12 | // Passed to --extensionTestsPath
13 | const extensionTestsPath = path.resolve(__dirname, './index');
14 |
15 | const testWorkspace = path.resolve(__dirname, '../../e2e')
16 |
17 |
18 | // Download VS Code, unzip it and run the integration test
19 | await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: [testWorkspace]});
20 | } catch (err) {
21 | console.error('Failed to run tests');
22 | process.exit(1);
23 | }
24 | }
25 |
26 | main();
27 |
28 |
--------------------------------------------------------------------------------
/test/table-navigator.test.ts:
--------------------------------------------------------------------------------
1 | import * as assert from 'assert';
2 | import * as vscode from 'vscode';
3 | import { Table, TableNavigator, RowType } from '../src/ttTable';
4 |
5 | suite('TableNavigator', () => {
6 | let table: Table;
7 | let navigator: TableNavigator;
8 |
9 | setup(() => {
10 | table = new Table();
11 | table.addRow(RowType.Data, ['Column 1', 'Column 2']);
12 | table.addRow(RowType.Separator, ['', '']);
13 | table.addRow(RowType.Data, ['1', '2']);
14 | table.addRow(RowType.Data, ['3', '4']);
15 | table.addRow(RowType.Separator, ['', '']);
16 |
17 | navigator = new TableNavigator(table);
18 | });
19 |
20 | test('constructor should initialize table property', () => {
21 | assert.equal(navigator.table, table);
22 | });
23 |
24 | suite('nextCell', () => {
25 | test('should select first column when cursor in the beginning of line', () => {
26 | const pos = new vscode.Position(0, 0);
27 | const newPos = navigator.nextCell(pos);
28 |
29 | assert.equal(newPos!.line, 0);
30 | assert.equal(newPos!.character, 2);
31 | });
32 |
33 | test('should navigate next cell', () => {
34 | const pos = new vscode.Position(0, 2);
35 | const newPos = navigator.nextCell(pos);
36 | assert.equal(newPos!.line, 0);
37 | assert.equal(newPos!.character, 13);
38 | });
39 |
40 | test('should jump to next row', () => {
41 | const pos = new vscode.Position(2, 13);
42 | const newPos = navigator.nextCell(pos);
43 | assert.equal(newPos!.line, 3);
44 | assert.equal(newPos!.character, 2);
45 | });
46 |
47 | test('should skip separator row', () => {
48 | const pos = new vscode.Position(0, 13);
49 | const newPos = navigator.nextCell(pos);
50 | assert.equal(newPos!.line, 2);
51 | assert.equal(newPos!.character, 2);
52 | });
53 |
54 | test('should not move if cursor is on separator and it\'s the last line', () => {
55 | const pos = new vscode.Position(4, 13);
56 | const newPos = navigator.nextCell(pos);
57 | assert.equal(newPos, undefined);
58 | });
59 |
60 | test('should not move if cursor in last cell and there is separator line below', () => {
61 | const pos = new vscode.Position(3, 13);
62 | const newPos = navigator.nextCell(pos);
63 | assert.equal(newPos, undefined);
64 | });
65 | });
66 |
67 | suite('previousCell', () => {
68 | test('should navigate previous cell', () => {
69 | const pos = new vscode.Position(0, 13);
70 | const newPos = navigator.previousCell(pos);
71 | assert.equal(newPos!.line, 0);
72 | assert.equal(newPos!.character, 2);
73 | });
74 |
75 | test('should jump to prev row', () => {
76 | const pos = new vscode.Position(1, 2);
77 | const newPos = navigator.previousCell(pos);
78 | assert.equal(newPos!.line, 0);
79 | assert.equal(newPos!.character, 13);
80 | });
81 | });
82 | });
83 |
--------------------------------------------------------------------------------
/test/ttMarkdown.test.ts:
--------------------------------------------------------------------------------
1 | import * as assert from 'assert';
2 | import { MarkdownParser } from '../src/ttMarkdown';
3 | import { RowType } from '../src/ttTable';
4 |
5 | suite('Text tables. Markdown', () => {
6 | suite('Parser', () => {
7 | let parser: MarkdownParser;
8 | setup(() => {
9 | parser = new MarkdownParser();
10 | });
11 |
12 | test('should return undefined when incorrect text provided', () => {
13 | const table = parser.parse('');
14 | assert.equal(table, undefined);
15 | });
16 |
17 | test('should return table when correct text provided', () => {
18 | const table = parser.parse('a');
19 | assert.notEqual(table, undefined);
20 | });
21 |
22 | test('should add row when string starts with |', () => {
23 | const table = parser.parse('|');
24 | if (table !== undefined) {
25 | assert.equal(table.rows.length, 1);
26 | assert.equal(table.rows[0].type, RowType.Data);
27 | assert.equal(table.cols.length, 1);
28 | }
29 | });
30 |
31 | test('should parse "| -" as separator row', () => {
32 | const table = parser.parse('| -');
33 | assert.notEqual(table, undefined);
34 | if (table !== undefined) {
35 | assert.equal(table.rows.length, 1);
36 | assert.equal(table.rows[0].type, RowType.Separator);
37 | }
38 | });
39 |
40 | test('should parse "| :-" as separator row', () => {
41 | const table = parser.parse('| :-');
42 | assert.notEqual(table, undefined);
43 | if (table !== undefined) {
44 | assert.equal(table.rows.length, 1);
45 | assert.equal(table.rows[0].type, RowType.Separator);
46 | }
47 | });
48 |
49 | test('should split columns by |', () => {
50 | const table = parser.parse('||||');
51 | if (table !== undefined) {
52 | assert.equal(table.rows.length, 1);
53 | assert.equal(table.cols.length, 3);
54 | }
55 | });
56 |
57 | test('should handle last characters as column', () => {
58 | const table = parser.parse('||Last col');
59 | if (table !== undefined) {
60 | assert.equal(table.cols.length, 2);
61 | }
62 | });
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/test/ttOrg.test.ts:
--------------------------------------------------------------------------------
1 | import * as assert from 'assert';
2 | import { OrgParser } from '../src/ttOrg';
3 | import { RowType } from '../src/ttTable';
4 |
5 | suite('Text tables. Org', () => {
6 | suite('Parser', () => {
7 | let parser: OrgParser;
8 | setup(() => {
9 | parser = new OrgParser();
10 | });
11 |
12 | test('should return undefined when incorrect text provided', () => {
13 | const table = parser.parse('');
14 | assert.equal(table, undefined);
15 | });
16 |
17 | test('should return table when correct text provided', () => {
18 | const table = parser.parse('a');
19 | assert.notEqual(table, undefined);
20 | });
21 |
22 | test('should add row when string starts with |', () => {
23 | const table = parser.parse('|');
24 | if (table !== undefined) {
25 | assert.equal(table.rows.length, 1);
26 | assert.equal(table.rows[0].type, RowType.Data);
27 | assert.equal(table.cols.length, 1);
28 | }
29 | });
30 |
31 | test('should parse |- as separator row', () => {
32 | const table = parser.parse('|-');
33 | assert.notEqual(table, undefined);
34 | if (table !== undefined) {
35 | assert.equal(table.rows.length, 1);
36 | assert.equal(table.rows[0].type, RowType.Separator);
37 | }
38 | });
39 |
40 | test('should split columns by |', () => {
41 | const table = parser.parse('||||');
42 | if (table !== undefined) {
43 | assert.equal(table.rows.length, 1);
44 | assert.equal(table.cols.length, 3);
45 | }
46 | });
47 |
48 | test('should handle last characters as column', () => {
49 | const table = parser.parse('||Last col');
50 | if (table !== undefined) {
51 | assert.equal(table.cols.length, 2);
52 | }
53 | });
54 | });
55 | });
56 |
--------------------------------------------------------------------------------
/test/ttTable.test.ts:
--------------------------------------------------------------------------------
1 | import * as assert from 'assert';
2 | import { Table, RowType } from '../src/ttTable';
3 |
4 | suite('Text tables. Table', () => {
5 | let table: Table;
6 |
7 | setup(() => {
8 | table = new Table();
9 | });
10 |
11 | test('It creates', () => {
12 | assert.notEqual(table, undefined);
13 | });
14 |
15 | test('It should add rows', () => {
16 | table.addRow(RowType.Data, []);
17 | assert.equal(table.rows.length, 1);
18 | });
19 |
20 | test('It should update cols when row values provided', () => {
21 | table.addRow(RowType.Data, ['Value1', 'Value2']);
22 | assert.equal(table.cols.length, 2);
23 |
24 | table.addRow(RowType.Data, ['NewValue1', 'NewValue2', 'NewValue3']);
25 | assert.equal(table.cols.length, 3);
26 | });
27 |
28 | test('It should recalculate columns widths when adding values', () => {
29 | table.addRow(RowType.Data, ['C']);
30 | assert.equal(table.cols[0].width, 1);
31 |
32 | table.addRow(RowType.Data, ['Column']);
33 | assert.equal(table.cols[0].width, 6);
34 | });
35 |
36 | test('getAt returns value of cell', () => {
37 | table.addRow(RowType.Data, ['1.1', '1.2']);
38 | table.addRow(RowType.Data, ['2.1', '2.2']);
39 |
40 | assert.equal(table.getAt(0, 0), '1.1');
41 | assert.equal(table.getAt(0, 1), '1.2');
42 | assert.equal(table.getAt(1, 0), '2.1');
43 | assert.equal(table.getAt(1, 1), '2.2');
44 | });
45 |
46 | test('getRow returns array of data in row', () => {
47 | table.addRow(RowType.Data, ['1', '2']);
48 |
49 | assert.deepEqual(table.getRow(0), ['1', '2']);
50 | });
51 |
52 | test('setAt should set new value for cell', () => {
53 | table.addRow(RowType.Data, ['1', '2']);
54 | table.setAt(0, 0, 'NewValue');
55 | assert.equal(table.getAt(0, 0), 'NewValue');
56 | assert.deepEqual(table.getRow(0), ['NewValue', '2']);
57 | });
58 |
59 | test('setAt should update column width', () => {
60 | table.addRow(RowType.Data, ['1']);
61 | table.setAt(0, 0, 'Long');
62 | assert.equal(table.cols[0].width, 4);
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es6",
5 | "outDir": "out",
6 | "lib": [
7 | "es6"
8 | ],
9 | "sourceMap": true,
10 | "rootDir": ".",
11 | /* Strict Type-Checking Option */
12 | "strict": true, /* enable all strict type-checking options */
13 | /* Additional Checks */
14 | "noUnusedLocals": true, /* Report errors on unused locals. */
15 | "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
16 | "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
17 | "noUnusedParameters": true, /* Report errors on unused parameters. */
18 | },
19 | "exclude": [
20 | "node_modules",
21 | ".vscode-test"
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------