From 8afb223aefa871a635e8d83ddca654c491376d26 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Mon, 27 Apr 2020 20:33:09 +0200
Subject: [PATCH] Finish movie processing code

---
 package-lock.json          | 3196 +-----------------------------------
 package.json               |    4 +-
 src/directory_walker.js    |   60 +-
 src/index.js               |  111 +-
 src/metadata_loader.js     |   85 +-
 src/old_metadata_loader.js |   22 -
 src/util/download-file.js  |   25 +
 src/util/statistics.js     |    2 +-
 src/util/video-mime.js     |  143 +-
 9 files changed, 347 insertions(+), 3301 deletions(-)
 create mode 100644 src/util/download-file.js

diff --git a/package-lock.json b/package-lock.json
index 2288a80..3452f79 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -80,6 +80,14 @@
         "tweetnacl": "^0.14.3"
       }
     },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -192,6 +200,11 @@
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
       "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
     },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
+    },
     "forever-agent": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@@ -280,6 +293,11 @@
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
       "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
     },
+    "hoek": {
+      "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",
       "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -343,11 +361,36 @@
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
     },
+    "isemail": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz",
+      "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==",
+      "requires": {
+        "punycode": "2.x.x"
+      }
+    },
     "isstream": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
       "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
     },
+    "joi": {
+      "version": "13.7.0",
+      "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz",
+      "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==",
+      "requires": {
+        "hoek": "5.x.x",
+        "isemail": "3.x.x",
+        "topo": "3.x.x"
+      },
+      "dependencies": {
+        "hoek": {
+          "version": "5.0.4",
+          "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz",
+          "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w=="
+        }
+      }
+    },
     "jsbn": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -435,19 +478,6 @@
         "minimist": "^1.2.5"
       }
     },
-    "mp4box": {
-      "version": "0.3.20",
-      "resolved": "https://registry.npmjs.org/mp4box/-/mp4box-0.3.20.tgz",
-      "integrity": "sha512-9I1wOBql0c9BsIPDGHY97dcH5kT7hG0Tx6SAaJvXf+A6Z0zBfGy7L1vEfjMKgjXSjtdXWL7gO+8a5euikaFTEA==",
-      "requires": {
-        "npm": "^6.9.0"
-      }
-    },
-    "mpeg4-mimetype": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/mpeg4-mimetype/-/mpeg4-mimetype-1.0.0.tgz",
-      "integrity": "sha512-m55dj9RdYxUyq+fmka0Dq505GYaJZHqBqgTMvWY6v0484XYKRUIeco+pI9TWB9M1eFrXi7eN5syvgYH+Czrl3g=="
-    },
     "ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -468,6 +498,15 @@
         "sax": "^1.2.4"
       }
     },
+    "node-expat": {
+      "version": "2.3.18",
+      "resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.3.18.tgz",
+      "integrity": "sha512-9dIrDxXePa9HSn+hhlAg1wXkvqOjxefEbMclGxk2cEnq/Y3U7Qo5HNNqeo3fQ4bVmLhcdt3YN1TZy7WMZy4MHw==",
+      "requires": {
+        "bindings": "^1.5.0",
+        "nan": "^2.13.2"
+      }
+    },
     "node-fetch": {
       "version": "2.6.0",
       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
@@ -508,3112 +547,6 @@
         "osenv": "^0.1.4"
       }
     },
