diff --git a/VERSION.md b/VERSION.md
index afa2b35..abb1658 100644
--- a/VERSION.md
+++ b/VERSION.md
@@ -1 +1 @@
-1.8.0
\ No newline at end of file
+1.9.0
\ No newline at end of file
diff --git a/libs/browser-id3-writer/README.md b/libs/browser-id3-writer/README.md
new file mode 100644
index 0000000..bc1017d
--- /dev/null
+++ b/libs/browser-id3-writer/README.md
@@ -0,0 +1,306 @@
+# Browser ID3 Writer
+
+[![npm package][npm-badge]][npm] [![Travis][build-badge]][build]
+
+[build-badge]: https://img.shields.io/travis/egoroof/browser-id3-writer/master.svg?style=flat-square
+[build]: https://travis-ci.org/egoroof/browser-id3-writer
+
+[npm-badge]: https://img.shields.io/npm/v/browser-id3-writer.svg?style=flat-square
+[npm]: https://www.npmjs.org/package/browser-id3-writer
+
+Pure JS library for writing [ID3 (v2.3)](http://id3.org/id3v2.3.0) tag to MP3 files in browsers and Node.js.
+It can't read the tag so use another lib to do it.
+
+**Note**: the library removes existing ID3 tag (v2.2, v2.3 and v2.4).
+
+Works in Node.js 4+, IE10+ and all modern browsers.
+
+Here is an online demonstration: [egoroof.ru/browser-id3-writer/](https://egoroof.ru/browser-id3-writer/)
+
+## Table of Contents
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Browser](#browser)
+ 1. [Get ArrayBuffer of song](#get-arraybuffer-of-song)
+ 2. [Add a tag](#add-a-tag)
+ 3. [Save file](#save-file)
+ 4. [Memory control](#memory-control)
+ - [Node.js](#nodejs)
+- [Supported frames](#supported-frames)
+- [APIC picture types](#apic-picture-types)
+
+## Installation
+
+Take latest version [here](https://unpkg.com/browser-id3-writer) or with npm:
+
+```
+npm install browser-id3-writer --save
+```
+
+## Usage
+
+### Browser
+
+#### Get ArrayBuffer of song
+
+In browsers you should first get
+[ArrayBuffer](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
+of the song you would like to add ID3 tag.
+
+##### FileReader
+
+For example you can create file input and use
+[FileReader](https://developer.mozilla.org/en/docs/Web/API/FileReader):
+
+```html
+
+
+```
+
+##### XMLHttpRequest
+
+To get arrayBuffer from remote server you can use
+[XMLHttpRequest](https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest):
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.open('GET', urlToSongFile, true);
+xhr.responseType = 'arraybuffer';
+xhr.onload = function () {
+ if (xhr.status === 200) {
+ const arrayBuffer = xhr.response;
+ // go next
+ } else {
+ // handle error
+ console.error(xhr.statusText + ' (' + xhr.status + ')');
+ }
+};
+xhr.onerror = function() {
+ // handle error
+ console.error('Network error');
+};
+xhr.send();
+```
+
+#### Add a tag
+
+Create new `ID3Writer` instance with arrayBuffer of your song, set frames and add a tag:
+
+```js
+// arrayBuffer of song or empty arrayBuffer if you just want only id3 tag without song
+const writer = new ID3Writer(arrayBuffer);
+writer.setFrame('TIT2', 'Home')
+ .setFrame('TPE1', ['Eminem', '50 Cent'])
+ .setFrame('TALB', 'Friday Night Lights')
+ .setFrame('TYER', 2004)
+ .setFrame('TRCK', '6/8')
+ .setFrame('TCON', ['Soundtrack'])
+ .setFrame('TBPM', 128)
+ .setFrame('WPAY', 'https://google.com')
+ .setFrame('TKEY', 'Fbm')
+ .setFrame('APIC', {
+ type: 3,
+ data: coverArrayBuffer,
+ description: 'Super picture'
+ });
+writer.addTag();
+```
+
+#### Save file
+
+Now you can save it to file as you want:
+
+```js
+const taggedSongBuffer = writer.arrayBuffer;
+const blob = writer.getBlob();
+const url = writer.getURL();
+```
+
+For example you can save file using [FileSaver.js](https://github.com/eligrey/FileSaver.js/):
+
+```js
+saveAs(blob, 'song with tags.mp3');
+```
+
+If you are writing chromium extension you can save file using
+[Downloads API](https://developer.chrome.com/extensions/downloads):
+
+```js
+chrome.downloads.download({
+ url: url,
+ filename: 'song with tags.mp3'
+});
+```
+
+#### Memory control
+
+When you generate URLs via `writer.getURL()` you should know
+that whole file is kept in memory until you close the page or move to another one.
+So if you generate lots of URLs in a single page you should manually free memory
+after you finish downloading file:
+
+```js
+URL.revokeObjectURL(url); // if you know url or
+writer.revokeURL(); // if you have access to writer
+```
+
+### Node.js
+
+Simple example with blocking IO:
+
+```js
+const ID3Writer = require('browser-id3-writer');
+const fs = require('fs');
+
+const songBuffer = fs.readFileSync('path_to_song.mp3');
+const coverBuffer = fs.readFileSync('path_to_cover.jpg');
+
+const writer = new ID3Writer(songBuffer);
+writer.setFrame('TIT2', 'Home')
+ .setFrame('TPE1', ['Eminem', '50 Cent'])
+ .setFrame('TALB', 'Friday Night Lights')
+ .setFrame('TYER', 2004)
+ .setFrame('APIC', {
+ type: 3,
+ data: coverBuffer,
+ description: 'Super picture'
+ });
+writer.addTag();
+
+const taggedSongBuffer = Buffer.from(writer.arrayBuffer);
+fs.writeFileSync('song_with_tags.mp3', taggedSongBuffer);
+```
+
+You can also create only ID3 tag without song and use it as you want:
+
+```js
+const writer = new ID3Writer(Buffer.alloc(0));
+writer.padding = 0; // default 4096
+writer.setFrame('TIT2', 'Home');
+writer.addTag();
+const id3Buffer = Buffer.from(writer.arrayBuffer);
+```
+
+## Supported frames
+
+Have not found needed frame? Open a new issue and we'll discuss it.
+
+**array of strings:**
+
+- TPE1 (song artists)
+- TCOM (song composers)
+- TCON (song genres)
+
+**string**
+
+- TIT2 (song title)
+- TALB (album title)
+- TPE2 (album artist)
+- TPE3 (conductor/performer refinement)
+- TPE4 (interpreted, remixed, or otherwise modified by)
+- TRCK (song number in album): '5' or '5/10'
+- TPOS (album disc number): '1' or '1/3'
+- TPUB (label name)
+- TKEY (initial key)
+- TMED (media type)
+- WCOM (commercial information)
+- WCOP (copyright/Legal information)
+- WOAF (official audio file webpage)
+- WOAR (official artist/performer webpage)
+- WOAS (official audio source webpage)
+- WORS (official internet radio station homepage)
+- WPAY (payment)
+- WPUB (publishers official webpage)
+
+**integer**
+
+- TLEN (song duration in milliseconds)
+- TYER (album release year)
+- TBPM (beats per minute)
+
+**object**
+
+- COMM (comments):
+
+```js
+writer.setFrame('COMM', {
+ description: 'description here',
+ text: 'text here'
+});
+```
+
+- USLT (unsychronised lyrics):
+
+```js
+writer.setFrame('USLT', {
+ description: 'description here',
+ lyrics: 'lyrics here'
+});
+```
+
+- TXXX (user defined text):
+
+```js
+writer.setFrame('TXXX', {
+ description: 'description here',
+ value: 'value here'
+});
+```
+
+- APIC (attached picture):
+
+```js
+writer.setFrame('APIC', {
+ type: 3,
+ data: coverArrayBuffer,
+ description: 'description here',
+ useUnicodeEncoding: false
+});
+```
+
+`useUnicodeEncoding` should only be `true` when description contains non-Western characters.
+When it's set to `true` some program might not be able to read the picture correctly.
+See [#42](https://github.com/egoroof/browser-id3-writer/issues/42).
+
+## APIC picture types
+
+| Type | Name |
+|------|-------------------------------------|
+| 0 | Other |
+| 1 | 32x32 pixels 'file icon' (PNG only) |
+| 2 | Other file icon |
+| 3 | Cover (front) |
+| 4 | Cover (back) |
+| 5 | Leaflet page |
+| 6 | Media (e.g. lable side of CD) |
+| 7 | Lead artist/lead performer/soloist |
+| 8 | Artist/performer |
+| 9 | Conductor |
+| 10 | Band/Orchestra |
+| 11 | Composer |
+| 12 | Lyricist/text writer |
+| 13 | Recording Location |
+| 14 | During recording |
+| 15 | During performance |
+| 16 | Movie/video screen capture |
+| 17 | A bright coloured fish |
+| 18 | Illustration |
+| 19 | Band/artist logotype |
+| 20 | Publisher/Studio logotype |
diff --git a/libs/browser-id3-writer/index.js b/libs/browser-id3-writer/index.js
new file mode 100644
index 0000000..7e11a5e
--- /dev/null
+++ b/libs/browser-id3-writer/index.js
@@ -0,0 +1 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.ID3Writer=t()}(this,function(){"use strict";function r(e){return String(e).split("").map(function(e){return e.charCodeAt(0)})}function u(e){return new Uint8Array(r(e))}function h(e){var t=new Uint8Array(2*e.length);return new Uint16Array(t.buffer).set(r(e)),t}return function(){var e=t.prototype;function t(e){if(!(e&&"object"==typeof e&&"byteLength"in e))throw new Error("First argument should be an instance of ArrayBuffer or Buffer");this.arrayBuffer=e,this.padding=4096,this.frames=[],this.url=""}return e._setIntegerFrame=function(e,t){var r,n=parseInt(t,10);this.frames.push({name:e,value:n,size:(r=n.toString().length,11+r)})},e._setStringFrame=function(e,t){var r,n=t.toString();this.frames.push({name:e,value:n,size:(r=n.length,13+2*r)})},e._setPictureFrame=function(e,t,r,n){var a,s,i,c,o=function(e){if(!e||!e.length)return null;if(255===e[0]&&216===e[1]&&255===e[2])return"image/jpeg";if(137===e[0]&&80===e[1]&&78===e[2]&&71===e[3])return"image/png";if(71===e[0]&&73===e[1]&&70===e[2])return"image/gif";if(87===e[8]&&69===e[9]&&66===e[10]&&80===e[11])return"image/webp";var t=73===e[0]&&73===e[1]&&42===e[2]&&0===e[3],r=77===e[0]&&77===e[1]&&0===e[2]&&42===e[3];return t||r?"image/tiff":66===e[0]&&77===e[1]?"image/bmp":0===e[0]&&0===e[1]&&1===e[2]&&0===e[3]?"image/x-icon":null}(new Uint8Array(t)),u=r.toString();if(!o)throw new Error("Unknown picture MIME type");r||(n=!1),this.frames.push({name:"APIC",value:t,pictureType:e,mimeType:o,useUnicodeEncoding:n,description:u,size:(a=t.byteLength,s=o.length,i=u.length,c=n,11+s+1+1+(c?2+2*(i+1):i+1)+a)})},e._setLyricsFrame=function(e,t){var r,n,a=e.toString(),s=t.toString();this.frames.push({name:"USLT",value:s,description:a,size:(r=a.length,n=s.length,16+2*r+2+2+2*n)})},e._setCommentFrame=function(e,t){var r,n,a=e.toString(),s=t.toString();this.frames.push({name:"COMM",value:s,description:a,size:(r=a.length,n=s.length,16+2*r+2+2+2*n)})},e._setUserStringFrame=function(e,t){var r,n,a=e.toString(),s=t.toString();this.frames.push({name:"TXXX",description:a,value:s,size:(r=a.length,n=s.length,13+2*r+2+2+2*n)})},e._setUrlLinkFrame=function(e,t){var r,n=t.toString();this.frames.push({name:e,value:n,size:(r=n.length,10+r)})},e.setFrame=function(e,t){switch(e){case"TPE1":case"TCOM":case"TCON":if(!Array.isArray(t))throw new Error(e+" frame value should be an array of strings");var r="TCON"===e?";":"/",n=t.join(r);this._setStringFrame(e,n);break;case"TIT2":case"TALB":case"TPE2":case"TPE3":case"TPE4":case"TRCK":case"TPOS":case"TMED":case"TSRC":case"TDAT":case"TCOP":case"TPUB":this._setStringFrame(e,t);break;case"TBPM":case"TLEN":case"TYER":this._setIntegerFrame(e,t);break;case"USLT":if(!("object"==typeof t&&"description"in t&&"lyrics"in t))throw new Error("USLT frame value should be an object with keys description and lyrics");this._setLyricsFrame(t.description,t.lyrics);break;case"APIC":if(!("object"==typeof t&&"type"in t&&"data"in t&&"description"in t))throw new Error("APIC frame value should be an object with keys type, data and description");if(t.type<0||20>>21&(t=127),e>>>14&t,e>>>7&t,e&t],i.set(o,c),c+=o.length,this.frames.forEach(function(e){var t,r;switch(o=u(e.name),i.set(o,c),c+=o.length,t=e.size-10,o=[t>>>24&(r=255),t>>>16&r,t>>>8&r,t&r],i.set(o,c),c+=o.length,c+=2,e.name){case"WCOM":case"WCOP":case"WOAF":case"WOAR":case"WOAS":case"WORS":case"WPAY":case"WPUB":o=u(e.value),i.set(o,c),c+=o.length;break;case"TPE1":case"TCOM":case"TCOP":case"TCON":case"TIT2":case"TALB":case"TPE2":case"TPE3":case"TPE4":case"TRCK":case"TPOS":case"TKEY":case"TMED":case"TSRC":case"TDAT":case"TPUB":o=[1].concat(n),i.set(o,c),c+=o.length,o=h(e.value),i.set(o,c),c+=o.length;break;case"TXXX":case"USLT":case"COMM":o=[1],"USLT"!==e.name&&"COMM"!==e.name||(o=o.concat(a)),o=o.concat(n),i.set(o,c),c+=o.length,o=h(e.description),i.set(o,c),c+=o.length,o=[0,0].concat(n),i.set(o,c),c+=o.length,o=h(e.value),i.set(o,c),c+=o.length;break;case"TBPM":case"TLEN":case"TYER":c++,o=u(e.value),i.set(o,c),c+=o.length;break;case"APIC":o=[e.useUnicodeEncoding?1:0],i.set(o,c),c+=o.length,o=u(e.mimeType),i.set(o,c),c+=o.length,o=[0,e.pictureType],i.set(o,c),c+=o.length,e.useUnicodeEncoding?(o=[].concat(n),i.set(o,c),c+=o.length,o=h(e.description),i.set(o,c),c+=o.length,c+=2):(o=u(e.description),i.set(o,c),c+=o.length,c++),i.set(new Uint8Array(e.value),c),c+=e.value.byteLength}}),c+=this.padding,i.set(new Uint8Array(this.arrayBuffer),c),this.arrayBuffer=s},e.getBlob=function(){return new Blob([this.arrayBuffer],{type:"audio/mpeg"})},e.getURL=function(){return this.url||(this.url=URL.createObjectURL(this.getBlob())),this.url},e.revokeURL=function(){URL.revokeObjectURL(this.url)},t}()});
\ No newline at end of file
diff --git a/libs/flac-metadata/.gitignore b/libs/flac-metadata/.gitignore
new file mode 100644
index 0000000..496ee2c
--- /dev/null
+++ b/libs/flac-metadata/.gitignore
@@ -0,0 +1 @@
+.DS_Store
\ No newline at end of file
diff --git a/libs/flac-metadata/README.md b/libs/flac-metadata/README.md
new file mode 100644
index 0000000..dc27500
--- /dev/null
+++ b/libs/flac-metadata/README.md
@@ -0,0 +1,143 @@
+# flac-metadata
+
+A FLAC metadata processor for Node.js, implemented as Transform stream.
+
+## Installation
+
+```npm install flac-metadata```
+
+## Usage Examples
+
+Some simple examples to get you started:
+
+#### Noop
+
+Does nothing, just pipes a source FLAC through the Processor into a target FLAC.
+
+```js
+var fs = require("fs");
+var flac = require("flac-metadata");
+
+var reader = fs.createReadStream("source.flac");
+var writer = fs.createWriteStream("target.flac");
+var processor = new flac.Processor();
+
+reader.pipe(processor).pipe(writer);
+```
+
+#### Trace Metadata
+
+Traces out the metadata from a FLAC file.
+
+```js
+var fs = require("fs");
+var flac = require("flac-metadata");
+
+var reader = fs.createReadStream("source.flac");
+var processor = new flac.Processor({ parseMetaDataBlocks: true });
+processor.on("postprocess", function(mdb) {
+ console.log(mdb.toString());
+});
+
+reader.pipe(processor);
+```
+
+The output should be something like this:
+
+```
+[MetaDataBlockStreamInfo] type: 0, isLast: false
+ minBlockSize: 4096
+ maxBlockSize: 4096
+ minFrameSize: 14
+ maxFrameSize: 12389
+ samples: 9750804
+ sampleRate: 44100
+ channels: 2
+ bitsPerSample: 16
+ duration: 3:41.107
+ checksum: 1746dff27beb6d1875a88cfeed8a576b
+
+[MetaDataBlockVorbisComment] type: 4, isLast: false
+ vendor: reference libFLAC 1.2.1 20070917
+ comments:
+ ALBUM: Close to the Glass
+ ARTIST: The Notwist
+ GENRE: Rock
+ DATE: 2014
+ TITLE: Signals
+
+[MetaDataBlockPicture] type: 6, isLast: true
+ pictureType: 3
+ mimeType: image/png
+ description:
+ width: 120
+ height: 120
+ bitsPerPixel: 32
+ colors: 0
+ pictureData: 391383
+```
+
+#### Strip All Metadata
+
+Pipes a source FLAC through the Processor into a target FLAC, removing all metadata.
+
+```js
+var fs = require("fs");
+var flac = require("flac-metadata");
+
+var reader = fs.createReadStream("source.flac");
+var writer = fs.createWriteStream("target.flac");
+var processor = new flac.Processor();
+
+processor.on("preprocess", function(mdb) {
+ // STREAMINFO is always the first (and only mandatory) metadata block.
+ if (mdb.type === flac.Processor.MDB_TYPE_STREAMINFO) {
+ // When a metadata block's isLast flag is set to true in preprocess,
+ // subsequent blocks are automatically discarded.
+ mdb.isLast = true;
+ }
+});
+
+reader.pipe(processor).pipe(writer);
+```
+
+#### Inject Metadata
+
+Injects a VORBIS_COMMENT block (and removes the existing one, if any).
+
+```js
+var fs = require("fs");
+var flac = require("flac-metadata");
+
+var reader = fs.createReadStream("source.flac");
+var writer = fs.createWriteStream("target.flac");
+var processor = new flac.Processor();
+
+var vendor = "reference libFLAC 1.2.1 20070917";
+var comments = [
+ "ARTIST=Boyracer",
+ "TITLE=I've Got It And It's Not Worth Having",
+ "ALBUM=B Is For Boyracer",
+ "TRACKNUMBER=A1",
+ "DATE=1993",
+ "DISCOGS=22379"
+];
+
+processor.on("preprocess", function(mdb) {
+ // Remove existing VORBIS_COMMENT block, if any.
+ if (mdb.type === flac.Processor.MDB_TYPE_VORBIS_COMMENT) {
+ mdb.remove();
+ }
+ // Inject new VORBIS_COMMENT block.
+ if (mdb.removed || mdb.isLast) {
+ var mdbVorbis = flac.data.MetaDataBlockVorbisComment.create(mdb.isLast, vendor, comments);
+ this.push(mdbVorbis.publish());
+ }
+});
+
+reader.pipe(processor).pipe(writer);
+```
+
+## License
+
+MIT
diff --git a/libs/flac-metadata/index.js b/libs/flac-metadata/index.js
new file mode 100644
index 0000000..9d72b14
--- /dev/null
+++ b/libs/flac-metadata/index.js
@@ -0,0 +1,8 @@
+module.exports.Processor = require("./lib/Processor");
+
+module.exports.data = {
+ MetaDataBlock: require("./lib/data/MetaDataBlock"),
+ MetaDataBlockStreamInfo: require("./lib/data/MetaDataBlockStreamInfo"),
+ MetaDataBlockVorbisComment: require("./lib/data/MetaDataBlockVorbisComment"),
+ MetaDataBlockPicture: require("./lib/data/MetaDataBlockPicture")
+};
diff --git a/libs/flac-metadata/lib/Processor.js b/libs/flac-metadata/lib/Processor.js
new file mode 100644
index 0000000..f0a54c2
--- /dev/null
+++ b/libs/flac-metadata/lib/Processor.js
@@ -0,0 +1,218 @@
+var util = require("util");
+var stream = require('stream');
+var Transform = stream.Transform || require('readable-stream').Transform;
+
+var MetaDataBlock = require("./data/MetaDataBlock");
+var MetaDataBlockStreamInfo = require("./data/MetaDataBlockStreamInfo");
+var MetaDataBlockVorbisComment = require("./data/MetaDataBlockVorbisComment");
+var MetaDataBlockPicture = require("./data/MetaDataBlockPicture");
+
+const STATE_IDLE = 0;
+const STATE_MARKER = 1;
+const STATE_MDB_HEADER = 2;
+const STATE_MDB = 3;
+const STATE_PASS_THROUGH = 4;
+
+
+var Processor = function (options) {
+
+ this.state = STATE_IDLE;
+
+ this.isFlac = false;
+
+ this.buf;
+ this.bufPos = 0;
+
+ this.mdb;
+ this.mdbLen = 0;
+ this.mdbLast = false;
+ this.mdbPush = false;
+ this.mdbLastWritten = false;
+
+ this.parseMetaDataBlocks = false;
+
+ if (!(this instanceof Processor)) return new Processor(options);
+ if (options && !!options.parseMetaDataBlocks) { this.parseMetaDataBlocks = true; }
+ Transform.call(this, options);
+}
+
+util.inherits(Processor, Transform);
+
+// MDB types
+Processor.MDB_TYPE_STREAMINFO = 0;
+Processor.MDB_TYPE_PADDING = 1;
+Processor.MDB_TYPE_APPLICATION = 2;
+Processor.MDB_TYPE_SEEKTABLE = 3;
+Processor.MDB_TYPE_VORBIS_COMMENT = 4;
+Processor.MDB_TYPE_CUESHEET = 5;
+Processor.MDB_TYPE_PICTURE = 6;
+Processor.MDB_TYPE_INVALID = 127;
+
+Processor.prototype._transform = function (chunk, enc, done) {
+ var chunkPos = 0;
+ var chunkLen = chunk.length;
+ var isChunkProcessed = false;
+ var _this = this;
+
+ function _safePush (minCapacity, persist, validate) {
+ var slice;
+ var chunkAvailable = chunkLen - chunkPos;
+ var isDone = (chunkAvailable + this.bufPos >= minCapacity);
+ validate = (typeof validate === "function") ? validate : function() { return true; };
+ if (isDone) {
+ // Enough data available
+ if (persist) {
+ // Persist the entire block so it can be parsed
+ if (this.bufPos > 0) {
+ // Part of this block's data is in backup buffer, copy rest over
+ chunk.copy(this.buf, this.bufPos, chunkPos, chunkPos + minCapacity - this.bufPos);
+ slice = this.buf.slice(0, minCapacity);
+ } else {
+ // Entire block fits in current chunk
+ slice = chunk.slice(chunkPos, chunkPos + minCapacity);
+ }
+ } else {
+ slice = chunk.slice(chunkPos, chunkPos + minCapacity - this.bufPos);
+ }
+ // Push block after validation
+ validate(slice, isDone) && _this.push(slice);
+ chunkPos += minCapacity - this.bufPos;
+ this.bufPos = 0;
+ this.buf = null;
+ } else {
+ // Not enough data available
+ if (persist) {
+ // Copy/append incomplete block to backup buffer
+ this.buf = this.buf || new Buffer(minCapacity);
+ chunk.copy(this.buf, this.bufPos, chunkPos, chunkLen);
+ } else {
+ // Push incomplete block after validation
+ slice = chunk.slice(chunkPos, chunkLen);
+ validate(slice, isDone) && _this.push(slice);
+ }
+ this.bufPos += chunkLen - chunkPos;
+ }
+ return isDone;
+ };
+ var safePush = _safePush.bind(this);
+
+ while (!isChunkProcessed) {
+ switch (this.state) {
+ case STATE_IDLE:
+ this.state = STATE_MARKER;
+ break;
+ case STATE_MARKER:
+ if (safePush(4, true, this._validateMarker.bind(this))) {
+ this.state = this.isFlac ? STATE_MDB_HEADER : STATE_PASS_THROUGH;
+ } else {
+ isChunkProcessed = true;
+ }
+ break;
+ case STATE_MDB_HEADER:
+ if (safePush(4, true, this._validateMDBHeader.bind(this))) {
+ this.state = STATE_MDB;
+ } else {
+ isChunkProcessed = true;
+ }
+ break;
+ case STATE_MDB:
+ if (safePush(this.mdbLen, this.parseMetaDataBlocks, this._validateMDB.bind(this))) {
+ if (this.mdb.isLast) {
+ // This MDB has the isLast flag set to true.
+ // Ignore all following MDBs.
+ this.mdbLastWritten = true;
+ }
+ this.emit("postprocess", this.mdb);
+ this.state = this.mdbLast ? STATE_PASS_THROUGH : STATE_MDB_HEADER;
+ } else {
+ isChunkProcessed = true;
+ }
+ break;
+ case STATE_PASS_THROUGH:
+ safePush(chunkLen - chunkPos, false);
+ isChunkProcessed = true;
+ break;
+ }
+ }
+
+ done();
+}
+
+Processor.prototype._validateMarker = function(slice, isDone) {
+ this.isFlac = (slice.toString("utf8", 0) === "fLaC");
+ // TODO: completely bail out if file is not a FLAC?
+ return true;
+}
+
+Processor.prototype._validateMDBHeader = function(slice, isDone) {
+ // Parse MDB header
+ var header = slice.readUInt32BE(0);
+ var type = (header >>> 24) & 0x7f;
+ this.mdbLast = (((header >>> 24) & 0x80) !== 0);
+ this.mdbLen = header & 0xffffff;
+
+ // Create appropriate MDB object
+ // (data is injected later in _validateMDB, if parseMetaDataBlocks option is set to true)
+ switch (type) {
+ case Processor.MDB_TYPE_STREAMINFO:
+ this.mdb = new MetaDataBlockStreamInfo(this.mdbLast);
+ break;
+ case Processor.MDB_TYPE_VORBIS_COMMENT:
+ this.mdb = new MetaDataBlockVorbisComment(this.mdbLast);
+ break;
+ case Processor.MDB_TYPE_PICTURE:
+ this.mdb = new MetaDataBlockPicture(this.mdbLast);
+ break;
+ case Processor.MDB_TYPE_PADDING:
+ case Processor.MDB_TYPE_APPLICATION:
+ case Processor.MDB_TYPE_SEEKTABLE:
+ case Processor.MDB_TYPE_CUESHEET:
+ case Processor.MDB_TYPE_INVALID:
+ default:
+ this.mdb = new MetaDataBlock(this.mdbLast, type);
+ break
+ }
+
+ this.emit("preprocess", this.mdb);
+
+ if (this.mdbLastWritten) {
+ // A previous MDB had the isLast flag set to true.
+ // Ignore all following MDBs.
+ this.mdb.remove();
+ } else {
+ // The consumer may change the MDB's isLast flag in the preprocess handler.
+ // Here that flag is updated in the MDB header.
+ if (this.mdbLast !== this.mdb.isLast) {
+ if (this.mdb.isLast) {
+ header |= 0x80000000;
+ } else {
+ header &= 0x7fffffff;
+ }
+ slice.writeUInt32BE(header >>> 0, 0);
+ }
+ }
+ this.mdbPush = !this.mdb.removed;
+ return this.mdbPush;
+}
+
+Processor.prototype._validateMDB = function(slice, isDone) {
+ // Parse the MDB if parseMetaDataBlocks option is set to true
+ if (this.parseMetaDataBlocks && isDone) {
+ this.mdb.parse(slice);
+ }
+ return this.mdbPush;
+}
+
+Processor.prototype._flush = function(done) {
+ // All chunks have been processed
+ // Clean up
+ this.state = STATE_IDLE;
+ this.mdbLastWritten = false;
+ this.isFlac = false;
+ this.bufPos = 0;
+ this.buf = null;
+ this.mdb = null;
+ done();
+}
+
+module.exports = Processor;
diff --git a/libs/flac-metadata/lib/data/MetaDataBlock.js b/libs/flac-metadata/lib/data/MetaDataBlock.js
new file mode 100644
index 0000000..cc1421d
--- /dev/null
+++ b/libs/flac-metadata/lib/data/MetaDataBlock.js
@@ -0,0 +1,21 @@
+var MetaDataBlock = module.exports = function(isLast, type) {
+ this.isLast = isLast;
+ this.type = type;
+ this.error = null;
+ this.hasData = false;
+ this.removed = false;
+}
+
+MetaDataBlock.prototype.remove = function() {
+ this.removed = true;
+}
+
+MetaDataBlock.prototype.parse = function(buffer) {
+}
+
+MetaDataBlock.prototype.toString = function() {
+ var str = "[MetaDataBlock]";
+ str += " type: " + this.type;
+ str += ", isLast: " + this.isLast;
+ return str;
+}
diff --git a/libs/flac-metadata/lib/data/MetaDataBlockPicture.js b/libs/flac-metadata/lib/data/MetaDataBlockPicture.js
new file mode 100644
index 0000000..5694664
--- /dev/null
+++ b/libs/flac-metadata/lib/data/MetaDataBlockPicture.js
@@ -0,0 +1,131 @@
+var util = require("util");
+var MetaDataBlock = require("./MetaDataBlock");
+
+var MetaDataBlockPicture = module.exports = function(isLast) {
+ MetaDataBlock.call(this, isLast, 6);
+
+ this.pictureType = 0;
+ this.mimeType = "";
+ this.description = "";
+ this.width = 0;
+ this.height = 0;
+ this.bitsPerPixel = 0;
+ this.colors = 0;
+ this.pictureData = null;
+}
+
+util.inherits(MetaDataBlockPicture, MetaDataBlock);
+
+MetaDataBlockPicture.create = function(isLast, pictureType, mimeType, description, width, height, bitsPerPixel, colors, pictureData) {
+ var mdb = new MetaDataBlockPicture(isLast);
+ mdb.pictureType = pictureType;
+ mdb.mimeType = mimeType;
+ mdb.description = description;
+ mdb.width = width;
+ mdb.height = height;
+ mdb.bitsPerPixel = bitsPerPixel;
+ mdb.colors = colors;
+ mdb.pictureData = pictureData;
+ mdb.hasData = true;
+ return mdb;
+}
+
+MetaDataBlockPicture.prototype.parse = function(buffer) {
+ try {
+
+ var pos = 0;
+
+ this.pictureType = buffer.readUInt32BE(pos);
+ pos += 4;
+
+ var mimeTypeLength = buffer.readUInt32BE(pos);
+ this.mimeType = buffer.toString("utf8", pos + 4, pos + 4 + mimeTypeLength);
+ pos += 4 + mimeTypeLength;
+
+ var descriptionLength = buffer.readUInt32BE(pos);
+ this.description = buffer.toString("utf8", pos + 4, pos + 4 + descriptionLength);
+ pos += 4 + descriptionLength;
+
+ this.width = buffer.readUInt32BE(pos);
+ this.height = buffer.readUInt32BE(pos + 4);
+ this.bitsPerPixel = buffer.readUInt32BE(pos + 8);
+ this.colors = buffer.readUInt32BE(pos + 12);
+ pos += 16;
+
+ var pictureDataLength = buffer.readUInt32BE(pos);
+ this.pictureData = new Buffer(pictureDataLength);
+ buffer.copy(this.pictureData, 0, pos + 4, pictureDataLength);
+
+ this.hasData = true;
+
+ }
+ catch (e) {
+ this.error = e;
+ this.hasData = false;
+ }
+}
+
+MetaDataBlockPicture.prototype.publish = function() {
+ var pos = 0;
+ var size = this.getSize();
+ var buffer = new Buffer(4 + size);
+
+ var header = size;
+ header |= (this.type << 24);
+ header |= (this.isLast ? 0x80000000 : 0);
+ buffer.writeUInt32BE(header >>> 0, pos);
+ pos += 4;
+
+ buffer.writeUInt32BE(this.pictureType, pos);
+ pos += 4;
+
+ var mimeTypeLen = Buffer.byteLength(this.mimeType);
+ buffer.writeUInt32BE(mimeTypeLen, pos);
+ buffer.write(this.mimeType, pos + 4);
+ pos += 4 + mimeTypeLen;
+
+ var descriptionLen = Buffer.byteLength(this.description);
+ buffer.writeUInt32BE(descriptionLen, pos);
+ buffer.write(this.description, pos + 4);
+ pos += 4 + descriptionLen;
+
+ buffer.writeUInt32BE(this.width, pos);
+ buffer.writeUInt32BE(this.height, pos + 4);
+ buffer.writeUInt32BE(this.bitsPerPixel, pos + 8);
+ buffer.writeUInt32BE(this.colors, pos + 12);
+ pos += 16;
+
+ buffer.writeUInt32BE(this.pictureData.length, pos);
+ this.pictureData.copy(buffer, pos + 4);
+
+ return buffer;
+}
+
+MetaDataBlockPicture.prototype.getSize = function() {
+ var size = 4;
+ size += 4 + Buffer.byteLength(this.mimeType);
+ size += 4 + Buffer.byteLength(this.description);
+ size += 16;
+ size += 4 + this.pictureData.length;
+ return size;
+}
+
+MetaDataBlockPicture.prototype.toString = function() {
+ var str = "[MetaDataBlockPicture]";
+ str += " type: " + this.type;
+ str += ", isLast: " + this.isLast;
+ if (this.error) {
+ str += "\n ERROR: " + this.error;
+ }
+ if (this.hasData) {
+ str += "\n pictureType: " + this.pictureType;
+ str += "\n mimeType: " + this.mimeType;
+ str += "\n description: " + this.description;
+ str += "\n width: " + this.width;
+ str += "\n height: " + this.height;
+ str += "\n bitsPerPixel: " + this.bitsPerPixel;
+ str += "\n colors: " + this.colors;
+ str += "\n pictureData: " + (this.pictureData ? this.pictureData.length : "");
+ }
+ return str;
+}
diff --git a/libs/flac-metadata/lib/data/MetaDataBlockStreamInfo.js b/libs/flac-metadata/lib/data/MetaDataBlockStreamInfo.js
new file mode 100644
index 0000000..c178a06
--- /dev/null
+++ b/libs/flac-metadata/lib/data/MetaDataBlockStreamInfo.js
@@ -0,0 +1,86 @@
+var util = require("util");
+var MetaDataBlock = require("./MetaDataBlock");
+
+var MetaDataBlockStreamInfo = module.exports = function(isLast) {
+ MetaDataBlock.call(this, isLast, 0);
+
+ this.minBlockSize = 0;
+ this.maxBlockSize = 0;
+ this.minFrameSize = 0;
+ this.maxFrameSize = 0;
+ this.sampleRate = 0;
+ this.channels = 0;
+ this.bitsPerSample = 0;
+ this.samples = 0;
+ this.checksum = null;
+ this.duration = 0;
+ this.durationStr = "0:00.000";
+}
+
+util.inherits(MetaDataBlockStreamInfo, MetaDataBlock);
+
+MetaDataBlockStreamInfo.prototype.remove = function() {
+ console.error("WARNING: Can't remove StreamInfo block!");
+}
+
+MetaDataBlockStreamInfo.prototype.parse = function(buffer) {
+ try {
+
+ var pos = 0;
+
+ this.minBlockSize = buffer.readUInt16BE(pos);
+ this.maxBlockSize = buffer.readUInt16BE(pos + 2);
+ this.minFrameSize = (buffer.readUInt8(pos + 4) << 16) | buffer.readUInt16BE(pos + 5);
+ this.maxFrameSize = (buffer.readUInt8(pos + 7) << 16) | buffer.readUInt16BE(pos + 8);
+
+ var tmp = buffer.readUInt32BE(pos + 10);
+ this.sampleRate = tmp >>> 12;
+ this.channels = (tmp >>> 9) & 0x07;
+ this.bitsPerSample = (tmp >>> 4) & 0x1f;
+ this.samples = +((tmp & 0x0f) << 4) + buffer.readUInt32BE(pos + 14);
+
+ this.checksum = new Buffer(16);
+ buffer.copy(this.checksum, 0, 18, 34);
+
+ this.duration = this.samples / this.sampleRate;
+
+ var minutes = "" + Math.floor(this.duration / 60);
+ var seconds = pad(Math.floor(this.duration % 60), 2);
+ var milliseconds = pad(Math.round(((this.duration % 60) - Math.floor(this.duration % 60)) * 1000), 3);
+ this.durationStr = minutes + ":" + seconds + "." + milliseconds;
+
+ this.hasData = true;
+
+ }
+ catch (e) {
+ this.error = e;
+ this.hasData = false;
+ }
+}
+
+MetaDataBlockStreamInfo.prototype.toString = function() {
+ var str = "[MetaDataBlockStreamInfo]";
+ str += " type: " + this.type;
+ str += ", isLast: " + this.isLast;
+ if (this.error) {
+ str += "\n ERROR: " + this.error;
+ }
+ if (this.hasData) {
+ str += "\n minBlockSize: " + this.minBlockSize;
+ str += "\n maxBlockSize: " + this.maxBlockSize;
+ str += "\n minFrameSize: " + this.minFrameSize;
+ str += "\n maxFrameSize: " + this.maxFrameSize;
+ str += "\n samples: " + this.samples;
+ str += "\n sampleRate: " + this.sampleRate;
+ str += "\n channels: " + (this.channels + 1);
+ str += "\n bitsPerSample: " + (this.bitsPerSample + 1);
+ str += "\n duration: " + this.durationStr;
+ str += "\n checksum: " + (this.checksum ? this.checksum.toString("hex") : "");
+ }
+ return str;
+}
+
+function pad(n, width) {
+ n = "" + n;
+ return (n.length >= width) ? n : new Array(width - n.length + 1).join("0") + n;
+}
diff --git a/libs/flac-metadata/lib/data/MetaDataBlockVorbisComment.js b/libs/flac-metadata/lib/data/MetaDataBlockVorbisComment.js
new file mode 100644
index 0000000..bd82f8a
--- /dev/null
+++ b/libs/flac-metadata/lib/data/MetaDataBlockVorbisComment.js
@@ -0,0 +1,108 @@
+var util = require("util");
+var MetaDataBlock = require("./MetaDataBlock");
+
+var MetaDataBlockVorbisComment = module.exports = function(isLast) {
+ MetaDataBlock.call(this, isLast, 4);
+
+ this.vendor = "";
+ this.comments = [];
+}
+
+util.inherits(MetaDataBlockVorbisComment, MetaDataBlock);
+
+MetaDataBlockVorbisComment.create = function(isLast, vendor, comments) {
+ var mdb = new MetaDataBlockVorbisComment(isLast);
+ mdb.vendor = vendor;
+ mdb.comments = comments;
+ mdb.hasData = true;
+ return mdb;
+}
+
+MetaDataBlockVorbisComment.prototype.parse = function(buffer) {
+ try {
+
+ var pos = 0;
+
+ var vendorLen = buffer.readUInt32LE(pos);
+ var vendor = buffer.toString("utf8", pos + 4, pos + 4 + vendorLen);
+ this.vendor = vendor;
+ pos += 4 + vendorLen;
+
+ var commentCount = buffer.readUInt32LE(pos);
+ pos += 4;
+
+ while (commentCount-- > 0) {
+ var commentLen = buffer.readUInt32LE(pos);
+ var comment = buffer.toString("utf8", pos + 4, pos + 4 + commentLen);
+ this.comments.push(comment);
+ pos += 4 + commentLen;
+ }
+
+ this.hasData = true;
+
+ }
+ catch (e) {
+ this.error = e;
+ this.hasData = false;
+ }
+}
+
+MetaDataBlockVorbisComment.prototype.publish = function() {
+ var pos = 0;
+ var size = this.getSize();
+ var buffer = new Buffer(4 + size);
+
+ var header = size;
+ header |= (this.type << 24);
+ header |= (this.isLast ? 0x80000000 : 0);
+ buffer.writeUInt32BE(header >>> 0, pos);
+ pos += 4;
+
+ var vendorLen = Buffer.byteLength(this.vendor);
+ buffer.writeUInt32LE(vendorLen, pos);
+ buffer.write(this.vendor, pos + 4);
+ pos += 4 + vendorLen;
+
+ var commentCount = this.comments.length;
+ buffer.writeUInt32LE(commentCount, pos);
+ pos += 4;
+
+ for (var i = 0; i < commentCount; i++) {
+ var comment = this.comments[i];
+ var commentLen = Buffer.byteLength(comment);
+ buffer.writeUInt32LE(commentLen, pos);
+ buffer.write(comment, pos + 4);
+ pos += 4 + commentLen;
+ }
+
+ return buffer;
+}
+
+MetaDataBlockVorbisComment.prototype.getSize = function() {
+ var size = 8 + Buffer.byteLength(this.vendor);
+ for (var i = 0; i < this.comments.length; i++) {
+ size += 4 + Buffer.byteLength(this.comments[i]);
+ }
+ return size;
+}
+
+MetaDataBlockVorbisComment.prototype.toString = function() {
+ var str = "[MetaDataBlockVorbisComment]";
+ str += " type: " + this.type;
+ str += ", isLast: " + this.isLast;
+ if (this.error) {
+ str += "\n ERROR: " + this.error;
+ }
+ if (this.hasData) {
+ str += "\n vendor: " + this.vendor;
+ if (this.comments.length) {
+ str += "\n comments:";
+ for (var i = 0; i < this.comments.length; i++) {
+ str += "\n " + this.comments[i].split("=").join(": ");
+ }
+ } else {
+ str += "\n comments: none";
+ }
+ }
+ return str;
+}
diff --git a/libs/flac-metadata/package.json b/libs/flac-metadata/package.json
new file mode 100644
index 0000000..e45c0cc
--- /dev/null
+++ b/libs/flac-metadata/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "flac-metadata",
+ "description": "FLAC metadata processor implemented as Transform stream",
+ "keywords": ["flac", "metadata", "audio"],
+ "author": "Claus Wahlers (http://wahlers.com.br/claus/)",
+ "homepage": "https://github.com/claus/flac-metadata",
+ "version": "0.1.1",
+ "license": "MIT",
+ "main": "index.js",
+ "directories": {
+ "lib": "./lib"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/claus/flac-metadata.git"
+ },
+ "bugs": {
+ "url": "https://github.com/claus/flac-metadata/issues",
+ "email": "claus@codeazur.com.br"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+}
diff --git a/libs/node-memory-stats/index.js b/libs/node-memory-stats/index.js
new file mode 100644
index 0000000..7dec6c0
--- /dev/null
+++ b/libs/node-memory-stats/index.js
@@ -0,0 +1,31 @@
+const WindowsPlatform = require('./platforms/windows');
+const LinuxPlatform = require('./platforms/linux');
+const DarwinPlatform = require('./platforms/darwin');
+
+
+function getMethods() {
+ const classes = {
+ 'win32': WindowsPlatform,
+ 'linux': LinuxPlatform,
+ 'darwin': DarwinPlatform
+ };
+
+ return classes[process.platform];
+}
+
+const methods = getMethods();
+
+function total() {
+ return methods.getTotalMemory();
+}
+
+function used() {
+ return methods.getUsedMemory();
+}
+
+function free() {
+ return methods.getFreeMemory();
+}
+
+
+module.exports = {total, used, free};
diff --git a/libs/node-memory-stats/platforms/darwin.js b/libs/node-memory-stats/platforms/darwin.js
new file mode 100644
index 0000000..0e65d8d
--- /dev/null
+++ b/libs/node-memory-stats/platforms/darwin.js
@@ -0,0 +1,37 @@
+const exec = require('child_process').execSync;
+
+module.exports = class Darwin {
+ static getTotalMemory() {
+ return parseInt(exec('sysctl -n hw.memsize', {'encoding': 'utf8'}), 10);
+ }
+
+ static getUsedMemory() {
+ const memoryTypes = ['active', 'wired down', 'inactive'];
+ const pageSize = this.getPageSize();
+ let totalMemoryUsed = 0;
+
+ memoryTypes.forEach((memoryType) => {
+ totalMemoryUsed += this.getMemoryTypeUsage(memoryType);
+ });
+
+ return (totalMemoryUsed * pageSize);
+ }
+
+ static getFreeMemory() {
+ return this.getTotalMemory() - this.getUsedMemory();
+ }
+
+ static getPageSize() {
+ return parseInt(exec('sysctl -n hw.pagesize', {'encoding': 'utf8'}), 10);
+ }
+
+ static getMemoryTypeUsage(memoryType) {
+ let position = 3;
+
+ if (1 < memoryType.split(' ').length) {
+ position = 4;
+ }
+
+ return parseInt(exec(`vm_stat | grep 'Pages ${memoryType}:' | awk '{print $${position}}'`, {'encoding': 'utf8'}), 10);
+ }
+};
diff --git a/libs/node-memory-stats/platforms/linux.js b/libs/node-memory-stats/platforms/linux.js
new file mode 100644
index 0000000..fae64fa
--- /dev/null
+++ b/libs/node-memory-stats/platforms/linux.js
@@ -0,0 +1,15 @@
+const exec = require('child_process').execSync;
+
+module.exports = class Linux {
+ static getTotalMemory() {
+ return parseInt(exec('free -b | grep "Mem:" | awk \'{print $2}\'', {'encoding': 'utf8'}), 10);
+ }
+
+ static getUsedMemory() {
+ return parseInt(exec('free -b | grep "Mem:" | awk \'{print $7}\'', {'encoding': 'utf8'}), 10);
+ }
+
+ static getFreeMemory() {
+ return this.getTotalMemory() - this.getUsedMemory();
+ }
+};
diff --git a/libs/node-memory-stats/platforms/windows.js b/libs/node-memory-stats/platforms/windows.js
new file mode 100644
index 0000000..d8c255f
--- /dev/null
+++ b/libs/node-memory-stats/platforms/windows.js
@@ -0,0 +1,15 @@
+const exec = require('child_process').execSync;
+
+module.exports = class Windows {
+ static getTotalMemory() {
+ return parseInt(exec('wmic OS get TotalVisibleMemorySize /value', {'encoding': 'utf8'}).trim().split('=')[1], 10) * 1024;
+ }
+
+ static getUsedMemory() {
+ return this.getTotalMemory() - this.getFreeMemory();
+ }
+
+ static getFreeMemory() {
+ return parseInt(exec('wmic OS get FreePhysicalMemory /value', {'encoding': 'utf8'}).trim().split('=')[1], 10) * 1024;
+ }
+};
diff --git a/package-lock.json b/package-lock.json
index fc9fd69..91a717b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "SMLoadr",
- "version": "1.8.0",
+ "version": "1.9.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -10,23 +10,15 @@
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"requires": {
"co": "4.6.0",
- "fast-deep-equal": "1.0.0",
+ "fast-deep-equal": "1.1.0",
"fast-json-stable-stringify": "2.0.0",
"json-schema-traverse": "0.3.1"
}
},
- "ansi-escape-sequences": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz",
- "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==",
- "requires": {
- "array-back": "2.0.0"
- }
- },
"ansi-escapes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
- "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ=="
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+ "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
},
"ansi-regex": {
"version": "3.0.0",
@@ -34,9 +26,9 @@
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "1.9.1"
}
@@ -68,6 +60,11 @@
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -79,9 +76,9 @@
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
- "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
+ "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w=="
},
"bcrypt-pbkdf": {
"version": "1.0.1",
@@ -102,46 +99,31 @@
"resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
"integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
"requires": {
- "hoek": "4.2.0"
+ "hoek": "4.2.1"
}
},
- "browser-id3-writer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/browser-id3-writer/-/browser-id3-writer-4.0.0.tgz",
- "integrity": "sha512-Q8ufttKbt1+vu5giG81o+yvNHg54NdNoWi1sFgCMAsOSKF7XvsjlfRZc4vKzbxP5LTnkoFRY2RusC5mM+Kkq8Q=="
- },
- "buffer-alloc": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.1.0.tgz",
- "integrity": "sha1-BVFNM78WVtNUDGhPZbEgLpDsowM=",
+ "cache-manager": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-2.9.0.tgz",
+ "integrity": "sha1-Xh9jF8oaJeQN3zZacWJ1evFSNT4=",
"requires": {
- "buffer-alloc-unsafe": "0.1.1",
- "buffer-fill": "0.1.0"
+ "async": "1.5.2",
+ "lru-cache": "4.0.0"
}
},
- "buffer-alloc-unsafe": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz",
- "integrity": "sha1-/+H2dVHdBVc33iUzN7/oU9+rGmo="
- },
- "buffer-fill": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-0.1.0.tgz",
- "integrity": "sha1-ypRw6NTRuXf9dUP04qtqfclRAag="
- },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"chalk": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
- "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
"requires": {
- "ansi-styles": "3.2.0",
+ "ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
- "supports-color": "4.5.0"
+ "supports-color": "5.3.0"
}
},
"chardet": {
@@ -191,17 +173,17 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"combined-stream": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
- "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"requires": {
"delayed-stream": "1.0.0"
}
},
"command-line-args": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.1.tgz",
- "integrity": "sha512-gRJDcIjFSzMcmG/GrJlgL0wWoAxr11mVzCq32bjka0endupm9meLwvoJUKc4HDeFiEIB2X3GvNrhF5cKO4Bd4A==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.2.tgz",
+ "integrity": "sha512-/qPcbL8zpqg53x4rAaqMFlRV4opN3pbla7I7k9x8kyOBMQoGT6WltjN6sXZuxOXw6DgdK7Ad+ijYS5gjcr7vlA==",
"requires": {
"argv-tools": "0.1.1",
"array-back": "2.0.0",
@@ -211,13 +193,13 @@
}
},
"command-line-usage": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
- "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-5.0.4.tgz",
+ "integrity": "sha512-h17lBwC5bl5RdukPbXji75+cg2/Qbny6kGsmLoy34s9DNH90RwRvJKb+VU5j4YY9HzYl7twLaOWDJQ4b9U+p/Q==",
"requires": {
- "ansi-escape-sequences": "4.0.0",
"array-back": "2.0.0",
- "table-layout": "0.4.2",
+ "chalk": "2.3.2",
+ "table-layout": "0.4.3",
"typical": "2.6.1"
}
},
@@ -239,7 +221,7 @@
"resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
"integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
"requires": {
- "hoek": "4.2.0"
+ "hoek": "4.2.1"
}
}
}
@@ -279,6 +261,11 @@
"jsbn": "0.1.1"
}
},
+ "escape-regexp": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/escape-regexp/-/escape-regexp-0.0.1.tgz",
+ "integrity": "sha1-9EvaEtRbvfnLf4Yu5+SCez3TIlQ="
+ },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -290,12 +277,12 @@
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
},
"external-editor": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz",
- "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+ "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"requires": {
"chardet": "0.4.2",
- "iconv-lite": "0.4.19",
+ "iconv-lite": "0.4.21",
"tmp": "0.0.33"
}
},
@@ -305,9 +292,9 @@
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
- "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
@@ -331,34 +318,38 @@
"test-value": "3.0.0"
}
},
- "flac-metadata": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/flac-metadata/-/flac-metadata-0.1.1.tgz",
- "integrity": "sha1-wC+KBtJL1bad4rhVEsbkW9j5F2w="
- },
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
- "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"requires": {
"asynckit": "0.4.0",
- "combined-stream": "1.0.5",
- "mime-types": "2.1.17"
+ "combined-stream": "1.0.6",
+ "mime-types": "2.1.18"
}
},
- "fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
+ "fs-finder": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/fs-finder/-/fs-finder-1.8.1.tgz",
+ "integrity": "sha1-EG/qiqidCvNDNgZj1YVYYsrhuHQ=",
"requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
+ "async": "0.2.10",
+ "escape-regexp": "0.0.1",
+ "moment": "2.5.1",
+ "operator-compare": "1.0.3",
+ "q": "1.0.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
+ }
}
},
"getpass": {
@@ -372,7 +363,8 @@
"graceful-fs": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "optional": true
},
"har-schema": {
"version": "2.0.0",
@@ -389,9 +381,9 @@
}
},
"has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"hawk": {
"version": "6.0.2",
@@ -400,14 +392,14 @@
"requires": {
"boom": "4.3.1",
"cryptiles": "3.1.2",
- "hoek": "4.2.0",
+ "hoek": "4.2.1",
"sntp": "2.1.0"
}
},
"hoek": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
- "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
+ "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA=="
},
"http-signature": {
"version": "1.2.0",
@@ -416,13 +408,16 @@
"requires": {
"assert-plus": "1.0.0",
"jsprim": "1.4.1",
- "sshpk": "1.13.1"
+ "sshpk": "1.14.1"
}
},
"iconv-lite": {
- "version": "0.4.19",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
- "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ "version": "0.4.21",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
+ "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
+ "requires": {
+ "safer-buffer": "2.1.2"
+ }
},
"inherits": {
"version": "2.0.1",
@@ -430,20 +425,20 @@
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
},
"inquirer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.0.1.tgz",
- "integrity": "sha512-si5Jmjj6ngjkDSPt/MwuIysUNNKu8SGWnweZE2QXRfd5SKJgDown8IDbHQiS5WLxqEQDQC0Vjcgtpw1XyZJWpw==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz",
+ "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==",
"requires": {
- "ansi-escapes": "3.0.0",
- "chalk": "2.3.0",
+ "ansi-escapes": "3.1.0",
+ "chalk": "2.3.2",
"cli-cursor": "2.1.0",
"cli-width": "2.2.0",
- "external-editor": "2.1.0",
+ "external-editor": "2.2.0",
"figures": "2.0.0",
- "lodash": "4.17.4",
+ "lodash": "4.17.5",
"mute-stream": "0.0.7",
"run-async": "2.3.0",
- "rxjs": "5.5.6",
+ "rxjs": "5.5.8",
"string-width": "2.1.1",
"strip-ansi": "4.0.0",
"through": "2.3.8"
@@ -510,9 +505,9 @@
}
},
"lodash": {
- "version": "4.17.4",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw=="
},
"lodash.camelcase": {
"version": "4.3.0",
@@ -524,33 +519,44 @@
"resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
"integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4="
},
+ "log": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/log/-/log-1.4.0.tgz",
+ "integrity": "sha1-S6HYkP3iSbAx3KA7w36q8yVlbxw="
+ },
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
"requires": {
- "chalk": "2.3.0"
+ "chalk": "2.3.2"
+ }
+ },
+ "lru-cache": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.0.tgz",
+ "integrity": "sha1-tcvwFVbBaWb+vlTO7A+03JDfbCg=",
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.1.2"
}
},
"md5-file": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-3.2.3.tgz",
- "integrity": "sha512-3Tkp1piAHaworfcCgH0jKbTvj1jWWFgbvh2cXaNCgHwyTCBxxvD1Y04rmfpvdPm1P4oXMOpm6+2H7sr7v9v8Fw==",
- "requires": {
- "buffer-alloc": "1.1.0"
- }
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-4.0.0.tgz",
+ "integrity": "sha512-UC0qFwyAjn4YdPpKaDNw6gNxRf7Mcx7jC1UGCY4boCzgvU2Aoc1mOGzTtrjjLKhM5ivsnhoKpQVxKPp+1j1qwg=="
},
"mime-db": {
- "version": "1.30.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
- "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
},
"mime-types": {
- "version": "2.1.17",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
- "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"requires": {
- "mime-db": "1.30.0"
+ "mime-db": "1.33.0"
}
},
"mimic-fn": {
@@ -558,19 +564,16 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
"integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg="
},
+ "moment": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.5.1.tgz",
+ "integrity": "sha1-cUajkAUzBkynmdXnkvTkgO4Ogrw="
+ },
"mute-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
},
- "nano-cache": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/nano-cache/-/nano-cache-1.1.1.tgz",
- "integrity": "sha1-UQbZXzkstENZZU4hzAFa4hjnVGY=",
- "requires": {
- "extend": "3.0.1"
- }
- },
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
@@ -589,6 +592,11 @@
"resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
"integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c="
},
+ "operator-compare": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/operator-compare/-/operator-compare-1.0.3.tgz",
+ "integrity": "sha1-jQbQlLwbg6YH/JyfOABEeIZZGvk="
+ },
"ora": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-2.0.0.tgz",
@@ -645,11 +653,21 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+ },
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
+ "q": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz",
+ "integrity": "sha1-EYcq7t7okmgRCxCnGESP+xARKhQ="
+ },
"qs": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
@@ -661,41 +679,58 @@
"integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc="
},
"request": {
- "version": "2.83.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
- "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
+ "version": "2.85.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz",
+ "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==",
"requires": {
"aws-sign2": "0.7.0",
- "aws4": "1.6.0",
+ "aws4": "1.7.0",
"caseless": "0.12.0",
- "combined-stream": "1.0.5",
+ "combined-stream": "1.0.6",
"extend": "3.0.1",
"forever-agent": "0.6.1",
- "form-data": "2.3.1",
+ "form-data": "2.3.2",
"har-validator": "5.0.3",
"hawk": "6.0.2",
"http-signature": "1.2.0",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
- "mime-types": "2.1.17",
+ "mime-types": "2.1.18",
"oauth-sign": "0.8.2",
"performance-now": "2.1.0",
"qs": "6.5.1",
"safe-buffer": "5.1.1",
"stringstream": "0.0.5",
- "tough-cookie": "2.3.3",
+ "tough-cookie": "2.3.4",
"tunnel-agent": "0.6.0",
"uuid": "3.2.1"
}
},
- "request-promise-cache": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/request-promise-cache/-/request-promise-cache-1.0.6.tgz",
- "integrity": "sha1-d8opARFlG0UnLzFA6cDoNXCHiMM=",
+ "request-plus": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/request-plus/-/request-plus-1.0.1.tgz",
+ "integrity": "sha1-ANlMJReog5qdtP3PCq8WoP30ngs=",
"requires": {
- "nano-cache": "1.1.1",
- "request": "2.83.0"
+ "request-promise-native": "1.0.5"
+ }
+ },
+ "request-promise-core": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
+ "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
+ "requires": {
+ "lodash": "4.17.5"
+ }
+ },
+ "request-promise-native": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
+ "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
+ "requires": {
+ "request-promise-core": "1.1.1",
+ "stealthy-require": "1.1.1",
+ "tough-cookie": "2.3.4"
}
},
"restore-cursor": {
@@ -716,9 +751,9 @@
}
},
"rxjs": {
- "version": "5.5.6",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz",
- "integrity": "sha512-v4Q5HDC0FHAQ7zcBX7T2IL6O5ltl1a2GX4ENjPXg6SjDY69Cmx9v4113C99a4wGF16ClPv5Z8mghuYorVkg/kg==",
+ "version": "5.5.8",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.8.tgz",
+ "integrity": "sha512-Bz7qou7VAIoGiglJZbzbXa4vpX5BmTTN2Dj/se6+SwADtw4SihqBIiEa7VmTXJ8pynvq0iFr5Gx9VLyye1rIxQ==",
"requires": {
"symbol-observable": "1.0.1"
}
@@ -728,6 +763,11 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
"sanitize-filename": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz",
@@ -746,13 +786,13 @@
"resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
"integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
"requires": {
- "hoek": "4.2.0"
+ "hoek": "4.2.1"
}
},
"sshpk": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
- "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
+ "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
"requires": {
"asn1": "0.2.3",
"assert-plus": "1.0.0",
@@ -764,6 +804,11 @@
"tweetnacl": "0.14.5"
}
},
+ "stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
+ },
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -787,11 +832,11 @@
}
},
"supports-color": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "3.0.0"
}
},
"symbol-observable": {
@@ -800,9 +845,9 @@
"integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ="
},
"table-layout": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.2.tgz",
- "integrity": "sha512-tygyl5+eSHj4chpq5Zfy6cpc7MOUBClAW9ozghFH7hg9bAUzShOYn+/vUzTRkKOSLJWKfgYtP2tAU2c0oAD8eg==",
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.3.tgz",
+ "integrity": "sha512-MIhflPM38ejKrFwWwC3P9x3eHvMo5G5AmNo29Qtz2HpBl5KD2GCcmOErjgNtUQLv/qaqVDagfJY3rJLPDvEgLg==",
"requires": {
"array-back": "2.0.0",
"deep-extend": "0.5.0",
@@ -834,9 +879,9 @@
}
},
"tough-cookie": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
- "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
"requires": {
"punycode": "1.4.1"
}
@@ -868,11 +913,6 @@
"resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
"integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0="
},
- "universalify": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
- "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
- },
"utf8-byte-length": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
@@ -917,6 +957,11 @@
"reduce-flatten": "1.0.1",
"typical": "2.6.1"
}
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
}
}
}
diff --git a/package.json b/package.json
index 4f1c7e3..05a0d3f 100644
--- a/package.json
+++ b/package.json
@@ -1,25 +1,33 @@
{
"name": "SMLoadr",
- "version": "1.8.0",
+ "version": "1.9.0",
"description": "A streaming music downloader written in NodeJS.",
"author": "SMLoadrDev",
"license": "Unlicense",
"main": "SMLoadr.js",
"bin": "SMLoadr.js",
+ "repository": {
+ "type": "git",
+ "url": "https://git.teknik.io/SMLoadrDev/SMLoadr.git"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
"dependencies": {
"bluebird": "^3.5.1",
- "browser-id3-writer": "^4.0.0",
- "chalk": "^2.3.0",
- "command-line-args": "^5.0.1",
- "command-line-usage": "^4.1.0",
- "flac-metadata": "^0.1.1",
- "fs-extra": "^5.0.0",
- "inquirer": "^5.0.1",
+ "cache-manager": "^2.9.0",
+ "chalk": "^2.3.2",
+ "command-line-args": "^5.0.2",
+ "command-line-usage": "^5.0.4",
+ "fs-finder": "^1.8.1",
+ "inquirer": "^5.2.0",
"jsonfile": "^4.0.0",
- "md5-file": "^3.2.3",
+ "log": "^1.4.0",
+ "md5-file": "^4.0.0",
"openurl": "^1.1.1",
"ora": "^2.0.0",
- "request-promise-cache": "^1.0.6",
+ "request": "^2.85.0",
+ "request-plus": "^1.0.1",
"sanitize-filename": "^1.6.1",
"util": "^0.10.3"
}