diff --git a/.gitignore b/.gitignore index c231ee16..92481947 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ bower_components # Build-related dist/ -docs/ tmp coverage/ .build_cache/ diff --git a/CHANGES.md b/CHANGES.md index a682c5e7..d660a472 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,10 +1,9 @@ -videojs-wavesurfer changelog -============================ +# videojs-wavesurfer changelog -3.0.0 - unreleased ------------------- +## 3.0.0 - unreleased - Support for video.js progress control (#93) +- Move documentation into docsify website (#100) - Bump required video.js version to 7.0.5 or newer - Bump required wavesurfer.js version to 3.3.0 or newer @@ -15,23 +14,20 @@ videojs-wavesurfer changelog using the config instead -2.11.0 - 2019/10/11 -------------------- +## 2.11.0 - 2019/10/11 - Fix loading peaks data from JSON files (#90) - Add `style` and `sass` entries to `package.json` - Specify non-minified videojs-wavesurfer in `main` entry of `package.json` -2.10.0 - 2019/09/30 -------------------- +## 2.10.0 - 2019/09/30 - New `abort` event; triggered when wavesurfer.js fetch call is cancelled (#87) - Bump required wavesurfer.js version to 3.1.0 -2.9.0 - 2019/07/14 ------------------- +## 2.9.0 - 2019/07/14 - Replace usage of `WaveSurfer.util.ajax()` with `WaveSurfer.util.fetchFile()` - Bump required wavesurfer.js version to 3.0.0 @@ -39,71 +35,61 @@ videojs-wavesurfer changelog for `canvas` in the Picture-In-Picture browser API -2.8.0 - 2019/03/18 ------------------- +## 2.8.0 - 2019/03/18 - Move event types to separate class - Bump required wavesurfer.js version to 2.2.1 - Display `video` element in video example (#8) -2.7.0 - 2019/02/08 ------------------- +## 2.7.0 - 2019/02/08 - Fix hiding `playToggle` control - Fix ES export syntax for `Wavesurfer` -2.6.4 - 2019/02/04 ------------------- +## 2.6.4 - 2019/02/04 - Bump required wavesurfer.js version to 2.1.3 for Safari browser improvement -2.6.3 - 2018/12/03 ------------------- +## 2.6.3 - 2018/12/03 - Improve API documentation (#77) -2.6.2 - 2018/11/19 ------------------- +## 2.6.2 - 2018/11/19 - Bump required wavesurfer.js version to 2.1.1 for microphone support in the Safari browser - Examples: add Safari browser workaround (#47) -2.6.1 - 2018/10/07 ------------------- +## 2.6.1 - 2018/10/07 - Fix hiding time controls (#73) -2.6.0 - 2018/10/04 ------------------- +## 2.6.0 - 2018/10/04 - Bump required wavesurfer.js version to 2.1.0 for microphone support in the MS Edge browser -2.5.1 - 2018/08/08 ------------------- +## 2.5.1 - 2018/08/08 - Fix minified CSS file (#69) - Add example showing integration with wavesurfer.js cursor plugin (#67) -2.5.0 - 2018/06/03 ------------------- +## 2.5.0 - 2018/06/03 - Bugfix: replace custom tech for text tracks to fix high CPU usage and issue with regular video.js players on the same page (#60, #62) -2.4.0 - 2018/05/15 ------------------- +## 2.4.0 - 2018/05/15 - Add plugin style `vjs-wavesurfer` and prefix all custom plugin styles with this selector. This should prevent clashes with regular video.js players @@ -112,69 +98,59 @@ videojs-wavesurfer changelog - Compile SCSS into CSS using webpack -2.3.2 - 2018/05/07 ------------------- +## 2.3.2 - 2018/05/07 - Package library using webpack 4 -2.3.1 - 2018/04/30 ------------------- +## 2.3.1 - 2018/04/30 - Make sure plugin is only registered once - Add `isDestroyed` method - Add more tests -2.3.0 - 2018/04/16 ------------------- +## 2.3.0 - 2018/04/16 - Package library using webpack (#55) - Add unit tests using karma/webpack/jasmine (#55) - Check if wavesurfer exists when calling destroy -2.2.2 - 2018/03/06 ------------------- +## 2.2.2 - 2018/03/06 - Add ability to pass array of peaks data to `load` (#52) -2.2.1 - 2018/02/20 ------------------- +## 2.2.1 - 2018/02/20 - Fix tech for compatibility with video.js 6.7.x (#49 by @mfairchild365) -2.2.0 - 2018/01/23 ------------------- +## 2.2.0 - 2018/01/23 - Support for changing audio output device using `setAudioOutput(deviceId)` - Added example that shows how to select an audio input device - Bump required wavesurfer.js version to 2.0.3 for setSinkId feature -2.1.4 - 2018/01/14 ------------------- +## 2.1.4 - 2018/01/14 - Bump required wavesurfer.js version to 2.0.2 for Chrome volume deprecation fix -2.1.3 - 2017/12/22 ------------------- +## 2.1.3 - 2017/12/22 - Bump required wavesurfer.js version to 2.0.1 -2.1.2 - 2017/12/13 ------------------- +## 2.1.2 - 2017/12/13 - Fix compatibility issue with videojs-record plugin (#46) -2.1.1 - 2017/12/12 ------------------- +## 2.1.1 - 2017/12/12 - Added support for changing the playback rate (#43) - Added `.videojs-wavesurfer` CSS class (#44 by @eiennosihaisya) @@ -185,33 +161,28 @@ videojs-wavesurfer changelog @mfairchild365) -2.1.0 - 2017/12/05 ------------------- +## 2.1.0 - 2017/12/05 - Caption/subtitle support (#36 by @mfairchild365) -2.0.3 - 2017/11/30 ------------------- +## 2.0.3 - 2017/11/30 - Fix Windows build -2.0.2 - 2017/11/15 ------------------- +## 2.0.2 - 2017/11/15 - Updated `load` function to optionally load an array of pre-rendered peak data (#38 by @rbwest) -2.0.1 - 2017/10/03 ------------------- +## 2.0.1 - 2017/10/03 - Support for video.js 6.3.1 and newer -2.0.0 - 2017/10/03 ------------------- +## 2.0.0 - 2017/10/03 - Rewrite plugin using ES6 (#29) - video.js 6.0 or newer is now required: older versions are no longer supported @@ -228,102 +199,86 @@ videojs-wavesurfer changelog plugin, e.g. `player.wavesurfer().getDuration()` -1.3.6 - 2017/09/23 ------------------- +## 1.3.6 - 2017/09/23 - Bugfix: properly update current time and duration display components (#34) -1.3.5 - 2017/09/19 ------------------- +## 1.3.5 - 2017/09/19 - Bugfix: correct the uiElements check (#26) -1.3.4 - 2017/09/19 ------------------- +## 1.3.4 - 2017/09/19 - Restricted required wavesurfer.js version to < 2.0.0 -1.3.3 - 2017/05/27 ------------------- +## 1.3.3 - 2017/05/27 - Use `video.js` AMD module name (#30) -1.3.2 - 2017/04/09 ------------------- +## 1.3.2 - 2017/04/09 - Use `videojs.registerPlugin` in video.js 6.0.0 and newer (#27) -1.3.1 - 2017/02/26 ------------------- +## 1.3.1 - 2017/02/26 - Added `getDuration` and `getCurrentTime` methods -1.3.0 - 2017/02/13 ------------------- +## 1.3.0 - 2017/02/13 - Moved main script out of root into a new `src/js` directory - NPM package now includes `dist` directory with minified files -1.2.7 - 2017/01/15 ------------------- +## 1.2.7 - 2017/01/15 - Added `playbackFinish` event (#24) -1.2.6 - 2016/09/30 ------------------- +## 1.2.6 - 2016/09/30 - Bugfix: made sure the `debug` option has a default value (`false`) -1.2.5 - 2016/09/30 ------------------- +## 1.2.5 - 2016/09/30 - Added `waveReady` event, useful for initializing wavesurfer.js plugins - Added support for the wavesurfer.js `splitChannels` option (#21) -1.2.4 - 2016/09/16 ------------------- +## 1.2.4 - 2016/09/16 - Added `exportImage` to save an image of the waveform - Bumped required wavesurfer.js version to 1.2.0 for `exportImage` method -1.2.3 - 2016/08/27 ------------------- +## 1.2.3 - 2016/08/27 - Bugfix: added compatibility for video.js 5.11.0 and newer (#20) -1.2.2 - 2016/08/08 ------------------- +## 1.2.2 - 2016/08/08 - Bugfix: corrected Node name for wavesurfer.js module (#19 by @monachilada) -1.2.1 - 2016/05/22 ------------------- +## 1.2.1 - 2016/05/22 - Documentation updates -1.2.0 - 2016/03/25 ------------------- +## 1.2.0 - 2016/03/25 - Prevented negative or invalid values in `formatTime` - Documentation updates -1.1.0 - 2016/02/26 ------------------- +## 1.1.0 - 2016/02/26 - Catch microphone device errors - Bumped required wavesurfer.js version to 1.0.57 for microphone plugin fixes @@ -331,169 +286,143 @@ videojs-wavesurfer changelog - Bugfix: pass wavesurfer config to microphone plugin -1.0.6 - 2016/01/17 ------------------- +## 1.0.6 - 2016/01/17 - Fixed issues with Firefox for Android (#15) -1.0.5 - 2016/01/17 ------------------- +## 1.0.5 - 2016/01/17 - Propagate wavesurfer errors properly (#13 by @xlc) -1.0.4 - 2015/12/21 ------------------- +## 1.0.4 - 2015/12/21 - Fixed wrong video.js module require for browserify -1.0.3 - 2015/10/15 ------------------- +## 1.0.3 - 2015/10/15 - Fixed missing amd/node/global browser dependency for wavesurfer -1.0.2 - 2015/10/15 ------------------- +## 1.0.2 - 2015/10/15 - Made sure controlBar is always showing (if `controls: true`) - Fixed module Node/AMD/browser globals -1.0.1 - 2015/10/14 ------------------- +## 1.0.1 - 2015/10/14 - Bugfix: use flex for controlBar so other plugins, like videojs-record, can add more controls to it. -1.0.0 - 2015/10/12 ------------------- +## 1.0.0 - 2015/10/12 - Support for video.js 5 - Dropped support for video.js 4.x -0.9.9 - 2015/10/06 ------------------- +## 0.9.9 - 2015/10/06 - Use new `microphone.pause` and `microphone.play` during `live` mode - Bumped minimum version for wavesurfer.js to 1.0.44 (for microphone plugin updates) -0.9.8 - 2015/10/04 ------------------- +## 0.9.8 - 2015/10/04 - Updated bower and npm so only video.js v4.x releases are fetched, v5.0 is not supported yet (#5). - Added ability to override waveform height (#9) -0.9.7 - 2015/08/27 ------------------- +## 0.9.7 - 2015/08/27 - Allow custom wavesurfer container (#7) -0.9.6 - 2015/03/19 ------------------- +## 0.9.6 - 2015/03/19 - Microphone plugin (if enabled) now also being removed in `destroy` -0.9.5 - 2015/03/03 ------------------- +## 0.9.5 - 2015/03/03 - Compatibility fix for video.js 4.12 -0.9.4 - 2015/02/18 ------------------- +## 0.9.4 - 2015/02/18 - Compatibility with video.js 4.12.0 -0.9.3 - 2015/02/18 ------------------- +## 0.9.3 - 2015/02/18 - Documented video support and added an example (#3) -0.9.2 - 2015/02/12 ------------------- +## 0.9.2 - 2015/02/12 - Updated metadata for video -0.9.1 - 2015/01/14 ------------------- +## 0.9.1 - 2015/01/14 - Documentation and packaging fixes. -0.9.0 - 2015/01/06 ------------------- +## 0.9.0 - 2015/01/06 - Bugfixes -0.8.1 - 2014/12/17 ------------------- +## 0.8.1 - 2014/12/17 - Fixed bug with loading `Blob` or `File` objects -0.8.0 - 2014/12/17 ------------------- +## 0.8.0 - 2014/12/17 - Added microphone support for live audio visualization -0.7.0 - 2014/12/08 ------------------- +## 0.7.0 - 2014/12/08 - Ignore fullscreen mode when no valid src was loaded - Hide loading spinner when no valid src is found - Fixed issue with currentTimeDisplay's internal timer -0.6.0 - 2014/11/25 ------------------- +## 0.6.0 - 2014/11/25 - Bugfixes -0.5.0 - 2014/11/25 ------------------- +## 0.5.0 - 2014/11/25 - Bugfixes -0.4.0 - 2014/11/19 ------------------- +## 0.4.0 - 2014/11/19 - Added `msDisplayMax` plugin setting - Minor bugfixes, more docs -0.3.0 - 2014/11/14 ------------------- +## 0.3.0 - 2014/11/14 - Added fullscreen feature - Fixed issue with auto-play (#2) - Made package available on bower and npm -0.2.0 - 2014/10/05 ------------------- +## 0.2.0 - 2014/10/05 -- Compatibility with videojs 4.6 - 4.9 +- Compatibility with video.js 4.6 - 4.9 -0.1.0 - 2014/03/18 ------------------- +## 0.1.0 - 2014/03/18 - Initial release diff --git a/LICENSE b/LICENSE index 447ac244..bd87de03 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2019 Collab +Copyright (c) 2014-2020 Collab 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 diff --git a/README.md b/README.md index bad34af6..5f912d7d 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -Video.js Wavesurfer -=================== +videojs-wavesurfer +================== A [video.js](http://www.videojs.com/) plugin that adds a navigable waveform for audio and video files, using the [wavesurfer.js](https://github.com/katspaugh/wavesurfer.js) library. Includes support for fullscreen mode and [real-time visualization of microphone -input](#microphone-plugin). +input](https://collab-project.github.io/videojs-wavesurfer/#/microphone). -![Screenshot](examples/img/screenshot.png?raw=true "Screenshot") +![Screenshot](docs/img/screenshot.png?raw=true "Screenshot") [![npm version](https://img.shields.io/npm/v/videojs-wavesurfer.svg?style=flat)](https://www.npmjs.com/package/videojs-wavesurfer) [![npm](https://img.shields.io/npm/dm/videojs-wavesurfer.svg)](https://github.com/collab-project/videojs-wavesurfer/releases) @@ -16,438 +16,10 @@ input](#microphone-plugin). ![Size](https://img.shields.io/bundlephobia/minzip/videojs-wavesurfer.svg?style=flat) ![Stars](https://img.shields.io/github/stars/collab-project/videojs-wavesurfer.svg?style=social) -Table of Contents ------------------ +## Documentation -- [Installation](#installation) -- [Using the Plugin](#using-the-plugin) -- [Plugin Options](#plugin-options) -- [Examples](#examples) -- [Methods](#methods) - - [Other wavesurfer.js methods](#other-wavesurferjs-methods) -- [Events](#events) -- [Customizing controls](#customizing-controls) -- [Responsive layout](#responsive-layout) -- [Text Tracks](#text-tracks) -- [Microphone plugin](#microphone-plugin) -- [Using peaks for long audio files](#using-peaks-for-large-audio-files) -- [Change audio output or input device](#change-audio-output-or-input-device) -- [Webpack](#webpack) -- [Using with React](#using-with-react) -- [Using other frameworks](#using-other-frameworks) -- [More features using other plugins](#more-features-using-other-plugins) -- [Development](#development) -- [License](#license) -- [Donate](#donate) +The documentation and examples can be found on: https://collab-project.github.io/videojs-wavesurfer -Installation ------------- - -You can use [npm](https://www.npmjs.org) (`npm install videojs-wavesurfer`) to install the -plugin, or [download it here](https://github.com/collab-project/videojs-wavesurfer/releases). -If you want to try the examples, check [these instructions below](#examples). - -Since v3.0 this plugin is compatible with video.js 7.0.5 and wavesurfer.js 3.2.0 and -newer. If you want to use this plugin with an older video.js or wavesurfer.js version, -check the [archived releases](https://github.com/collab-project/videojs-wavesurfer/releases) -for an older release of this plugin. - -Take a look at the [changelog](./CHANGES.md) when upgrading from a previous -version of videojs-wavesurfer. - -Using the Plugin ----------------- - -The plugin depends on the video.js and wavesurfer.js libraries: - -```html - - - - - - - -``` - -The plugin automatically registers itself when the `videojs.wavesurfer.js` -script is loaded: - -```html - -``` - -Add an `audio` element: - -```html - -``` - -Or `video` element: - -```html - -``` - -Plugin Options --------------- - -Configure the player using the video.js -[options](https://github.com/videojs/video.js/blob/master/docs/guides/options.md), -and enable the plugin by adding a `wavesurfer` entry with the related wavesurfer.js -[options](https://wavesurfer-js.org/docs/options.html): - -```javascript -let player = videojs('myClip', { - controls: true, - autoplay: false, - loop: false, - fluid: false, - width: 600, - height: 300, - plugins: { - wavesurfer: { - backend: 'MediaElement', - msDisplayMax: 10, - debug: true, - waveColor: 'grey', - progressColor: 'black', - cursorColor: 'black', - hideScrollbar: true - } - } -}, function() { - // print version information at startup - let msg = 'Using video.js ' + videojs.VERSION + - ' with videojs-wavesurfer ' + - videojs.getPluginVersion('wavesurfer') + - ' and wavesurfer.js ' + WaveSurfer.VERSION; - videojs.log(msg); - - // load url - player.src({src: 'media/hal.wav', type: 'audio/wav'}); -}); -``` - -The additional options for this plugin are: - -| option | type | default | description | -| ------ | ---- | ------- | ----------- | -| `peaks` | string | `null` | The URL of the JSON file with peaks data corresponding to the source audio/video file. See the [peaks section](#using-peaks-for-large-audio-files) below for more information. | -| `debug` | boolean | `false` | Display internal log messages using the `videojs.log` method. | -| `msDisplayMax` | float | `3` | Indicates the number of seconds that is considered the boundary value for displaying milliseconds in the time controls. An audio clip with a total length of 2 seconds and a `msDisplayMax` of 3 will use the format `M:SS:MMM`. Clips with a duration that is longer than `msDisplayMax` will be displayed as `M:SS` or `HH:MM:SS`.| - -Examples --------- - -See the full `audio` example ([demo](https://collab-project.github.io/videojs-wavesurfer/examples/index.html) or [source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/index.html)) and -the `video` example ([demo](https://collab-project.github.io/videojs-wavesurfer/examples/video.html) or [source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/video.html)). - -To try out the examples locally, download the [zipfile](https://github.com/collab-project/videojs-wavesurfer/archive/master.zip) -and unpack it, or checkout the repository using Git: -``` -git clone https://github.com/collab-project/videojs-wavesurfer.git -``` - -And install the dependencies using npm: -``` -cd videojs-wavesurfer -npm install -``` - -Build the library and assets once: - -``` -npm run build -``` - -And start the local webserver for the examples: -``` -npm run start -``` - -And open http://localhost:8080/examples/index.html in a browser. - -Methods -------- - -Methods for this plugin documented below are available on the `wavesurfer` method -of the video.js player instance. For example: - -```javascript -player.on('ready', function() { - player.wavesurfer().destroy(); -}); -``` - -| Method | Description | -| ------ | ----------- | -| `destroy` | Destroys the wavesurfer instance and children (including the video.js player). | -| `load(url)` | Load the clip at `url`. Also supports loading [File](https://developer.mozilla.org/nl/docs/Web/API/File) or [Blob](https://developer.mozilla.org/nl/docs/Web/API/Blob) objects. | -| `setVolume(level)` | Set the volume level (value between 0.0 and 1.0). | -| `play` | Start playback. | -| `pause` | Pause playback. | -| `getDuration` | Get the length of the stream in seconds. Returns 0 if no stream is available (yet). | -| `getCurrentTime` | Get the current time (in seconds) of the stream during playback. Returns 0 if no stream is available (yet). | -| `exportImage(format, quality)` | Save waveform image as data URI. Default format is `'image/png'`. | -| `setAudioOutput(deviceId)` | Change the audio output device using its [deviceId](https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/deviceId). | - -Other wavesurfer.js methods ---------------------------- - -You can access the wavesurfer instance, for example to call the -wavesurfer.js `seekTo` method, by using the `surfer` property of the -`wavesurfer` plugin instance: - -```javascript -player.wavesurfer().surfer.seekTo(1); -``` - -Events ------- - -Plugin events that are available on the video.js player instance. For example: - -```javascript -player.on('waveReady', function(event) { - console.log('waveform is ready!'); -}); -``` - -| Event | Description | -| ----- | ----------- | -| `waveReady` | Audio is loaded, decoded and the waveform is drawn. | -| `playbackFinish` | Audio playback finished. | -| `audioOutputReady` | Audio output was changed and is now active. | -| `abort` | Audio loading process was interrupted and cancelled. | -| `error` | Error occurred. | - -Customizing controls --------------------- - -To disable and hide specific controls, use the video.js `controlBar` option: - -```javascript -controlBar: { - // hide fullscreen control - fullscreenToggle: false -}, -``` - -Responsive layout ------------------ - -The `fluid` option for video.js will resize the player according to the size -of the window. - -Configure the player; enable the video.js `'fluid'` option: - -```javascript -fluid: true -``` - -See the full `fluid` example -([demo](https://collab-project.github.io/videojs-wavesurfer/examples/fluid.html) or -[source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/fluid.html)). - -Text Tracks ------------ - -Text tracks (or captions/subtitles) are a feature of HTML5 for displaying -time-triggered text to the user. Video.js offers a cross-browser implementation -of text tracks. For more information, check the -[documentation](https://github.com/videojs/video.js/blob/master/docs/guides/text-tracks.md). - -![Text tracks screenshot](examples/img/text-tracks.png?raw=true "Text tracks screenshot") - -See the full `texttrack` example -([demo](https://collab-project.github.io/videojs-wavesurfer/examples/texttrack.html) or -[source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/texttrack.html)). - -Microphone plugin ------------------ - -It's also possible to use a microphone for real-time rendering of the audio waveform. This -uses the [microphone plugin](https://github.com/katspaugh/wavesurfer.js/blob/master/src/plugin/microphone.js) -that comes with wavesurfer.js. - -Include the additional `wavesurfer.microphone.js` plugin on your page. - -```html - -``` - -Add an `audio` element: - -```html - -``` - -Hide irrelevant controls, specify the `WebAudio` backend and enable the microphone plugin: - -```javascript -let player = videojs('myLiveAudio', { - controls: true, - width: 600, - height: 300, - controlBar: { - currentTimeDisplay: false, - timeDivider: false, - durationDisplay: false, - remainingTimeDisplay: false, - volumePanel: false, - progressControl: false - }, - plugins: { - wavesurfer: { - debug: true, - backend: 'WebAudio', - waveColor: 'black', - cursorWidth: 0, - interact: false, - hideScrollbar: true, - plugins: [ - // enable microphone plugin - WaveSurfer.microphone.create({ - bufferSize: 4096, - numberOfInputChannels: 1, - numberOfOutputChannels: 1, - constraints: { - video: false, - audio: true - } - }) - ] - } - } -}); -``` - -The microphone plugin has additional configuration -[options](https://wavesurfer-js.org/plugins/microphone.html). - -See the full `live` example -([demo](https://collab-project.github.io/videojs-wavesurfer/examples/live.html) or -[source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/live.html)). - -Using peaks for large audio files --------------------------------- - -When you're dealing with long audio files, it's sometimes useful to generate the waveform data, -called peaks, on the server. This allows wavesurfer.js to load the peaks JSON data and create the -waveform from that pre-rendered peak data. This JSON file can be generated using the -[bbc/audiowaveform](https://github.com/bbc/audiowaveform) utility. For more information, see the -[wavesurfer.js FAQ](https://wavesurfer-js.org/faq/). - -See the full `peaks` example -([demo](https://collab-project.github.io/videojs-wavesurfer/examples/peaks.html) or -[source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/peaks.html)). - -Change audio output or input device ------------------------------------ - -If your device has multiple audio output devices, use `setAudioOutput(deviceId)` to change -the active audio output device, and listen for the `audioOutputReady` event to be notified -when the new output device is active. - -```javascript -// change audio output device -player.wavesurfer().setAudioOutput(deviceId); -``` - -See the full `output` example -([demo](https://collab-project.github.io/videojs-wavesurfer/examples/output.html) or -[source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/output.html)). - -If your device has multiple audio input devices and you want to display -these devices and allow the user to choose one, check out the the full `input` example -([demo](https://collab-project.github.io/videojs-wavesurfer/examples/input.html) or -[source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/input.html)). - -Webpack -------- - -The [webpack](https://github.com/collab-project/videojs-wavesurfer/wiki/Webpack) wiki page shows how to configure webpack for videojs-wavesurfer. - -Using with React ----------------- - -The React [wiki page](https://github.com/collab-project/videojs-wavesurfer/wiki/React) wiki page -shows how to get started with React and videojs-wavesurfer using the -[create-react-app](https://github.com/facebook/create-react-app) tool. - -Alternatively, the `react` example shows how to integrate this plugin in a [React](https://reactjs.org) component -([demo](https://collab-project.github.io/videojs-wavesurfer/examples/react/index.html) or -[source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/react/index.html)). - -Using other frameworks ----------------------- - -The [Angular](https://github.com/collab-project/videojs-wavesurfer/wiki/Angular) wiki page shows how to setup Angular and videojs-wavesurfer. - -The [Vue.js](https://github.com/collab-project/videojs-wavesurfer/wiki/Vue.js) wiki page shows how to setup Vue.js and videojs-wavesurfer. - -More features using other plugins ---------------------------------- - -Check the `plugin` example that extends the player with the wavesurfer.js cursor plugin -([demo](https://collab-project.github.io/videojs-wavesurfer/examples/plugin.html) or -[source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/plugin.html)). - -The Video.js community created -[lots of plugins](https://github.com/videojs/video.js/wiki/Plugins) -that can be used to enhance the player's functionality. Plugins actually -tested with `videojs-wavesurfer`: - -- [videojs-record](https://github.com/collab-project/videojs-record) - Adds - support for recording audio/video/image files. - -Development ------------ - -Install dependencies using npm: - -``` -npm install -``` - -Build development and minified versions of the library and stylesheets: - -``` -npm run build -``` - -Generated files are placed in the `dist` directory. - -During development: - -``` -npm run start -``` - -This will watch the source directory and rebuild when any changes -are detected. It will also serve the files on http://127.0.0.1:8080. - -Generate the API documentation (placed in the `docs` directory): - -``` -npm run docs -``` - -All commands for development are listed in the `package.json` file and -are run using: - -``` -npm run -``` - -License -------- +## License This work is licensed under the [MIT License](LICENSE). - -Donate ------- - -Please consider donating if you like this project. Bitcoin is accepted -and can be sent to `3PmXCqUggtq7KUWPbpN8WhMnb1Mfb1jbq8`. diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..f14d65cc --- /dev/null +++ b/docs/README.md @@ -0,0 +1,10 @@ +# videojs-wavesurfer + +A [video.js](http://www.videojs.com/) plugin that adds a navigable waveform +for audio and video files, using the [wavesurfer.js](https://github.com/katspaugh/wavesurfer.js) +library. + +Includes support for fullscreen mode and [real-time visualization of microphone +input](#microphone-plugin). + +![Screenshot](img/screenshot.png?raw=true "videojs-wavesurfer") diff --git a/docs/_sidebar.md b/docs/_sidebar.md new file mode 100644 index 00000000..31668779 --- /dev/null +++ b/docs/_sidebar.md @@ -0,0 +1,27 @@ +- Getting started + - [Installation](install.md) + - [Usage](usage.md) + - [Examples](examples.md) + +- Guide + - [Options](options.md) + - [Methods](methods.md) + - [Events](events.md) + - [Customizing controls](controls.md) + - [Reponsive layout](responsive.md) + - [Text tracks](text-tracks.md) + - [Microphone plugin](microphone.md) + - [Using peaks for large audio files](peaks.md) + - [Change audio device](change-device.md) + - [More features using other plugins](plugins.md) + +- Frameworks + - [Webpack](webpack.md) + - [React](react.md) + - [Angular](angular.md) + - [Vue](vue.md) + +- [Development](development.md) +- [Changelog](https://github.com/collab-project/videojs-wavesurfer/blob/master/CHANGES.md) +- [License](license.md) +- [Donate](donate.md) diff --git a/docs/angular.md b/docs/angular.md new file mode 100644 index 00000000..31929fd3 --- /dev/null +++ b/docs/angular.md @@ -0,0 +1,305 @@ +# Angular + +This document describes how to setup [Angular](https://angular.io) with videojs-wavesurfer. + +For more information, check the video.js [documentation](https://github.com/videojs/video.js/blob/master/docs/guides/angular.md) +for Angular. + +## Installation + +Create a project directory, e.g. `angular-videojs-wavesurfer`. + +Create a `package.json` file inside that project directory that lists the project +dependencies: + +```json +{ + "name": "angular-videojs-wavesurfer", + "version": "1.0.0", + "scripts": { + "start": "webpack-dev-server --mode development" + }, + "dependencies": { + "@angular/common": "^8.1.2", + "@angular/compiler": "^8.1.2", + "@angular/core": "^8.1.2", + "@angular/forms": "^8.1.2", + "@angular/platform-browser": "^8.1.2", + "@angular/platform-browser-dynamic": "^8.1.2", + "@angular/router": "^8.1.2", + "core-js": "^3.1.4", + "rxjs": "^6.5.2", + "zone.js": "^0.9.1" + }, + "devDependencies": { + "@types/node": "^12.6.8", + "html-webpack-plugin": "^3.2.0", + "raw-loader": "^3.1.0", + "ts-loader": "^6.0.4", + "typescript": "^3.5.3", + "webpack": "^4.36.1", + "webpack-cli": "^3.3.6", + "webpack-dev-server": "^3.7.2" + } +} +``` + +Install the dependencies: + +```console +npm install +``` + +Install and save `videojs-wavesurfer` and `@types/video.js`: + +```console +npm install --save videojs-record @types/video.js +``` + +## Configuration + +Create `tsconfig.json`: + +```json +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "ES5" + } +} +``` + +Create a Webpack configuration file called `webpack.config.js`: + +```javascript +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const ProvidePlugin = require('webpack/lib/ProvidePlugin'); + +module.exports = { + entry: './src/main.ts', + resolve: { + extensions: ['.ts', '.js'], + alias: { + videojs: 'video.js', + WaveSurfer: 'wavesurfer.js' + } + }, + module: { + rules: [ + { + test: /\.ts$/, + use: ['ts-loader'] + }, + { + test: /\.(html|css)$/, + use: 'raw-loader' + } + ] + }, + plugins: [ + new ProvidePlugin({ + videojs: 'video.js/dist/video.cjs.js' + }), + new HtmlWebpackPlugin({ template: './src/index.html' }) + ] +} +``` + +## Sample Project + +Create the `src/app/` directory and add a new Angular component for videojs-wavesurfer +in `src/app/videojs.wavesurfer.component.ts`: + +```javascript +import { + Component, + OnInit, + OnDestroy, + ElementRef +} from '@angular/core'; + +import videojs from 'video.js'; +import * as WaveSurfer from 'wavesurfer.js'; + +/* +// Required imports when using videojs-wavesurfer 'live' mode with the microphone plugin +import * as adapter from 'webrtc-adapter/out/adapter_no_global.js'; +import * as MicrophonePlugin from 'wavesurfer.js/dist/plugin/wavesurfer.microphone.js'; +WaveSurfer.microphone = MicrophonePlugin; +*/ + +// Register videojs-wavesurfer plugin +import * as Wavesurfer from 'videojs-wavesurfer/dist/videojs.wavesurfer.js'; + +@Component({ + selector: 'videojs-wavesurfer', + template: ` + + + ` +}) + +export class VideoJSWavesurferComponent implements OnInit, OnDestroy { + + // reference to the element itself: used to access events and methods + private _elementRef: ElementRef + + // index to create unique ID for component + idx = 'clip1'; + + private config: any; + private player: any; + private plugin: any; + + // constructor initializes our declared vars + constructor(elementRef: ElementRef) { + this.player = false; + + // save reference to plugin (so it initializes) + this.plugin = Wavesurfer; + + // video.js configuration + this.config = { + controls: true, + autoplay: false, + fluid: false, + loop: false, + width: 600, + height: 300, + plugins: { + // configure videojs-wavesurfer plugin + wavesurfer: { + src: '/hal.wav', + msDisplayMax: 10, + debug: true, + waveColor: '#4A4A22', + progressColor: 'black', + cursorColor: 'black', + hideScrollbar: true + } + } + }; + } + + ngOnInit() {} + + // use ngAfterViewInit to make sure we initialize the videojs element + // after the component template itself has been rendered + ngAfterViewInit() { + // ID with which to access the template's audio element + let el = 'audio_' + this.idx; + + // setup the player via the unique element ID + this.player = videojs(document.getElementById(el), this.config, () => { + console.log('player ready! id:', el); + + // print version information at startup + var msg = 'Using video.js ' + videojs.VERSION + + ' with videojs-wavesurfer ' + videojs.getPluginVersion('wavesurfer') + + ' and wavesurfer.js ' + WaveSurfer.VERSION; + videojs.log(msg); + }); + + this.player.on('waveReady', event => { + console.log('waveform is ready!'); + }); + + this.player.on('playbackFinish', event => { + console.log('playback finished.'); + }); + + // error handling + this.player.on('error', (element, error) => { + console.warn(error); + }); + + this.player.on('deviceError', () => { + console.error('device error:', this.player.deviceErrorCode); + }); + } + + // use ngOnDestroy to detach event handlers and remove the player + ngOnDestroy() { + if (this.player) { + this.player.dispose(); + this.player = false; + } + } + +} +``` + +Create the Angular app module in `src/app/app.module.ts`: + +```ts +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { VideoJSWavesurferComponent } from './videojs.wavesurfer.component'; + +@NgModule({ + imports: [BrowserModule], + declarations: [VideoJSWavesurferComponent], + bootstrap: [VideoJSWavesurferComponent] +}) +export class AppModule { } +``` + +Create an Angular polyfills file in `src/polyfills.ts`: + +```ts +import 'core-js/features/reflect'; +import 'zone.js/dist/zone'; +``` + +Create the Angular main file in `src/main.ts`: + +```ts +import './polyfills'; + +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); +``` + +And finally, create the main index HTML file in `src/index.html`: + +```html + + + + + Angular videojs-wavesurfer example + + + + + + +