-    "npm": {
-      "version": "6.14.4",
-      "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.4.tgz",
-      "integrity": "sha512-B8UDDbWvdkW6RgXFn8/h2cHJP/u/FPa4HWeGzW23aNEBARN3QPrRaHqPIZW2NSN3fW649gtgUDNZpaRs0zTMPw==",
-      "requires": {
-        "JSONStream": "^1.3.5",
-        "abbrev": "~1.1.1",
-        "ansicolors": "~0.3.2",
-        "ansistyles": "~0.1.3",
-        "aproba": "^2.0.0",
-        "archy": "~1.0.0",
-        "bin-links": "^1.1.7",
-        "bluebird": "^3.5.5",
-        "byte-size": "^5.0.1",
-        "cacache": "^12.0.3",
-        "call-limit": "^1.1.1",
-        "chownr": "^1.1.4",
-        "ci-info": "^2.0.0",
-        "cli-columns": "^3.1.2",
-        "cli-table3": "^0.5.1",
-        "cmd-shim": "^3.0.3",
-        "columnify": "~1.5.4",
-        "config-chain": "^1.1.12",
-        "debuglog": "*",
-        "detect-indent": "~5.0.0",
-        "detect-newline": "^2.1.0",
-        "dezalgo": "~1.0.3",
-        "editor": "~1.0.0",
-        "figgy-pudding": "^3.5.1",
-        "find-npm-prefix": "^1.0.2",
-        "fs-vacuum": "~1.2.10",
-        "fs-write-stream-atomic": "~1.0.10",
-        "gentle-fs": "^2.3.0",
-        "glob": "^7.1.6",
-        "graceful-fs": "^4.2.3",
-        "has-unicode": "~2.0.1",
-        "hosted-git-info": "^2.8.8",
-        "iferr": "^1.0.2",
-        "imurmurhash": "*",
-        "infer-owner": "^1.0.4",
-        "inflight": "~1.0.6",
-        "inherits": "^2.0.4",
-        "ini": "^1.3.5",
-        "init-package-json": "^1.10.3",
-        "is-cidr": "^3.0.0",
-        "json-parse-better-errors": "^1.0.2",
-        "lazy-property": "~1.0.0",
-        "libcipm": "^4.0.7",
-        "libnpm": "^3.0.1",
-        "libnpmaccess": "^3.0.2",
-        "libnpmhook": "^5.0.3",
-        "libnpmorg": "^1.0.1",
-        "libnpmsearch": "^2.0.2",
-        "libnpmteam": "^1.0.2",
-        "libnpx": "^10.2.2",
-        "lock-verify": "^2.1.0",
-        "lockfile": "^1.0.4",
-        "lodash._baseindexof": "*",
-        "lodash._baseuniq": "~4.6.0",
-        "lodash._bindcallback": "*",
-        "lodash._cacheindexof": "*",
-        "lodash._createcache": "*",
-        "lodash._getnative": "*",
-        "lodash.clonedeep": "~4.5.0",
-        "lodash.restparam": "*",
-        "lodash.union": "~4.6.0",
-        "lodash.uniq": "~4.5.0",
-        "lodash.without": "~4.4.0",
-        "lru-cache": "^5.1.1",
-        "meant": "~1.0.1",
-        "mississippi": "^3.0.0",
-        "mkdirp": "^0.5.4",
-        "move-concurrently": "^1.0.1",
-        "node-gyp": "^5.1.0",
-        "nopt": "~4.0.1",
-        "normalize-package-data": "^2.5.0",
-        "npm-audit-report": "^1.3.2",
-        "npm-cache-filename": "~1.0.2",
-        "npm-install-checks": "^3.0.2",
-        "npm-lifecycle": "^3.1.4",
-        "npm-package-arg": "^6.1.1",
-        "npm-packlist": "^1.4.8",
-        "npm-pick-manifest": "^3.0.2",
-        "npm-profile": "^4.0.4",
-        "npm-registry-fetch": "^4.0.3",
-        "npm-user-validate": "~1.0.0",
-        "npmlog": "~4.1.2",
-        "once": "~1.4.0",
-        "opener": "^1.5.1",
-        "osenv": "^0.1.5",
-        "pacote": "^9.5.12",
-        "path-is-inside": "~1.0.2",
-        "promise-inflight": "~1.0.1",
-        "qrcode-terminal": "^0.12.0",
-        "query-string": "^6.8.2",
-        "qw": "~1.0.1",
-        "read": "~1.0.7",
-        "read-cmd-shim": "^1.0.5",
-        "read-installed": "~4.0.3",
-        "read-package-json": "^2.1.1",
-        "read-package-tree": "^5.3.1",
-        "readable-stream": "^3.6.0",
-        "readdir-scoped-modules": "^1.1.0",
-        "request": "^2.88.0",
-        "retry": "^0.12.0",
-        "rimraf": "^2.7.1",
-        "safe-buffer": "^5.1.2",
-        "semver": "^5.7.1",
-        "sha": "^3.0.0",
-        "slide": "~1.1.6",
-        "sorted-object": "~2.0.1",
-        "sorted-union-stream": "~2.1.3",
-        "ssri": "^6.0.1",
-        "stringify-package": "^1.0.1",
-        "tar": "^4.4.13",
-        "text-table": "~0.2.0",
-        "tiny-relative-date": "^1.3.0",
-        "uid-number": "0.0.6",
-        "umask": "~1.1.0",
-        "unique-filename": "^1.1.1",
-        "unpipe": "~1.0.0",
-        "update-notifier": "^2.5.0",
-        "uuid": "^3.3.3",
-        "validate-npm-package-license": "^3.0.4",
-        "validate-npm-package-name": "~3.0.0",
-        "which": "^1.3.1",
-        "worker-farm": "^1.7.0",
-        "write-file-atomic": "^2.4.3"
-      },
-      "dependencies": {
-        "JSONStream": {
-          "version": "1.3.5",
-          "bundled": true,
-          "requires": {
-            "jsonparse": "^1.2.0",
-            "through": ">=2.2.7 <3"
-          }
-        },
-        "abbrev": {
-          "version": "1.1.1",
-          "bundled": true
-        },
-        "agent-base": {
-          "version": "4.3.0",
-          "bundled": true,
-          "requires": {
-            "es6-promisify": "^5.0.0"
-          }
-        },
-        "agentkeepalive": {
-          "version": "3.5.2",
-          "bundled": true,
-          "requires": {
-            "humanize-ms": "^1.2.1"
-          }
-        },
-        "ajv": {
-          "version": "5.5.2",
-          "bundled": true,
-          "requires": {
-            "co": "^4.6.0",
-            "fast-deep-equal": "^1.0.0",
-            "fast-json-stable-stringify": "^2.0.0",
-            "json-schema-traverse": "^0.3.0"
-          }
-        },
-        "ansi-align": {
-          "version": "2.0.0",
-          "bundled": true,
-          "requires": {
-            "string-width": "^2.0.0"
-          }
-        },
-        "ansi-regex": {
-          "version": "2.1.1",
-          "bundled": true
-        },
-        "ansi-styles": {
-          "version": "3.2.1",
-          "bundled": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "ansicolors": {
-          "version": "0.3.2",
-          "bundled": true
-        },
-        "ansistyles": {
-          "version": "0.1.3",
-          "bundled": true
-        },
-        "aproba": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "archy": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "are-we-there-yet": {
-          "version": "1.1.4",
-          "bundled": true,
-          "requires": {
-            "delegates": "^1.0.0",
-            "readable-stream": "^2.0.6"
-          },
-          "dependencies": {
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "asap": {
-          "version": "2.0.6",
-          "bundled": true
-        },
-        "asn1": {
-          "version": "0.2.4",
-          "bundled": true,
-          "requires": {
-            "safer-buffer": "~2.1.0"
-          }
-        },
-        "assert-plus": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "asynckit": {
-          "version": "0.4.0",
-          "bundled": true
-        },
-        "aws-sign2": {
-          "version": "0.7.0",
-          "bundled": true
-        },
-        "aws4": {
-          "version": "1.8.0",
-          "bundled": true
-        },
-        "balanced-match": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "bcrypt-pbkdf": {
-          "version": "1.0.2",
-          "bundled": true,
-          "optional": true,
-          "requires": {
-            "tweetnacl": "^0.14.3"
-          }
-        },
-        "bin-links": {
-          "version": "1.1.7",
-          "bundled": true,
-          "requires": {
-            "bluebird": "^3.5.3",
-            "cmd-shim": "^3.0.0",
-            "gentle-fs": "^2.3.0",
-            "graceful-fs": "^4.1.15",
-            "npm-normalize-package-bin": "^1.0.0",
-            "write-file-atomic": "^2.3.0"
-          }
-        },
-        "bluebird": {
-          "version": "3.5.5",
-          "bundled": true
-        },
-        "boxen": {
-          "version": "1.3.0",
-          "bundled": true,
-          "requires": {
-            "ansi-align": "^2.0.0",
-            "camelcase": "^4.0.0",
-            "chalk": "^2.0.1",
-            "cli-boxes": "^1.0.0",
-            "string-width": "^2.0.0",
-            "term-size": "^1.2.0",
-            "widest-line": "^2.0.0"
-          }
-        },
-        "brace-expansion": {
-          "version": "1.1.11",
-          "bundled": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "buffer-from": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "builtins": {
-          "version": "1.0.3",
-          "bundled": true
-        },
-        "byline": {
-          "version": "5.0.0",
-          "bundled": true
-        },
-        "byte-size": {
-          "version": "5.0.1",
-          "bundled": true
-        },
-        "cacache": {
-          "version": "12.0.3",
-          "bundled": true,
-          "requires": {
-            "bluebird": "^3.5.5",
-            "chownr": "^1.1.1",
-            "figgy-pudding": "^3.5.1",
-            "glob": "^7.1.4",
-            "graceful-fs": "^4.1.15",
-            "infer-owner": "^1.0.3",
-            "lru-cache": "^5.1.1",
-            "mississippi": "^3.0.0",
-            "mkdirp": "^0.5.1",
-            "move-concurrently": "^1.0.1",
-            "promise-inflight": "^1.0.1",
-            "rimraf": "^2.6.3",
-            "ssri": "^6.0.1",
-            "unique-filename": "^1.1.1",
-            "y18n": "^4.0.0"
-          }
-        },
-        "call-limit": {
-          "version": "1.1.1",
-          "bundled": true
-        },
-        "camelcase": {
-          "version": "4.1.0",
-          "bundled": true
-        },
-        "capture-stack-trace": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "caseless": {
-          "version": "0.12.0",
-          "bundled": true
-        },
-        "chalk": {
-          "version": "2.4.1",
-          "bundled": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "chownr": {
-          "version": "1.1.4",
-          "bundled": true
-        },
-        "ci-info": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "cidr-regex": {
-          "version": "2.0.10",
-          "bundled": true,
-          "requires": {
-            "ip-regex": "^2.1.0"
-          }
-        },
-        "cli-boxes": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "cli-columns": {
-          "version": "3.1.2",
-          "bundled": true,
-          "requires": {
-            "string-width": "^2.0.0",
-            "strip-ansi": "^3.0.1"
-          }
-        },
-        "cli-table3": {
-          "version": "0.5.1",
-          "bundled": true,
-          "requires": {
-            "colors": "^1.1.2",
-            "object-assign": "^4.1.0",
-            "string-width": "^2.1.1"
-          }
-        },
-        "cliui": {
-          "version": "4.1.0",
-          "bundled": true,
-          "requires": {
-            "string-width": "^2.1.1",
-            "strip-ansi": "^4.0.0",
-            "wrap-ansi": "^2.0.0"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "3.0.0",
-              "bundled": true
-            },
-            "strip-ansi": {
-              "version": "4.0.0",
-              "bundled": true,
-              "requires": {
-                "ansi-regex": "^3.0.0"
-              }
-            }
-          }
-        },
-        "clone": {
-          "version": "1.0.4",
-          "bundled": true
-        },
-        "cmd-shim": {
-          "version": "3.0.3",
-          "bundled": true,
-          "requires": {
-            "graceful-fs": "^4.1.2",
-            "mkdirp": "~0.5.0"
-          }
-        },
-        "co": {
-          "version": "4.6.0",
-          "bundled": true
-        },
-        "code-point-at": {
-          "version": "1.1.0",
-          "bundled": true
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "bundled": true,
-          "requires": {
-            "color-name": "^1.1.1"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "bundled": true
-        },
-        "colors": {
-          "version": "1.3.3",
-          "bundled": true,
-          "optional": true
-        },
-        "columnify": {
-          "version": "1.5.4",
-          "bundled": true,
-          "requires": {
-            "strip-ansi": "^3.0.0",
-            "wcwidth": "^1.0.0"
-          }
-        },
-        "combined-stream": {
-          "version": "1.0.6",
-          "bundled": true,
-          "requires": {
-            "delayed-stream": "~1.0.0"
-          }
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "bundled": true
-        },
-        "concat-stream": {
-          "version": "1.6.2",
-          "bundled": true,
-          "requires": {
-            "buffer-from": "^1.0.0",
-            "inherits": "^2.0.3",
-            "readable-stream": "^2.2.2",
-            "typedarray": "^0.0.6"
-          },
-          "dependencies": {
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "config-chain": {
-          "version": "1.1.12",
-          "bundled": true,
-          "requires": {
-            "ini": "^1.3.4",
-            "proto-list": "~1.2.1"
-          }
-        },
-        "configstore": {
-          "version": "3.1.2",
-          "bundled": 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"
-          }
-        },
-        "console-control-strings": {
-          "version": "1.1.0",
-          "bundled": true
-        },
-        "copy-concurrently": {
-          "version": "1.0.5",
-          "bundled": true,
-          "requires": {
-            "aproba": "^1.1.1",
-            "fs-write-stream-atomic": "^1.0.8",
-            "iferr": "^0.1.5",
-            "mkdirp": "^0.5.1",
-            "rimraf": "^2.5.4",
-            "run-queue": "^1.0.0"
-          },
-          "dependencies": {
-            "aproba": {
-              "version": "1.2.0",
-              "bundled": true
-            },
-            "iferr": {
-              "version": "0.1.5",
-              "bundled": true
-            }
-          }
-        },
-        "core-util-is": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "create-error-class": {
-          "version": "3.0.2",
-          "bundled": true,
-          "requires": {
-            "capture-stack-trace": "^1.0.0"
-          }
-        },
-        "cross-spawn": {
-          "version": "5.1.0",
-          "bundled": true,
-          "requires": {
-            "lru-cache": "^4.0.1",
-            "shebang-command": "^1.2.0",
-            "which": "^1.2.9"
-          },
-          "dependencies": {
-            "lru-cache": {
-              "version": "4.1.5",
-              "bundled": true,
-              "requires": {
-                "pseudomap": "^1.0.2",
-                "yallist": "^2.1.2"
-              }
-            },
-            "yallist": {
-              "version": "2.1.2",
-              "bundled": true
-            }
-          }
-        },
-        "crypto-random-string": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "cyclist": {
-          "version": "0.2.2",
-          "bundled": true
-        },
-        "dashdash": {
-          "version": "1.14.1",
-          "bundled": true,
-          "requires": {
-            "assert-plus": "^1.0.0"
-          }
-        },
-        "debug": {
-          "version": "3.1.0",
-          "bundled": true,
-          "requires": {
-            "ms": "2.0.0"
-          },
-          "dependencies": {
-            "ms": {
-              "version": "2.0.0",
-              "bundled": true
-            }
-          }
-        },
-        "debuglog": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "decamelize": {
-          "version": "1.2.0",
-          "bundled": true
-        },
-        "decode-uri-component": {
-          "version": "0.2.0",
-          "bundled": true
-        },
-        "deep-extend": {
-          "version": "0.6.0",
-          "bundled": true
-        },
-        "defaults": {
-          "version": "1.0.3",
-          "bundled": true,
-          "requires": {
-            "clone": "^1.0.2"
-          }
-        },
-        "define-properties": {
-          "version": "1.1.3",
-          "bundled": true,
-          "requires": {
-            "object-keys": "^1.0.12"
-          }
-        },
-        "delayed-stream": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "delegates": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "detect-indent": {
-          "version": "5.0.0",
-          "bundled": true
-        },
-        "detect-newline": {
-          "version": "2.1.0",
-          "bundled": true
-        },
-        "dezalgo": {
-          "version": "1.0.3",
-          "bundled": true,
-          "requires": {
-            "asap": "^2.0.0",
-            "wrappy": "1"
-          }
-        },
-        "dot-prop": {
-          "version": "4.2.0",
-          "bundled": true,
-          "requires": {
-            "is-obj": "^1.0.0"
-          }
-        },
-        "dotenv": {
-          "version": "5.0.1",
-          "bundled": true
-        },
-        "duplexer3": {
-          "version": "0.1.4",
-          "bundled": true
-        },
-        "duplexify": {
-          "version": "3.6.0",
-          "bundled": true,
-          "requires": {
-            "end-of-stream": "^1.0.0",
-            "inherits": "^2.0.1",
-            "readable-stream": "^2.0.0",
-            "stream-shift": "^1.0.0"
-          },
-          "dependencies": {
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "ecc-jsbn": {
-          "version": "0.1.2",
-          "bundled": true,
-          "optional": true,
-          "requires": {
-            "jsbn": "~0.1.0",
-            "safer-buffer": "^2.1.0"
-          }
-        },
-        "editor": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "encoding": {
-          "version": "0.1.12",
-          "bundled": true,
-          "requires": {
-            "iconv-lite": "~0.4.13"
-          }
-        },
-        "end-of-stream": {
-          "version": "1.4.1",
-          "bundled": true,
-          "requires": {
-            "once": "^1.4.0"
-          }
-        },
-        "env-paths": {
-          "version": "2.2.0",
-          "bundled": true
-        },
-        "err-code": {
-          "version": "1.1.2",
-          "bundled": true
-        },
-        "errno": {
-          "version": "0.1.7",
-          "bundled": true,
-          "requires": {
-            "prr": "~1.0.1"
-          }
-        },
-        "es-abstract": {
-          "version": "1.12.0",
-          "bundled": true,
-          "requires": {
-            "es-to-primitive": "^1.1.1",
-            "function-bind": "^1.1.1",
-            "has": "^1.0.1",
-            "is-callable": "^1.1.3",
-            "is-regex": "^1.0.4"
-          }
-        },
-        "es-to-primitive": {
-          "version": "1.2.0",
-          "bundled": true,
-          "requires": {
-            "is-callable": "^1.1.4",
-            "is-date-object": "^1.0.1",
-            "is-symbol": "^1.0.2"
-          }
-        },
-        "es6-promise": {
-          "version": "4.2.8",
-          "bundled": true
-        },
-        "es6-promisify": {
-          "version": "5.0.0",
-          "bundled": true,
-          "requires": {
-            "es6-promise": "^4.0.3"
-          }
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "bundled": true
-        },
-        "execa": {
-          "version": "0.7.0",
-          "bundled": true,
-          "requires": {
-            "cross-spawn": "^5.0.1",
-            "get-stream": "^3.0.0",
-            "is-stream": "^1.1.0",
-            "npm-run-path": "^2.0.0",
-            "p-finally": "^1.0.0",
-            "signal-exit": "^3.0.0",
-            "strip-eof": "^1.0.0"
-          },
-          "dependencies": {
-            "get-stream": {
-              "version": "3.0.0",
-              "bundled": true
-            }
-          }
-        },
-        "extend": {
-          "version": "3.0.2",
-          "bundled": true
-        },
-        "extsprintf": {
-          "version": "1.3.0",
-          "bundled": true
-        },
-        "fast-deep-equal": {
-          "version": "1.1.0",
-          "bundled": true
-        },
-        "fast-json-stable-stringify": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "figgy-pudding": {
-          "version": "3.5.1",
-          "bundled": true
-        },
-        "find-npm-prefix": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "find-up": {
-          "version": "2.1.0",
-          "bundled": true,
-          "requires": {
-            "locate-path": "^2.0.0"
-          }
-        },
-        "flush-write-stream": {
-          "version": "1.0.3",
-          "bundled": true,
-          "requires": {
-            "inherits": "^2.0.1",
-            "readable-stream": "^2.0.4"
-          },
-          "dependencies": {
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "forever-agent": {
-          "version": "0.6.1",
-          "bundled": true
-        },
-        "form-data": {
-          "version": "2.3.2",
-          "bundled": true,
-          "requires": {
-            "asynckit": "^0.4.0",
-            "combined-stream": "1.0.6",
-            "mime-types": "^2.1.12"
-          }
-        },
-        "from2": {
-          "version": "2.3.0",
-          "bundled": true,
-          "requires": {
-            "inherits": "^2.0.1",
-            "readable-stream": "^2.0.0"
-          },
-          "dependencies": {
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "fs-minipass": {
-          "version": "1.2.7",
-          "bundled": true,
-          "requires": {
-            "minipass": "^2.6.0"
-          },
-          "dependencies": {
-            "minipass": {
-              "version": "2.9.0",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "^5.1.2",
-                "yallist": "^3.0.0"
-              }
-            }
-          }
-        },
-        "fs-vacuum": {
-          "version": "1.2.10",
-          "bundled": true,
-          "requires": {
-            "graceful-fs": "^4.1.2",
-            "path-is-inside": "^1.0.1",
-            "rimraf": "^2.5.2"
-          }
-        },
-        "fs-write-stream-atomic": {
-          "version": "1.0.10",
-          "bundled": true,
-          "requires": {
-            "graceful-fs": "^4.1.2",
-            "iferr": "^0.1.5",
-            "imurmurhash": "^0.1.4",
-            "readable-stream": "1 || 2"
-          },
-          "dependencies": {
-            "iferr": {
-              "version": "0.1.5",
-              "bundled": true
-            },
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "function-bind": {
-          "version": "1.1.1",
-          "bundled": true
-        },
-        "gauge": {
-          "version": "2.7.4",
-          "bundled": true,
-          "requires": {
-            "aproba": "^1.0.3",
-            "console-control-strings": "^1.0.0",
-            "has-unicode": "^2.0.0",
-            "object-assign": "^4.1.0",
-            "signal-exit": "^3.0.0",
-            "string-width": "^1.0.1",
-            "strip-ansi": "^3.0.1",
-            "wide-align": "^1.1.0"
-          },
-          "dependencies": {
-            "aproba": {
-              "version": "1.2.0",
-              "bundled": true
-            },
-            "string-width": {
-              "version": "1.0.2",
-              "bundled": true,
-              "requires": {
-                "code-point-at": "^1.0.0",
-                "is-fullwidth-code-point": "^1.0.0",
-                "strip-ansi": "^3.0.0"
-              }
-            }
-          }
-        },
-        "genfun": {
-          "version": "5.0.0",
-          "bundled": true
-        },
-        "gentle-fs": {
-          "version": "2.3.0",
-          "bundled": true,
-          "requires": {
-            "aproba": "^1.1.2",
-            "chownr": "^1.1.2",
-            "cmd-shim": "^3.0.3",
-            "fs-vacuum": "^1.2.10",
-            "graceful-fs": "^4.1.11",
-            "iferr": "^0.1.5",
-            "infer-owner": "^1.0.4",
-            "mkdirp": "^0.5.1",
-            "path-is-inside": "^1.0.2",
-            "read-cmd-shim": "^1.0.1",
-            "slide": "^1.1.6"
-          },
-          "dependencies": {
-            "aproba": {
-              "version": "1.2.0",
-              "bundled": true
-            },
-            "iferr": {
-              "version": "0.1.5",
-              "bundled": true
-            }
-          }
-        },
-        "get-caller-file": {
-          "version": "1.0.3",
-          "bundled": true
-        },
-        "get-stream": {
-          "version": "4.1.0",
-          "bundled": true,
-          "requires": {
-            "pump": "^3.0.0"
-          }
-        },
-        "getpass": {
-          "version": "0.1.7",
-          "bundled": true,
-          "requires": {
-            "assert-plus": "^1.0.0"
-          }
-        },
-        "glob": {
-          "version": "7.1.6",
-          "bundled": true,
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.0.4",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
-          }
-        },
-        "global-dirs": {
-          "version": "0.1.1",
-          "bundled": true,
-          "requires": {
-            "ini": "^1.3.4"
-          }
-        },
-        "got": {
-          "version": "6.7.1",
-          "bundled": true,
-          "requires": {
-            "create-error-class": "^3.0.0",
-            "duplexer3": "^0.1.4",
-            "get-stream": "^3.0.0",
-            "is-redirect": "^1.0.0",
-            "is-retry-allowed": "^1.0.0",
-            "is-stream": "^1.0.0",
-            "lowercase-keys": "^1.0.0",
-            "safe-buffer": "^5.0.1",
-            "timed-out": "^4.0.0",
-            "unzip-response": "^2.0.1",
-            "url-parse-lax": "^1.0.0"
-          },
-          "dependencies": {
-            "get-stream": {
-              "version": "3.0.0",
-              "bundled": true
-            }
-          }
-        },
-        "graceful-fs": {
-          "version": "4.2.3",
-          "bundled": true
-        },
-        "har-schema": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "har-validator": {
-          "version": "5.1.0",
-          "bundled": true,
-          "requires": {
-            "ajv": "^5.3.0",
-            "har-schema": "^2.0.0"
-          }
-        },
-        "has": {
-          "version": "1.0.3",
-          "bundled": true,
-          "requires": {
-            "function-bind": "^1.1.1"
-          }
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "bundled": true
-        },
-        "has-symbols": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "has-unicode": {
-          "version": "2.0.1",
-          "bundled": true
-        },
-        "hosted-git-info": {
-          "version": "2.8.8",
-          "bundled": true
-        },
-        "http-cache-semantics": {
-          "version": "3.8.1",
-          "bundled": true
-        },
-        "http-proxy-agent": {
-          "version": "2.1.0",
-          "bundled": true,
-          "requires": {
-            "agent-base": "4",
-            "debug": "3.1.0"
-          }
-        },
-        "http-signature": {
-          "version": "1.2.0",
-          "bundled": true,
-          "requires": {
-            "assert-plus": "^1.0.0",
-            "jsprim": "^1.2.2",
-            "sshpk": "^1.7.0"
-          }
-        },
-        "https-proxy-agent": {
-          "version": "2.2.4",
-          "bundled": true,
-          "requires": {
-            "agent-base": "^4.3.0",
-            "debug": "^3.1.0"
-          }
-        },
-        "humanize-ms": {
-          "version": "1.2.1",
-          "bundled": true,
-          "requires": {
-            "ms": "^2.0.0"
-          }
-        },
-        "iconv-lite": {
-          "version": "0.4.23",
-          "bundled": true,
-          "requires": {
-            "safer-buffer": ">= 2.1.2 < 3"
-          }
-        },
-        "iferr": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "ignore-walk": {
-          "version": "3.0.3",
-          "bundled": true,
-          "requires": {
-            "minimatch": "^3.0.4"
-          }
-        },
-        "import-lazy": {
-          "version": "2.1.0",
-          "bundled": true
-        },
-        "imurmurhash": {
-          "version": "0.1.4",
-          "bundled": true
-        },
-        "infer-owner": {
-          "version": "1.0.4",
-          "bundled": true
-        },
-        "inflight": {
-          "version": "1.0.6",
-          "bundled": true,
-          "requires": {
-            "once": "^1.3.0",
-            "wrappy": "1"
-          }
-        },
-        "inherits": {
-          "version": "2.0.4",
-          "bundled": true
-        },
-        "ini": {
-          "version": "1.3.5",
-          "bundled": true
-        },
-        "init-package-json": {
-          "version": "1.10.3",
-          "bundled": true,
-          "requires": {
-            "glob": "^7.1.1",
-            "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0",
-            "promzard": "^0.3.0",
-            "read": "~1.0.1",
-            "read-package-json": "1 || 2",
-            "semver": "2.x || 3.x || 4 || 5",
-            "validate-npm-package-license": "^3.0.1",
-            "validate-npm-package-name": "^3.0.0"
-          }
-        },
-        "invert-kv": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "ip": {
-          "version": "1.1.5",
-          "bundled": true
-        },
-        "ip-regex": {
-          "version": "2.1.0",
-          "bundled": true
-        },
-        "is-callable": {
-          "version": "1.1.4",
-          "bundled": true
-        },
-        "is-ci": {
-          "version": "1.2.1",
-          "bundled": true,
-          "requires": {
-            "ci-info": "^1.5.0"
-          },
-          "dependencies": {
-            "ci-info": {
-              "version": "1.6.0",
-              "bundled": true
-            }
-          }
-        },
-        "is-cidr": {
-          "version": "3.0.0",
-          "bundled": true,
-          "requires": {
-            "cidr-regex": "^2.0.10"
-          }
-        },
-        "is-date-object": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "1.0.0",
-          "bundled": true,
-          "requires": {
-            "number-is-nan": "^1.0.0"
-          }
-        },
-        "is-installed-globally": {
-          "version": "0.1.0",
-          "bundled": true,
-          "requires": {
-            "global-dirs": "^0.1.0",
-            "is-path-inside": "^1.0.0"
-          }
-        },
-        "is-npm": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "is-obj": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "is-path-inside": {
-          "version": "1.0.1",
-          "bundled": true,
-          "requires": {
-            "path-is-inside": "^1.0.1"
-          }
-        },
-        "is-redirect": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "is-regex": {
-          "version": "1.0.4",
-          "bundled": true,
-          "requires": {
-            "has": "^1.0.1"
-          }
-        },
-        "is-retry-allowed": {
-          "version": "1.2.0",
-          "bundled": true
-        },
-        "is-stream": {
-          "version": "1.1.0",
-          "bundled": true
-        },
-        "is-symbol": {
-          "version": "1.0.2",
-          "bundled": true,
-          "requires": {
-            "has-symbols": "^1.0.0"
-          }
-        },
-        "is-typedarray": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "isexe": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "isstream": {
-          "version": "0.1.2",
-          "bundled": true
-        },
-        "jsbn": {
-          "version": "0.1.1",
-          "bundled": true,
-          "optional": true
-        },
-        "json-parse-better-errors": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "json-schema": {
-          "version": "0.2.3",
-          "bundled": true
-        },
-        "json-schema-traverse": {
-          "version": "0.3.1",
-          "bundled": true
-        },
-        "json-stringify-safe": {
-          "version": "5.0.1",
-          "bundled": true
-        },
-        "jsonparse": {
-          "version": "1.3.1",
-          "bundled": true
-        },
-        "jsprim": {
-          "version": "1.4.1",
-          "bundled": true,
-          "requires": {
-            "assert-plus": "1.0.0",
-            "extsprintf": "1.3.0",
-            "json-schema": "0.2.3",
-            "verror": "1.10.0"
-          }
-        },
-        "latest-version": {
-          "version": "3.1.0",
-          "bundled": true,
-          "requires": {
-            "package-json": "^4.0.0"
-          }
-        },
-        "lazy-property": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "lcid": {
-          "version": "2.0.0",
-          "bundled": true,
-          "requires": {
-            "invert-kv": "^2.0.0"
-          }
-        },
-        "libcipm": {
-          "version": "4.0.7",
-          "bundled": true,
-          "requires": {
-            "bin-links": "^1.1.2",
-            "bluebird": "^3.5.1",
-            "figgy-pudding": "^3.5.1",
-            "find-npm-prefix": "^1.0.2",
-            "graceful-fs": "^4.1.11",
-            "ini": "^1.3.5",
-            "lock-verify": "^2.0.2",
-            "mkdirp": "^0.5.1",
-            "npm-lifecycle": "^3.0.0",
-            "npm-logical-tree": "^1.2.1",
-            "npm-package-arg": "^6.1.0",
-            "pacote": "^9.1.0",
-            "read-package-json": "^2.0.13",
-            "rimraf": "^2.6.2",
-            "worker-farm": "^1.6.0"
-          }
-        },
-        "libnpm": {
-          "version": "3.0.1",
-          "bundled": true,
-          "requires": {
-            "bin-links": "^1.1.2",
-            "bluebird": "^3.5.3",
-            "find-npm-prefix": "^1.0.2",
-            "libnpmaccess": "^3.0.2",
-            "libnpmconfig": "^1.2.1",
-            "libnpmhook": "^5.0.3",
-            "libnpmorg": "^1.0.1",
-            "libnpmpublish": "^1.1.2",
-            "libnpmsearch": "^2.0.2",
-            "libnpmteam": "^1.0.2",
-            "lock-verify": "^2.0.2",
-            "npm-lifecycle": "^3.0.0",
-            "npm-logical-tree": "^1.2.1",
-            "npm-package-arg": "^6.1.0",
-            "npm-profile": "^4.0.2",
-            "npm-registry-fetch": "^4.0.0",
-            "npmlog": "^4.1.2",
-            "pacote": "^9.5.3",
-            "read-package-json": "^2.0.13",
-            "stringify-package": "^1.0.0"
-          }
-        },
-        "libnpmaccess": {
-          "version": "3.0.2",
-          "bundled": true,
-          "requires": {
-            "aproba": "^2.0.0",
-            "get-stream": "^4.0.0",
-            "npm-package-arg": "^6.1.0",
-            "npm-registry-fetch": "^4.0.0"
-          }
-        },
-        "libnpmconfig": {
-          "version": "1.2.1",
-          "bundled": true,
-          "requires": {
-            "figgy-pudding": "^3.5.1",
-            "find-up": "^3.0.0",
-            "ini": "^1.3.5"
-          },
-          "dependencies": {
-            "find-up": {
-              "version": "3.0.0",
-              "bundled": true,
-              "requires": {
-                "locate-path": "^3.0.0"
-              }
-            },
-            "locate-path": {
-              "version": "3.0.0",
-              "bundled": true,
-              "requires": {
-                "p-locate": "^3.0.0",
-                "path-exists": "^3.0.0"
-              }
-            },
-            "p-limit": {
-              "version": "2.2.0",
-              "bundled": true,
-              "requires": {
-                "p-try": "^2.0.0"
-              }
-            },
-            "p-locate": {
-              "version": "3.0.0",
-              "bundled": true,
-              "requires": {
-                "p-limit": "^2.0.0"
-              }
-            },
-            "p-try": {
-              "version": "2.2.0",
-              "bundled": true
-            }
-          }
-        },
-        "libnpmhook": {
-          "version": "5.0.3",
-          "bundled": true,
-          "requires": {
-            "aproba": "^2.0.0",
-            "figgy-pudding": "^3.4.1",
-            "get-stream": "^4.0.0",
-            "npm-registry-fetch": "^4.0.0"
-          }
-        },
-        "libnpmorg": {
-          "version": "1.0.1",
-          "bundled": true,
-          "requires": {
-            "aproba": "^2.0.0",
-            "figgy-pudding": "^3.4.1",
-            "get-stream": "^4.0.0",
-            "npm-registry-fetch": "^4.0.0"
-          }
-        },
-        "libnpmpublish": {
-          "version": "1.1.2",
-          "bundled": true,
-          "requires": {
-            "aproba": "^2.0.0",
-            "figgy-pudding": "^3.5.1",
-            "get-stream": "^4.0.0",
-            "lodash.clonedeep": "^4.5.0",
-            "normalize-package-data": "^2.4.0",
-            "npm-package-arg": "^6.1.0",
-            "npm-registry-fetch": "^4.0.0",
-            "semver": "^5.5.1",
-            "ssri": "^6.0.1"
-          }
-        },
-        "libnpmsearch": {
-          "version": "2.0.2",
-          "bundled": true,
-          "requires": {
-            "figgy-pudding": "^3.5.1",
-            "get-stream": "^4.0.0",
-            "npm-registry-fetch": "^4.0.0"
-          }
-        },
-        "libnpmteam": {
-          "version": "1.0.2",
-          "bundled": true,
-          "requires": {
-            "aproba": "^2.0.0",
-            "figgy-pudding": "^3.4.1",
-            "get-stream": "^4.0.0",
-            "npm-registry-fetch": "^4.0.0"
-          }
-        },
-        "libnpx": {
-          "version": "10.2.2",
-          "bundled": true,
-          "requires": {
-            "dotenv": "^5.0.1",
-            "npm-package-arg": "^6.0.0",
-            "rimraf": "^2.6.2",
-            "safe-buffer": "^5.1.0",
-            "update-notifier": "^2.3.0",
-            "which": "^1.3.0",
-            "y18n": "^4.0.0",
-            "yargs": "^11.0.0"
-          }
-        },
-        "locate-path": {
-          "version": "2.0.0",
-          "bundled": true,
-          "requires": {
-            "p-locate": "^2.0.0",
-            "path-exists": "^3.0.0"
-          }
-        },
-        "lock-verify": {
-          "version": "2.1.0",
-          "bundled": true,
-          "requires": {
-            "npm-package-arg": "^6.1.0",
-            "semver": "^5.4.1"
-          }
-        },
-        "lockfile": {
-          "version": "1.0.4",
-          "bundled": true,
-          "requires": {
-            "signal-exit": "^3.0.2"
-          }
-        },
-        "lodash._baseindexof": {
-          "version": "3.1.0",
-          "bundled": true
-        },
-        "lodash._baseuniq": {
-          "version": "4.6.0",
-          "bundled": true,
-          "requires": {
-            "lodash._createset": "~4.0.0",
-            "lodash._root": "~3.0.0"
-          }
-        },
-        "lodash._bindcallback": {
-          "version": "3.0.1",
-          "bundled": true
-        },
-        "lodash._cacheindexof": {
-          "version": "3.0.2",
-          "bundled": true
-        },
-        "lodash._createcache": {
-          "version": "3.1.2",
-          "bundled": true,
-          "requires": {
-            "lodash._getnative": "^3.0.0"
-          }
-        },
-        "lodash._createset": {
-          "version": "4.0.3",
-          "bundled": true
-        },
-        "lodash._getnative": {
-          "version": "3.9.1",
-          "bundled": true
-        },
-        "lodash._root": {
-          "version": "3.0.1",
-          "bundled": true
-        },
-        "lodash.clonedeep": {
-          "version": "4.5.0",
-          "bundled": true
-        },
-        "lodash.restparam": {
-          "version": "3.6.1",
-          "bundled": true
-        },
-        "lodash.union": {
-          "version": "4.6.0",
-          "bundled": true
-        },
-        "lodash.uniq": {
-          "version": "4.5.0",
-          "bundled": true
-        },
-        "lodash.without": {
-          "version": "4.4.0",
-          "bundled": true
-        },
-        "lowercase-keys": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "lru-cache": {
-          "version": "5.1.1",
-          "bundled": true,
-          "requires": {
-            "yallist": "^3.0.2"
-          }
-        },
-        "make-dir": {
-          "version": "1.3.0",
-          "bundled": true,
-          "requires": {
-            "pify": "^3.0.0"
-          }
-        },
-        "make-fetch-happen": {
-          "version": "5.0.2",
-          "bundled": true,
-          "requires": {
-            "agentkeepalive": "^3.4.1",
-            "cacache": "^12.0.0",
-            "http-cache-semantics": "^3.8.1",
-            "http-proxy-agent": "^2.1.0",
-            "https-proxy-agent": "^2.2.3",
-            "lru-cache": "^5.1.1",
-            "mississippi": "^3.0.0",
-            "node-fetch-npm": "^2.0.2",
-            "promise-retry": "^1.1.1",
-            "socks-proxy-agent": "^4.0.0",
-            "ssri": "^6.0.0"
-          }
-        },
-        "map-age-cleaner": {
-          "version": "0.1.3",
-          "bundled": true,
-          "requires": {
-            "p-defer": "^1.0.0"
-          }
-        },
-        "meant": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "mem": {
-          "version": "4.3.0",
-          "bundled": true,
-          "requires": {
-            "map-age-cleaner": "^0.1.1",
-            "mimic-fn": "^2.0.0",
-            "p-is-promise": "^2.0.0"
-          },
-          "dependencies": {
-            "mimic-fn": {
-              "version": "2.1.0",
-              "bundled": true
-            }
-          }
-        },
-        "mime-db": {
-          "version": "1.35.0",
-          "bundled": true
-        },
-        "mime-types": {
-          "version": "2.1.19",
-          "bundled": true,
-          "requires": {
-            "mime-db": "~1.35.0"
-          }
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "bundled": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "minizlib": {
-          "version": "1.3.3",
-          "bundled": true,
-          "requires": {
-            "minipass": "^2.9.0"
-          },
-          "dependencies": {
-            "minipass": {
-              "version": "2.9.0",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "^5.1.2",
-                "yallist": "^3.0.0"
-              }
-            }
-          }
-        },
-        "mississippi": {
-          "version": "3.0.0",
-          "bundled": true,
-          "requires": {
-            "concat-stream": "^1.5.0",
-            "duplexify": "^3.4.2",
-            "end-of-stream": "^1.1.0",
-            "flush-write-stream": "^1.0.0",
-            "from2": "^2.1.0",
-            "parallel-transform": "^1.1.0",
-            "pump": "^3.0.0",
-            "pumpify": "^1.3.3",
-            "stream-each": "^1.1.0",
-            "through2": "^2.0.0"
-          }
-        },
-        "mkdirp": {
-          "version": "0.5.4",
-          "bundled": true,
-          "requires": {
-            "minimist": "^1.2.5"
-          },
-          "dependencies": {
-            "minimist": {
-              "version": "1.2.5",
-              "bundled": true
-            }
-          }
-        },
-        "move-concurrently": {
-          "version": "1.0.1",
-          "bundled": true,
-          "requires": {
-            "aproba": "^1.1.1",
-            "copy-concurrently": "^1.0.0",
-            "fs-write-stream-atomic": "^1.0.8",
-            "mkdirp": "^0.5.1",
-            "rimraf": "^2.5.4",
-            "run-queue": "^1.0.3"
-          },
-          "dependencies": {
-            "aproba": {
-              "version": "1.2.0",
-              "bundled": true
-            }
-          }
-        },
-        "ms": {
-          "version": "2.1.1",
-          "bundled": true
-        },
-        "mute-stream": {
-          "version": "0.0.7",
-          "bundled": true
-        },
-        "nice-try": {
-          "version": "1.0.5",
-          "bundled": true
-        },
-        "node-fetch-npm": {
-          "version": "2.0.2",
-          "bundled": true,
-          "requires": {
-            "encoding": "^0.1.11",
-            "json-parse-better-errors": "^1.0.0",
-            "safe-buffer": "^5.1.1"
-          }
-        },
-        "node-gyp": {
-          "version": "5.1.0",
-          "bundled": true,
-          "requires": {
-            "env-paths": "^2.2.0",
-            "glob": "^7.1.4",
-            "graceful-fs": "^4.2.2",
-            "mkdirp": "^0.5.1",
-            "nopt": "^4.0.1",
-            "npmlog": "^4.1.2",
-            "request": "^2.88.0",
-            "rimraf": "^2.6.3",
-            "semver": "^5.7.1",
-            "tar": "^4.4.12",
-            "which": "^1.3.1"
-          }
-        },
-        "nopt": {
-          "version": "4.0.1",
-          "bundled": true,
-          "requires": {
-            "abbrev": "1",
-            "osenv": "^0.1.4"
-          }
-        },
-        "normalize-package-data": {
-          "version": "2.5.0",
-          "bundled": true,
-          "requires": {
-            "hosted-git-info": "^2.1.4",
-            "resolve": "^1.10.0",
-            "semver": "2 || 3 || 4 || 5",
-            "validate-npm-package-license": "^3.0.1"
-          },
-          "dependencies": {
-            "resolve": {
-              "version": "1.10.0",
-              "bundled": true,
-              "requires": {
-                "path-parse": "^1.0.6"
-              }
-            }
-          }
-        },
-        "npm-audit-report": {
-          "version": "1.3.2",
-          "bundled": true,
-          "requires": {
-            "cli-table3": "^0.5.0",
-            "console-control-strings": "^1.1.0"
-          }
-        },
-        "npm-bundled": {
-          "version": "1.1.1",
-          "bundled": true,
-          "requires": {
-            "npm-normalize-package-bin": "^1.0.1"
-          }
-        },
-        "npm-cache-filename": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "npm-install-checks": {
-          "version": "3.0.2",
-          "bundled": true,
-          "requires": {
-            "semver": "^2.3.0 || 3.x || 4 || 5"
-          }
-        },
-        "npm-lifecycle": {
-          "version": "3.1.4",
-          "bundled": true,
-          "requires": {
-            "byline": "^5.0.0",
-            "graceful-fs": "^4.1.15",
-            "node-gyp": "^5.0.2",
-            "resolve-from": "^4.0.0",
-            "slide": "^1.1.6",
-            "uid-number": "0.0.6",
-            "umask": "^1.1.0",
-            "which": "^1.3.1"
-          }
-        },
-        "npm-logical-tree": {
-          "version": "1.2.1",
-          "bundled": true
-        },
-        "npm-normalize-package-bin": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "npm-package-arg": {
-          "version": "6.1.1",
-          "bundled": true,
-          "requires": {
-            "hosted-git-info": "^2.7.1",
-            "osenv": "^0.1.5",
-            "semver": "^5.6.0",
-            "validate-npm-package-name": "^3.0.0"
-          }
-        },
-        "npm-packlist": {
-          "version": "1.4.8",
-          "bundled": true,
-          "requires": {
-            "ignore-walk": "^3.0.1",
-            "npm-bundled": "^1.0.1",
-            "npm-normalize-package-bin": "^1.0.1"
-          }
-        },
-        "npm-pick-manifest": {
-          "version": "3.0.2",
-          "bundled": true,
-          "requires": {
-            "figgy-pudding": "^3.5.1",
-            "npm-package-arg": "^6.0.0",
-            "semver": "^5.4.1"
-          }
-        },
-        "npm-profile": {
-          "version": "4.0.4",
-          "bundled": true,
-          "requires": {
-            "aproba": "^1.1.2 || 2",
-            "figgy-pudding": "^3.4.1",
-            "npm-registry-fetch": "^4.0.0"
-          }
-        },
-        "npm-registry-fetch": {
-          "version": "4.0.3",
-          "bundled": true,
-          "requires": {
-            "JSONStream": "^1.3.4",
-            "bluebird": "^3.5.1",
-            "figgy-pudding": "^3.4.1",
-            "lru-cache": "^5.1.1",
-            "make-fetch-happen": "^5.0.0",
-            "npm-package-arg": "^6.1.0",
-            "safe-buffer": "^5.2.0"
-          },
-          "dependencies": {
-            "safe-buffer": {
-              "version": "5.2.0",
-              "bundled": true
-            }
-          }
-        },
-        "npm-run-path": {
-          "version": "2.0.2",
-          "bundled": true,
-          "requires": {
-            "path-key": "^2.0.0"
-          }
-        },
-        "npm-user-validate": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "npmlog": {
-          "version": "4.1.2",
-          "bundled": true,
-          "requires": {
-            "are-we-there-yet": "~1.1.2",
-            "console-control-strings": "~1.1.0",
-            "gauge": "~2.7.3",
-            "set-blocking": "~2.0.0"
-          }
-        },
-        "number-is-nan": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "oauth-sign": {
-          "version": "0.9.0",
-          "bundled": true
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "bundled": true
-        },
-        "object-keys": {
-          "version": "1.0.12",
-          "bundled": true
-        },
-        "object.getownpropertydescriptors": {
-          "version": "2.0.3",
-          "bundled": true,
-          "requires": {
-            "define-properties": "^1.1.2",
-            "es-abstract": "^1.5.1"
-          }
-        },
-        "once": {
-          "version": "1.4.0",
-          "bundled": true,
-          "requires": {
-            "wrappy": "1"
-          }
-        },
-        "opener": {
-          "version": "1.5.1",
-          "bundled": true
-        },
-        "os-homedir": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "os-locale": {
-          "version": "3.1.0",
-          "bundled": true,
-          "requires": {
-            "execa": "^1.0.0",
-            "lcid": "^2.0.0",
-            "mem": "^4.0.0"
-          },
-          "dependencies": {
-            "cross-spawn": {
-              "version": "6.0.5",
-              "bundled": true,
-              "requires": {
-                "nice-try": "^1.0.4",
-                "path-key": "^2.0.1",
-                "semver": "^5.5.0",
-                "shebang-command": "^1.2.0",
-                "which": "^1.2.9"
-              }
-            },
-            "execa": {
-              "version": "1.0.0",
-              "bundled": true,
-              "requires": {
-                "cross-spawn": "^6.0.0",
-                "get-stream": "^4.0.0",
-                "is-stream": "^1.1.0",
-                "npm-run-path": "^2.0.0",
-                "p-finally": "^1.0.0",
-                "signal-exit": "^3.0.0",
-                "strip-eof": "^1.0.0"
-              }
-            }
-          }
-        },
-        "os-tmpdir": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "osenv": {
-          "version": "0.1.5",
-          "bundled": true,
-          "requires": {
-            "os-homedir": "^1.0.0",
-            "os-tmpdir": "^1.0.0"
-          }
-        },
-        "p-defer": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "p-finally": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "p-is-promise": {
-          "version": "2.1.0",
-          "bundled": true
-        },
-        "p-limit": {
-          "version": "1.2.0",
-          "bundled": true,
-          "requires": {
-            "p-try": "^1.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "2.0.0",
-          "bundled": true,
-          "requires": {
-            "p-limit": "^1.1.0"
-          }
-        },
-        "p-try": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "package-json": {
-          "version": "4.0.1",
-          "bundled": true,
-          "requires": {
-            "got": "^6.7.1",
-            "registry-auth-token": "^3.0.1",
-            "registry-url": "^3.0.3",
-            "semver": "^5.1.0"
-          }
-        },
-        "pacote": {
-          "version": "9.5.12",
-          "bundled": true,
-          "requires": {
-            "bluebird": "^3.5.3",
-            "cacache": "^12.0.2",
-            "chownr": "^1.1.2",
-            "figgy-pudding": "^3.5.1",
-            "get-stream": "^4.1.0",
-            "glob": "^7.1.3",
-            "infer-owner": "^1.0.4",
-            "lru-cache": "^5.1.1",
-            "make-fetch-happen": "^5.0.0",
-            "minimatch": "^3.0.4",
-            "minipass": "^2.3.5",
-            "mississippi": "^3.0.0",
-            "mkdirp": "^0.5.1",
-            "normalize-package-data": "^2.4.0",
-            "npm-normalize-package-bin": "^1.0.0",
-            "npm-package-arg": "^6.1.0",
-            "npm-packlist": "^1.1.12",
-            "npm-pick-manifest": "^3.0.0",
-            "npm-registry-fetch": "^4.0.0",
-            "osenv": "^0.1.5",
-            "promise-inflight": "^1.0.1",
-            "promise-retry": "^1.1.1",
-            "protoduck": "^5.0.1",
-            "rimraf": "^2.6.2",
-            "safe-buffer": "^5.1.2",
-            "semver": "^5.6.0",
-            "ssri": "^6.0.1",
-            "tar": "^4.4.10",
-            "unique-filename": "^1.1.1",
-            "which": "^1.3.1"
-          },
-          "dependencies": {
-            "minipass": {
-              "version": "2.9.0",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "^5.1.2",
-                "yallist": "^3.0.0"
-              }
-            }
-          }
-        },
-        "parallel-transform": {
-          "version": "1.1.0",
-          "bundled": true,
-          "requires": {
-            "cyclist": "~0.2.2",
-            "inherits": "^2.0.3",
-            "readable-stream": "^2.1.5"
-          },
-          "dependencies": {
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "path-exists": {
-          "version": "3.0.0",
-          "bundled": true
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "path-is-inside": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "path-key": {
-          "version": "2.0.1",
-          "bundled": true
-        },
-        "path-parse": {
-          "version": "1.0.6",
-          "bundled": true
-        },
-        "performance-now": {
-          "version": "2.1.0",
-          "bundled": true
-        },
-        "pify": {
-          "version": "3.0.0",
-          "bundled": true
-        },
-        "prepend-http": {
-          "version": "1.0.4",
-          "bundled": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "promise-inflight": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "promise-retry": {
-          "version": "1.1.1",
-          "bundled": true,
-          "requires": {
-            "err-code": "^1.0.0",
-            "retry": "^0.10.0"
-          },
-          "dependencies": {
-            "retry": {
-              "version": "0.10.1",
-              "bundled": true
-            }
-          }
-        },
-        "promzard": {
-          "version": "0.3.0",
-          "bundled": true,
-          "requires": {
-            "read": "1"
-          }
-        },
-        "proto-list": {
-          "version": "1.2.4",
-          "bundled": true
-        },
-        "protoduck": {
-          "version": "5.0.1",
-          "bundled": true,
-          "requires": {
-            "genfun": "^5.0.0"
-          }
-        },
-        "prr": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "pseudomap": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "psl": {
-          "version": "1.1.29",
-          "bundled": true
-        },
-        "pump": {
-          "version": "3.0.0",
-          "bundled": true,
-          "requires": {
-            "end-of-stream": "^1.1.0",
-            "once": "^1.3.1"
-          }
-        },
-        "pumpify": {
-          "version": "1.5.1",
-          "bundled": true,
-          "requires": {
-            "duplexify": "^3.6.0",
-            "inherits": "^2.0.3",
-            "pump": "^2.0.0"
-          },
-          "dependencies": {
-            "pump": {
-              "version": "2.0.1",
-              "bundled": true,
-              "requires": {
-                "end-of-stream": "^1.1.0",
-                "once": "^1.3.1"
-              }
-            }
-          }
-        },
-        "punycode": {
-          "version": "1.4.1",
-          "bundled": true
-        },
-        "qrcode-terminal": {
-          "version": "0.12.0",
-          "bundled": true
-        },
-        "qs": {
-          "version": "6.5.2",
-          "bundled": true
-        },
-        "query-string": {
-          "version": "6.8.2",
-          "bundled": true,
-          "requires": {
-            "decode-uri-component": "^0.2.0",
-            "split-on-first": "^1.0.0",
-            "strict-uri-encode": "^2.0.0"
-          }
-        },
-        "qw": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "rc": {
-          "version": "1.2.8",
-          "bundled": 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",
-              "bundled": true
-            }
-          }
-        },
-        "read": {
-          "version": "1.0.7",
-          "bundled": true,
-          "requires": {
-            "mute-stream": "~0.0.4"
-          }
-        },
-        "read-cmd-shim": {
-          "version": "1.0.5",
-          "bundled": true,
-          "requires": {
-            "graceful-fs": "^4.1.2"
-          }
-        },
-        "read-installed": {
-          "version": "4.0.3",
-          "bundled": true,
-          "requires": {
-            "debuglog": "^1.0.1",
-            "graceful-fs": "^4.1.2",
-            "read-package-json": "^2.0.0",
-            "readdir-scoped-modules": "^1.0.0",
-            "semver": "2 || 3 || 4 || 5",
-            "slide": "~1.1.3",
-            "util-extend": "^1.0.1"
-          }
-        },
-        "read-package-json": {
-          "version": "2.1.1",
-          "bundled": true,
-          "requires": {
-            "glob": "^7.1.1",
-            "graceful-fs": "^4.1.2",
-            "json-parse-better-errors": "^1.0.1",
-            "normalize-package-data": "^2.0.0",
-            "npm-normalize-package-bin": "^1.0.0"
-          }
-        },
-        "read-package-tree": {
-          "version": "5.3.1",
-          "bundled": true,
-          "requires": {
-            "read-package-json": "^2.0.0",
-            "readdir-scoped-modules": "^1.0.0",
-            "util-promisify": "^2.1.0"
-          }
-        },
-        "readable-stream": {
-          "version": "3.6.0",
-          "bundled": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        },
-        "readdir-scoped-modules": {
-          "version": "1.1.0",
-          "bundled": true,
-          "requires": {
-            "debuglog": "^1.0.1",
-            "dezalgo": "^1.0.0",
-            "graceful-fs": "^4.1.2",
-            "once": "^1.3.0"
-          }
-        },
-        "registry-auth-token": {
-          "version": "3.4.0",
-          "bundled": true,
-          "requires": {
-            "rc": "^1.1.6",
-            "safe-buffer": "^5.0.1"
-          }
-        },
-        "registry-url": {
-          "version": "3.1.0",
-          "bundled": true,
-          "requires": {
-            "rc": "^1.0.1"
-          }
-        },
-        "request": {
-          "version": "2.88.0",
-          "bundled": true,
-          "requires": {
-            "aws-sign2": "~0.7.0",
-            "aws4": "^1.8.0",
-            "caseless": "~0.12.0",
-            "combined-stream": "~1.0.6",
-            "extend": "~3.0.2",
-            "forever-agent": "~0.6.1",
-            "form-data": "~2.3.2",
-            "har-validator": "~5.1.0",
-            "http-signature": "~1.2.0",
-            "is-typedarray": "~1.0.0",
-            "isstream": "~0.1.2",
-            "json-stringify-safe": "~5.0.1",
-            "mime-types": "~2.1.19",
-            "oauth-sign": "~0.9.0",
-            "performance-now": "^2.1.0",
-            "qs": "~6.5.2",
-            "safe-buffer": "^5.1.2",
-            "tough-cookie": "~2.4.3",
-            "tunnel-agent": "^0.6.0",
-            "uuid": "^3.3.2"
-          }
-        },
-        "require-directory": {
-          "version": "2.1.1",
-          "bundled": true
-        },
-        "require-main-filename": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "resolve-from": {
-          "version": "4.0.0",
-          "bundled": true
-        },
-        "retry": {
-          "version": "0.12.0",
-          "bundled": true
-        },
-        "rimraf": {
-          "version": "2.7.1",
-          "bundled": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "run-queue": {
-          "version": "1.0.3",
-          "bundled": true,
-          "requires": {
-            "aproba": "^1.1.1"
-          },
-          "dependencies": {
-            "aproba": {
-              "version": "1.2.0",
-              "bundled": true
-            }
-          }
-        },
-        "safe-buffer": {
-          "version": "5.1.2",
-          "bundled": true
-        },
-        "safer-buffer": {
-          "version": "2.1.2",
-          "bundled": true
-        },
-        "semver": {
-          "version": "5.7.1",
-          "bundled": true
-        },
-        "semver-diff": {
-          "version": "2.1.0",
-          "bundled": true,
-          "requires": {
-            "semver": "^5.0.3"
-          }
-        },
-        "set-blocking": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "sha": {
-          "version": "3.0.0",
-          "bundled": true,
-          "requires": {
-            "graceful-fs": "^4.1.2"
-          }
-        },
-        "shebang-command": {
-          "version": "1.2.0",
-          "bundled": true,
-          "requires": {
-            "shebang-regex": "^1.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "signal-exit": {
-          "version": "3.0.2",
-          "bundled": true
-        },
-        "slide": {
-          "version": "1.1.6",
-          "bundled": true
-        },
-        "smart-buffer": {
-          "version": "4.1.0",
-          "bundled": true
-        },
-        "socks": {
-          "version": "2.3.3",
-          "bundled": true,
-          "requires": {
-            "ip": "1.1.5",
-            "smart-buffer": "^4.1.0"
-          }
-        },
-        "socks-proxy-agent": {
-          "version": "4.0.2",
-          "bundled": true,
-          "requires": {
-            "agent-base": "~4.2.1",
-            "socks": "~2.3.2"
-          },
-          "dependencies": {
-            "agent-base": {
-              "version": "4.2.1",
-              "bundled": true,
-              "requires": {
-                "es6-promisify": "^5.0.0"
-              }
-            }
-          }
-        },
-        "sorted-object": {
-          "version": "2.0.1",
-          "bundled": true
-        },
-        "sorted-union-stream": {
-          "version": "2.1.3",
-          "bundled": true,
-          "requires": {
-            "from2": "^1.3.0",
-            "stream-iterate": "^1.1.0"
-          },
-          "dependencies": {
-            "from2": {
-              "version": "1.3.0",
-              "bundled": true,
-              "requires": {
-                "inherits": "~2.0.1",
-                "readable-stream": "~1.1.10"
-              }
-            },
-            "isarray": {
-              "version": "0.0.1",
-              "bundled": true
-            },
-            "readable-stream": {
-              "version": "1.1.14",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.1",
-                "isarray": "0.0.1",
-                "string_decoder": "~0.10.x"
-              }
-            },
-            "string_decoder": {
-              "version": "0.10.31",
-              "bundled": true
-            }
-          }
-        },
-        "spdx-correct": {
-          "version": "3.0.0",
-          "bundled": true,
-          "requires": {
-            "spdx-expression-parse": "^3.0.0",
-            "spdx-license-ids": "^3.0.0"
-          }
-        },
-        "spdx-exceptions": {
-          "version": "2.1.0",
-          "bundled": true
-        },
-        "spdx-expression-parse": {
-          "version": "3.0.0",
-          "bundled": true,
-          "requires": {
-            "spdx-exceptions": "^2.1.0",
-            "spdx-license-ids": "^3.0.0"
-          }
-        },
-        "spdx-license-ids": {
-          "version": "3.0.3",
-          "bundled": true
-        },
-        "split-on-first": {
-          "version": "1.1.0",
-          "bundled": true
-        },
-        "sshpk": {
-          "version": "1.14.2",
-          "bundled": true,
-          "requires": {
-            "asn1": "~0.2.3",
-            "assert-plus": "^1.0.0",
-            "bcrypt-pbkdf": "^1.0.0",
-            "dashdash": "^1.12.0",
-            "ecc-jsbn": "~0.1.1",
-            "getpass": "^0.1.1",
-            "jsbn": "~0.1.0",
-            "safer-buffer": "^2.0.2",
-            "tweetnacl": "~0.14.0"
-          }
-        },
-        "ssri": {
-          "version": "6.0.1",
-          "bundled": true,
-          "requires": {
-            "figgy-pudding": "^3.5.1"
-          }
-        },
-        "stream-each": {
-          "version": "1.2.2",
-          "bundled": true,
-          "requires": {
-            "end-of-stream": "^1.1.0",
-            "stream-shift": "^1.0.0"
-          }
-        },
-        "stream-iterate": {
-          "version": "1.2.0",
-          "bundled": true,
-          "requires": {
-            "readable-stream": "^2.1.5",
-            "stream-shift": "^1.0.0"
-          },
-          "dependencies": {
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "stream-shift": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "strict-uri-encode": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "string-width": {
-          "version": "2.1.1",
-          "bundled": true,
-          "requires": {
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^4.0.0"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "3.0.0",
-              "bundled": true
-            },
-            "is-fullwidth-code-point": {
-              "version": "2.0.0",
-              "bundled": true
-            },
-            "strip-ansi": {
-              "version": "4.0.0",
-              "bundled": true,
-              "requires": {
-                "ansi-regex": "^3.0.0"
-              }
-            }
-          }
-        },
-        "string_decoder": {
-          "version": "1.3.0",
-          "bundled": true,
-          "requires": {
-            "safe-buffer": "~5.2.0"
-          },
-          "dependencies": {
-            "safe-buffer": {
-              "version": "5.2.0",
-              "bundled": true
-            }
-          }
-        },
-        "stringify-package": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "bundled": true,
-          "requires": {
-            "ansi-regex": "^2.0.0"
-          }
-        },
-        "strip-eof": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "strip-json-comments": {
-          "version": "2.0.1",
-          "bundled": true
-        },
-        "supports-color": {
-          "version": "5.4.0",
-          "bundled": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        },
-        "tar": {
-          "version": "4.4.13",
-          "bundled": true,
-          "requires": {
-            "chownr": "^1.1.1",
-            "fs-minipass": "^1.2.5",
-            "minipass": "^2.8.6",
-            "minizlib": "^1.2.1",
-            "mkdirp": "^0.5.0",
-            "safe-buffer": "^5.1.2",
-            "yallist": "^3.0.3"
-          },
-          "dependencies": {
-            "minipass": {
-              "version": "2.9.0",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "^5.1.2",
-                "yallist": "^3.0.0"
-              }
-            }
-          }
-        },
-        "term-size": {
-          "version": "1.2.0",
-          "bundled": true,
-          "requires": {
-            "execa": "^0.7.0"
-          }
-        },
-        "text-table": {
-          "version": "0.2.0",
-          "bundled": true
-        },
-        "through": {
-          "version": "2.3.8",
-          "bundled": true
-        },
-        "through2": {
-          "version": "2.0.3",
-          "bundled": true,
-          "requires": {
-            "readable-stream": "^2.1.5",
-            "xtend": "~4.0.1"
-          },
-          "dependencies": {
-            "readable-stream": {
-              "version": "2.3.6",
-              "bundled": true,
-              "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
-              }
-            },
-            "string_decoder": {
-              "version": "1.1.1",
-              "bundled": true,
-              "requires": {
-                "safe-buffer": "~5.1.0"
-              }
-            }
-          }
-        },
-        "timed-out": {
-          "version": "4.0.1",
-          "bundled": true
-        },
-        "tiny-relative-date": {
-          "version": "1.3.0",
-          "bundled": true
-        },
-        "tough-cookie": {
-          "version": "2.4.3",
-          "bundled": true,
-          "requires": {
-            "psl": "^1.1.24",
-            "punycode": "^1.4.1"
-          }
-        },
-        "tunnel-agent": {
-          "version": "0.6.0",
-          "bundled": true,
-          "requires": {
-            "safe-buffer": "^5.0.1"
-          }
-        },
-        "tweetnacl": {
-          "version": "0.14.5",
-          "bundled": true,
-          "optional": true
-        },
-        "typedarray": {
-          "version": "0.0.6",
-          "bundled": true
-        },
-        "uid-number": {
-          "version": "0.0.6",
-          "bundled": true
-        },
-        "umask": {
-          "version": "1.1.0",
-          "bundled": true
-        },
-        "unique-filename": {
-          "version": "1.1.1",
-          "bundled": true,
-          "requires": {
-            "unique-slug": "^2.0.0"
-          }
-        },
-        "unique-slug": {
-          "version": "2.0.0",
-          "bundled": true,
-          "requires": {
-            "imurmurhash": "^0.1.4"
-          }
-        },
-        "unique-string": {
-          "version": "1.0.0",
-          "bundled": true,
-          "requires": {
-            "crypto-random-string": "^1.0.0"
-          }
-        },
-        "unpipe": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "unzip-response": {
-          "version": "2.0.1",
-          "bundled": true
-        },
-        "update-notifier": {
-          "version": "2.5.0",
-          "bundled": true,
-          "requires": {
-            "boxen": "^1.2.1",
-            "chalk": "^2.0.1",
-            "configstore": "^3.0.0",
-            "import-lazy": "^2.1.0",
-            "is-ci": "^1.0.10",
-            "is-installed-globally": "^0.1.0",
-            "is-npm": "^1.0.0",
-            "latest-version": "^3.0.0",
-            "semver-diff": "^2.0.0",
-            "xdg-basedir": "^3.0.0"
-          }
-        },
-        "url-parse-lax": {
-          "version": "1.0.0",
-          "bundled": true,
-          "requires": {
-            "prepend-http": "^1.0.1"
-          }
-        },
-        "util-deprecate": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "util-extend": {
-          "version": "1.0.3",
-          "bundled": true
-        },
-        "util-promisify": {
-          "version": "2.1.0",
-          "bundled": true,
-          "requires": {
-            "object.getownpropertydescriptors": "^2.0.3"
-          }
-        },
-        "uuid": {
-          "version": "3.3.3",
-          "bundled": true
-        },
-        "validate-npm-package-license": {
-          "version": "3.0.4",
-          "bundled": true,
-          "requires": {
-            "spdx-correct": "^3.0.0",
-            "spdx-expression-parse": "^3.0.0"
-          }
-        },
-        "validate-npm-package-name": {
-          "version": "3.0.0",
-          "bundled": true,
-          "requires": {
-            "builtins": "^1.0.3"
-          }
-        },
-        "verror": {
-          "version": "1.10.0",
-          "bundled": true,
-          "requires": {
-            "assert-plus": "^1.0.0",
-            "core-util-is": "1.0.2",
-            "extsprintf": "^1.2.0"
-          }
-        },
-        "wcwidth": {
-          "version": "1.0.1",
-          "bundled": true,
-          "requires": {
-            "defaults": "^1.0.3"
-          }
-        },
-        "which": {
-          "version": "1.3.1",
-          "bundled": true,
-          "requires": {
-            "isexe": "^2.0.0"
-          }
-        },
-        "which-module": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "wide-align": {
-          "version": "1.1.2",
-          "bundled": true,
-          "requires": {
-            "string-width": "^1.0.2"
-          },
-          "dependencies": {
-            "string-width": {
-              "version": "1.0.2",
-              "bundled": true,
-              "requires": {
-                "code-point-at": "^1.0.0",
-                "is-fullwidth-code-point": "^1.0.0",
-                "strip-ansi": "^3.0.0"
-              }
-            }
-          }
-        },
-        "widest-line": {
-          "version": "2.0.1",
-          "bundled": true,
-          "requires": {
-            "string-width": "^2.1.1"
-          }
-        },
-        "worker-farm": {
-          "version": "1.7.0",
-          "bundled": true,
-          "requires": {
-            "errno": "~0.1.7"
-          }
-        },
-        "wrap-ansi": {
-          "version": "2.1.0",
-          "bundled": true,
-          "requires": {
-            "string-width": "^1.0.1",
-            "strip-ansi": "^3.0.1"
-          },
-          "dependencies": {
-            "string-width": {
-              "version": "1.0.2",
-              "bundled": true,
-              "requires": {
-                "code-point-at": "^1.0.0",
-                "is-fullwidth-code-point": "^1.0.0",
-                "strip-ansi": "^3.0.0"
-              }
-            }
-          }
-        },
-        "wrappy": {
-          "version": "1.0.2",
-          "bundled": true
-        },
-        "write-file-atomic": {
-          "version": "2.4.3",
-          "bundled": true,
-          "requires": {
-            "graceful-fs": "^4.1.11",
-            "imurmurhash": "^0.1.4",
-            "signal-exit": "^3.0.2"
-          }
-        },
-        "xdg-basedir": {
-          "version": "3.0.0",
-          "bundled": true
-        },
-        "xtend": {
-          "version": "4.0.1",
-          "bundled": true
-        },
-        "y18n": {
-          "version": "4.0.0",
-          "bundled": true
-        },
-        "yallist": {
-          "version": "3.0.3",
-          "bundled": true
-        },
-        "yargs": {
-          "version": "11.1.1",
-          "bundled": true,
-          "requires": {
-            "cliui": "^4.0.0",
-            "decamelize": "^1.1.1",
-            "find-up": "^2.1.0",
-            "get-caller-file": "^1.0.1",
-            "os-locale": "^3.1.0",
-            "require-directory": "^2.1.1",
-            "require-main-filename": "^1.0.1",
-            "set-blocking": "^2.0.0",
-            "string-width": "^2.0.0",
-            "which-module": "^2.0.0",
-            "y18n": "^3.2.1",
-            "yargs-parser": "^9.0.2"
-          },
-          "dependencies": {
-            "y18n": {
-              "version": "3.2.1",
-              "bundled": true
-            }
-          }
-        },
-        "yargs-parser": {
-          "version": "9.0.2",
-          "bundled": true,
-          "requires": {
-            "camelcase": "^4.1.0"
-          }
-        }
-      }
-    },
     "npm-bundled": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
@@ -3907,6 +840,21 @@
         "yallist": "^3.0.3"
       }
     },
+    "topo": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz",
+      "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==",
+      "requires": {
+        "hoek": "6.x.x"
+      },
+      "dependencies": {
+        "hoek": {
+          "version": "6.1.3",
+          "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz",
+          "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ=="
+        }
+      }
+    },
     "tough-cookie": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@@ -3983,6 +931,16 @@
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
     },
+    "xml2json": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/xml2json/-/xml2json-0.12.0.tgz",
+      "integrity": "sha512-EPJHRWJnJUYbJlzR4pBhZODwWdi2IaYGtDdteJi0JpZ4OD31IplWALuit8r73dJuM4iHZdDVKY1tLqY2UICejg==",
+      "requires": {
+        "hoek": "^4.2.1",
+        "joi": "^13.1.2",
+        "node-expat": "^2.3.18"
+      }
+    },
     "yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
diff --git a/package.json b/package.json
index cad28d8..7979757 100644
--- a/package.json
+++ b/package.json
@@ -11,13 +11,13 @@
   "type": "module",
   "dependencies": {
     "fs": "0.0.1-security",
-    "mp4box": "^0.3.20",
     "node-fetch": "^2.6.0",
     "node-tvdb": "^4.1.0",
     "path": "^0.12.7",
     "pnormaldist": "^1.0.1",
     "sqlite3": "^4.1.1",
     "typescript": "^3.8.3",
-    "uuid": "^7.0.3"
+    "uuid": "^7.0.3",
+    "xml2json": "^0.12.0"
   }
 }
diff --git a/src/directory_walker.js b/src/directory_walker.js
index 5946b22..f96daa2 100644
--- a/src/directory_walker.js
+++ b/src/directory_walker.js
@@ -1,15 +1,16 @@
 import path from 'path';
 import {promises as fsPromises} from 'fs';
-import parseMediaInfo from "./util/video-mime";
 
 class FileManager {
     basePath;
+    videoMimeParser;
 
     moviesPath;
     showsPath;
 
-    constructor(basePath) {
+    constructor(basePath, videoMimeParser) {
         this.basePath = basePath;
+        this.videoMimeParser = videoMimeParser;
     }
 
     async updateConfiguration() {
@@ -32,7 +33,9 @@ class FileManager {
             .readdir(this.moviesPath, {withFileTypes: true})
             .then(result => result
                 .filter(dir => dir.isDirectory())
-                .map(dir => dir.name)
+                .map(dir => {
+                    return path.join(this.moviesPath, dir.name)
+                })
             );
     }
 
@@ -41,15 +44,28 @@ class FileManager {
             .readdir(this.showsPath, {withFileTypes: true})
             .then(result => result
                 .filter(dir => dir.isDirectory())
-                .map(dir => dir.name)
+                .map(dir => {
+                    return path.join(this.moviesPath, dir.name)
+                })
             );
     }
 
+    async findIds(filePath) {
+        return await fsPromises
+            .readFile(path.join(filePath, "metadata.json"))
+            .then(result => {
+                if (!result) return null;
+                const json = JSON.parse(result)
+                if (!json) return null;
+                return json.ids
+            }).catch(_ => null);
+    }
+
     async findMedia(base) {
         const files = await fsPromises
             .readdir(base, {withFileTypes: true})
             .then(result => result
-                .filter(dir => dir.isFile())
+                .filter(dir => !dir.isDirectory())
                 .map(dir => dir.name)
             );
 
@@ -57,13 +73,12 @@ class FileManager {
 
         const subtitleBase = path.join(base, "subtitles");
         const subtitleFiles = (await fsPromises
-            .readdir(subtitleBase, {withFileTypes: true})
-            .then(result => result
-                .filter(dir => dir.isFile())
-                .map(dir => dir.name)
-            ).catch(err => {
-                // Do nothing, just means file does not exist
-            })) || [];
+                .readdir(subtitleBase, {withFileTypes: true})
+                .then(result => result
+                    .filter(dir => dir.isFile())
+                    .map(dir => dir.name)
+                ).catch(_ => null)) // Do nothing, just means file does not exist
+            || [];
         const subtitles = subtitleFiles.filter(fileName =>
             fileName.endsWith(".srt") ||
             fileName.endsWith(".ttml") ||
@@ -71,12 +86,19 @@ class FileManager {
             fileName.endsWith(".vtt")
         )
 
-        const mediaFiles = dashManifest ? [] : files.filter(fileName =>
+        const mediaFiles = dashManifest ? [dashManifest] : files.filter(fileName =>
             fileName.endsWith(".mp4") ||
             fileName.endsWith(".webm") ||
             fileName.endsWith(".ogg")
         )
 
+        const media = await Promise.all(mediaFiles.map(fileName => this.videoMimeParser.parseMediaInfo(path.join(base, fileName)).then(metadata => {
+            return {
+                src: encodeURI(path.relative(this.basePath, path.join(base, fileName))),
+                ...metadata
+            }
+        })));
+
         return {
             subtitles: subtitles.map(name => {
                 const {language, region, specifier, format} = /^(?<language>\p{L}+)(?:-(?<region>\p{L}+))?(?:\.(?<specifier>.+))?\.(?<format>[^.]+)$/u.exec(name).groups;
@@ -85,18 +107,10 @@ class FileManager {
                     region: region,
                     specifier: specifier,
                     format: format,
-                    src: path.join("subtitles", name)
+                    src: encodeURI(path.relative(this.basePath, path.join(base, "subtitles", name)))
                 }
             }),
-            media: dashManifest ? [{
-                src: dashManifest,
-                container: "application/xml+dash"
-            }] : await Promise.all(mediaFiles.map(fileName => parseMediaInfo(path.join(base, fileName)).then(metadata => {
-                return {
-                    src: fileName,
-                    ...metadata
-                }
-            })))
+            media: media
         }
     }
 }
diff --git a/src/index.js b/src/index.js
index d3fc9e6..c69f990 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,7 @@
 import process from 'process';
 
 import path from 'path';
+import {promises as fsPromises} from 'fs';
 
 import ImdbApi from './api/imdb_api';
 import TmdbApi from './api/tmdb_api';
@@ -9,7 +10,7 @@ import FanartApi from './api/fanart_api';
 
 import MetadataLoader from "./metadata_loader";
 import FileManager from "./directory_walker";
-import parseMediaInfo from "./util/video-mime";
+import VideoMimeParser from "./util/video-mime";
 
 async function main() {
     const args = process.argv.slice(2);
@@ -21,55 +22,73 @@ async function main() {
     const tvdbApi = new TvdbApi(process.env.TVDB_API_KEY);
     const fanartApi = new FanartApi(process.env.FANART_API_KEY);
 
+    const videoMimeParser = new VideoMimeParser(process.env.MP4INFO_PATH || "mp4info", process.env.FFPROBE_PATH || "ffprobe");
     const loader = new MetadataLoader(imdbApi, tmdbApi, tvdbApi, fanartApi);
-    const fileManager = new FileManager(basePath);
+    const fileManager = new FileManager(basePath, videoMimeParser);
     await fileManager.updateConfiguration();
 
-    console.log(JSON.stringify(
-        await fileManager.findMedia(path.join(fileManager.moviesPath, "Avengers: Endgame (2019)")),
-        null, 2
-    ));
-    console.log(JSON.stringify(
-        await fileManager.findMedia(path.join(fileManager.showsPath, "Steins;Gate (2011)", "S01E01")),
-        null, 2
-    ));
-    console.log(JSON.stringify(
-        await parseMediaInfo(path.join(fileManager.showsPath, "Steins;Gate (2011)", "S01E01", "1080-fragment.mp4")),
-        null, 2
-    ));
-
-    /*
-    let directoryPath = args[0];
-    if (directoryPath) {
-        const showsPath = path.join(directoryPath, "Shows");
-        const moviesPath = path.join(directoryPath, "Movies");
-
-        if (fs.existsSync(showsPath)) {
-            const shows = await fs.promises.readdir(showsPath);
-            for (let fileName of shows) {
-                const filePath = path.join(showsPath, fileName);
-                try {
-                    console.log("Processing show ", filePath);
-                    loader.processFile(true, tmdbApi, fanartApi, imdb, tvdbApi, uuid.v4(), filePath);
-                } catch (e) {
-                    console.error(e);
-                }
-            }
-        }
-        if (fs.existsSync(moviesPath)) {
-            const movies = await fs.promises.readdir(moviesPath);
-            for (let fileName of movies) {
-                const filePath = path.join(moviesPath, fileName);
-                try {
-                    console.log("Processing movie ", filePath);
-                    loader.processFile(false, tmdbApi, fanartApi, imdb, tvdbApi, uuid.v4(), filePath);
-                } catch (e) {
-                    console.error(e);
-                }
-            }
-        }
+    async function processMovie(filePath) {
+        const {name, year} = /^(?<name>.+) \((?<year>\d+)\)$/.exec(path.basename(filePath)).groups;
+
+        const ids = (await fileManager.findIds(filePath)) || (await loader.identifyMovie(name, year));
+        const [media, {metadata, images}] = await Promise.all([
+            fileManager.findMedia(filePath),
+            loader.loadMetadata(ids),
+        ]);
+        const imageData = await loader.processImages(basePath, filePath, images);
+
+        await Promise.all([
+            fsPromises.writeFile(path.join(filePath, "ids.json"), JSON.stringify(ids, null, 2)),
+            fsPromises.writeFile(path.join(filePath, "metadata.json"), JSON.stringify({
+                ...metadata,
+                ...media,
+                images: imageData.map(img => {
+                    return {
+                        type: img.type,
+                        src: img.src,
+                    }
+                }),
+            }, null, 2)),
+        ]);
+    }
+
+    async function processEpisode(ids, episodeIdentifier, filePath) {
+        const episodeIds = loader.identifyEpisode(ids, episodeIdentifier);
+        const {episodeMetadata, _} = await loader.loadMetadata(episodeIds, true)
+
+        await Promise.all([
+            fsPromises.writeFile(path.join(filePath, "ids.json"), JSON.stringify(episodeIds, null, 2)),
+            fsPromises.writeFile(path.join(filePath, "metadata.json"), JSON.stringify(episodeMetadata, null, 2)),
+        ]);
     }
-     */
+
+    async function processShow(filePath) {
+        if (1) return;
+
+        const {name, year} = /^(?<name>.+) \((?<year>\d+)\)$/.exec(path.basename(filePath)).groups;
+        const ids = (await fileManager.findIds(filePath)) || (await loader.identifyShow(name, year));
+        const episodes = fileManager.findEpisodes(filePath);
+
+        const {metadata, rawImages} = await Promise.all([
+            loader.loadMetadata(ids)
+        ]);
+        const images = await loader.processImages(basePath, filePath, rawImages);
+        await Promise.all([
+            ...episodes.map(async ({episodeIdentifier, filePath}) => await processEpisode(ids, episodeIdentifier, filePath)),
+            fsPromises.writeFile(path.join(filePath, "ids.json"), JSON.stringify(ids, null, 2)),
+            fsPromises.writeFile(path.join(filePath, "metadata.json"), JSON.stringify({
+                ...metadata,
+                episodes: episodes,
+                images: images,
+            }, null, 2)),
+        ]);
+    }
+
+    const [movies, shows] = await Promise.all([fileManager.listMovies(), fileManager.listShows()]);
+    await Promise.all([
+        ...movies.map(processMovie),
+        ...shows.map(processShow)
+    ]);
 }
 
 (async function () {
diff --git a/src/metadata_loader.js b/src/metadata_loader.js
index 4130f2e..1151072 100644
--- a/src/metadata_loader.js
+++ b/src/metadata_loader.js
@@ -1,4 +1,7 @@
 import ranking_confidence from './util/statistics';
+import uuid from 'uuid';
+import path from "path";
+import downloadFile from "./util/download-file";
 
 class MetadataLoader {
     imdb;
@@ -79,21 +82,26 @@ class MetadataLoader {
                 return {
                     confidence: ranking_confidence(element.vote_average, element.vote_count),
                     lang_quality: containsText ? (
-                        element.iso_639_1 === originalLanguage ? 2 :
+                        element.iso_639_1 === originalLanguage ? 1.5 :
                         element.iso_639_1 === null ? 1 :
                         0
                     ) : (
-                        element.iso_639_1 === null ? 2 :
+                        element.iso_639_1 === null ? 1.5 :
                         element.iso_639_1 === originalLanguage ? 1 :
                         0
                     ),
+                    megapixels: (element.height * element.width) / 1000000,
                     ...element
                 }
             }
         }
 
         function imageComparator(a, b) {
-            return (b.lang_quality * 10 + b.confidence) - (a.lang_quality * 10 + a.confidence)
+            function rank(element) {
+                return element.lang_quality * (0.01 + element.confidence) * Math.sqrt(element.megapixels)
+            }
+
+            return rank(b) - rank(a)
         }
 
         return {
@@ -105,28 +113,75 @@ class MetadataLoader {
         }
     }
 
-    async loadMetadata(ids) {
+    async identifyMovie(title, year) {
+        const results = await this.tmdb.request(`search/movie`, {
+            query: title,
+            primary_release_year: year
+        }).catch((e) => console.error(e));
+
+        const result = results.results.sort((a, b) => {
+            return b.popularity - a.popularity;
+        })[0];
+
+        return result ? {
+            uuid: uuid.v4(),
+            tmdb: result.id,
+            imdb: (await this.tmdb.request(`movie/${result.id}`)).imdb_id
+        } : null;
+    }
+
+    async processImages(basePath, filePath, images) {
+        const imageData = !images ? [] : [
+            !images.logo ? null : !images.logo.url ? null : {
+                type: "logo",
+                url: images.logo.url,
+                src: encodeURI(path.relative(basePath, path.join(filePath, "metadata", `logo${path.extname(images.logo.url)}`)))
+            },
+            !images.poster ? null : !images.poster.file_path ? null : {
+                type: "poster",
+                url: this.tmdb.getImageUrl(images.poster.file_path),
+                src: encodeURI(path.relative(basePath, path.join(filePath, "metadata", `poster${path.extname(images.poster.file_path)}`)))
+            },
+            !images.backdrop ? null : !images.backdrop.file_path ? null : {
+                type: "backdrop",
+                url: this.tmdb.getImageUrl(images.backdrop.file_path),
+                src: encodeURI(path.relative(basePath, path.join(filePath, "metadata", `backdrop${path.extname(images.backdrop.file_path)}`)))
+            }
+        ].filter(el => el !== null);
+
+        await Promise.all(imageData.map(img => downloadFile(img.url, path.join(filePath, "metadata", img.type + path.extname(img.url)))))
+
+        return imageData;
+    }
+
+    async loadMetadata(ids, isEpisode) {
         const titleType = await this.imdb.findTypeById(ids.imdb);
-        const tmdbSources = titleType === "tvSeries" ?
-            [`tv/${ids.tmdb}`, `tv/${ids.tmdb}/content_ratings`, `tv/${ids.tmdb}/translations`, `tv/${ids.tmdb}/images`] :
-            [`movie/${ids.tmdb}`, `movie/${ids.tmdb}/release_dates`, `movie/${ids.tmdb}/translations`, `movie/${ids.tmdb}/images`]
+
+        function tmdbSources() {
+            if (titleType !== "tvSeries") {
+                return [`movie/${ids.tmdb}`, `movie/${ids.tmdb}/translations`, `movie/${ids.tmdb}/release_dates`, `movie/${ids.tmdb}/images`]
+            } else if (!isEpisode) {
+                return [`tv/${ids.tmdb}`, `tv/${ids.tmdb}/translations`, `tv/${ids.tmdb}/content_ratings`, `tv/${ids.tmdb}/images`]
+            } else {
+                return [`tv/${ids.tmdb}`, `tv/${ids.tmdb}/translations`]
+            }
+        }
+
         const fanartSource = titleType === "tvSeries" ?
             `tv/${ids.tmdb}` :
             `movies/${ids.tmdb}`;
 
-        const [imdbResult, tmdbResult, tmdbContentRatings, tmdbTranslations, tmdbImages, fanartImages] = await Promise.all([
-            this.imdb.findById(ids.imdb),
-            ...tmdbSources.map(url => this.tmdb.request(url)),
-            this.fanart.request(fanartSource).catch((e) => {
-                // do nothing, it just means it wasn’t found
-            })
-        ]);
+        const [imdbResult, tmdbResult, tmdbTranslations, tmdbContentRatings, tmdbImages, fanartImages] = await Promise.all([
+            this.imdb.findById(ids.imdb).catch(_ => null),
+            ...tmdbSources().map(url => this.tmdb.request(url).catch(_ => null)),
+            isEpisode ? null : this.fanart.request(fanartSource).catch(_ => null) // do nothing, it just means it wasn’t found
+        ].filter(el => el !== null));
 
         const metadata = this.transformData(ids, imdbResult, tmdbResult, tmdbContentRatings, tmdbTranslations);
         return {
             metadata: metadata,
             // also use tvdb for images
-            images: this.chooseImages(metadata.originalLanguage, tmdbImages, fanartImages),
+            images: isEpisode ? null : this.chooseImages(metadata.originalLanguage, tmdbImages, fanartImages),
         };
     }
 }
diff --git a/src/old_metadata_loader.js b/src/old_metadata_loader.js
index f13b2e3..5dd6f7d 100644
--- a/src/old_metadata_loader.js
+++ b/src/old_metadata_loader.js
@@ -58,28 +58,6 @@ function downloadImage(url, filePath) {
     }));
 }
 
-async function processSubtitles(filePath) {
-    const subtitlesPath = path.join(filePath, 'subtitles');
-    let subtitles;
-    if (fs.existsSync(subtitlesPath)) {
-        const files = await fs.promises.readdir(subtitlesPath);
-        subtitles = files.map((filename) => {
-            const match = /^(?<language>.+)(?<specifier>-.+)?\.(?<type>.*)$/.exec(path.basename(filename));
-            if (match) {
-                const {language, specifier, type} = match.groups;
-                return {
-                    language: language,
-                    specifier: specifier,
-                    type: type,
-                }
-            } else {
-                return null;
-            }
-        }).filter(el => el);
-    }
-    return subtitles;
-}
-
 async function processFile(isShow, tmdbApi, fanartApi, imdb, tvdbApi, uuid, filePath) {
     const {name, year} = /^(?<name>.+) \((?<year>\d+)\)$/.exec(path.basename(filePath)).groups;
 
diff --git a/src/util/download-file.js b/src/util/download-file.js
new file mode 100644
index 0000000..5207943
--- /dev/null
+++ b/src/util/download-file.js
@@ -0,0 +1,25 @@
+import fs from 'fs';
+import path from 'path';
+import https from 'https';
+
+function downloadFile(url, filePath) {
+    return new Promise(((resolve, reject) => {
+        fs.mkdirSync(path.dirname(filePath), {recursive: true})
+        const file = fs.createWriteStream(filePath);
+        https.get(url, function (response) {
+            response.pipe(file);
+            file.on('close', function () {
+                resolve();
+            })
+            file.on('finish', function () {
+                file.close()
+            });
+        }).on('error', function (err) {
+            fs.unlink(filePath, function () {
+                reject(err);
+            });
+        });
+    }));
+}
+
+export default downloadFile;
\ No newline at end of file
diff --git a/src/util/statistics.js b/src/util/statistics.js
index fdeed21..39a92d1 100644
--- a/src/util/statistics.js
+++ b/src/util/statistics.js
@@ -1,6 +1,6 @@
 import pnormaldist from 'pnormaldist';
 
-const DEFAULT_CONFIDENCE = 0.95;
+const DEFAULT_CONFIDENCE = 0.9;
 
 function ranking_confidence(value, n, confidence) {
     if (n === 0) return 0;
diff --git a/src/util/video-mime.js b/src/util/video-mime.js
index 24021db..7a42433 100644
--- a/src/util/video-mime.js
+++ b/src/util/video-mime.js
@@ -1,93 +1,90 @@
-import fs from 'fs';
+import fs, {promises as fsPromises} from 'fs';
 import path from 'path';
-import {exec} from "child_process";
-import MP4Box from 'mp4box';
+import xml2json from 'xml2json';
+import {exec} from 'child_process';
 import promisify from "./promisify";
 
-async function parseMediaInfoWebm(filePath) {
-    const [stdout] = await promisify(exec, `ffprobe -print_format json -show_format -show_streams -bitexact "${filePath}"`);
-    return JSON.parse(stdout);
-}
+class VideoMimeParser {
+    mp4boxPath;
+    ffprobePath;
 
-function processMediaInfoWebm(info) {
-    console.log(JSON.stringify(info, null, 2));
-    return {
-        container: "video/webm",
-        tracks: {
-            video: info.streams.filter(track => track.codec_type === "video").map(track => {
-                return {
-                    // FIXME: this is broken thanks to ffmpeg
-                    codec: `${track.codec_name}.${track.profile}.${track.level}.`
-                }
-            }),
-            audio: info.streams.filter(track => track.codec_type === "audio").map(track => {
-                return {
+    constructor(mp4boxPath, ffprobePath) {
+        this.mp4boxPath = mp4boxPath;
+        this.ffprobePath = ffprobePath;
+    }
 
+    async parseMediaInfoDash(filePath) {
+        const info = xml2json.toJson(await fsPromises.readFile(filePath), {object: true});
+        return {
+            container: "application/xml+dash",
+            tracks: info.MPD.Period.AdaptationSet.map((track, i) => {
+                return {
+                    id: i,
+                    type: track.mimeType.substr(0, track.mimeType.indexOf('/')),
+                    codec: [...new Set(track.Representation.map(r => r.codecs))].join(","),
+                    bitrate: track.Representation.map(r => r.bandwidth).sort()[0],
+                    language: track.lang
                 }
             })
-        }
-    };
-}
-
-function parseMediaInfoMp4(filePath) {
-    return new Promise((resolve, reject) => {
-        const mp4boxfile = MP4Box.createFile(); /* eslint-disable-line new-cap */
-        const stream = fs.createReadStream(filePath);
-
-        mp4boxfile.onReady = (info) => {
-            resolve(info);
-            stream.close();
         };
+    }
 
-        mp4boxfile.onError = err => stream.destroy(err);
-
-        let offset = 0;
-        stream.on('data', function (chunk) {
-            var arrayBuffer = new Uint8Array(chunk).buffer;
-            arrayBuffer.fileStart = offset;
-            offset += chunk.byteLength;
-            mp4boxfile.appendBuffer(arrayBuffer);
-        });
-        stream.on('error', reject);
-        stream.on('end', () => reject(new Error('Invalid file type.')));
-    });
-}
-
-function processMediaInfoMp4(info) {
-    return {
-        container: "video/mp4",
-        duration: info.duration,
-        tracks: {
-            video: info.videoTracks.map(track => {
+    async parseMediaInfoWebm(filePath) {
+        const [stdout] = await exec(`${this.ffprobePath} -print_format json -show_format -show_streams -bitexact -- "${filePath}"`)
+        const info = JSON.parse(stdout);
+        return {
+            container: "video/webm",
+            duration: +info.format.duration,
+            tracks: info.streams.filter(track => ["audio", "video"].includes(track.codec_type.toLowerCase())).map(track => {
                 return {
-                    id: track.id,
-                    bitrate: Math.round(track.bitrate),
-                    language: track.language,
-                    codec: track.codec,
+                    id: track.index,
+                    type: track.type.toLowerCase(),
+                    codecs: [
+                        track.codec_name
+                    ],
+                    language: null,
                 }
-            }),
-            audio: info.audioTracks.map(track => {
+            })
+        };
+    }
+
+    async parseMediaInfoMp4(filePath) {
+        const [stdout] = await promisify(exec, `${this.mp4boxPath} --format json "${filePath}"`);
+        const info = JSON.parse(stdout.replace(/,\s*([\]}])/g, "$1"));
+        return {
+            container: "video/mp4",
+            duration: +info.movie.duration,
+            tracks: info.tracks.filter(track => ["audio", "video"].includes(track.type.toLowerCase())).map(track => {
                 return {
                     id: track.id,
-                    bitrate: Math.round(track.bitrate),
-                    language: track.language,
-                    codec: track.codec,
+                    type: track.type.toLowerCase(),
+                    codecs: [
+                        track.sample_descriptions[0].codecs_string
+                    ],
+                    language: track.language === "und" ? null : track.language,
                 }
             })
-        }
+        };
     }
-}
 
-async function parseMediaInfo(filePath) {
-    switch (path.extname(filePath)) {
-        case '.mp4':
-            return processMediaInfoMp4(await parseMediaInfoMp4(filePath));
-        case '.webm':
-            return processMediaInfoWebm(await parseMediaInfoWebm(filePath));
-        default:
-            console.error(`Invalid extension: ${path.extname(filePath)} for path ${filePath}`)
-            return null;
+    async parseMediaInfo(filePath) {
+        switch (path.extname(filePath)) {
+            case '.mpd':
+                return await this.parseMediaInfoDash(filePath);
+            case '.mp4':
+            case '.mp4v':
+            case '.mp4a':
+            case '.mv4':
+            case '.m4a':
+            case '.m4b':
+                return await this.parseMediaInfoMp4(filePath);
+            case '.webm':
+                return await this.parseMediaInfoWebm(filePath);
+            default:
+                console.error(`Invalid extension: ${path.extname(filePath)} for path ${filePath}`)
+                return null;
+        }
     }
 }
 
-export default parseMediaInfo
\ No newline at end of file
+export default VideoMimeParser
\ No newline at end of file
-- 
GitLab