├── resources
└── screencasts
│ ├── screencast-2.gif
│ └── screencast-1.svg
├── .editorconfig
├── lib
├── theme.js
├── predict-progressbar-width.js
├── parse-ffmpeg-log.js
├── formatter.js
├── progress-bar.js
└── main.js
├── .gitignore
├── .npmignore
├── .jsdoc.json
├── LICENSE
├── CONTRIBUTING.md
├── package.json
├── .eslintrc
├── README.md
└── yarn.lock
/resources/screencasts/screencast-2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sidneys/ffmpeg-progressbar-cli/HEAD/resources/screencasts/screencast-2.gif
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 4
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [.eslintrc]
13 | indent_size = 2
14 |
15 | [*.json]
16 | indent_size = 2
17 |
18 | [*.md]
19 | trim_trailing_whitespace = false
20 |
21 | [*.yml]
22 | indent_size = 2
23 |
--------------------------------------------------------------------------------
/lib/theme.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 |
4 | /**
5 | * Modules
6 | * External
7 | * @constant
8 | */
9 | const chalk = require('chalk')
10 |
11 | /**
12 | * @namespace chalk
13 | * @function chalk.rgb
14 | */
15 |
16 | /**
17 | * @module theme
18 | */
19 | module.exports = {
20 | filenameLabel: chalk.rgb(180, 255, 220),
21 | filename: chalk.rgb(0, 255, 155).bold,
22 | beam: chalk.rgb(64, 0, 255),
23 | percentage: chalk.rgb(226, 217, 255),
24 | etaLabel: chalk.rgb(255, 180, 150),
25 | eta: chalk.rgb(255, 55, 0).bold,
26 | prompt: chalk.rgb(255, 230, 0).bold,
27 | error: chalk.rgb(255, 0, 0).bold,
28 | warning: chalk.rgb(255, 165, 0).bold
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## BASE
2 |
3 | # macOS
4 | .DS_Store
5 |
6 | # Logs
7 | logs
8 | *.log
9 |
10 | # Temporary
11 | temp
12 | tmp
13 |
14 | # Caches
15 | .cache
16 | cache
17 | .sass-cache
18 |
19 | # JetBrains
20 | .idea
21 | *.sln.iml
22 |
23 | # VSCode
24 | .vscode
25 |
26 | # Compiled
27 | build
28 |
29 | # Generated documentation
30 | RELEASENOTES.md
31 |
32 |
33 | ## NODE.JS
34 |
35 | # Modules
36 | node_modules
37 | jspm_packages
38 | bower_components
39 |
40 | # Runtime data
41 | pids
42 | *.pid
43 | *.seed
44 |
45 | # Directory for instrumented libs generated by jscoverage/JSCover
46 | lib-cov
47 |
48 | # Coverage directory used by tools like istanbul
49 | coverage
50 |
51 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
52 | .grunt
53 |
54 | # Generated documentation
55 | docs
56 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | ## BASE
2 |
3 | # macOS
4 | .DS_Store
5 |
6 | # Logs
7 | logs
8 | *.log
9 |
10 | # Temporary
11 | temp
12 | tmp
13 |
14 | # Caches
15 | .cache
16 | cache
17 | .sass-cache
18 |
19 | # JetBrains
20 | .idea
21 | *.sln.iml
22 |
23 | # VSCode
24 | .vscode
25 |
26 | # Compiled
27 | build
28 |
29 | # Generated documentation
30 | RELEASENOTES.md
31 |
32 |
33 | ## NODE.JS
34 |
35 | # Modules
36 | node_modules
37 | jspm_packages
38 | bower_components
39 |
40 | # Runtime data
41 | pids
42 | *.pid
43 | *.seed
44 |
45 | # Directory for instrumented libs generated by jscoverage/JSCover
46 | lib-cov
47 |
48 | # Coverage directory used by tools like istanbul
49 | coverage
50 |
51 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
52 | .grunt
53 |
54 | # Generated documentation
55 | docs
56 |
--------------------------------------------------------------------------------
/.jsdoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "tags": {
3 | "allowUnknownTags": true
4 | },
5 | "source": {
6 | "include": [
7 | "./lib",
8 | "package.json",
9 | "README.md"
10 | ],
11 | "includePattern": ".js$",
12 | "excludePattern": "(node_modules/|docs)"
13 | },
14 | "plugins": ["plugins/markdown"],
15 | "opts": {
16 | "destination": "./docs",
17 | "encoding": "utf8",
18 | "recurse": true,
19 | "template": "./node_modules/docdash",
20 | "verbose": true
21 | },
22 | "markdown": {
23 | "parser": "gfm",
24 | "hardwrap": true
25 | },
26 | "templates": {
27 | "cleverLinks": false,
28 | "monospaceLinks": false,
29 | "default": {
30 | "outputSourceFiles": true,
31 | "includeDate": false
32 | }
33 | },
34 | "docdash": {
35 | "static": false,
36 | "sort": true
37 | }
38 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 sidneys.github.io
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Creating Issues
4 |
5 | To file bug reports and feature suggestions, use the ["Issues"](https://github.com/sidneys/ffmpeg-progressbar-cli/issues?q=is%3Aissue) page.
6 |
7 | 1. Make sure the issue has not been filed before.
8 | 1. Create a new issue by filling out [the issue form](https://github.com/sidneys/ffmpeg-progressbar-cli/issues/new).
9 | 1. If an issue requires more information and receives no further input, it will be closed.
10 |
11 |
12 | ## Creating Pull Requests
13 |
14 | To create pull requests, use the ["Pull Requests"](https://github.com/sidneys/ffmpeg-progressbar-cli/pulls) page.
15 |
16 | 1. [Create a new Issue](#creating-issues) describing the Bug or Feature you are addressing, to let others know you are working on it.
17 | 1. If a related issue exists, add a comment to let others know that you'll submit a pull request.
18 | 1. Create a new pull request by filling out [the pull request form](https://github.com/sidneys/ffmpeg-progressbar-cli/pulls/compare).
19 |
20 |
21 | ### Setup
22 |
23 | 1. Fork the repository.
24 | 1. Clone your fork.
25 | 1. Make a branch for your change.
26 | 1. Run `npm install`.
27 |
28 | ## Commit Messages
29 |
30 | Use the `Conventional Commits` format.
31 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ffmpeg-progressbar-cli",
3 | "version": "1.5.0",
4 | "description": "A colored progress bar for FFmpeg. Simply use `ffmpeg-bar` instead of `ffmpeg`.",
5 | "license": "MIT",
6 | "homepage": "https://github.com/sidneys/ffmpeg-progressbar-cli",
7 | "author": {
8 | "name": "sidneys",
9 | "email": "sidneys.github.io@outlook.com",
10 | "url": "https://sidneys.github.io"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "https://github.com/sidneys/ffmpeg-progressbar-cli.git"
15 | },
16 | "bugs": {
17 | "url": "https://github.com/sidneys/ffmpeg-progressbar-cli/issues"
18 | },
19 | "engines": {
20 | "node": ">=8.11.3"
21 | },
22 | "os": [
23 | "darwin",
24 | "win32",
25 | "linux"
26 | ],
27 | "keywords": [
28 | "FFmpeg",
29 | "progress bar",
30 | "colored",
31 | "media",
32 | "commandline",
33 | "terminal",
34 | "cli",
35 | "video",
36 | "conversion"
37 | ],
38 | "preferGlobal": true,
39 | "dependencies": {
40 | "@sidneys/cli-progress": "^2.2.0",
41 | "app-root-path": "^2.1.0",
42 | "chalk": "^2.4.1",
43 | "ellipsize": "^0.1.0",
44 | "ini": "^1.3.5",
45 | "moment": "^2.22.2",
46 | "moment-duration-format": "^2.2.2",
47 | "string-width": "^2.1.1",
48 | "which": "^1.3.1",
49 | "window-size": "^1.1.1"
50 | },
51 | "devDependencies": {
52 | "docdash": "^1.0.0",
53 | "eslint": "^5.9.0",
54 | "jsdoc": "^3.5.5"
55 | },
56 | "main": "./lib/main.js",
57 | "bin": {
58 | "ffmpeg-bar": "./lib/main.js"
59 | },
60 | "scripts": {
61 | "docs": "jsdoc --verbose --configure .jsdoc.json",
62 | "start": "node ./lib/main.js"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/lib/predict-progressbar-width.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 |
4 | /**
5 | * Modules
6 | * External
7 | * @constant
8 | */
9 | const windowSize = require('window-size')
10 |
11 |
12 | /**
13 | * Calculate the progress bars' text components width (fixed width)
14 | * @param {Number} targetFilenameLength - Target filename length
15 | * @returns {Number} - String length
16 | *
17 | * @private
18 | */
19 | let predictTextWidth = (targetFilenameLength) => {
20 | // console.debug('predictTextWidth()')
21 |
22 | // TEXT LABEL WIDTH
23 | // 🎬 Rendering 12
24 | // BAR_FILENAME_LENGTH 10
25 | // | {percentagePad}% | ETA {etaTimecode} 20
26 |
27 | const barTextWidth = 12 + targetFilenameLength + 20
28 |
29 | const correctionFactor = 4
30 |
31 | return barTextWidth - correctionFactor
32 | }
33 |
34 | /**
35 | * Calculate the progress bars' beam width (variable width)
36 | * @param {Number} targetFilenameLength - Target filename length
37 | * @param {Number} targetBarBeamRatio - Target bar beam ratio
38 | * @returns {Number} - String length
39 | *
40 | * @private
41 | */
42 | let predictBeamWidth = (targetFilenameLength, targetBarBeamRatio) => {
43 | // console.debug('predictBeamWidth()')
44 |
45 | const barBeamWidth = (windowSize.get().width - predictTextWidth(targetFilenameLength)) * targetBarBeamRatio
46 |
47 | return Math.floor(barBeamWidth)
48 | }
49 |
50 | /**
51 | * Calculate the progress bars' beam total width
52 | * @param {Number} targetFilenameLength - Target filename length
53 | * @param {Number} targetBarBeamRatio - Target bar beam ratio
54 | * @returns {Number} - String length
55 | */
56 | let predictTotalWidth = (targetFilenameLength, targetBarBeamRatio) => {
57 | // console.debug('approximateBarWidth()')
58 |
59 | return predictTextWidth(targetFilenameLength) + predictBeamWidth(targetFilenameLength, targetBarBeamRatio)
60 | }
61 |
62 |
63 | /**
64 | * @module predict-progressbar-width.js
65 | */
66 | module.exports = {
67 | beam: predictBeamWidth,
68 | text: predictTextWidth,
69 | total: predictTotalWidth
70 | }
71 |
72 |
--------------------------------------------------------------------------------
/lib/parse-ffmpeg-log.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * Modules
5 | * Node
6 | * @constant
7 | */
8 | const path = require('path')
9 |
10 | /**
11 | * Modules
12 | * External
13 | * @constant
14 | */
15 | const moment = require('moment')
16 | /* eslint-disable no-unused-vars */
17 | const momentDurationFormat = require('moment-duration-format')
18 | /* eslint-enable */
19 |
20 |
21 | /**
22 | * Parse FFmpeg log for "y/N" question
23 | * @param {String} text - FFmpeg Log Output
24 | * @returns {String|void} - First output filepath
25 | */
26 | let parseFFmpegLogForQuestion = (text) => {
27 | // console.debug('searchQuestionLog')
28 |
29 | let questionLine = text.match(/.*(\[y\/N\]).*$/gmi)
30 |
31 | if (!questionLine) { return }
32 |
33 | questionLine = questionLine[0]
34 | questionLine = questionLine.replace(/\'/gmi, '')
35 |
36 | return questionLine
37 | }
38 |
39 | /**
40 | * Parse FFmpeg log for "Duration: "
41 | * @param {String} text - FFmpeg Log Output
42 | * @returns {Number|void} - Duration (milliseconds)
43 | */
44 | let parseFFmpegLogForDuration = (text) => {
45 | // console.debug('searchDurationLog')
46 |
47 | const durationList = text.match(/Duration: (.{2}):(.{2}):(.{2}).(.{2})/)
48 |
49 | if (!durationList) { return }
50 |
51 | // Grep
52 | const timecode = `${durationList[1]}:${durationList[2]}:${durationList[3]}.${durationList[4].padEnd(3, '0')}`
53 |
54 | // Format
55 | const timecodeMoment = moment.duration(timecode)
56 |
57 | return timecodeMoment.asMilliseconds()
58 | }
59 |
60 | /**
61 | * Parse FFmpeg log for "Output #0"
62 | * @param {String} text - FFmpeg Log Output
63 | * @returns {String|void} - First output filepath
64 | */
65 | let parseFFmpegLogForOutput = (text) => {
66 | // console.debug('searchOutputLog')
67 |
68 | let outputLine = text.match(/(?:Output #0).*$/gmi)
69 |
70 | if (!outputLine) { return }
71 |
72 | outputLine = outputLine[0]
73 | outputLine = outputLine.match(/'(.*?)'/gmi)[0]
74 | outputLine = outputLine.replace(/\'/gmi, '')
75 |
76 | return path.resolve(outputLine)
77 | }
78 |
79 |
80 | /**
81 | * @exports parse-ffmpeg-log
82 | */
83 | module.exports = {
84 | output: parseFFmpegLogForOutput,
85 | duration: parseFFmpegLogForDuration,
86 | question: parseFFmpegLogForQuestion
87 | }
88 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "node": true
6 | },
7 | "parserOptions": {
8 | "ecmaVersion": 6,
9 | "ecmaFeatures": {
10 | "globalReturn": true,
11 | "impliedStrict": true,
12 | "jsx": true
13 | }
14 | },
15 | "root": true,
16 | "rules": {
17 | "brace-style": [
18 | "error",
19 | "1tbs",
20 | {
21 | "allowSingleLine": true
22 | }
23 | ],
24 | "camelcase": "off",
25 | "comma-dangle": [
26 | "error",
27 | "never"
28 | ],
29 | "comma-style": [
30 | "error",
31 | "last"
32 | ],
33 | "curly": "error",
34 | "dot-notation": "off",
35 | "eol-last": "error",
36 | "eqeqeq": "error",
37 | "indent": [
38 | "error",
39 | 4,
40 | {
41 | "MemberExpression": "off",
42 | "SwitchCase": 1
43 | }
44 | ],
45 | "key-spacing": [
46 | "error",
47 | {
48 | "afterColon": true,
49 | "beforeColon": false
50 | }
51 | ],
52 | "keyword-spacing": [
53 | "error",
54 | {
55 | "after": true,
56 | "before": true
57 | }
58 | ],
59 | "linebreak-style": [
60 | "error",
61 | "unix"
62 | ],
63 | "no-bitwise": "off",
64 | "no-caller": "error",
65 | "no-mixed-spaces-and-tabs": "error",
66 | "no-multi-str": "error",
67 | "no-trailing-spaces": "error",
68 | "no-undef": "error",
69 | "no-unused-vars": [
70 | "error",
71 | {
72 | "args": "none",
73 | "vars": "local"
74 | }
75 | ],
76 | "no-use-before-define": [
77 | "error",
78 | {
79 | "functions": false
80 | }
81 | ],
82 | "no-with": "error",
83 | "object-curly-spacing": [
84 | "error",
85 | "always"
86 | ],
87 | "object-shorthand": "off",
88 | "quotes": [
89 | "error",
90 | "single",
91 | {
92 | "allowTemplateLiterals": true
93 | }
94 | ],
95 | "semi": [
96 | "error",
97 | "never"
98 | ],
99 | "space-before-blocks": [
100 | "error",
101 | "always"
102 | ],
103 | "space-before-function-paren": [
104 | "error",
105 | {
106 | "anonymous": "ignore",
107 | "named": "never"
108 | }
109 | ],
110 | "space-in-parens": [
111 | "error",
112 | "never"
113 | ],
114 | "space-infix-ops": "error",
115 | "space-unary-ops": [
116 | "error",
117 | {
118 | "words": false,
119 | "nonwords": false
120 | }
121 | ],
122 | "valid-jsdoc": [
123 | "warn",
124 | {
125 | "requireReturn": false,
126 | "requireReturnDescription": false
127 | }
128 | ],
129 | "wrap-iife": "off"
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/lib/formatter.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 |
4 | /**
5 | * Modules
6 | * Node
7 | * @constant
8 | */
9 | const path = require('path')
10 |
11 | /**
12 | * Modules
13 | * External
14 | * @constant
15 | */
16 | const appRootPath = require('app-root-path')
17 | appRootPath.setPath(path.join(__dirname, '..'))
18 | const ellipsize = require('ellipsize')
19 | const stringWidth = require('string-width')
20 |
21 |
22 | /**
23 | * Ellipse character
24 | * @type {string}
25 | * @constant
26 | * @default
27 | */
28 | const ellipseCharacter = '…'
29 |
30 | /**
31 | * Convert file paths to prettified file name
32 | * @param {String} filePath - File path
33 | * @param {Number=} targetLength - File name length before adding ellipsis
34 | * @returns {String} - File name
35 | */
36 | let filepathToFilename = (filePath, targetLength = 10) => {
37 | // console.debug('prettyFilenameForFilepath')
38 |
39 | let fileName
40 |
41 | // Format fileName
42 | const fileExtension = path.extname(filePath)
43 | const fileTitle = path.basename(filePath, fileExtension)
44 |
45 | // Lengths
46 | const fileExtensionLength = stringWidth(fileExtension)
47 | const fileTitleLength = stringWidth(fileTitle)
48 | const fileNameLength = fileTitleLength + fileExtensionLength
49 |
50 | /**
51 | * File name string formatter
52 | * Handles most edge cases of file name/file extension lengths
53 | */
54 | if (fileNameLength > targetLength) {
55 | if (fileExtensionLength < (targetLength - 2)) {
56 | // Name too long: ellipse title, leave extension as-is
57 | // filetit….extension
58 | fileName = `${ellipsize(fileTitle, targetLength - fileExtensionLength, { ellipse: ellipseCharacter })}${fileExtension}`
59 | } else {
60 | // Name too long, extension too long: Ellipse title, hide extension
61 | // filetit…
62 | fileName = `${ellipsize(fileTitle, targetLength, { ellipse: ellipseCharacter })}`
63 | }
64 | } else if (fileNameLength < targetLength) {
65 | if (fileNameLength >= (targetLength - 1)) {
66 | // Name too short by less than 2 characters: pad title left
67 | // filetitle.extension
68 | fileName = `${fileTitle}${fileExtension}`.padStart(targetLength, ' ')
69 | } else {
70 | // Name too short by more than 2 characters: Prefix ellipsed directory tree
71 | // …ocuments/filetitle.extension
72 | fileName = `${ellipseCharacter}${filePath.substr(filePath.length - targetLength + 1, filePath.length - 1)}`
73 | }
74 | } else {
75 | // File name has perfect length
76 | fileName = `${fileTitle}${fileExtension}`
77 | }
78 |
79 | return fileName
80 | }
81 |
82 |
83 | /**
84 | * Convert fraction to zero-padded percentage
85 | * @param {String} fraction - Fraction
86 | * @param {String=} pad - Pad character
87 | * @returns {String} - percentage
88 | */
89 | let fractionToPercentage = (fraction, pad = '0') => {
90 | // console.debug('fractionToPercentagePad')
91 |
92 | return String(Math.round(fraction * 100)).padStart(3, pad)
93 | }
94 |
95 | /**
96 | * @exports format-string
97 | */
98 | module.exports = {
99 | filepathToFilename: filepathToFilename,
100 | fractionToPercentage: fractionToPercentage
101 | }
102 |
103 |
104 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ffmpeg-progressbar-cli [](https://npmjs.com/package/ffmpeg-progressbar-cli)
2 |
3 |
4 | 
5 | ffmpeg-progressbar-cli is a colored progress bar for FFmpeg.
6 | Simply use ffmpeg-bar instead of ffmpeg.
7 |
8 |
9 |
10 | ## Contents
11 |
12 | 1. [Installation](#installation)
13 | 1. [Usage](#usage)
14 | 1. [Configuration](#configuration)
15 | 1. [Requirements](#requirements)
16 | 1. [Compatibility](#compatibility)
17 | 1. [Contribute](#contribute)
18 | 1. [Author](#author)
19 |
20 |
21 | ## Installation
22 |
23 | ```bash
24 | $ npm install --global ffmpeg-progressbar-cli
25 | ```
26 |
27 |
28 | ## Usage
29 |
30 | The installation process adds the `ffmpeg-bar` command to your system.
31 | This is a transparent wrapper, passing all commands to `ffmpeg`.
32 |
33 | To use it, simply launch `ffmpeg-bar` instead of `ffmpeg`, or replace `ffmpeg` with `ffmpeg-bar` inside your scripts.
34 |
35 |
36 | As long as no errors are encountered, the output of `ffmpeg-bar` will consist of a progress bar, the estimated time until process completion and a percentage.
37 |
38 | ###### Examples
39 |
40 | ```bash
41 | $> ffmpeg-bar -i input.mp4 output.avi
42 | ```
43 |
44 | ```bash
45 | $> ffmpeg-bar -i input.avi -b:v 64k -bufsize 64k output.avi
46 | ```
47 |
48 | ```bash
49 | $> ffmpeg-bar -i in.mkv -map_metadata:s:a 0:g out.mkv
50 | ```
51 |
52 |
53 | ## Configuration
54 |
55 | For configuration purposes, `ffmpeg-progressbar-cli` exposes these environmental variables:
56 |
57 |
58 | ##### `BAR_FILENAME_LENGTH`
59 | The maximum number of characters of the filename label displayed next to the progress bar beam *(default: 20)*
60 |
61 | ###### Example
62 |
63 | ```bash
64 | $> BAR_FILENAME_LENGTH=7 ffmpeg-bar -i in.mp4 output.mp4
65 | ```
66 |
67 | ##### `BAR_BEAM_RATIO `
68 |
69 | The share of (available) horizontal display real estate the progress bar beam should occupy *(default: 0.75)*
70 |
71 | ###### Example
72 |
73 | ```bash
74 | $> BAR_BAR_SIZE_RATIO=0.5 ffmpeg-bar -i in.mp4 output.mp4
75 | ```
76 |
77 | ## Requirements
78 |
79 | - [Node.js](https://nodejs.org/), v8.11 or later
80 | - [FFmpeg](https://ffmpeg.org/), installed correctly
81 |
82 |
83 | ## Compatibility
84 |
85 | Tested on
86 |
87 | - macOS 10.13, 10.14 Beta
88 | - Windows 10 1803
89 | - Ubuntu 18.04
90 |
91 |
92 | ## Contribute 
93 |
94 | Read the contribution [documentation](https://github.com/sidneys/ffmpeg-progressbar-cli/blob/master/CONTRIBUTING.md).
95 |
96 |
97 | ## License
98 |
99 | MIT
100 |
101 |
102 | ## Author
103 |
104 | [sidneys](http://sidneys.github.io) 2018
105 |
106 |
--------------------------------------------------------------------------------
/lib/progress-bar.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 |
4 | /**
5 | * Modules
6 | * Node
7 | * @constant
8 | */
9 | const path = require('path')
10 |
11 | /**
12 | * Modules
13 | * External
14 | * @constant
15 | */
16 | const appRootPath = require('app-root-path')
17 | appRootPath.setPath(path.join(__dirname, '..'))
18 | const CliProgress = require('@sidneys/cli-progress')
19 | const moment = require('moment')
20 | /* eslint-disable no-unused-vars */
21 | const momentDurationFormat = require('moment-duration-format')
22 | /* eslint-enable */
23 |
24 | /**
25 | * Modules
26 | * Internal
27 | * @constant
28 | */
29 | const formatter = require('./formatter')
30 | const theme = require('./theme')
31 |
32 | /**
33 | * Timecode format
34 | * @constant
35 | * @default
36 | */
37 | const etaFormat = 'HH:mm:ss'
38 |
39 | /**
40 | * Convert seconds into timecode format
41 | * @param {Number} seconds - Duration in seconds
42 | * @returns {String} - Timecode / HH:mm:ss
43 | */
44 | let convertSecondsToTimecode = (seconds) => {
45 | // console.debug('convertSecondsToTimecode')
46 |
47 | return moment.duration(seconds, 'seconds').format(etaFormat, { trim: false })
48 | }
49 |
50 | /**
51 | * Progress Bar Singleton
52 | * @external {CliProgress.Bar}
53 | */
54 | let progressBar
55 |
56 | /**
57 | * Wrapper for progressBar constructor
58 | * @param {Object=} options - Options
59 | * @returns {CliProgress.Bar} - progressBar
60 | */
61 | let createBar = (options) => {
62 | // console.debug('createProgressbar')
63 |
64 | const baseOptions = {
65 | format: `🎞 ${theme.filenameLabel('Rendering')} ${theme.filename('{filename}')} | ${theme.beam('{bar}')} ${theme.percentage('{percentagePad}%')} | ${theme.etaLabel('ETA')} ${theme.eta('{etaTimecode}')}`,
66 | fps: 20,
67 | barsize: 60,
68 | barCompleteChar: '\u2593',
69 | barIncompleteChar: '\u2591',
70 | etaBuffer: 64,
71 | hideCursor: true,
72 | stream: process.stdout,
73 | align: 'center',
74 | stopOnComplete: true,
75 | clearOnComplete: false
76 | }
77 |
78 | const finalOptions = Object.assign(baseOptions, options)
79 |
80 | // DEBUG
81 | // console.debug('configuration', require('util').inspect(finalOptions, /** @type {InspectOptions} */ { showHidden: true, colors: true, compact: true }))
82 |
83 | return new CliProgress.Bar(finalOptions)
84 | }
85 |
86 | /**
87 | * Wrapper for progressBar.start
88 | * @param {Number} totalValue - Total value
89 | * @param {Object=} payload - Extra Payload
90 | * @param {String=} annotation - Annotation
91 | * @public
92 | */
93 | let startBar = (totalValue, payload, annotation) => {
94 | // console.debug('startProgressbar')
95 |
96 | const startPayload = {
97 | etaTimecode: convertSecondsToTimecode(0),
98 | percentagePad: '00'
99 | }
100 |
101 | const finalPayload = Object.assign(startPayload, payload)
102 |
103 | // DEBUG
104 | // console.debug('startBar', 'payload', require('util').inspect(finalPayload, /** @type {InspectOptions} */ { showHidden: true, colors: true, compact: true }))
105 |
106 | progressBar.start(totalValue, 0, finalPayload, annotation)
107 | }
108 |
109 | /**
110 | * Wrapper for progressBar.update
111 | * @param {Number} currentValue - Current value
112 | * @param {Object=} payload - Payload
113 | * @param {String=} annotation - Annotation
114 | * @public
115 | */
116 | let updateBar = (currentValue, payload, annotation) => {
117 | // console.debug('updateProgressbar')
118 |
119 | const updatePayload = {
120 | percentagePad: formatter.fractionToPercentage(progressBar.value / progressBar.total, ' '),
121 | etaTimecode: convertSecondsToTimecode(progressBar.eta.eta)
122 | }
123 |
124 | const finalPayload = Object.assign(updatePayload, payload)
125 |
126 | // DEBUG
127 | // console.debug('updateBar', 'payload', require('util').inspect(finalPayload, /** @type {InspectOptions} */ { showHidden: true, colors: true, compact: true }))
128 |
129 | progressBar.update(currentValue, finalPayload, annotation)
130 | }
131 |
132 | /**
133 | * @typedef {Object} progressBar
134 | * @extends {CliProgress}
135 | * @property {function} bar
136 | * @property {function} start
137 | * @property {function} update
138 | */
139 |
140 | /**
141 | * @param {Object} options - Progress Bar options
142 | * @exports progressBar
143 | * @returns {Object}
144 | */
145 | module.exports = (options) => {
146 | progressBar = createBar(options)
147 |
148 | return {
149 | bar: progressBar,
150 | start: startBar,
151 | update: updateBar
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/lib/main.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict'
3 |
4 | /**
5 | * The maximum number of characters of the filename label displayed next to the progress bar beam.
6 | * @constant
7 | * @default
8 | */
9 | const BAR_FILENAME_LENGTH = process.env.BAR_FILENAME_LENGTH || 20
10 |
11 | /**
12 | * The share of (available) horizontal display real estate the progress bar beam should occupy.
13 | * @constant
14 | */
15 | const BAR_BEAM_RATIO = process.env.BAR_SIZE_RATIO || 0.75
16 |
17 |
18 | /**
19 | * Modules
20 | * Node
21 | * @constant
22 | */
23 | const childProcess = require('child_process')
24 | const os = require('os')
25 | const readline = require('readline')
26 | const path = require('path')
27 |
28 | /**
29 | * Modules
30 | * External
31 | * @constant
32 | */
33 | const appRootPath = require('app-root-path')
34 | appRootPath.setPath(path.join(__dirname, '..'))
35 | const ellipsize = require('ellipsize')
36 | const ini = require('ini')
37 | const which = require('which')
38 |
39 | /**
40 | * Modules
41 | * Internal
42 | * @constant
43 | */
44 | const progressBar = require('./progress-bar')
45 | const parseFFmpegLog = require('./parse-ffmpeg-log')
46 | const predictProgressbarWidth = require('./predict-progressbar-width')
47 | const formatter = require('./formatter')
48 | const theme = require('./theme')
49 |
50 |
51 | /**
52 | * FFmpeg Binary
53 | * @constant
54 | */
55 | const ffmpegFilepath = which.sync('ffmpeg')
56 |
57 | /**
58 | * FFmpeg arguments
59 | * @constant
60 | */
61 | const ffmpegUserArgsList = process.argv.slice(2)
62 | const ffmpegPreparationTaskArgsList = [...ffmpegUserArgsList]
63 | const ffmpegPrimaryTaskArgsList = ['-y', '-loglevel', 'error', '-progress', 'pipe:1', ...ffmpegUserArgsList]
64 |
65 |
66 | /**
67 | * @typedef {ChildProcess} Task
68 | * @inherits {NodeJS.EventEmitter}
69 | * @property {NodeJS.ReadableStream} stdout - stdout Stream
70 | * @property {NodeJS.ReadableStream} stderr - stderr Stream
71 | * @property {NodeJS.WritableStream} stdin - stdin Stream
72 | * @property {function} on - NodeJS.EventEmitter.on
73 | */
74 |
75 | /**
76 | * Primary Task
77 | * This task runs the FFmpeg commands provided.
78 | * @param {Number} totalTimeMs - Total duration (ms)
79 | * @param {String} filePath - Output target filepath
80 | */
81 | let startPrimaryTask = (totalTimeMs, filePath) => {
82 | // console.debug('startPrimaryTask()')
83 |
84 | const progressbarWidth = predictProgressbarWidth.beam(Number(BAR_FILENAME_LENGTH), BAR_BEAM_RATIO)
85 |
86 | /**
87 | * Create Progress Bar
88 | * @type {progressBar}
89 | */
90 | const bar = progressBar({
91 | barsize: progressbarWidth
92 | })
93 |
94 | /**
95 | * Startup status
96 | * @type {Boolean}
97 | */
98 | let didStart = false
99 |
100 | /**
101 | * Last error log
102 | * @type {String}
103 | */
104 | let lastError
105 |
106 | // DEBUG
107 | // lastError = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzstuvwxyz'
108 |
109 | /**
110 | * Main Task
111 | * @type {Task}
112 | */
113 | const mainTask = childProcess.spawn(ffmpegFilepath, ffmpegPrimaryTaskArgsList)
114 |
115 | /**
116 | * Handles mainTask.stdout
117 | * @param {Buffer|String} data - FFmpeg Live Log Output Buffer
118 | */
119 | let onData = (data) => {
120 | if (!didStart) {
121 | // Bar::start()
122 | bar.start(totalTimeMs, {
123 | filename: formatter.filepathToFilename(filePath, BAR_FILENAME_LENGTH)
124 | })
125 | didStart = true
126 | }
127 |
128 | // Parse sparse output of nearly undocumented `-progress` argument 🤬🤬🤬
129 | // That is, key-value-pairs in .ini format
130 | const progressDictionary = ini.decode(data.toString())
131 |
132 | const currentTimeMicroseconds = Number(progressDictionary['out_time_ms'])
133 | const currentTimeMs = Math.round(currentTimeMicroseconds / 1000)
134 |
135 | // Bar::update() (noncritical errors are written to Bar.annotation)
136 | bar.update(currentTimeMs, null, !!lastError ? theme.warning(ellipsize(lastError, progressbarWidth + 7)) : null)
137 |
138 | // DEBUG
139 | // console.debug('progress (ms)', progressMilliseconds, 'duration (ms)', durationMilliseconds, 'fraction', (progressMilliseconds / durationMilliseconds))
140 | }
141 |
142 | /**
143 | * @fires mainTask#onData
144 | * @interface mainTask.stdout
145 | */
146 | mainTask.stdout.on('data', onData)
147 |
148 | /**
149 | * @fires mainTask#onData
150 | * @interface mainTask.stderr
151 | */
152 | mainTask.stderr.on('data', (data) => {
153 | // Error: Persist last line fo error logs to lastError
154 | const dataLines = data.toString().trim().split(os.EOL)
155 | lastError = dataLines[dataLines.length - 1]
156 | })
157 |
158 | /**
159 | * @interface Process.ReadStream
160 | */
161 | process.stdin.pipe(mainTask.stdin)
162 |
163 | /**
164 | * @listens mainTask#close
165 | */
166 | mainTask.on('close', (code, signal) => {
167 | // DEBUG
168 | // console.debug('mainTask#close', 'code:', code, 'signal:', signal)
169 |
170 | // Set bar to 100%
171 | bar.update(totalTimeMs)
172 |
173 | // Restore cursor
174 | process.stdout.write('\x1B[?25h')
175 |
176 | // Exit
177 | process.exit(code)
178 | })
179 | }
180 |
181 | /**
182 | * Preparation Task
183 | * This spawns a preliminary process, which gathers information about the output (filename, duration) which cannot be gathered via "ffmpeg -progress"
184 | */
185 | let startPreparationTask = () => {
186 | // console.debug('startPreparationTask()')
187 |
188 | /**
189 | * Preparation Task
190 | */
191 | const prepTask = childProcess.spawn(ffmpegFilepath, ffmpegPreparationTaskArgsList)
192 |
193 | /**
194 | * Duration of output file
195 | * @type {Number}
196 | */
197 | let outputDuration
198 |
199 | /**
200 | * Name of output file
201 | * @type {String}
202 | */
203 | let outputFilename
204 |
205 | /**
206 | * Last error log
207 | * @type {String}
208 | */
209 | let lastError
210 |
211 | /**
212 | * Question status
213 | * @type {Boolean}
214 | */
215 | let didShowQuestion = false
216 |
217 | /**
218 | * Handles prepTask.stdout
219 | * @param {Buffer|String} data - FFmpeg Live Log Output Buffer
220 | */
221 | let onData = (data) => {
222 | data = data.toString()
223 | if (parseFFmpegLog.duration(data)) { outputDuration = parseFFmpegLog.duration(data) }
224 | if (parseFFmpegLog.output(data)) { outputFilename = parseFFmpegLog.output(data) }
225 |
226 | if (outputDuration && outputFilename) {
227 | if (didShowQuestion) {
228 | readline.moveCursor(process.stderr, 0, -1)
229 | readline.clearLine(process.stderr, 0)
230 | }
231 | // Send SIGKILL: preparation task succeeded
232 | prepTask.kill('SIGKILL')
233 | startPrimaryTask(outputDuration, outputFilename)
234 | }
235 | }
236 |
237 | /**
238 | * @fires prepTask#onData
239 | * @interface prepTask.stdout
240 | */
241 | prepTask.stdout.on('data', onData)
242 |
243 | /**
244 | * @fires prepTask#onData
245 | * @interface prepTask.stderr
246 | */
247 | prepTask.stderr.on('data', (data) => {
248 | if ((parseFFmpegLog.question(data.toString()))) {
249 | // Question: Show Question + whitespace
250 | process.stdout.write(theme.prompt(parseFFmpegLog.question(data.toString().trim())))
251 | process.stdout.write(' ')
252 | didShowQuestion = true
253 | } else {
254 | // Error: Persist last line fo error logs to lastError
255 | const dataLines = data.toString().trim().split(os.EOL)
256 | lastError = dataLines[dataLines.length - 1]
257 | }
258 | onData(data)
259 | })
260 |
261 | /**
262 | * @interface Process.ReadStream
263 | */
264 | process.stdin.pipe(prepTask.stdin)
265 |
266 | /**
267 | * @listens prepTask#close
268 | */
269 | prepTask.on('close', (code, signal) => {
270 | // DEBUG
271 | // console.debug('prepTask#close', 'code:', code, 'signal:', signal)
272 |
273 | // SIGKILL (fired by us) caused the process to close: ignore
274 | if (signal === 'SIGKILL') { return }
275 |
276 | // Other SIGNAL caused the process to close: Abort
277 | if (lastError) {
278 | // Show last error message
279 | process.stderr.write(theme.error(lastError))
280 | }
281 | process.stdout.write(os.EOL)
282 | process.exit(code)
283 | })
284 | }
285 |
286 |
287 | /**
288 | * Main
289 | */
290 | if (require.main === module) {
291 | startPreparationTask()
292 | }
293 |
--------------------------------------------------------------------------------
/resources/screencasts/screencast-1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/code-frame@^7.0.0":
6 | version "7.0.0"
7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
8 | integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==
9 | dependencies:
10 | "@babel/highlight" "^7.0.0"
11 |
12 | "@babel/highlight@^7.0.0":
13 | version "7.0.0"
14 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
15 | integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==
16 | dependencies:
17 | chalk "^2.0.0"
18 | esutils "^2.0.2"
19 | js-tokens "^4.0.0"
20 |
21 | "@sidneys/cli-progress@^2.2.0":
22 | version "2.2.0"
23 | resolved "https://registry.yarnpkg.com/@sidneys/cli-progress/-/cli-progress-2.2.0.tgz#c7fc07f927b2f8e1f3d809a056043a26e36ee812"
24 | dependencies:
25 | colors "^1.3.2"
26 | string-width "^2.1.1"
27 |
28 | acorn-jsx@^4.1.1:
29 | version "4.1.1"
30 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e"
31 | dependencies:
32 | acorn "^5.0.3"
33 |
34 | acorn@^5.0.3, acorn@^5.6.0:
35 | version "5.7.1"
36 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8"
37 |
38 | ajv@^6.5.3:
39 | version "6.5.5"
40 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1"
41 | integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==
42 | dependencies:
43 | fast-deep-equal "^2.0.1"
44 | fast-json-stable-stringify "^2.0.0"
45 | json-schema-traverse "^0.4.1"
46 | uri-js "^4.2.2"
47 |
48 | ansi-escapes@^3.0.0:
49 | version "3.1.0"
50 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
51 |
52 | ansi-regex@^3.0.0:
53 | version "3.0.0"
54 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
55 |
56 | ansi-styles@^3.2.1:
57 | version "3.2.1"
58 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
59 | dependencies:
60 | color-convert "^1.9.0"
61 |
62 | app-root-path@^2.1.0:
63 | version "2.1.0"
64 | resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a"
65 |
66 | argparse@^1.0.7:
67 | version "1.0.10"
68 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
69 | dependencies:
70 | sprintf-js "~1.0.2"
71 |
72 | array-union@^1.0.1:
73 | version "1.0.2"
74 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
75 | dependencies:
76 | array-uniq "^1.0.1"
77 |
78 | array-uniq@^1.0.1:
79 | version "1.0.3"
80 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
81 |
82 | arrify@^1.0.0:
83 | version "1.0.1"
84 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
85 |
86 | babylon@7.0.0-beta.19:
87 | version "7.0.0-beta.19"
88 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.19.tgz#e928c7e807e970e0536b078ab3e0c48f9e052503"
89 |
90 | balanced-match@^1.0.0:
91 | version "1.0.0"
92 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
93 |
94 | bluebird@~3.5.0:
95 | version "3.5.1"
96 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
97 |
98 | brace-expansion@^1.1.7:
99 | version "1.1.11"
100 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
101 | dependencies:
102 | balanced-match "^1.0.0"
103 | concat-map "0.0.1"
104 |
105 | caller-path@^0.1.0:
106 | version "0.1.0"
107 | resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
108 | dependencies:
109 | callsites "^0.2.0"
110 |
111 | callsites@^0.2.0:
112 | version "0.2.0"
113 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
114 |
115 | catharsis@~0.8.9:
116 | version "0.8.9"
117 | resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.9.tgz#98cc890ca652dd2ef0e70b37925310ff9e90fc8b"
118 | dependencies:
119 | underscore-contrib "~0.3.0"
120 |
121 | chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1:
122 | version "2.4.1"
123 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
124 | dependencies:
125 | ansi-styles "^3.2.1"
126 | escape-string-regexp "^1.0.5"
127 | supports-color "^5.3.0"
128 |
129 | chardet@^0.7.0:
130 | version "0.7.0"
131 | resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
132 | integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
133 |
134 | circular-json@^0.3.1:
135 | version "0.3.3"
136 | resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
137 |
138 | cli-cursor@^2.1.0:
139 | version "2.1.0"
140 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
141 | dependencies:
142 | restore-cursor "^2.0.0"
143 |
144 | cli-width@^2.0.0:
145 | version "2.2.0"
146 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
147 |
148 | color-convert@^1.9.0:
149 | version "1.9.2"
150 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147"
151 | dependencies:
152 | color-name "1.1.1"
153 |
154 | color-name@1.1.1:
155 | version "1.1.1"
156 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689"
157 |
158 | colors@^1.3.2:
159 | version "1.3.2"
160 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b"
161 |
162 | concat-map@0.0.1:
163 | version "0.0.1"
164 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
165 |
166 | cross-spawn@^6.0.5:
167 | version "6.0.5"
168 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
169 | dependencies:
170 | nice-try "^1.0.4"
171 | path-key "^2.0.1"
172 | semver "^5.5.0"
173 | shebang-command "^1.2.0"
174 | which "^1.2.9"
175 |
176 | debug@^4.0.1:
177 | version "4.1.0"
178 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87"
179 | integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==
180 | dependencies:
181 | ms "^2.1.1"
182 |
183 | deep-is@~0.1.3:
184 | version "0.1.3"
185 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
186 |
187 | define-property@^1.0.0:
188 | version "1.0.0"
189 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6"
190 | dependencies:
191 | is-descriptor "^1.0.0"
192 |
193 | del@^2.0.2:
194 | version "2.2.2"
195 | resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
196 | dependencies:
197 | globby "^5.0.0"
198 | is-path-cwd "^1.0.0"
199 | is-path-in-cwd "^1.0.0"
200 | object-assign "^4.0.1"
201 | pify "^2.0.0"
202 | pinkie-promise "^2.0.0"
203 | rimraf "^2.2.8"
204 |
205 | docdash@^1.0.0:
206 | version "1.0.0"
207 | resolved "https://registry.yarnpkg.com/docdash/-/docdash-1.0.0.tgz#5b7df10fed3d341fc4416a8978c65ad561869d18"
208 |
209 | doctrine@^2.1.0:
210 | version "2.1.0"
211 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
212 | dependencies:
213 | esutils "^2.0.2"
214 |
215 | ellipsize@^0.1.0:
216 | version "0.1.0"
217 | resolved "https://registry.yarnpkg.com/ellipsize/-/ellipsize-0.1.0.tgz#9d43682d44b91ad16ebd84268ac103170a6553f8"
218 |
219 | escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5:
220 | version "1.0.5"
221 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
222 |
223 | eslint-scope@^4.0.0:
224 | version "4.0.0"
225 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172"
226 | dependencies:
227 | esrecurse "^4.1.0"
228 | estraverse "^4.1.1"
229 |
230 | eslint-utils@^1.3.1:
231 | version "1.3.1"
232 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512"
233 |
234 | eslint-visitor-keys@^1.0.0:
235 | version "1.0.0"
236 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
237 |
238 | eslint@^5.9.0:
239 | version "5.9.0"
240 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e"
241 | integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w==
242 | dependencies:
243 | "@babel/code-frame" "^7.0.0"
244 | ajv "^6.5.3"
245 | chalk "^2.1.0"
246 | cross-spawn "^6.0.5"
247 | debug "^4.0.1"
248 | doctrine "^2.1.0"
249 | eslint-scope "^4.0.0"
250 | eslint-utils "^1.3.1"
251 | eslint-visitor-keys "^1.0.0"
252 | espree "^4.0.0"
253 | esquery "^1.0.1"
254 | esutils "^2.0.2"
255 | file-entry-cache "^2.0.0"
256 | functional-red-black-tree "^1.0.1"
257 | glob "^7.1.2"
258 | globals "^11.7.0"
259 | ignore "^4.0.6"
260 | imurmurhash "^0.1.4"
261 | inquirer "^6.1.0"
262 | is-resolvable "^1.1.0"
263 | js-yaml "^3.12.0"
264 | json-stable-stringify-without-jsonify "^1.0.1"
265 | levn "^0.3.0"
266 | lodash "^4.17.5"
267 | minimatch "^3.0.4"
268 | mkdirp "^0.5.1"
269 | natural-compare "^1.4.0"
270 | optionator "^0.8.2"
271 | path-is-inside "^1.0.2"
272 | pluralize "^7.0.0"
273 | progress "^2.0.0"
274 | regexpp "^2.0.1"
275 | require-uncached "^1.0.3"
276 | semver "^5.5.1"
277 | strip-ansi "^4.0.0"
278 | strip-json-comments "^2.0.1"
279 | table "^5.0.2"
280 | text-table "^0.2.0"
281 |
282 | espree@^4.0.0:
283 | version "4.0.0"
284 | resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634"
285 | dependencies:
286 | acorn "^5.6.0"
287 | acorn-jsx "^4.1.1"
288 |
289 | esprima@^4.0.0:
290 | version "4.0.1"
291 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
292 |
293 | esquery@^1.0.1:
294 | version "1.0.1"
295 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
296 | dependencies:
297 | estraverse "^4.0.0"
298 |
299 | esrecurse@^4.1.0:
300 | version "4.2.1"
301 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
302 | dependencies:
303 | estraverse "^4.1.0"
304 |
305 | estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
306 | version "4.2.0"
307 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
308 |
309 | esutils@^2.0.2:
310 | version "2.0.2"
311 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
312 |
313 | external-editor@^3.0.0:
314 | version "3.0.3"
315 | resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27"
316 | integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==
317 | dependencies:
318 | chardet "^0.7.0"
319 | iconv-lite "^0.4.24"
320 | tmp "^0.0.33"
321 |
322 | fast-deep-equal@^2.0.1:
323 | version "2.0.1"
324 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
325 |
326 | fast-json-stable-stringify@^2.0.0:
327 | version "2.0.0"
328 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
329 |
330 | fast-levenshtein@~2.0.4:
331 | version "2.0.6"
332 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
333 |
334 | figures@^2.0.0:
335 | version "2.0.0"
336 | resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
337 | dependencies:
338 | escape-string-regexp "^1.0.5"
339 |
340 | file-entry-cache@^2.0.0:
341 | version "2.0.0"
342 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
343 | dependencies:
344 | flat-cache "^1.2.1"
345 | object-assign "^4.0.1"
346 |
347 | flat-cache@^1.2.1:
348 | version "1.3.0"
349 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
350 | dependencies:
351 | circular-json "^0.3.1"
352 | del "^2.0.2"
353 | graceful-fs "^4.1.2"
354 | write "^0.2.1"
355 |
356 | fs.realpath@^1.0.0:
357 | version "1.0.0"
358 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
359 |
360 | functional-red-black-tree@^1.0.1:
361 | version "1.0.1"
362 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
363 |
364 | glob@^7.0.3, glob@^7.0.5, glob@^7.1.2:
365 | version "7.1.2"
366 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
367 | dependencies:
368 | fs.realpath "^1.0.0"
369 | inflight "^1.0.4"
370 | inherits "2"
371 | minimatch "^3.0.4"
372 | once "^1.3.0"
373 | path-is-absolute "^1.0.0"
374 |
375 | globals@^11.7.0:
376 | version "11.7.0"
377 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
378 |
379 | globby@^5.0.0:
380 | version "5.0.0"
381 | resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
382 | dependencies:
383 | array-union "^1.0.1"
384 | arrify "^1.0.0"
385 | glob "^7.0.3"
386 | object-assign "^4.0.1"
387 | pify "^2.0.0"
388 | pinkie-promise "^2.0.0"
389 |
390 | graceful-fs@^4.1.2, graceful-fs@^4.1.9:
391 | version "4.1.11"
392 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
393 |
394 | has-flag@^3.0.0:
395 | version "3.0.0"
396 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
397 |
398 | iconv-lite@^0.4.24:
399 | version "0.4.24"
400 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
401 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
402 | dependencies:
403 | safer-buffer ">= 2.1.2 < 3"
404 |
405 | ignore@^4.0.6:
406 | version "4.0.6"
407 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
408 | integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
409 |
410 | imurmurhash@^0.1.4:
411 | version "0.1.4"
412 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
413 |
414 | inflight@^1.0.4:
415 | version "1.0.6"
416 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
417 | dependencies:
418 | once "^1.3.0"
419 | wrappy "1"
420 |
421 | inherits@2:
422 | version "2.0.3"
423 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
424 |
425 | ini@^1.3.5:
426 | version "1.3.5"
427 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
428 |
429 | inquirer@^6.1.0:
430 | version "6.2.0"
431 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8"
432 | integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==
433 | dependencies:
434 | ansi-escapes "^3.0.0"
435 | chalk "^2.0.0"
436 | cli-cursor "^2.1.0"
437 | cli-width "^2.0.0"
438 | external-editor "^3.0.0"
439 | figures "^2.0.0"
440 | lodash "^4.17.10"
441 | mute-stream "0.0.7"
442 | run-async "^2.2.0"
443 | rxjs "^6.1.0"
444 | string-width "^2.1.0"
445 | strip-ansi "^4.0.0"
446 | through "^2.3.6"
447 |
448 | is-accessor-descriptor@^1.0.0:
449 | version "1.0.0"
450 | resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656"
451 | dependencies:
452 | kind-of "^6.0.0"
453 |
454 | is-buffer@^1.1.5:
455 | version "1.1.6"
456 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
457 |
458 | is-data-descriptor@^1.0.0:
459 | version "1.0.0"
460 | resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7"
461 | dependencies:
462 | kind-of "^6.0.0"
463 |
464 | is-descriptor@^1.0.0:
465 | version "1.0.2"
466 | resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec"
467 | dependencies:
468 | is-accessor-descriptor "^1.0.0"
469 | is-data-descriptor "^1.0.0"
470 | kind-of "^6.0.2"
471 |
472 | is-fullwidth-code-point@^2.0.0:
473 | version "2.0.0"
474 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
475 |
476 | is-number@^3.0.0:
477 | version "3.0.0"
478 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
479 | dependencies:
480 | kind-of "^3.0.2"
481 |
482 | is-path-cwd@^1.0.0:
483 | version "1.0.0"
484 | resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
485 |
486 | is-path-in-cwd@^1.0.0:
487 | version "1.0.1"
488 | resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
489 | dependencies:
490 | is-path-inside "^1.0.0"
491 |
492 | is-path-inside@^1.0.0:
493 | version "1.0.1"
494 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
495 | dependencies:
496 | path-is-inside "^1.0.1"
497 |
498 | is-promise@^2.1.0:
499 | version "2.1.0"
500 | resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
501 |
502 | is-resolvable@^1.1.0:
503 | version "1.1.0"
504 | resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
505 |
506 | isexe@^2.0.0:
507 | version "2.0.0"
508 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
509 |
510 | js-tokens@^4.0.0:
511 | version "4.0.0"
512 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
513 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
514 |
515 | js-yaml@^3.12.0:
516 | version "3.12.0"
517 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
518 | integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==
519 | dependencies:
520 | argparse "^1.0.7"
521 | esprima "^4.0.0"
522 |
523 | js2xmlparser@~3.0.0:
524 | version "3.0.0"
525 | resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-3.0.0.tgz#3fb60eaa089c5440f9319f51760ccd07e2499733"
526 | dependencies:
527 | xmlcreate "^1.0.1"
528 |
529 | jsdoc@^3.5.5:
530 | version "3.5.5"
531 | resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.5.5.tgz#484521b126e81904d632ff83ec9aaa096708fa4d"
532 | dependencies:
533 | babylon "7.0.0-beta.19"
534 | bluebird "~3.5.0"
535 | catharsis "~0.8.9"
536 | escape-string-regexp "~1.0.5"
537 | js2xmlparser "~3.0.0"
538 | klaw "~2.0.0"
539 | marked "~0.3.6"
540 | mkdirp "~0.5.1"
541 | requizzle "~0.2.1"
542 | strip-json-comments "~2.0.1"
543 | taffydb "2.6.2"
544 | underscore "~1.8.3"
545 |
546 | json-schema-traverse@^0.4.1:
547 | version "0.4.1"
548 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
549 |
550 | json-stable-stringify-without-jsonify@^1.0.1:
551 | version "1.0.1"
552 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
553 |
554 | kind-of@^3.0.2:
555 | version "3.2.2"
556 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
557 | dependencies:
558 | is-buffer "^1.1.5"
559 |
560 | kind-of@^6.0.0, kind-of@^6.0.2:
561 | version "6.0.2"
562 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
563 |
564 | klaw@~2.0.0:
565 | version "2.0.0"
566 | resolved "https://registry.yarnpkg.com/klaw/-/klaw-2.0.0.tgz#59c128e0dc5ce410201151194eeb9cbf858650f6"
567 | dependencies:
568 | graceful-fs "^4.1.9"
569 |
570 | levn@^0.3.0, levn@~0.3.0:
571 | version "0.3.0"
572 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
573 | dependencies:
574 | prelude-ls "~1.1.2"
575 | type-check "~0.3.2"
576 |
577 | lodash@^4.17.10:
578 | version "4.17.11"
579 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
580 | integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
581 |
582 | lodash@^4.17.5:
583 | version "4.17.10"
584 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
585 |
586 | marked@~0.3.6:
587 | version "0.3.19"
588 | resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790"
589 |
590 | mimic-fn@^1.0.0:
591 | version "1.2.0"
592 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
593 |
594 | minimatch@^3.0.4:
595 | version "3.0.4"
596 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
597 | dependencies:
598 | brace-expansion "^1.1.7"
599 |
600 | minimist@0.0.8:
601 | version "0.0.8"
602 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
603 |
604 | mkdirp@^0.5.1, mkdirp@~0.5.1:
605 | version "0.5.1"
606 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
607 | dependencies:
608 | minimist "0.0.8"
609 |
610 | moment-duration-format@^2.2.2:
611 | version "2.2.2"
612 | resolved "https://registry.yarnpkg.com/moment-duration-format/-/moment-duration-format-2.2.2.tgz#b957612de26016c9ad9eb6087c054573e5127779"
613 |
614 | moment@^2.22.2:
615 | version "2.22.2"
616 | resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
617 |
618 | ms@^2.1.1:
619 | version "2.1.1"
620 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
621 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
622 |
623 | mute-stream@0.0.7:
624 | version "0.0.7"
625 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
626 |
627 | natural-compare@^1.4.0:
628 | version "1.4.0"
629 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
630 |
631 | nice-try@^1.0.4:
632 | version "1.0.4"
633 | resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
634 |
635 | object-assign@^4.0.1:
636 | version "4.1.1"
637 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
638 |
639 | once@^1.3.0:
640 | version "1.4.0"
641 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
642 | dependencies:
643 | wrappy "1"
644 |
645 | onetime@^2.0.0:
646 | version "2.0.1"
647 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
648 | dependencies:
649 | mimic-fn "^1.0.0"
650 |
651 | optionator@^0.8.2:
652 | version "0.8.2"
653 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
654 | dependencies:
655 | deep-is "~0.1.3"
656 | fast-levenshtein "~2.0.4"
657 | levn "~0.3.0"
658 | prelude-ls "~1.1.2"
659 | type-check "~0.3.2"
660 | wordwrap "~1.0.0"
661 |
662 | os-tmpdir@~1.0.2:
663 | version "1.0.2"
664 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
665 |
666 | path-is-absolute@^1.0.0:
667 | version "1.0.1"
668 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
669 |
670 | path-is-inside@^1.0.1, path-is-inside@^1.0.2:
671 | version "1.0.2"
672 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
673 |
674 | path-key@^2.0.1:
675 | version "2.0.1"
676 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
677 |
678 | pify@^2.0.0:
679 | version "2.3.0"
680 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
681 |
682 | pinkie-promise@^2.0.0:
683 | version "2.0.1"
684 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
685 | dependencies:
686 | pinkie "^2.0.0"
687 |
688 | pinkie@^2.0.0:
689 | version "2.0.4"
690 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
691 |
692 | pluralize@^7.0.0:
693 | version "7.0.0"
694 | resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
695 |
696 | prelude-ls@~1.1.2:
697 | version "1.1.2"
698 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
699 |
700 | progress@^2.0.0:
701 | version "2.0.0"
702 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
703 |
704 | punycode@^2.1.0:
705 | version "2.1.1"
706 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
707 |
708 | regexpp@^2.0.1:
709 | version "2.0.1"
710 | resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
711 | integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
712 |
713 | require-uncached@^1.0.3:
714 | version "1.0.3"
715 | resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
716 | dependencies:
717 | caller-path "^0.1.0"
718 | resolve-from "^1.0.0"
719 |
720 | requizzle@~0.2.1:
721 | version "0.2.1"
722 | resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.1.tgz#6943c3530c4d9a7e46f1cddd51c158fc670cdbde"
723 | dependencies:
724 | underscore "~1.6.0"
725 |
726 | resolve-from@^1.0.0:
727 | version "1.0.1"
728 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
729 |
730 | restore-cursor@^2.0.0:
731 | version "2.0.0"
732 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
733 | dependencies:
734 | onetime "^2.0.0"
735 | signal-exit "^3.0.2"
736 |
737 | rimraf@^2.2.8:
738 | version "2.6.2"
739 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
740 | dependencies:
741 | glob "^7.0.5"
742 |
743 | run-async@^2.2.0:
744 | version "2.3.0"
745 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
746 | dependencies:
747 | is-promise "^2.1.0"
748 |
749 | rxjs@^6.1.0:
750 | version "6.3.3"
751 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
752 | integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==
753 | dependencies:
754 | tslib "^1.9.0"
755 |
756 | "safer-buffer@>= 2.1.2 < 3":
757 | version "2.1.2"
758 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
759 |
760 | semver@^5.5.0:
761 | version "5.5.0"
762 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
763 |
764 | semver@^5.5.1:
765 | version "5.6.0"
766 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
767 | integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
768 |
769 | shebang-command@^1.2.0:
770 | version "1.2.0"
771 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
772 | dependencies:
773 | shebang-regex "^1.0.0"
774 |
775 | shebang-regex@^1.0.0:
776 | version "1.0.0"
777 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
778 |
779 | signal-exit@^3.0.2:
780 | version "3.0.2"
781 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
782 |
783 | slice-ansi@1.0.0:
784 | version "1.0.0"
785 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
786 | dependencies:
787 | is-fullwidth-code-point "^2.0.0"
788 |
789 | sprintf-js@~1.0.2:
790 | version "1.0.3"
791 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
792 |
793 | string-width@^2.1.0, string-width@^2.1.1:
794 | version "2.1.1"
795 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
796 | dependencies:
797 | is-fullwidth-code-point "^2.0.0"
798 | strip-ansi "^4.0.0"
799 |
800 | strip-ansi@^4.0.0:
801 | version "4.0.0"
802 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
803 | dependencies:
804 | ansi-regex "^3.0.0"
805 |
806 | strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
807 | version "2.0.1"
808 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
809 |
810 | supports-color@^5.3.0:
811 | version "5.4.0"
812 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
813 | dependencies:
814 | has-flag "^3.0.0"
815 |
816 | table@^5.0.2:
817 | version "5.1.0"
818 | resolved "https://registry.yarnpkg.com/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7"
819 | integrity sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg==
820 | dependencies:
821 | ajv "^6.5.3"
822 | lodash "^4.17.10"
823 | slice-ansi "1.0.0"
824 | string-width "^2.1.1"
825 |
826 | taffydb@2.6.2:
827 | version "2.6.2"
828 | resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268"
829 |
830 | text-table@^0.2.0:
831 | version "0.2.0"
832 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
833 |
834 | through@^2.3.6:
835 | version "2.3.8"
836 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
837 |
838 | tmp@^0.0.33:
839 | version "0.0.33"
840 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
841 | dependencies:
842 | os-tmpdir "~1.0.2"
843 |
844 | tslib@^1.9.0:
845 | version "1.9.3"
846 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
847 | integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
848 |
849 | type-check@~0.3.2:
850 | version "0.3.2"
851 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
852 | dependencies:
853 | prelude-ls "~1.1.2"
854 |
855 | underscore-contrib@~0.3.0:
856 | version "0.3.0"
857 | resolved "https://registry.yarnpkg.com/underscore-contrib/-/underscore-contrib-0.3.0.tgz#665b66c24783f8fa2b18c9f8cbb0e2c7d48c26c7"
858 | dependencies:
859 | underscore "1.6.0"
860 |
861 | underscore@1.6.0, underscore@~1.6.0:
862 | version "1.6.0"
863 | resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
864 |
865 | underscore@~1.8.3:
866 | version "1.8.3"
867 | resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
868 |
869 | uri-js@^4.2.2:
870 | version "4.2.2"
871 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
872 | integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
873 | dependencies:
874 | punycode "^2.1.0"
875 |
876 | which@^1.2.9, which@^1.3.1:
877 | version "1.3.1"
878 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
879 | dependencies:
880 | isexe "^2.0.0"
881 |
882 | window-size@^1.1.1:
883 | version "1.1.1"
884 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-1.1.1.tgz#9858586580ada78ab26ecd6978a6e03115c1af20"
885 | dependencies:
886 | define-property "^1.0.0"
887 | is-number "^3.0.0"
888 |
889 | wordwrap@~1.0.0:
890 | version "1.0.0"
891 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
892 |
893 | wrappy@1:
894 | version "1.0.2"
895 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
896 |
897 | write@^0.2.1:
898 | version "0.2.1"
899 | resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
900 | dependencies:
901 | mkdirp "^0.5.1"
902 |
903 | xmlcreate@^1.0.1:
904 | version "1.0.2"
905 | resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-1.0.2.tgz#fa6bf762a60a413fb3dd8f4b03c5b269238d308f"
906 |
--------------------------------------------------------------------------------