Angular + videojs-wavesurfer

+ + + +``` + +## Content + +Download the [example audio file](https://github.com/collab-project/videojs-wavesurfer/raw/master/examples/media/hal.wav) +and place it in the project directory. + +## Run example + +Start the development server: + +```console +npm start +``` + +And open http://localhost:8080/ in a browser. diff --git a/docs/change-device.md b/docs/change-device.md new file mode 100644 index 00000000..2f33ef07 --- /dev/null +++ b/docs/change-device.md @@ -0,0 +1,30 @@ +# Change device + +## Output + +### Example + +- [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/output.html) +- [demo source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/output.html) + + +### Usage + +If your device has multiple audio output devices, use `setAudioOutput(deviceId)` to change +the active audio output device, and listen for the `audioOutputReady` event to be notified +when the new output device is active. + +```javascript +// change audio output device +player.wavesurfer().setAudioOutput(deviceId); +``` + +## Input + +If your device has multiple audio input devices and you want to display +these devices and allow the user to choose one, check out the input example. + +#### Example + +- [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/input.html) +- [demo source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/input.html) diff --git a/docs/controls.md b/docs/controls.md new file mode 100644 index 00000000..b6fa0e62 --- /dev/null +++ b/docs/controls.md @@ -0,0 +1,12 @@ +# Customizing controls + +To disable and hide specific controls, use the video.js `controlBar` option: + +```javascript +controlBar: { + // hide fullscreen control + fullscreenToggle: false +} +``` + +For more information, see the video.js [component options](https://github.com/videojs/video.js/blob/master/docs/guides/options.md#component-options). diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 00000000..2c61ae63 --- /dev/null +++ b/docs/development.md @@ -0,0 +1,37 @@ +# Development + +Install dependencies using npm: + +``` +npm install +``` + +Build development and minified versions of the library and stylesheets: + +``` +npm run build +``` + +Generated files are placed in the `dist` directory. + +During development: + +``` +npm run start +``` + +This will watch the source directory and rebuild when any changes +are detected. It will also serve the files on http://127.0.0.1:8080. + +Generate the API documentation (placed in the `docs` directory): + +``` +npm run docs +``` + +All commands for development are listed in the `package.json` file and +are run using: + +``` +npm run +``` diff --git a/docs/donate.md b/docs/donate.md new file mode 100644 index 00000000..358c061a --- /dev/null +++ b/docs/donate.md @@ -0,0 +1,4 @@ +# Donate + +Please consider donating if you like this project. Bitcoin is accepted +and can be sent to `3PmXCqUggtq7KUWPbpN8WhMnb1Mfb1jbq8`. diff --git a/docs/events.md b/docs/events.md new file mode 100644 index 00000000..e1f1432e --- /dev/null +++ b/docs/events.md @@ -0,0 +1,19 @@ +# Events + +The events for this plugin are available on the video.js player instance. + +For example: + +```javascript +player.on('waveReady', function(event) { + console.log('waveform is ready!'); +}); +``` + +| Event | Description | +| ----- | ----------- | +| `waveReady` | Audio is loaded, decoded and the waveform is drawn. | +| `playbackFinish` | Audio playback finished. | +| `audioOutputReady` | Audio output was changed and is now active. | +| `abort` | Audio loading process was interrupted and cancelled. | +| `error` | Error occurred. | diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 00000000..58ffdeba --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,47 @@ +# Examples + +View the examples online: + +| Example | Description | Demo | Source | +| --- | --- | --- | --- | +| **Audio** | Basic audio example | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/index.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/index.html) | +| **Video** | Basic video example | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/video.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/video.html) | +| **Responsive** | Enable [responsive layout](responsive.md) | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/fluid.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/fluid.html) | +| **Text tracks** | Display [text tracks](text-tracks.md) | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/texttrack.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/texttrack.html) | +| **Microphone** | Real-time waveform rendering of [microphone](microphone.md) | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/live.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/live.html) | +| **Peaks** | Use JSON [peaks data](peaks.md) to render waveform | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/peaks.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/peaks.html) | +| **Output device** | Change audio [output device](change-device.md) | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/output.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/output.html) | +| **Input device** | Change audio [input device](change-device.md) | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/input.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/input.html) | +| **Cursor** | Enable more [wavesurfer.js plugins](plugins.md) | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/plugin.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/plugin.html) | +| **React** | Basic [React](react.md) example | [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/react/index.html) | [example source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/react/index.html) | + +## Local + +To try out the examples locally either: + +- download the [zipfile](https://github.com/collab-project/videojs-wavesurfer/archive/master.zip) and unpack it +- or checkout the repository with Git: +```console +git clone https://github.com/collab-project/videojs-wavesurfer.git +``` + +1. Install the dependencies: + +```console +cd /path/to/videojs-wavesurfer +npm install +``` + +2. Build the library and assets once: + +```console +npm run build +``` + +3. And start the local examples webserver: + +```console +npm run start +``` + +Open http://localhost:8080/examples/index.html in a browser. diff --git a/examples/img/screenshot.png b/docs/img/screenshot.png similarity index 100% rename from examples/img/screenshot.png rename to docs/img/screenshot.png diff --git a/examples/img/text-tracks.png b/docs/img/text-tracks.png similarity index 100% rename from examples/img/text-tracks.png rename to docs/img/text-tracks.png diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..b298a6ce --- /dev/null +++ b/docs/index.html @@ -0,0 +1,24 @@ + + + + + videojs-wavesurfer + + + + + + +
+ + + + + + + diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 00000000..97e40ace --- /dev/null +++ b/docs/install.md @@ -0,0 +1,41 @@ +# Installation + +You can use [npm](https://www.npmjs.org) to install the plugin: + +``` +npm install videojs-wavesurfer +``` + +Or [download it from Github](https://github.com/collab-project/videojs-wavesurfer/releases). + +## CDN + +Using the [unpkg.com](https://unpkg.com) CDN: + +```html + + + + + +``` + +Alternative CDN locations: + +- https://cdn.jsdelivr.net/npm/videojs-wavesurfer/ +- https://cdnjs.com/libraries/videojs-wavesurfer +- http://www.bootcdn.cn/videojs-wavesurfer + +## Upgrade + +Since v3.0 this plugin is compatible with: + +- video.js 7.0.5 or newer +- wavesurfer.js 3.3.0 or newer + +If you want to use this plugin with an older video.js or wavesurfer.js version, +check the [archived releases](https://github.com/collab-project/videojs-wavesurfer/releases) +for an older release of this plugin. + +Also take a look at the [changelog](changelog.md) when upgrading from a previous +version of videojs-wavesurfer. diff --git a/docs/license.md b/docs/license.md new file mode 100644 index 00000000..2ad58116 --- /dev/null +++ b/docs/license.md @@ -0,0 +1,3 @@ +# License + +This work is licensed under the [MIT License](https://github.com/collab-project/videojs-wavesurfer/blob/master/LICENSE). diff --git a/docs/methods.md b/docs/methods.md new file mode 100644 index 00000000..4bef3bba --- /dev/null +++ b/docs/methods.md @@ -0,0 +1,34 @@ +# Methods + +Methods for this plugin are documented below. These are available on the +`wavesurfer` plugin instance of the video.js player. + +For example: + +```javascript +player.on('ready', function() { + player.wavesurfer().destroy(); +}); +``` + +| Method | Description | +| ------ | ----------- | +| `destroy` | Destroys the wavesurfer instance and children (including the video.js player). | +| `load(url)` | Load the clip at `url`. Also supports loading [File](https://developer.mozilla.org/nl/docs/Web/API/File) or [Blob](https://developer.mozilla.org/nl/docs/Web/API/Blob) objects. | +| `setVolume(level)` | Set the volume level (value between 0.0 and 1.0). | +| `play` | Start playback. | +| `pause` | Pause playback. | +| `getDuration` | Get the length of the stream in seconds. Returns 0 if no stream is available (yet). | +| `getCurrentTime` | Get the current time (in seconds) of the stream during playback. Returns 0 if no stream is available (yet). | +| `exportImage(format, quality)` | Save waveform image as data URI. Default format is `'image/png'`. | +| `setAudioOutput(deviceId)` | Change the audio output device using its [deviceId](https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/deviceId). | + +## Other wavesurfer.js methods + +You can access the wavesurfer instance, for example to call the +wavesurfer.js `seekTo` method, by using the `surfer` property of the +`wavesurfer` plugin instance: + +```javascript +player.wavesurfer().surfer.seekTo(1); +``` diff --git a/docs/microphone.md b/docs/microphone.md new file mode 100644 index 00000000..21f0d4f9 --- /dev/null +++ b/docs/microphone.md @@ -0,0 +1,67 @@ +# Microphone plugin + +It's also possible to use a microphone for real-time rendering of the audio waveform. This +uses the [microphone plugin](https://wavesurfer-js.org/plugins/microphone.html) that comes +with wavesurfer.js. + +## Example + +- [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/live.html) +- [demo source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/live.html) + +## Usage + +Include the additional `wavesurfer.microphone.js` plugin on your page. + +```html + +``` + +Add an `audio` element: + +```html + +``` + +Hide irrelevant controls, specify the `WebAudio` backend and enable the microphone plugin: + +```javascript +let player = videojs('myLiveAudio', { + controls: true, + width: 600, + height: 300, + controlBar: { + currentTimeDisplay: false, + timeDivider: false, + durationDisplay: false, + remainingTimeDisplay: false, + volumePanel: false, + progressControl: false + }, + plugins: { + wavesurfer: { + debug: true, + backend: 'WebAudio', + waveColor: 'black', + cursorWidth: 0, + interact: false, + hideScrollbar: true, + plugins: [ + // enable microphone plugin + WaveSurfer.microphone.create({ + bufferSize: 4096, + numberOfInputChannels: 1, + numberOfOutputChannels: 1, + constraints: { + video: false, + audio: true + } + }) + ] + } + } +}); +``` + +The wavesurfer.js microphone plugin has additional configuration +[options](https://wavesurfer-js.org/plugins/microphone.html). diff --git a/docs/options.md b/docs/options.md new file mode 100644 index 00000000..c644bab8 --- /dev/null +++ b/docs/options.md @@ -0,0 +1,14 @@ +# Options + +Configure the player with: + +- [video.js options](https://github.com/videojs/video.js/blob/master/docs/guides/options.md) +- [wavesurfer.js options](https://wavesurfer-js.org/docs/options.html) + +Additional options for this plugin are: + +| option | type | default | description | +| ------ | ---- | ------- | ----------- | +| `peaks` | string | `null` | The URL of the JSON file with peaks data corresponding to the source audio/video file. See the [peaks section](#using-peaks-for-large-audio-files) below for more information. | +| `debug` | boolean | `false` | Display internal log messages using the `videojs.log` method. | +| `msDisplayMax` | float | `3` | Indicates the number of seconds that is considered the boundary value for displaying milliseconds in the time controls. An audio clip with a total length of 2 seconds and a `msDisplayMax` of 3 will use the format `M:SS:MMM`. Clips with a duration that is longer than `msDisplayMax` will be displayed as `M:SS` or `HH:MM:SS`.| diff --git a/docs/peaks.md b/docs/peaks.md new file mode 100644 index 00000000..b968583c --- /dev/null +++ b/docs/peaks.md @@ -0,0 +1,28 @@ +# Using peaks for large audio files + +When you're dealing with long audio files, it's sometimes useful to generate the waveform data, +called peaks, on the server. This allows wavesurfer.js to load the peaks JSON data and create the +waveform from that pre-rendered peak data. This JSON file can be generated using the +[bbc/audiowaveform](https://github.com/bbc/audiowaveform) utility. + +For more information, see the wavesurfer.js [FAQ](https://wavesurfer-js.org/faq/). + +## Example + +- [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/peaks.html) +- [demo source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/peaks.html) + +## Usage + +Load peaks data: + +```javascript +// load file with peaks +player.src({ + src: 'media/hal.wav', + type: 'audio/wav', + // Use peaks from JSON file. See https://wavesurfer-js.org/faq/ + // for instructions on how to generate peaks + peaks: 'media/hal-peaks.json' +}); +``` diff --git a/docs/plugins.md b/docs/plugins.md new file mode 100644 index 00000000..30b33a95 --- /dev/null +++ b/docs/plugins.md @@ -0,0 +1,20 @@ +# More features using other plugins + +## video.js + +The Video.js community created +[lots of plugins](https://github.com/videojs/video.js/wiki/Plugins) +that can be used to enhance the player's functionality. + +Plugins actually tested with videojs-wavesurfer include: + +- [videojs-record](https://github.com/collab-project/videojs-record) - Adds + support for recording audio/video/image files. + +## wavesurfer.js + +The plugin example extends videojs-wavesurfer with the wavesurfer.js +[cursor plugin](https://wavesurfer-js.org/example/cursor/index.html): + +- [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/plugin.html) +- [demo source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/plugin.html) diff --git a/docs/react.md b/docs/react.md new file mode 100644 index 00000000..c36d3d89 --- /dev/null +++ b/docs/react.md @@ -0,0 +1,194 @@ +# React + +This page shows how to get started with [React](https://reactjs.org) and +videojs-wavesurfer using [create-react-app](https://github.com/facebook/create-react-app). + +For more information, check the video.js [documentation](https://github.com/videojs/video.js/blob/master/docs/guides/react.md) +for React. + +## Installation + +Create an example React application called `audio-app`: + +```console +npx create-react-app audio-app +``` + +Install videojs-wavesurfer: + +```console +cd audio-app +npm install --save videojs-wavesurfer +``` + +Install [react-app-wired](https://github.com/timarney/react-app-rewired) that we'll +use to configure Webpack: + +```console +npm install react-app-rewired --save-dev +``` + +## Application + +Edit `src/index.js`: + +```javascript +import React from 'react'; +import ReactDOM from 'react-dom'; +import './index.css'; +import App from './App'; +import * as serviceWorker from './serviceWorker'; + +const videoJsOptions = { + controls: true, + width: 600, + height: 300, + fluid: false, + plugins: { + wavesurfer: { + src: 'hal.wav', + msDisplayMax: 10, + debug: true, + waveColor: '#163b5b', + progressColor: 'black', + cursorColor: 'black', + hideScrollbar: true + } + } +}; + +ReactDOM.render(, document.getElementById('root')); + +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: http://bit.ly/CRA-PWA +serviceWorker.unregister(); +``` + +Edit `src/App.js`: + +```javascript +/* eslint-disable */ +import React, { Component } from 'react'; + +import './App.css'; + +import 'video.js/dist/video-js.css'; +import videojs from 'video.js'; + +import WaveSurfer from 'wavesurfer.js'; + +/* +// the following imports are only needed when you're using +// the microphone plugin +import 'webrtc-adapter'; + +import MicrophonePlugin from 'wavesurfer.js/dist/plugin/wavesurfer.microphone.js'; +WaveSurfer.microphone = MicrophonePlugin; +*/ + +// register videojs-wavesurfer plugin with this import +import 'videojs-wavesurfer/dist/css/videojs.wavesurfer.css'; +import Wavesurfer from 'videojs-wavesurfer/dist/videojs.wavesurfer.js'; + +class App extends Component { + componentDidMount() { + // instantiate Video.js + this.player = videojs(this.audioNode, this.props, () => { + // print version information at startup + var version_info = 'Using video.js ' + videojs.VERSION + + ' with videojs-wavesurfer ' + videojs.getPluginVersion('wavesurfer') + + ' and wavesurfer.js ' + WaveSurfer.VERSION; + videojs.log(version_info); + }); + + this.player.on('waveReady', (event) => { + console.log('waveform: ready!'); + }); + + this.player.on('playbackFinish', (event) => { + console.log('playback finished.'); + }); + + // error handling + this.player.on('error', (element, error) => { + console.error(error); + }); + } + + // destroy player on unmount + componentWillUnmount() { + if (this.player) { + this.player.dispose(); + } + } + render() { + return ( +
+ +
+ ); + } +} + +export default App; +``` + +Add this to `src/index.css`: + +```css +/* change player background color */ +#myAudio { + background-color: #ACB2F2; +} +``` + +## Webpack configuration + +Create a `config-overrides.js` file in the root directory: + +```javascript +const webpack = require("webpack"); + +module.exports = function override(config, env) { + // Extend the config to work with the videojs-wavesurfer project without ejecting create react app. + // Reference: https://github.com/collab-project/videojs-wavesurfer/wiki/React + const videojsPlugin = new webpack.ProvidePlugin({ + videojs: "video.js/dist/video.cjs.js" + }); + const videojsAlias = { + videojs: "video.js", + WaveSurfer: "wavesurfer.js" + }; + config.resolve.alias = { ...config.resolve.alias, ...videojsAlias }; + config.plugins.push(videojsPlugin); + return config; +}; +``` + +Change the existing calls to `react-scripts` in the `scripts` section of `package.json` +for `start`, `build` and `test`: + +```json +"scripts": { + "start": "react-app-rewired start", + "build": "react-app-rewired build", + "test": "react-app-rewired test --env=jsdom", + "eject": "react-scripts eject" +} +``` + +## Content + +Download the [example audio file](https://github.com/collab-project/videojs-wavesurfer/raw/master/examples/media/hal.wav) +and place it in the `public` directory. + +## Run + +Start the development server: + +``` +npm start +``` + +And open http://localhost:3000 in a browser. diff --git a/docs/responsive.md b/docs/responsive.md new file mode 100644 index 00000000..d885bc29 --- /dev/null +++ b/docs/responsive.md @@ -0,0 +1,17 @@ +# Responsive layout + +The `fluid` option for video.js will resize the player according to the size +of the window. + +Configure the player and enable the video.js `fluid` option: + +```javascript +fluid: true +``` + +For more information, see the video.js [layout documentation](https://github.com/videojs/video.js/blob/master/docs/guides/layout.md). + +## Example + +- [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/fluid.html) +- [demo source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/fluid.html) diff --git a/docs/text-tracks.md b/docs/text-tracks.md new file mode 100644 index 00000000..85f02528 --- /dev/null +++ b/docs/text-tracks.md @@ -0,0 +1,15 @@ +# Text Tracks + +Text tracks (or captions/subtitles) are a feature of HTML5 for displaying +time-triggered text to the user. Video.js offers a cross-browser implementation +of text tracks. + +For more information, check the video.js +[text tracks documentation](https://github.com/videojs/video.js/blob/master/docs/guides/text-tracks.md). + +![Text tracks screenshot](img/text-tracks.png?raw=true "Text tracks screenshot") + +## Example + +- [online demo](https://collab-project.github.io/videojs-wavesurfer/examples/texttrack.html) +- [demo source](https://github.com/collab-project/videojs-wavesurfer/blob/master/examples/texttrack.html) diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 00000000..0b79c913 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,79 @@ +# Usage + +The plugin depends on the video.js and wavesurfer.js libraries: + +```html + + + + + + + +``` + +The plugin automatically registers itself when the `videojs.wavesurfer.js` +script is loaded: + +```html + +``` + +Add an `audio` element: + +```html + +``` + +Or `video` element: + +```html + +``` + +Define the player configuration and enable the videojs-wavesurfer plugin by +adding a `wavesurfer` entry: + +```javascript +// configuration for video.js +let options = { + controls: true, + autoplay: false, + loop: false, + fluid: false, + width: 600, + height: 300, + plugins: { + // enable videojs-wavesurfer plugin + wavesurfer: { + // configure videojs-wavesurfer + backend: 'MediaElement', + msDisplayMax: 10, + debug: true, + waveColor: 'grey', + progressColor: 'black', + cursorColor: 'black', + hideScrollbar: true + } + } +}; +``` + +Finally, create the player and load a file: + +```javascript +let player = videojs('myClip', options, function() { + // print version information at startup + let msg = 'Using video.js ' + videojs.VERSION + + ' with videojs-wavesurfer ' + + videojs.getPluginVersion('wavesurfer') + + ' and wavesurfer.js ' + WaveSurfer.VERSION; + videojs.log(msg); + + // load wav file from url + player.src({src: 'media/hal.wav', type: 'audio/wav'}); +}); +``` + +Check the [options](options.md), [methods](methods.md) and [events](events.md) documentation +for more information. diff --git a/docs/vue.md b/docs/vue.md new file mode 100644 index 00000000..bc323484 --- /dev/null +++ b/docs/vue.md @@ -0,0 +1,170 @@ +# Vue + +This page shows how to get started with [Vue.js](https://vuejs.org/) and videojs-wavesurfer. + +For more information, check the video.js [documentation](https://github.com/videojs/video.js/blob/master/docs/guides/vue.md) for Vue.js. + +## Installation + +Install the [Vue.js CLI](https://cli.vuejs.org/guide/) globally: + +```console +npm install -g @vue/cli +``` + +Create a new application, e.g. `videojs-wavesurfer-app`: + +```console +vue create --preset default videojs-wavesurfer-app +``` + +Install videojs-wavesurfer: + +```console +cd videojs-wavesurfer-app +npm install --save videojs-wavesurfer +``` + +## Webpack config + +Create `vue.config.js` with the following content: + +```javascript +const webpack = require('webpack'); + +module.exports = { + configureWebpack: { + resolve: { + alias: { + videojs: 'video.js', + WaveSurfer: 'wavesurfer.js', + RecordRTC: 'recordrtc' + } + }, + plugins: [ + new webpack.ProvidePlugin({ + videojs: 'video.js/dist/video.cjs.js', + RecordRTC: 'recordrtc' + }) + ] + } +} +``` + +## Application + +Create `src/components/VideoJSWavesurfer.vue`: + +```html + + + +``` + +Change `src/App.vue` to: + +```html + + + + + +``` + +## Content + +Download the [example audio file](https://github.com/collab-project/videojs-wavesurfer/raw/master/examples/media/hal.wav) +and place it in the `public` directory. + +## Run example + +Start the Vue.js development server: + +```console +npm run serve +``` + +And open http://localhost:8080 in a browser. diff --git a/docs/webpack.md b/docs/webpack.md new file mode 100644 index 00000000..188d9cb2 --- /dev/null +++ b/docs/webpack.md @@ -0,0 +1,172 @@ +# Webpack + +This document describes how to setup [Webpack](https://webpack.js.org/) with videojs-wavesurfer. + +## Setup + +Install Webpack: + +```console +npm install webpack webpack-dev-server webpack-cli css-loader style-loader -D +``` + +Install videojs-wavesurfer: + +```console +npm install videojs-wavesurfer +``` + +## Webpack config + +Create the Webpack config file called `webpack.config.js`: + +```javascript +const path = require('path'); +const webpack = require('webpack'); +const basePath = path.resolve(__dirname); + +module.exports = { + context: path.join(basePath, 'src'), + entry: { + app: './app.js' + }, + output: { + path: path.join(basePath, 'dist'), + filename: '[name].bundle.js', + publicPath: '/dist' + }, + devServer: { + contentBase: basePath, + watchContentBase: true + }, + resolve: { + alias: { + videojs: 'video.js', + WaveSurfer: 'wavesurfer.js' + } + }, + plugins: [ + new webpack.ProvidePlugin({ + videojs: 'video.js/dist/video.cjs.js' + }) + ], + module: { + rules: [{ + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }] + } +}; +``` + +## Sample project + +Create `src/index.html` containing: + +```html + + + + + Webpack videojs-wavesurfer example + + + + + + + + + + + +``` + +And create `src/app.js`: + +```javascript +import video_css from 'video.js/dist/video-js.min.css'; +import videojs from 'video.js'; +import WaveSurfer from 'wavesurfer.js'; + +/* +// the following imports are only required when using the +// videojs-wavesurfer 'live' mode with the microphone plugin +import 'webrtc-adapter'; +import MicrophonePlugin from 'wavesurfer.js/dist/plugin/wavesurfer.microphone.js'; +WaveSurfer.microphone = MicrophonePlugin; +*/ + +// register videojs-wavesurfer plugin +import wavesurfer_css from 'videojs-wavesurfer/dist/css/videojs.wavesurfer.css'; +import Wavesurfer from 'videojs-wavesurfer/dist/videojs.wavesurfer.js'; + +let player; +const elementId = 'myAudio'; +const playerOptions = { + controls: true, + autoplay: false, + fluid: false, + loop: false, + width: 600, + height: 300, + plugins: { + // configure videojs-wavesurfer plugin + wavesurfer: { + src: '/hal.wav', + msDisplayMax: 10, + debug: true, + waveColor: '#4A4A22', + progressColor: 'black', + cursorColor: 'black', + hideScrollbar: true + } + } +}; + +// wait till DOM is ready +document.addEventListener('DOMContentLoaded', function() { + // create player + player = videojs(elementId, playerOptions, function() { + console.log('player ready! id:', elementId); + // print version information at startup + var msg = 'Using video.js ' + videojs.VERSION + + ' with videojs-wavesurfer ' + videojs.getPluginVersion('wavesurfer') + + ' and wavesurfer.js ' + WaveSurfer.VERSION; + videojs.log(msg); + }); + + player.on('waveReady', function(event) { + console.log('waveform is ready!'); + }); + + player.on('playbackFinish', function(event) { + console.log('playback finished.'); + }); + + // error handling + player.on('error', function(element, error) { + console.error('ERROR:', error); + }); +}); +``` + +## Content + +Download the [example audio file](https://github.com/collab-project/videojs-wavesurfer/raw/master/examples/media/hal.wav) +and place it in the root directory. + +## Run example + +Start the Webpack development server: + +``` +./node_modules/.bin/webpack-dev-server --mode=development +``` + +And open http://localhost:8080/src/index.html in a browser. diff --git a/package-lock.json b/package-lock.json index a5800be1..ee56319a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1774,6 +1774,21 @@ "integrity": "sha512-D5H5RjqqE+YxI2oeTgSRuIjdy/hli90H5mMd81bBrYlOfB/f4TBsKMoaWfzI5E4bmFzLfQJuvvepTaWrxVfBug==", "dev": true }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -2137,6 +2152,34 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, "ansi-colors": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", @@ -2905,6 +2948,47 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, + "boxen": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-3.2.0.tgz", + "integrity": "sha512-cU4J/+NodM3IHdSL2yN8bqYqnmlBTidDR4RC7nJs61ZmtGz8VZzM3HLQX0zY5mrSmPtR3xWwsq2jOUQqFZN8+A==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^2.4.2", + "cli-boxes": "^2.2.0", + "string-width": "^3.0.0", + "term-size": "^1.2.0", + "type-fest": "^0.3.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + } + } + }, "brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", @@ -3246,6 +3330,54 @@ "unset-value": "^1.0.0" } }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", @@ -3523,6 +3655,12 @@ "tslib": "^1.9.0" } }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -3630,6 +3768,12 @@ "glob": "^7.1.1" } }, + "cli-boxes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", + "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", + "dev": true + }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -3645,6 +3789,18 @@ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, + "clipboard": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", + "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", + "dev": true, + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -3704,6 +3860,15 @@ } } }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, "clone-stats": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", @@ -3966,6 +4131,31 @@ "typedarray": "^0.0.6" } }, + "configstore": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", + "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + } + } + }, "connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", @@ -3984,6 +4174,12 @@ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "dev": true }, + "connect-livereload": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.1.tgz", + "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==", + "dev": true + }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", @@ -4195,6 +4391,35 @@ } } }, + "cp-file": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", + "integrity": "sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "nested-error-stacks": "^2.0.0", + "p-event": "^4.1.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", @@ -4280,6 +4505,12 @@ "randomfill": "^1.0.3" } }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", @@ -4707,6 +4938,15 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, "deep-equal": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", @@ -4729,6 +4969,12 @@ } } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -4745,6 +4991,12 @@ "ip-regex": "^2.1.0" } }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -4809,6 +5061,13 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "dev": true, + "optional": true + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -4899,6 +5158,201 @@ "buffer-indexof": "^1.0.0" } }, + "docsify": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/docsify/-/docsify-4.11.3.tgz", + "integrity": "sha512-o9AvGb4vZOlmorg/58Kj6tNdfBaoSQUJZSFC6fJsfLjGFt45kiXhA2UmALnnVk5sol0WgSzxZlcZw6tu1gVu4Q==", + "dev": true, + "requires": { + "marked": "^0.7.0", + "medium-zoom": "^1.0.5", + "opencollective-postinstall": "^2.0.2", + "prismjs": "^1.19.0", + "strip-indent": "^3.0.0", + "tinydate": "^1.0.0", + "tweezer.js": "^1.4.0" + }, + "dependencies": { + "marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + } + } + }, + "docsify-cli": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/docsify-cli/-/docsify-cli-4.4.0.tgz", + "integrity": "sha512-Ve3aUIGbjPpcjRtb3QHJQ9wI0fETMve1bBdTIztWfPnAJ2tOAYO7XUDHe9864RheGOli5s8iI3BviY6CS1ZImA==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "connect": "^3.6.0", + "connect-livereload": "^0.6.0", + "cp-file": "^7.0.0", + "docsify": ">=3", + "docsify-server-renderer": ">=4", + "fs-extra": "^8.1.0", + "get-port": "^5.0.0", + "livereload": "^0.8.2", + "lru-cache": "^5.1.1", + "open": "^6.4.0", + "serve-static": "^1.12.1", + "update-notifier": "^3.0.1", + "yargonaut": "^1.1.2", + "yargs": "^14.2.0" + }, + "dependencies": { + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "yargs-parser": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "docsify-server-renderer": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/docsify-server-renderer/-/docsify-server-renderer-4.11.2.tgz", + "integrity": "sha512-j8hyZzrMI4JwOCZXqXXyzAi/k538m6liPdZVeCJgrvIPDlYAe1gDoXzwYZjSB/c9JfXi8kAbnsBjJ+GPw2yfJQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "docsify": "^4.10.2", + "node-fetch": "^2.6.0", + "resolve-pathname": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4989,6 +5443,12 @@ "is-obj": "^1.0.0" } }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "duplexify": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", @@ -5911,6 +6371,12 @@ "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", "dev": true }, + "figlet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.4.0.tgz", + "integrity": "sha512-CxxIjEKHlqGosgXaIA+sikGDdV6KZOOlzPJnYuPgQlOSHZP5h9WIghYI30fyXnwEVeSH7Hedy72gC6zJrFC+SQ==", + "dev": true + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -6881,6 +7347,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -7010,6 +7482,15 @@ "process": "~0.5.1" } }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -7106,6 +7587,35 @@ } } }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "dev": true, + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -7253,6 +7763,12 @@ } } }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -7601,6 +8117,12 @@ } } }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -7729,6 +8251,12 @@ "resolve-from": "^4.0.0" } }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, "import-local": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", @@ -8017,6 +8545,15 @@ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", "dev": true }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, "is-color-stop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", @@ -8123,12 +8660,39 @@ "is-extglob": "^1.0.0" } }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + }, + "dependencies": { + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + } + } + }, "is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", "dev": true }, + "is-npm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-3.0.0.tgz", + "integrity": "sha512-wsigDr1Kkschp2opC4G3yA6r9EgVA6NjRpWzIi9axXqeIaAATPRJc4uLujXe3Nd9uO8KoDyA4MD6aZSeXTADhA==", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -8284,6 +8848,12 @@ "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", "dev": true }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -8596,6 +9166,12 @@ } } }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -9015,6 +9591,15 @@ "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=" }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -9049,6 +9634,15 @@ "webpack-sources": "^1.1.0" } }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, "lazystream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", @@ -9118,6 +9712,107 @@ "uc.micro": "^1.0.1" } }, + "livereload": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.8.2.tgz", + "integrity": "sha512-8wCvhiCL4cGVoT3U5xoe+UjpiiVZLrlOvr6dbhb1VlyC5QarhrlyRRt4z7EMGO4KSgXj+tKF/dr284F28/wI+g==", + "dev": true, + "requires": { + "chokidar": "^2.1.5", + "opts": ">= 1.2.0", + "ws": "^6.2.1" + }, + "dependencies": { + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -9332,6 +10027,12 @@ "signal-exit": "^3.0.0" } }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -9474,6 +10175,12 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, + "medium-zoom": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.5.tgz", + "integrity": "sha512-aLGa6WlTuFKWvH88bqTrY5ztJMN+D0hd8UX6BYc4YSoPayppzETjZUcdVcksgaoQEMg4cZSmXPg846fTp2rjRQ==", + "dev": true + }, "mem": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", @@ -9619,6 +10326,12 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -9627,6 +10340,12 @@ "dom-walk": "^0.1.0" } }, + "min-indent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", + "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=", + "dev": true + }, "mini-css-extract-plugin": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", @@ -9938,12 +10657,24 @@ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, "nice-try": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", "dev": true }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "dev": true + }, "node-forge": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", @@ -10772,6 +11503,29 @@ "mimic-fn": "^2.1.0" } }, + "open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + }, + "dependencies": { + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + } + } + }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", @@ -10813,6 +11567,12 @@ "word-wrap": "^1.2.3" } }, + "opts": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/opts/-/opts-1.2.7.tgz", + "integrity": "sha512-hwZhzGGG/GQ7igxAVFOEun2N4fWul31qE9nfBdCnZGQCB5+L7tN9xZ+94B4aUpLOJx/of3zZs5XsuubayQYQjA==", + "dev": true + }, "ordered-read-streams": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", @@ -10859,12 +11619,27 @@ "os-tmpdir": "^1.0.0" } }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", "dev": true }, + "p-event": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.1.0.tgz", + "integrity": "sha512-4vAd06GCsgflX4wHN1JqrMzBh/8QZ4j+rzp0cd2scXRwuBEv+QR3wrVA5aLhWDLw4y2WgDKvzWF3CCLmVM1UgA==", + "dev": true, + "requires": { + "p-timeout": "^2.0.1" + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -10913,12 +11688,41 @@ "retry": "^0.12.0" } }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -10945,6 +11749,12 @@ "callsites": "^3.0.0" } }, + "parent-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", + "integrity": "sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=", + "dev": true + }, "parse-asn1": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", @@ -11848,6 +12658,15 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, + "prismjs": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz", + "integrity": "sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==", + "dev": true, + "requires": { + "clipboard": "^2.0.0" + } + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -12043,6 +12862,26 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -12296,6 +13135,24 @@ "unicode-match-property-value-ecmascript": "^1.2.0" } }, + "registry-auth-token": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", + "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, "regjsgen": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", @@ -12500,12 +13357,27 @@ "value-or-function": "^3.0.0" } }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -12877,6 +13749,13 @@ "integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw==", "dev": true }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "dev": true, + "optional": true + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -12898,6 +13777,15 @@ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", "dev": true }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -14651,6 +15539,49 @@ } } }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, "terser": { "version": "4.6.13", "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", @@ -14918,6 +15849,19 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true, + "optional": true + }, + "tinydate": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.2.0.tgz", + "integrity": "sha512-3GwPk8VhDFnUZ2TrgkhXJs6hcMAIIw4x/xkz+ayK6dGoQmp2nUwKzBXK0WnMsqkh6vfUhpqQicQF3rbshfyJkg==", + "dev": true + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -14964,6 +15908,12 @@ "kind-of": "^3.0.2" } }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", @@ -15062,6 +16012,12 @@ "dev": true, "optional": true }, + "tweezer.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz", + "integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -15243,6 +16199,15 @@ "through2-filter": "^2.0.0" } }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -15308,6 +16273,26 @@ "dev": true, "optional": true }, + "update-notifier": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-3.0.1.tgz", + "integrity": "sha512-grrmrB6Zb8DUiyDIaeRTBCkgISYUgETNe7NglEbVsrLWXeESnlCSP50WfRSj/GmzMPl6Uchj24S/p80nP/ZQrQ==", + "dev": true, + "requires": { + "boxen": "^3.0.0", + "chalk": "^2.0.1", + "configstore": "^4.0.0", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.1.0", + "is-npm": "^3.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, "uri-js": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz", @@ -15359,6 +16344,23 @@ "requires-port": "^1.0.0" } }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + }, + "dependencies": { + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + } + } + }, "url-toolkit": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.1.6.tgz", @@ -16683,6 +17685,48 @@ } } }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -16766,6 +17810,17 @@ "mkdirp": "^0.5.1" } }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", @@ -16777,6 +17832,12 @@ "ultron": "~1.1.0" } }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, "xhr": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.0.tgz", @@ -16823,6 +17884,59 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, + "yargonaut": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", + "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "figlet": "^1.1.1", + "parent-require": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, "yargs": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", diff --git a/package.json b/package.json index 818e4311..1e227559 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "style": "dist/css/videojs.wavesurfer.css", "sass": "src/css/videojs.wavesurfer.scss", "directories": { - "doc": "./docs", + "docs": "./docs", "lib": "./src", "example": "./examples", "test": "./test" @@ -65,6 +65,7 @@ "browserslist": "^4.12.0", "css-loader": "^3.5.3", "date-fns": "^2.13.0", + "docsify-cli": "^4.4.0", "eslint": "^7.0.0", "htmlhint": "^0.11.0", "in-publish": "^2.0.1",