From a55501d51d4b9733c827b246c60472bd6d902dbd Mon Sep 17 00:00:00 2001 From: Hans Otto Wirtz Date: Sat, 7 Dec 2019 23:18:15 +0100 Subject: [PATCH 1/4] Add webpack, raw-loader, typescript --- .editorconfig | 7 + .gitignore | 1 + dist/content_script.js | 623 +---- dist/manifest.json | 9 +- dist/subadub.css | 3 + package-lock.json | 4736 +++++++++++++++++++++++++++++++++++++ package.json | 30 + res/icon128.png | Bin 0 -> 4425 bytes res/icon16.png | Bin 0 -> 575 bytes res/icon48.png | Bin 0 -> 1583 bytes res/manifest.json | 23 + src/content_script.ts | 16 + src/subadub.css | 3 + src/subadub.ts | 475 ++++ src/types/raw-loader.d.ts | 4 + tsconfig.json | 15 + webpack.config.js | 35 + 17 files changed, 5473 insertions(+), 507 deletions(-) create mode 100644 .editorconfig create mode 100644 dist/subadub.css create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 res/icon128.png create mode 100644 res/icon16.png create mode 100644 res/icon48.png create mode 100644 res/manifest.json create mode 100644 src/content_script.ts create mode 100644 src/subadub.css create mode 100644 src/subadub.ts create mode 100644 src/types/raw-loader.d.ts create mode 100644 tsconfig.json create mode 100644 webpack.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0a51807 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/.gitignore b/.gitignore index e43b0f9..646ac51 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +node_modules/ diff --git a/dist/content_script.js b/dist/content_script.js index a305770..77162bb 100644 --- a/dist/content_script.js +++ b/dist/content_script.js @@ -1,509 +1,122 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const subadub_1 = __importDefault(__webpack_require__(1)); +(() => { + const styleElem = document.createElement('link'); + styleElem.type = 'text/css'; + styleElem.rel = 'stylesheet'; + styleElem.id = 'subadub-style'; + styleElem.href = chrome.runtime.getURL("subadub.css"); + document.head.insertBefore(styleElem, document.head.firstChild); + const scriptElem = document.createElement('script'); + scriptElem.type = 'text/javascript'; + scriptElem.id = 'subadub-script'; + scriptElem.innerHTML = subadub_1.default; + document.head.insertBefore(scriptElem, document.head.firstChild); +})(); -// console.log('content script starting'); - -const styleElem = document.createElement('style'); -styleElem.type = 'text/css'; -styleElem.textContent = ` -`; -document.head.insertBefore(styleElem, document.head.firstChild); - - -const scriptElem = document.createElement('script'); -scriptElem.text = ` -(function initializeSubadub() { - const POLL_INTERVAL_MS = 500; - const WEBVTT_FMT = 'webvtt-lssdh-ios8'; - const URL_MOVIEID_REGEX = RegExp('/watch/([0-9]+)'); - - const SUBS_LIST_ELEM_ID = 'subadub-subs-list'; - const TOGGLE_DISPLAY_BUTTON_ID = 'subadub-toggle-display'; - const TRACK_ELEM_ID = 'subadub-track'; - const DOWNLOAD_BUTTON_ID = 'subadub-download'; - const CUSTOM_SUBS_ELEM_ID = 'subadub-custom-subs'; - - const trackListCache = new Map(); // from movie ID to list of available tracks - const webvttCache = new Map(); // from 'movieID/trackID' to blob - let urlMovieId; - let selectedTrackId; - let showSubsState = true; - - let targetSubsList = null; - let displayedSubsList = null; - - let targetTrackBlob = null; - let displayedTrackBlob = null; - - // Convert WebVTT text to plain text plus "simple" tags (allowed in SRT) - const TAG_REGEX = RegExp(']*)>', 'ig'); - function vttTextToSimple(s, netflixRTLFix) { - let simpleText = s; - - // strip tags except simple ones - simpleText = simpleText.replace(TAG_REGEX, function (match, p1) { - return ['i', 'u', 'b'].includes(p1.toLowerCase()) ? match : ''; - }); - - if (netflixRTLFix) { - // For each line, if it starts with lrm or rlm escape, wrap in LRE/RLE/PDF pair. - // This is weird, but needed for compatibility with Netflix. See issue #1. - const lines = simpleText.split('\\n'); - const newLines = []; - for (const line of lines) { - if (line.startsWith('‎')) { - newLines.push('\u202a' + line.slice(5) + '\u202c'); - } else if (line.startsWith('‏')) { - newLines.push('\u202b' + line.slice(5) + '\u202c'); - } else { - newLines.push(line); - } - } - simpleText = newLines.join('\\n'); - } - - return simpleText; - } - - function extractMovieTextTracks(movieObj) { - const movieId = movieObj.movieId; - - const usableTracks = []; - // console.log('timedtexttracks', movieObj.timedtexttracks); - for (const track of movieObj.timedtexttracks) { - if (track.isForcedNarrative || track.isNoneTrack) { - continue; // don't want these - } - - if (!track.cdnlist || !track.cdnlist.length) { - continue; - } - const firstCdnId = track.cdnlist[0].id; - - if (!track.ttDownloadables) { - continue; - } - - const webvttDL = track.ttDownloadables[WEBVTT_FMT]; - if (!webvttDL || !webvttDL.downloadUrls) { - continue; - } - - const bestUrl = webvttDL.downloadUrls[firstCdnId]; - if (!bestUrl) { - continue; - } - - const isClosedCaptions = track.rawTrackType === 'closedcaptions'; - - usableTracks.push({ - id: track.new_track_id, - language: track.language, - languageDescription: track.languageDescription, - bestUrl: bestUrl, - isClosedCaptions: isClosedCaptions, - }); - } - - // console.log('CACHING MOVIE TRACKS', movieId, usableTracks); - trackListCache.set(movieId, usableTracks); - renderAndReconcile(); - } - - function getSelectedTrackInfo() { - if (!urlMovieId || !selectedTrackId) { - throw new Error('Internal error, getSelectedTrackInfo called but urlMovieId or selectedTrackId is null'); - } - const trackList = trackListCache.get(urlMovieId); - const matchingTracks = trackList.filter(el => el.id === selectedTrackId); - if (matchingTracks.length !== 1) { - throw new Error('internal error, no matching track id'); - } - return matchingTracks[0]; - } - - function handleSubsListSetOrChange(selectElem) { - const trackId = selectElem.value; - // console.log('selecting track', trackId); - - selectedTrackId = trackId; - - if (!selectedTrackId) { - return; - } - - const cacheKey = urlMovieId + '/' + selectedTrackId; - if (!webvttCache.has(cacheKey)) { - const trackInfo = getSelectedTrackInfo(); - const url = trackInfo.bestUrl; - - fetch(url).then(function(response) { - if (response.ok) { - return response.blob(); - } - throw new Error('Bad response to WebVTT request'); - }).then(function(blob) { - webvttCache.set(cacheKey, new Blob([blob], {type: 'text/vtt'})); // set type to avoid warning - renderAndReconcile(); - }).catch(function(error) { - console.error('Failed to fetch WebVTT file', error.message); - }); - } - - // NOTE: We don't call renderAndReconcile here, caller should do it to avoid recursive loop bug - } - - function enableDownloadButton() { - const downloadButtonElem = document.getElementById(DOWNLOAD_BUTTON_ID); - if (downloadButtonElem) { - downloadButtonElem.style.color = 'black'; - downloadButtonElem.disabled = false; - } - } - - function disableDownloadButton() { - const downloadButtonElem = document.getElementById(DOWNLOAD_BUTTON_ID); - if (downloadButtonElem) { - downloadButtonElem.style.color = 'grey'; - downloadButtonElem.disabled = true; - } - } - - function downloadSRT() { - function formatTime(t) { - const date = new Date(0, 0, 0, 0, 0, 0, t*1000); - const hours = date.getHours().toString().padStart(2, '0'); - const minutes = date.getMinutes().toString().padStart(2, '0'); - const seconds = date.getSeconds().toString().padStart(2, '0'); - const ms = date.getMilliseconds().toString().padStart(3, '0'); - - return hours + ':' + minutes + ':' + seconds + ',' + ms; - } - - const trackElem = document.getElementById(TRACK_ELEM_ID); - if (!trackElem || !trackElem.track || !trackElem.track.cues) { - return; - } - - // Figure out video title - const srtFilenamePieces = []; - for (const elem of document.querySelectorAll('.video-title *')) { - if (!elem.firstElementChild && elem.textContent) { // only get 'leaf' elements with text - srtFilenamePieces.push(elem.textContent); - } - } - let srcFilename; - if (srtFilenamePieces.length) { - srtFilename = srtFilenamePieces.join('-'); - } else { - srtFilename = urlMovieId.toString(); // fallback in case UI changes - } - srtFilename += '_' + trackElem.track.language; // append language code - srtFilename += '.srt'; - - const srtChunks = []; - let idx = 1; - for (const cue of trackElem.track.cues) { - const cleanedText = vttTextToSimple(cue.text, true); - srtChunks.push(idx + '\\n' + formatTime(cue.startTime) + ' --> ' + formatTime(cue.endTime) + '\\n' + cleanedText + '\\n\\n'); - idx++; - } - - const srtBlob = new Blob(srtChunks, { type: 'text/srt' }); - const srtUrl = URL.createObjectURL(srtBlob); - - const tmpElem = document.createElement('a'); - tmpElem.setAttribute('href', srtUrl); - tmpElem.setAttribute('download', srtFilename); - tmpElem.style.display = 'none'; - document.body.appendChild(tmpElem); - tmpElem.click(); - document.body.removeChild(tmpElem); - } - - function updateToggleDisplay() { - const buttomElem = document.getElementById(TOGGLE_DISPLAY_BUTTON_ID); - if (buttomElem) { - if (showSubsState) { - buttomElem.textContent = 'Hide Subs [S]'; - } else { - buttomElem.textContent = 'Show Subs [S]'; - } - } - const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID); - if (subsElem) { - if (showSubsState) { - subsElem.style.visibility = 'visible'; - } else { - subsElem.style.visibility = 'hidden'; - } - } - } - - function renderAndReconcile() { - function addSubsList(tracks) { - const toggleDisplayButtonElem = document.createElement('button'); - toggleDisplayButtonElem.id = TOGGLE_DISPLAY_BUTTON_ID; - toggleDisplayButtonElem.style.cssText = 'margin: 5px; border: none; color: black; width: 8em'; - toggleDisplayButtonElem.addEventListener('click', function(e) { - e.preventDefault(); - showSubsState = !showSubsState; - updateToggleDisplay(); - }, false); - - const selectElem = document.createElement('select'); - selectElem.style.cssText = 'color: black; margin: 5px'; - selectElem.addEventListener('change', function(e) { - handleSubsListSetOrChange(e.target); - renderAndReconcile(); - }, false); - - let firstCCTrackId; - for (const track of tracks) { - const optElem = document.createElement('option'); - optElem.value = track.id; - optElem.textContent = track.languageDescription + (track.isClosedCaptions ? ' [CC]' : ''); - selectElem.appendChild(optElem); - - if (track.isClosedCaptions && !firstCCTrackId) { - firstCCTrackId = track.id; - } - } - if (firstCCTrackId) { - selectElem.value = firstCCTrackId; - } - - const downloadButtonElem = document.createElement('button'); - downloadButtonElem.id = DOWNLOAD_BUTTON_ID; - downloadButtonElem.textContent = 'Download SRT'; - downloadButtonElem.style.cssText = 'margin: 5px; border: none'; - downloadButtonElem.addEventListener('click', function(e) { - e.preventDefault(); - // console.log('download click'); - downloadSRT(); - }, false); - - const panelElem = document.createElement('div'); - panelElem.style.cssText = 'position: absolute; z-index: 1000; top: 0; right: 0; font-size: 16px; color: white'; - panelElem.appendChild(toggleDisplayButtonElem); - panelElem.appendChild(selectElem); - panelElem.appendChild(downloadButtonElem); - - const containerElem = document.createElement('div'); - containerElem.id = SUBS_LIST_ELEM_ID; - containerElem.style.cssText = 'width: 100%; height: 100%; position: absolute; top: 0; right: 0; bottom: 0; left: 0'; - containerElem.appendChild(panelElem); - - document.body.appendChild(containerElem); - - updateToggleDisplay(); - disableDownloadButton(); - - handleSubsListSetOrChange(selectElem); - } - - function removeSubsList() { - const el = document.getElementById(SUBS_LIST_ELEM_ID); - if (el) { - el.remove(); - } - } - - function addTrackElem(videoElem, blob, srclang) { - const trackElem = document.createElement('track'); - trackElem.id = TRACK_ELEM_ID; - trackElem.src = URL.createObjectURL(blob); - trackElem.kind = 'subtitles'; - trackElem.default = true; - trackElem.srclang = srclang; - videoElem.appendChild(trackElem); - trackElem.track.mode = 'hidden'; // this can only be set after appending - - trackElem.addEventListener('load', function() { - enableDownloadButton(); - }, false); - - const customSubsElem = document.createElement('div'); - customSubsElem.id = CUSTOM_SUBS_ELEM_ID; - customSubsElem.style.cssText = 'position: absolute; bottom: 20vh; left: 0; right: 0; color: white; font-size: 3vw; text-align: center; user-select: text; -moz-user-select: text; z-index: 100; pointer-events: none'; - - trackElem.addEventListener('cuechange', function(e) { - // Remove all children - while (customSubsElem.firstChild) { - customSubsElem.removeChild(customSubsElem.firstChild); - } - - const track = e.target.track; - // console.log('active now', track.activeCues); - for (const cue of track.activeCues) { - const cueElem = document.createElement('div'); - cueElem.style.cssText = 'background: rgba(0,0,0,0.8); white-space: pre-wrap; padding: 0.2em 0.3em; margin: 10px auto; width: fit-content; width: -moz-fit-content; pointer-events: auto'; - cueElem.innerHTML = vttTextToSimple(cue.text, true); // may contain simple tags like etc. - customSubsElem.appendChild(cueElem); - } - }, false); - - // Appending this to the player rather than the document fixes some issues: - // 1) Clicking on subtitle text doesn't take focus (keyboard events) away from player - // 2) Hover on subtitle prevents the "sleep" title screen from coming up, which is nice - const playerElem = document.querySelector('.NFPlayer'); - if (!playerElem) { - throw new Error("Couldn't find player element to append subtitles to"); - } - playerElem.appendChild(customSubsElem); - - updateToggleDisplay(); - } - - function removeTrackElem() { - const trackElem = document.getElementById(TRACK_ELEM_ID); - if (trackElem) { - trackElem.remove(); - } - - const customSubsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID); - if (customSubsElem) { - customSubsElem.remove(); - } - - disableDownloadButton(); - } - - // Determine what subs list should be - if (urlMovieId && (document.readyState === 'complete') && trackListCache.has(urlMovieId)) { - targetSubsList = trackListCache.get(urlMovieId); - } else { - targetSubsList = null; - } - - // Reconcile DOM if necessary - if (targetSubsList !== displayedSubsList) { - // console.log('updating subs list DOM', targetSubsList, displayedSubsList); - - removeSubsList(); - if (targetSubsList) { - addSubsList(targetSubsList); - } - - displayedSubsList = targetSubsList; - } - - // Determine what subs blob should be - const videoElem = document.querySelector('video'); - if (urlMovieId && selectedTrackId && videoElem) { - const cacheKey = urlMovieId + '/' + selectedTrackId; - if (webvttCache.has(cacheKey)) { - targetTrackBlob = webvttCache.get(cacheKey); - } else { - targetTrackBlob = null; - } - } else { - targetTrackBlob = null; - } - - // Reconcile DOM if necessary - if (targetTrackBlob !== displayedTrackBlob) { - // console.log('need to update track blob', targetTrackBlob, displayedTrackBlob); - - removeTrackElem(); - if (targetTrackBlob) { - // NOTE: super hacky to get the language code this way - const languageCode = getSelectedTrackInfo().language; - addTrackElem(videoElem, targetTrackBlob, languageCode); - } - - displayedTrackBlob = targetTrackBlob; - } - } - - const originalStringify = JSON.stringify; - JSON.stringify = function(value) { - if (value && value.params && value.params.profiles) { - value.params.profiles.unshift(WEBVTT_FMT); - // console.log('stringify', value); - } - if (value && value.ab && value.ab.profiles) { - value.ab.profiles.unshift(WEBVTT_FMT); - } - return originalStringify.apply(this, arguments); - }; - - const originalParse = JSON.parse; - JSON.parse = function() { - const value = originalParse.apply(this, arguments); - if (value && value.result && value.result.movieId && value.result.timedtexttracks) { - // console.log('parse', value); - extractMovieTextTracks(value.result); - } - return value; - } - - // Poll periodically to see if current movie has changed - setInterval(function() { - const movieIdMatch = URL_MOVIEID_REGEX.exec(window.location.pathname); - let movieId; - if (movieIdMatch) { - movieId = +movieIdMatch[1]; - } - urlMovieId = movieId; - if (!urlMovieId) { - selectedTrackId = null; - } - - renderAndReconcile(); - }, POLL_INTERVAL_MS); - - document.body.addEventListener('keydown', function(e) { - if ((e.keyCode === 67) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified C key - // console.log('copying subs text to clipboard'); - const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID); - if (subsElem) { - const pieces = []; - for (child of [...subsElem.children]) { - pieces.push(child.textContent); // copy as plain text - } - const text = pieces.join('\\n'); - navigator.clipboard.writeText(text); - } - } else if ((e.keyCode === 83) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified S key - const el = document.getElementById(TOGGLE_DISPLAY_BUTTON_ID); - if (el) { - el.click(); - } - } - }, false); - - let hideSubsListTimeout; - function hideSubsListTimerFunc() { - const el = document.getElementById(SUBS_LIST_ELEM_ID); - if (el) { - el.style.display = 'none'; - } - hideSubsListTimeout = null; - } - document.body.addEventListener('mousemove', function(e) { - // If there are any popups, make sure our subs don't block mouse events - const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID); - if (subsElem) { - const popup = document.querySelector('.popup-content'); - if (popup) { - subsElem.style.display = 'none'; - } else { - subsElem.style.display = 'block'; - } - } +/***/ }), +/* 1 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - // Show subs list and update timer to hide it - const subsListElem = document.getElementById(SUBS_LIST_ELEM_ID); - if (subsListElem) { - subsListElem.style.display = 'block'; - } - if (hideSubsListTimeout) { - clearTimeout(hideSubsListTimeout); - } - hideSubsListTimeout = setTimeout(hideSubsListTimerFunc, 3000); - }, false); -})(); -`; -document.head.insertBefore(scriptElem, document.head.firstChild); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ("function initializeSubadub() {\n console.info('Initializing Subadub');\n const POLL_INTERVAL_MS = 500;\n const WEBVTT_FMT = 'webvtt-lssdh-ios8';\n const URL_MOVIEID_REGEX = RegExp('/watch/([0-9]+)');\n const SUBS_LIST_ELEM_ID = 'subadub-subs-list';\n const TOGGLE_DISPLAY_BUTTON_ID = 'subadub-toggle-display';\n const TRACK_ELEM_ID = 'subadub-track';\n const DOWNLOAD_BUTTON_ID = 'subadub-download';\n const CUSTOM_SUBS_ELEM_ID = 'subadub-custom-subs';\n const trackListCache = new Map(); // from movie ID to list of available tracks\n const webvttCache = new Map(); // from 'movieID/trackID' to blob\n let urlMovieId;\n let selectedTrackId;\n let showSubsState = true;\n let targetSubsList = null;\n let displayedSubsList = null;\n let targetTrackBlob = null;\n let displayedTrackBlob = null;\n // Convert WebVTT text to plain text plus \"simple\" tags (allowed in SRT)\n const TAG_REGEX = RegExp(']*)>', 'ig');\n function vttTextToSimple(s, netflixRTLFix) {\n let simpleText = s;\n // strip tags except simple ones\n simpleText = simpleText.replace(TAG_REGEX, function (match, p1) {\n return ['i', 'u', 'b'].includes(p1.toLowerCase()) ? match : '';\n });\n if (netflixRTLFix) {\n // For each line, if it starts with lrm or rlm escape, wrap in LRE/RLE/PDF pair.\n // This is weird, but needed for compatibility with Netflix. See issue #1.\n const lines = simpleText.split('\\\\n');\n const newLines = [];\n for (const line of lines) {\n if (line.startsWith('‎')) {\n newLines.push('\\u202a' + line.slice(5) + '\\u202c');\n }\n else if (line.startsWith('‏')) {\n newLines.push('\\u202b' + line.slice(5) + '\\u202c');\n }\n else {\n newLines.push(line);\n }\n }\n simpleText = newLines.join('\\\\n');\n }\n return simpleText;\n }\n function extractMovieTextTracks(movieObj) {\n const movieId = movieObj.movieId;\n const usableTracks = [];\n console.log('timedtexttracks', movieObj.timedtexttracks);\n for (const track of movieObj.timedtexttracks) {\n if (track.isForcedNarrative || track.isNoneTrack) {\n continue; // don't want these\n }\n if (!track.cdnlist || !track.cdnlist.length) {\n continue;\n }\n const firstCdnId = track.cdnlist[0].id;\n if (!track.ttDownloadables) {\n continue;\n }\n const webvttDL = track.ttDownloadables[WEBVTT_FMT];\n if (!webvttDL || !webvttDL.downloadUrls) {\n continue;\n }\n const bestUrl = webvttDL.downloadUrls[firstCdnId];\n if (!bestUrl) {\n continue;\n }\n const isClosedCaptions = track.rawTrackType === 'closedcaptions';\n usableTracks.push({\n id: track.new_track_id,\n language: track.language,\n languageDescription: track.languageDescription,\n bestUrl: bestUrl,\n isClosedCaptions: isClosedCaptions,\n });\n }\n console.log('CACHING MOVIE TRACKS', movieId, usableTracks);\n trackListCache.set(movieId, usableTracks);\n renderAndReconcile();\n }\n function getSelectedTrackInfo() {\n if (!urlMovieId || !selectedTrackId) {\n throw new Error('Internal error, getSelectedTrackInfo called but urlMovieId or selectedTrackId is null');\n }\n const trackList = trackListCache.get(urlMovieId);\n const matchingTracks = trackList.filter(el => el.id === selectedTrackId);\n if (matchingTracks.length !== 1) {\n throw new Error('internal error, no matching track id');\n }\n return matchingTracks[0];\n }\n function handleSubsListSetOrChange(selectElem) {\n const trackId = selectElem.value;\n console.log('selecting track', trackId);\n selectedTrackId = trackId;\n if (!selectedTrackId) {\n return;\n }\n const cacheKey = urlMovieId + '/' + selectedTrackId;\n if (!webvttCache.has(cacheKey)) {\n const trackInfo = getSelectedTrackInfo();\n const url = trackInfo.bestUrl;\n fetch(url).then(function (response) {\n if (response.ok) {\n return response.blob();\n }\n throw new Error('Bad response to WebVTT request');\n }).then(function (blob) {\n webvttCache.set(cacheKey, new Blob([blob], { type: 'text/vtt' })); // set type to avoid warning\n renderAndReconcile();\n }).catch(function (error) {\n console.error('Failed to fetch WebVTT file', error.message);\n });\n }\n // NOTE: We don't call renderAndReconcile here, caller should do it to avoid recursive loop bug\n }\n function enableDownloadButton() {\n const downloadButtonElem = document.getElementById(DOWNLOAD_BUTTON_ID);\n if (downloadButtonElem) {\n downloadButtonElem.style.color = 'black';\n downloadButtonElem.disabled = false;\n }\n }\n function disableDownloadButton() {\n const downloadButtonElem = document.getElementById(DOWNLOAD_BUTTON_ID);\n if (downloadButtonElem) {\n downloadButtonElem.style.color = 'grey';\n downloadButtonElem.disabled = true;\n }\n }\n function downloadSRT() {\n function formatTime(t) {\n const date = new Date(0, 0, 0, 0, 0, 0, t * 1000);\n const hours = date.getHours().toString().padStart(2, '0');\n const minutes = date.getMinutes().toString().padStart(2, '0');\n const seconds = date.getSeconds().toString().padStart(2, '0');\n const ms = date.getMilliseconds().toString().padStart(3, '0');\n return hours + ':' + minutes + ':' + seconds + ',' + ms;\n }\n const trackElem = document.getElementById(TRACK_ELEM_ID);\n if (!trackElem || !trackElem.track || !trackElem.track.cues) {\n return;\n }\n // Figure out video title\n const srtFilenamePieces = [];\n for (const elem of document.querySelectorAll('.video-title *')) {\n if (!elem.firstElementChild && elem.textContent) { // only get 'leaf' elements with text\n srtFilenamePieces.push(elem.textContent);\n }\n }\n let srtFilename;\n if (srtFilenamePieces.length) {\n srtFilename = srtFilenamePieces.join('-');\n }\n else {\n srtFilename = urlMovieId.toString(); // fallback in case UI changes\n }\n srtFilename += '_' + trackElem.track.language; // append language code\n srtFilename += '.srt';\n const srtChunks = [];\n let idx = 1;\n for (const cue of trackElem.track.cues) {\n const cleanedText = vttTextToSimple(cue.text, true);\n srtChunks.push(idx + '\\\\n' + formatTime(cue.startTime) + ' --> ' + formatTime(cue.endTime) + '\\\\n' + cleanedText + '\\\\n\\\\n');\n idx++;\n }\n const srtBlob = new Blob(srtChunks, { type: 'text/srt' });\n const srtUrl = URL.createObjectURL(srtBlob);\n const tmpElem = document.createElement('a');\n tmpElem.setAttribute('href', srtUrl);\n tmpElem.setAttribute('download', srtFilename);\n tmpElem.style.display = 'none';\n document.body.appendChild(tmpElem);\n tmpElem.click();\n document.body.removeChild(tmpElem);\n }\n function updateToggleDisplay() {\n const buttomElem = document.getElementById(TOGGLE_DISPLAY_BUTTON_ID);\n if (buttomElem) {\n if (showSubsState) {\n buttomElem.textContent = 'Hide Subs [S]';\n }\n else {\n buttomElem.textContent = 'Show Subs [S]';\n }\n }\n const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID);\n if (subsElem) {\n if (showSubsState) {\n subsElem.style.visibility = 'visible';\n }\n else {\n subsElem.style.visibility = 'hidden';\n }\n }\n }\n function renderAndReconcile() {\n function addSubsList(tracks) {\n const toggleDisplayButtonElem = document.createElement('button');\n toggleDisplayButtonElem.id = TOGGLE_DISPLAY_BUTTON_ID;\n toggleDisplayButtonElem.style.cssText = 'margin: 5px; border: none; color: black; width: 8em';\n toggleDisplayButtonElem.addEventListener('click', function (e) {\n e.preventDefault();\n showSubsState = !showSubsState;\n updateToggleDisplay();\n }, false);\n const selectElem = document.createElement('select');\n selectElem.style.cssText = 'color: black; margin: 5px';\n selectElem.addEventListener('change', function (e) {\n handleSubsListSetOrChange(e.target);\n renderAndReconcile();\n }, false);\n let firstCCTrackId;\n for (const track of tracks) {\n const optElem = document.createElement('option');\n optElem.value = track.id;\n optElem.textContent = track.languageDescription + (track.isClosedCaptions ? ' [CC]' : '');\n selectElem.appendChild(optElem);\n if (track.isClosedCaptions && !firstCCTrackId) {\n firstCCTrackId = track.id;\n }\n }\n if (firstCCTrackId) {\n selectElem.value = firstCCTrackId;\n }\n const downloadButtonElem = document.createElement('button');\n downloadButtonElem.id = DOWNLOAD_BUTTON_ID;\n downloadButtonElem.textContent = 'Download SRT';\n downloadButtonElem.style.cssText = 'margin: 5px; border: none';\n downloadButtonElem.addEventListener('click', function (e) {\n e.preventDefault();\n console.log('download click');\n downloadSRT();\n }, false);\n const panelElem = document.createElement('div');\n panelElem.style.cssText = 'position: absolute; z-index: 1000; top: 0; right: 0; font-size: 16px; color: white';\n panelElem.appendChild(toggleDisplayButtonElem);\n panelElem.appendChild(selectElem);\n panelElem.appendChild(downloadButtonElem);\n const containerElem = document.createElement('div');\n containerElem.id = SUBS_LIST_ELEM_ID;\n containerElem.style.cssText = 'width: 100%; height: 100%; position: absolute; top: 0; right: 0; bottom: 0; left: 0';\n containerElem.appendChild(panelElem);\n document.body.appendChild(containerElem);\n updateToggleDisplay();\n disableDownloadButton();\n handleSubsListSetOrChange(selectElem);\n }\n function removeSubsList() {\n const el = document.getElementById(SUBS_LIST_ELEM_ID);\n if (el) {\n el.remove();\n }\n }\n function addTrackElem(videoElem, blob, srclang) {\n const trackElem = document.createElement('track');\n trackElem.id = TRACK_ELEM_ID;\n trackElem.src = URL.createObjectURL(blob);\n trackElem.kind = 'subtitles';\n trackElem.default = true;\n trackElem.srclang = srclang;\n videoElem.appendChild(trackElem);\n trackElem.track.mode = 'hidden'; // this can only be set after appending\n trackElem.addEventListener('load', () => {\n enableDownloadButton();\n }, false);\n const customSubsElem = document.createElement('div');\n customSubsElem.id = CUSTOM_SUBS_ELEM_ID;\n customSubsElem.style.cssText = 'position: absolute; bottom: 20vh; left: 0; right: 0; color: white; font-size: 3vw; text-align: center; user-select: text; -moz-user-select: text; z-index: 100; pointer-events: none';\n trackElem.addEventListener('cuechange', (e) => {\n // Remove all children\n while (customSubsElem.firstChild) {\n customSubsElem.removeChild(customSubsElem.firstChild);\n }\n const track = e.target.track;\n console.log('active now', track.activeCues);\n for (const cue of track.activeCues) {\n const cueElem = document.createElement('div');\n cueElem.style.cssText = 'background: rgba(0,0,0,0.8); white-space: pre-wrap; padding: 0.2em 0.3em; margin: 10px auto; width: fit-content; width: -moz-fit-content; pointer-events: auto';\n cueElem.innerHTML = vttTextToSimple(cue.text, true); // may contain simple tags like etc.\n customSubsElem.appendChild(cueElem);\n }\n }, false);\n // Appending this to the player rather than the document fixes some issues:\n // 1) Clicking on subtitle text doesn't take focus (keyboard events) away from player\n // 2) Hover on subtitle prevents the \"sleep\" title screen from coming up, which is nice\n const playerElem = document.querySelector('.NFPlayer');\n if (!playerElem) {\n throw new Error(\"Couldn't find player element to append subtitles to\");\n }\n playerElem.appendChild(customSubsElem);\n updateToggleDisplay();\n }\n function removeTrackElem() {\n const trackElem = document.getElementById(TRACK_ELEM_ID);\n if (trackElem) {\n trackElem.remove();\n }\n const customSubsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID);\n if (customSubsElem) {\n customSubsElem.remove();\n }\n disableDownloadButton();\n }\n // Determine what subs list should be\n if (urlMovieId && (document.readyState === 'complete') && trackListCache.has(urlMovieId)) {\n targetSubsList = trackListCache.get(urlMovieId);\n }\n else {\n targetSubsList = null;\n }\n // Reconcile DOM if necessary\n if (targetSubsList !== displayedSubsList) {\n console.log('updating subs list DOM', targetSubsList, displayedSubsList);\n removeSubsList();\n if (targetSubsList) {\n addSubsList(targetSubsList);\n }\n displayedSubsList = targetSubsList;\n }\n // Determine what subs blob should be\n const videoElem = document.querySelector('video');\n if (urlMovieId && selectedTrackId && videoElem) {\n const cacheKey = urlMovieId + '/' + selectedTrackId;\n if (webvttCache.has(cacheKey)) {\n targetTrackBlob = webvttCache.get(cacheKey);\n }\n else {\n targetTrackBlob = null;\n }\n }\n else {\n targetTrackBlob = null;\n }\n // Reconcile DOM if necessary\n if (targetTrackBlob !== displayedTrackBlob) {\n console.log('need to update track blob', targetTrackBlob, displayedTrackBlob);\n removeTrackElem();\n if (targetTrackBlob) {\n // NOTE: super hacky to get the language code this way\n const languageCode = getSelectedTrackInfo().language;\n addTrackElem(videoElem, targetTrackBlob, languageCode);\n }\n displayedTrackBlob = targetTrackBlob;\n }\n }\n // Poll periodically to see if current movie has changed\n setInterval(function () {\n const movieIdMatch = URL_MOVIEID_REGEX.exec(window.location.pathname);\n let movieId;\n if (movieIdMatch) {\n movieId = +movieIdMatch[1];\n }\n urlMovieId = movieId;\n if (!urlMovieId) {\n selectedTrackId = null;\n }\n renderAndReconcile();\n }, POLL_INTERVAL_MS);\n document.body.addEventListener('keydown', function (e) {\n if ((e.keyCode === 67) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified C key\n console.log('copying subs text to clipboard');\n const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID);\n if (subsElem) {\n const pieces = [];\n for (const child of [...subsElem.children]) {\n pieces.push(child.textContent); // copy as plain text\n }\n const text = pieces.join('\\\\n');\n navigator.clipboard.writeText(text);\n }\n }\n else if ((e.keyCode === 83) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified S key\n const el = document.getElementById(TOGGLE_DISPLAY_BUTTON_ID);\n if (el) {\n el.click();\n }\n }\n }, false);\n let hideSubsListTimeout;\n function hideSubsListTimerFunc() {\n const el = document.getElementById(SUBS_LIST_ELEM_ID);\n if (el) {\n el.style.display = 'none';\n }\n hideSubsListTimeout = null;\n }\n document.body.addEventListener('mousemove', function (e) {\n // If there are any popups, make sure our subs don't block mouse events\n const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID);\n if (subsElem) {\n const popup = document.querySelector('.popup-content');\n if (popup) {\n subsElem.style.display = 'none';\n }\n else {\n subsElem.style.display = 'block';\n }\n }\n // Show subs list and update timer to hide it\n const subsListElem = document.getElementById(SUBS_LIST_ELEM_ID);\n if (subsListElem) {\n subsListElem.style.display = 'block';\n }\n if (hideSubsListTimeout) {\n clearTimeout(hideSubsListTimeout);\n }\n hideSubsListTimeout = setTimeout(hideSubsListTimerFunc, 3000);\n }, false);\n}\ninitializeSubadub();\n"); -// console.log('content script finished'); +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/dist/manifest.json b/dist/manifest.json index b360faf..617a762 100644 --- a/dist/manifest.json +++ b/dist/manifest.json @@ -1,4 +1,5 @@ - { +{ + "$schema": "http://json.schemastore.org/chrome-manifest", "manifest_version": 2, "name": "Subadub", "description" : "Enhanced Netflix subtitles for foreign language study", @@ -14,5 +15,9 @@ "run_at": "document_end", "js": ["content_script.js"] } + ], + "web_accessible_resources": [ + "subadub.js", + "subadub.css" ] - } +} diff --git a/dist/subadub.css b/dist/subadub.css new file mode 100644 index 0000000..55f2396 --- /dev/null +++ b/dist/subadub.css @@ -0,0 +1,3 @@ +.subadub { + background: red; +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b579161 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4736 @@ +{ + "name": "subadub", + "version": "0.1.5", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/chrome": { + "version": "0.0.91", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.91.tgz", + "integrity": "sha512-vNvo9lJkp1AvViWrUwe1bxhoMwr5dRZWlgr1DTuaNkz97LsG56lDX1sceWeZir2gRACJ5vdHtoRdVAvm8C75Ug==", + "dev": true, + "requires": { + "@types/filesystem": "*" + } + }, + "@types/filesystem": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.29.tgz", + "integrity": "sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw==", + "dev": true, + "requires": { + "@types/filewriter": "*" + } + }, + "@types/filewriter": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz", + "integrity": "sha1-wFTor02d11205jq8dviFFocU1LM=", + "dev": true + }, + "@types/node": { + "version": "12.12.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", + "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": 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" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "chownr": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": 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" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-webpack-plugin": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.5.tgz", + "integrity": "sha512-7N68eIoQTyudAuxkfPT7HzGoQ+TsmArN/I3HFwG+lVE3FNzqvZKIiaxtYh4o3BIznioxUvx9j26+Rtsc9htQUQ==", + "dev": true, + "requires": { + "cacache": "^12.0.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.1", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.0", + "webpack-log": "^2.0.0" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": 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" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": 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" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": 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, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": 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.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": 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" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", + "dev": true + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": 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" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": 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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", + "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "raw-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.0.tgz", + "integrity": "sha512-iINUOYvl1cGEmfoaLjnZXt4bKfT2LJnZZib5N/LLyAphC+Dd11vNP9CNVb38j+SAJpFI1uo8j9frmih53ASy7Q==", + "dev": true, + "requires": { + "loader-utils": "^1.2.3", + "schema-utils": "^2.5.0" + }, + "dependencies": { + "schema-utils": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.1.tgz", + "integrity": "sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" + } + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": 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" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "serialize-javascript": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.1.tgz", + "integrity": "sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz", + "integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz", + "integrity": "sha512-fdEb91kR2l+BVgES77N/NTXWZlpX6vX+pYPjnX5grcDYBF2CMnzJiXX4NNlna4l04lvCW39lZ+O/jSvUhHH/ew==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.1", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.1.tgz", + "integrity": "sha512-Dd9FekWuABGgjE1g0TlQJ+4dFUfYGbYcs52/HQObE0ZmUNjQlmLAS7xXsSzy23AMaMwipsx5sNHvoEpT2CZq1g==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", + "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webpack": { + "version": "4.41.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", + "integrity": "sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.1", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "webpack-cli": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz", + "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..39ab8c6 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "subadub", + "version": "0.1.5", + "description": "Enhanced Netflix subtitles for foreign language study", + "main": "dist/content_script.js", + "scripts": { + "build": "tsc && cp src/subadub.css res/* dist/" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/rsimmons/subadub.git" + }, + "author": "Russel Simmons", + "license": "MIT", + "bugs": { + "url": "https://github.com/rsimmons/subadub/issues" + }, + "homepage": "https://github.com/rsimmons/subadub#readme", + "devDependencies": { + "@types/chrome": "0.0.91", + "@types/node": "^12.12.14", + "copy-webpack-plugin": "^5.0.5", + "raw-loader": "^4.0.0", + "ts-loader": "^6.2.1", + "typescript": "^3.7.3", + "webpack": "^4.41.2", + "webpack-cli": "^3.3.10", + "webpack-merge": "^4.2.2" + } +} diff --git a/res/icon128.png b/res/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..42b127a94b96ce92257babbbaf0b1edbd0b1775c GIT binary patch literal 4425 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 { + const styleElem = document.createElement('link'); + styleElem.type = 'text/css'; + styleElem.rel = 'stylesheet'; + styleElem.id = 'subadub-style'; + styleElem.href = chrome.runtime.getURL("subadub.css"); + document.head.insertBefore(styleElem, document.head.firstChild); + + const scriptElem = document.createElement('script'); + scriptElem.type = 'text/javascript'; + scriptElem.id = 'subadub-script'; + scriptElem.innerHTML = rawSubadub; + document.head.insertBefore(scriptElem, document.head.firstChild); +})(); diff --git a/src/subadub.css b/src/subadub.css new file mode 100644 index 0000000..55f2396 --- /dev/null +++ b/src/subadub.css @@ -0,0 +1,3 @@ +.subadub { + background: red; +} diff --git a/src/subadub.ts b/src/subadub.ts new file mode 100644 index 0000000..df1b575 --- /dev/null +++ b/src/subadub.ts @@ -0,0 +1,475 @@ +function initializeSubadub() { + console.info('Initializing Subadub'); + + const POLL_INTERVAL_MS = 500; + const WEBVTT_FMT = 'webvtt-lssdh-ios8'; + const URL_MOVIEID_REGEX = RegExp('/watch/([0-9]+)'); + + const SUBS_LIST_ELEM_ID = 'subadub-subs-list'; + const TOGGLE_DISPLAY_BUTTON_ID = 'subadub-toggle-display'; + const TRACK_ELEM_ID = 'subadub-track'; + const DOWNLOAD_BUTTON_ID = 'subadub-download'; + const CUSTOM_SUBS_ELEM_ID = 'subadub-custom-subs'; + + const trackListCache = new Map(); // from movie ID to list of available tracks + const webvttCache = new Map(); // from 'movieID/trackID' to blob + let urlMovieId; + let selectedTrackId; + let showSubsState = true; + + let targetSubsList = null; + let displayedSubsList = null; + + let targetTrackBlob = null; + let displayedTrackBlob = null; + + // Convert WebVTT text to plain text plus "simple" tags (allowed in SRT) + const TAG_REGEX = RegExp(']*)>', 'ig'); + function vttTextToSimple(s, netflixRTLFix) { + let simpleText = s; + + // strip tags except simple ones + simpleText = simpleText.replace(TAG_REGEX, function (match, p1) { + return ['i', 'u', 'b'].includes(p1.toLowerCase()) ? match : ''; + }); + + if (netflixRTLFix) { + // For each line, if it starts with lrm or rlm escape, wrap in LRE/RLE/PDF pair. + // This is weird, but needed for compatibility with Netflix. See issue #1. + const lines = simpleText.split('\\n'); + const newLines = []; + for (const line of lines) { + if (line.startsWith('‎')) { + newLines.push('\u202a' + line.slice(5) + '\u202c'); + } else if (line.startsWith('‏')) { + newLines.push('\u202b' + line.slice(5) + '\u202c'); + } else { + newLines.push(line); + } + } + simpleText = newLines.join('\\n'); + } + + return simpleText; + } + + function extractMovieTextTracks(movieObj) { + const movieId = movieObj.movieId; + + const usableTracks = []; + console.log('timedtexttracks', movieObj.timedtexttracks); + for (const track of movieObj.timedtexttracks) { + if (track.isForcedNarrative || track.isNoneTrack) { + continue; // don't want these + } + + if (!track.cdnlist || !track.cdnlist.length) { + continue; + } + const firstCdnId = track.cdnlist[0].id; + + if (!track.ttDownloadables) { + continue; + } + + const webvttDL = track.ttDownloadables[WEBVTT_FMT]; + if (!webvttDL || !webvttDL.downloadUrls) { + continue; + } + + const bestUrl = webvttDL.downloadUrls[firstCdnId]; + if (!bestUrl) { + continue; + } + + const isClosedCaptions = track.rawTrackType === 'closedcaptions'; + + usableTracks.push({ + id: track.new_track_id, + language: track.language, + languageDescription: track.languageDescription, + bestUrl: bestUrl, + isClosedCaptions: isClosedCaptions, + }); + } + + console.log('CACHING MOVIE TRACKS', movieId, usableTracks); + trackListCache.set(movieId, usableTracks); + renderAndReconcile(); + } + + function getSelectedTrackInfo() { + if (!urlMovieId || !selectedTrackId) { + throw new Error('Internal error, getSelectedTrackInfo called but urlMovieId or selectedTrackId is null'); + } + const trackList = trackListCache.get(urlMovieId); + const matchingTracks = trackList.filter(el => el.id === selectedTrackId); + if (matchingTracks.length !== 1) { + throw new Error('internal error, no matching track id'); + } + return matchingTracks[0]; + } + + function handleSubsListSetOrChange(selectElem) { + const trackId = selectElem.value; + console.log('selecting track', trackId); + + selectedTrackId = trackId; + + if (!selectedTrackId) { + return; + } + + const cacheKey = urlMovieId + '/' + selectedTrackId; + if (!webvttCache.has(cacheKey)) { + const trackInfo = getSelectedTrackInfo(); + const url = trackInfo.bestUrl; + + fetch(url).then(function(response) { + if (response.ok) { + return response.blob(); + } + throw new Error('Bad response to WebVTT request'); + }).then(function(blob) { + webvttCache.set(cacheKey, new Blob([blob], {type: 'text/vtt'})); // set type to avoid warning + renderAndReconcile(); + }).catch(function(error) { + console.error('Failed to fetch WebVTT file', error.message); + }); + } + + // NOTE: We don't call renderAndReconcile here, caller should do it to avoid recursive loop bug + } + + function enableDownloadButton() { + const downloadButtonElem = document.getElementById(DOWNLOAD_BUTTON_ID) as HTMLButtonElement; + if (downloadButtonElem) { + downloadButtonElem.style.color = 'black'; + downloadButtonElem.disabled = false; + } + } + + function disableDownloadButton() { + const downloadButtonElem = document.getElementById(DOWNLOAD_BUTTON_ID) as HTMLButtonElement; + if (downloadButtonElem) { + downloadButtonElem.style.color = 'grey'; + downloadButtonElem.disabled = true; + } + } + + function downloadSRT() { + function formatTime(t) { + const date = new Date(0, 0, 0, 0, 0, 0, t*1000); + const hours = date.getHours().toString().padStart(2, '0'); + const minutes = date.getMinutes().toString().padStart(2, '0'); + const seconds = date.getSeconds().toString().padStart(2, '0'); + const ms = date.getMilliseconds().toString().padStart(3, '0'); + + return hours + ':' + minutes + ':' + seconds + ',' + ms; + } + + const trackElem = document.getElementById(TRACK_ELEM_ID) as HTMLTrackElement; + if (!trackElem || !trackElem.track || !trackElem.track.cues) { + return; + } + + // Figure out video title + const srtFilenamePieces = []; + for (const elem of document.querySelectorAll('.video-title *')) { + if (!elem.firstElementChild && elem.textContent) { // only get 'leaf' elements with text + srtFilenamePieces.push(elem.textContent); + } + } + let srtFilename; + if (srtFilenamePieces.length) { + srtFilename = srtFilenamePieces.join('-'); + } else { + srtFilename = urlMovieId.toString(); // fallback in case UI changes + } + srtFilename += '_' + trackElem.track.language; // append language code + srtFilename += '.srt'; + + const srtChunks = []; + let idx = 1; + for (const cue of trackElem.track.cues) { + const cleanedText = vttTextToSimple(cue.text, true); + srtChunks.push(idx + '\\n' + formatTime(cue.startTime) + ' --> ' + formatTime(cue.endTime) + '\\n' + cleanedText + '\\n\\n'); + idx++; + } + + const srtBlob = new Blob(srtChunks, { type: 'text/srt' }); + const srtUrl = URL.createObjectURL(srtBlob); + + const tmpElem = document.createElement('a'); + tmpElem.setAttribute('href', srtUrl); + tmpElem.setAttribute('download', srtFilename); + tmpElem.style.display = 'none'; + document.body.appendChild(tmpElem); + tmpElem.click(); + document.body.removeChild(tmpElem); + } + + function updateToggleDisplay() { + const buttomElem = document.getElementById(TOGGLE_DISPLAY_BUTTON_ID); + if (buttomElem) { + if (showSubsState) { + buttomElem.textContent = 'Hide Subs [S]'; + } else { + buttomElem.textContent = 'Show Subs [S]'; + } + } + const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID); + if (subsElem) { + if (showSubsState) { + subsElem.style.visibility = 'visible'; + } else { + subsElem.style.visibility = 'hidden'; + } + } + } + + function renderAndReconcile() { + function addSubsList(tracks) { + const toggleDisplayButtonElem = document.createElement('button'); + toggleDisplayButtonElem.id = TOGGLE_DISPLAY_BUTTON_ID; + toggleDisplayButtonElem.style.cssText = 'margin: 5px; border: none; color: black; width: 8em'; + toggleDisplayButtonElem.addEventListener('click', function(e) { + e.preventDefault(); + showSubsState = !showSubsState; + updateToggleDisplay(); + }, false); + + const selectElem = document.createElement('select'); + selectElem.style.cssText = 'color: black; margin: 5px'; + selectElem.addEventListener('change', function(e) { + handleSubsListSetOrChange(e.target); + renderAndReconcile(); + }, false); + + let firstCCTrackId; + for (const track of tracks) { + const optElem = document.createElement('option'); + optElem.value = track.id; + optElem.textContent = track.languageDescription + (track.isClosedCaptions ? ' [CC]' : ''); + selectElem.appendChild(optElem); + + if (track.isClosedCaptions && !firstCCTrackId) { + firstCCTrackId = track.id; + } + } + if (firstCCTrackId) { + selectElem.value = firstCCTrackId; + } + + const downloadButtonElem = document.createElement('button'); + downloadButtonElem.id = DOWNLOAD_BUTTON_ID; + downloadButtonElem.textContent = 'Download SRT'; + downloadButtonElem.style.cssText = 'margin: 5px; border: none'; + downloadButtonElem.addEventListener('click', function(e) { + e.preventDefault(); + console.log('download click'); + downloadSRT(); + }, false); + + const panelElem = document.createElement('div'); + panelElem.style.cssText = 'position: absolute; z-index: 1000; top: 0; right: 0; font-size: 16px; color: white'; + panelElem.appendChild(toggleDisplayButtonElem); + panelElem.appendChild(selectElem); + panelElem.appendChild(downloadButtonElem); + + const containerElem = document.createElement('div'); + containerElem.id = SUBS_LIST_ELEM_ID; + containerElem.style.cssText = 'width: 100%; height: 100%; position: absolute; top: 0; right: 0; bottom: 0; left: 0'; + containerElem.appendChild(panelElem); + + document.body.appendChild(containerElem); + + updateToggleDisplay(); + disableDownloadButton(); + + handleSubsListSetOrChange(selectElem); + } + + function removeSubsList() { + const el = document.getElementById(SUBS_LIST_ELEM_ID); + if (el) { + el.remove(); + } + } + + function addTrackElem(videoElem, blob, srclang) { + const trackElem = document.createElement('track'); + trackElem.id = TRACK_ELEM_ID; + trackElem.src = URL.createObjectURL(blob); + trackElem.kind = 'subtitles'; + trackElem.default = true; + trackElem.srclang = srclang; + videoElem.appendChild(trackElem); + trackElem.track.mode = 'hidden'; // this can only be set after appending + + trackElem.addEventListener('load', () => { + enableDownloadButton(); + }, false); + + const customSubsElem = document.createElement('div'); + customSubsElem.id = CUSTOM_SUBS_ELEM_ID; + customSubsElem.style.cssText = 'position: absolute; bottom: 20vh; left: 0; right: 0; color: white; font-size: 3vw; text-align: center; user-select: text; -moz-user-select: text; z-index: 100; pointer-events: none'; + + trackElem.addEventListener('cuechange', (e) => { + // Remove all children + while (customSubsElem.firstChild) { + customSubsElem.removeChild(customSubsElem.firstChild); + } + + const track = (e.target as HTMLTrackElement).track; + console.log('active now', track.activeCues); + for (const cue of track.activeCues) { + const cueElem = document.createElement('div'); + cueElem.style.cssText = 'background: rgba(0,0,0,0.8); white-space: pre-wrap; padding: 0.2em 0.3em; margin: 10px auto; width: fit-content; width: -moz-fit-content; pointer-events: auto'; + cueElem.innerHTML = vttTextToSimple(cue.text, true); // may contain simple tags like etc. + customSubsElem.appendChild(cueElem); + } + }, false); + + // Appending this to the player rather than the document fixes some issues: + // 1) Clicking on subtitle text doesn't take focus (keyboard events) away from player + // 2) Hover on subtitle prevents the "sleep" title screen from coming up, which is nice + const playerElem = document.querySelector('.NFPlayer'); + if (!playerElem) { + throw new Error("Couldn't find player element to append subtitles to"); + } + playerElem.appendChild(customSubsElem); + + updateToggleDisplay(); + } + + function removeTrackElem() { + const trackElem = document.getElementById(TRACK_ELEM_ID); + if (trackElem) { + trackElem.remove(); + } + + const customSubsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID); + if (customSubsElem) { + customSubsElem.remove(); + } + + disableDownloadButton(); + } + + // Determine what subs list should be + if (urlMovieId && (document.readyState === 'complete') && trackListCache.has(urlMovieId)) { + targetSubsList = trackListCache.get(urlMovieId); + } else { + targetSubsList = null; + } + + // Reconcile DOM if necessary + if (targetSubsList !== displayedSubsList) { + console.log('updating subs list DOM', targetSubsList, displayedSubsList); + + removeSubsList(); + if (targetSubsList) { + addSubsList(targetSubsList); + } + + displayedSubsList = targetSubsList; + } + + // Determine what subs blob should be + const videoElem = document.querySelector('video'); + if (urlMovieId && selectedTrackId && videoElem) { + const cacheKey = urlMovieId + '/' + selectedTrackId; + if (webvttCache.has(cacheKey)) { + targetTrackBlob = webvttCache.get(cacheKey); + } else { + targetTrackBlob = null; + } + } else { + targetTrackBlob = null; + } + + // Reconcile DOM if necessary + if (targetTrackBlob !== displayedTrackBlob) { + console.log('need to update track blob', targetTrackBlob, displayedTrackBlob); + + removeTrackElem(); + if (targetTrackBlob) { + // NOTE: super hacky to get the language code this way + const languageCode = getSelectedTrackInfo().language; + addTrackElem(videoElem, targetTrackBlob, languageCode); + } + + displayedTrackBlob = targetTrackBlob; + } + } + + // Poll periodically to see if current movie has changed + setInterval(function() { + const movieIdMatch = URL_MOVIEID_REGEX.exec(window.location.pathname); + let movieId; + if (movieIdMatch) { + movieId = +movieIdMatch[1]; + } + urlMovieId = movieId; + if (!urlMovieId) { + selectedTrackId = null; + } + + renderAndReconcile(); + }, POLL_INTERVAL_MS); + + document.body.addEventListener('keydown', function(e) { + if ((e.keyCode === 67) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified C key + console.log('copying subs text to clipboard'); + const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID) as HTMLDivElement; + if (subsElem) { + const pieces = []; + for (const child of [...subsElem.children]) { + pieces.push(child.textContent); // copy as plain text + } + const text = pieces.join('\\n'); + navigator.clipboard.writeText(text); + } + } else if ((e.keyCode === 83) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified S key + const el = document.getElementById(TOGGLE_DISPLAY_BUTTON_ID); + if (el) { + el.click(); + } + } + }, false); + + let hideSubsListTimeout; + function hideSubsListTimerFunc() { + const el = document.getElementById(SUBS_LIST_ELEM_ID); + if (el) { + el.style.display = 'none'; + } + hideSubsListTimeout = null; + } + + document.body.addEventListener('mousemove', function(e) { + // If there are any popups, make sure our subs don't block mouse events + const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID); + if (subsElem) { + const popup = document.querySelector('.popup-content'); + if (popup) { + subsElem.style.display = 'none'; + } else { + subsElem.style.display = 'block'; + } + } + + // Show subs list and update timer to hide it + const subsListElem = document.getElementById(SUBS_LIST_ELEM_ID); + if (subsListElem) { + subsListElem.style.display = 'block'; + } + if (hideSubsListTimeout) { + clearTimeout(hideSubsListTimeout); + } + hideSubsListTimeout = setTimeout(hideSubsListTimerFunc, 3000); + }, false); +} + +initializeSubadub(); diff --git a/src/types/raw-loader.d.ts b/src/types/raw-loader.d.ts new file mode 100644 index 0000000..25c2a57 --- /dev/null +++ b/src/types/raw-loader.d.ts @@ -0,0 +1,4 @@ +declare module 'raw-loader!*' { + const contents: string + export = contents +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6d6da5a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "esnext", + "lib": ["DOM", "DOM.Iterable", "esnext"], + "noImplicitAny": false, + "esModuleInterop": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": false, + "rootDir": "src", + "outDir": "dist", + "noEmitOnError": true, + "typeRoots": ["node_modules/@types", "src/types"] + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..fc60666 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,35 @@ +const webpack = require("webpack"); +const path = require('path'); +const CopyPlugin = require('copy-webpack-plugin'); + +module.exports = { + entry: { + content_script: path.resolve(__dirname, './src/content_script.ts') + }, + output: { + path: path.join(__dirname, './dist'), + filename: '[name].js' + }, + optimization: { + minimize: false + }, + mode: 'production', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/ + } + ] + }, + resolve: { + extensions: ['.ts', '.tsx', '.js'] + }, + plugins: [ + new CopyPlugin([ + { from: './res', to: '.' }, + { from: './src/subadub.css', to: 'subadub.css' } + ]) + ] +}; From 3ffb99d3a317a3c2fd9125a6ffba9a6d039274f5 Mon Sep 17 00:00:00 2001 From: Hans Otto Wirtz Date: Sun, 8 Dec 2019 00:20:47 +0100 Subject: [PATCH 2/4] Move styles to stylesheet, restyle --- .gitignore | 1 + dist/content_script.js | 122 ----------------------------------------- dist/icon128.png | Bin 4425 -> 0 bytes dist/icon16.png | Bin 575 -> 0 bytes dist/icon48.png | Bin 1583 -> 0 bytes dist/manifest.json | 23 -------- dist/subadub.css | 3 - package.json | 2 +- res/manifest.json | 4 +- src/content_script.ts | 4 +- src/subadub.css | 109 +++++++++++++++++++++++++++++++++++- src/subadub.ts | 82 ++++++++++++++++++--------- webpack.config.js | 5 +- 13 files changed, 175 insertions(+), 180 deletions(-) delete mode 100644 dist/content_script.js delete mode 100644 dist/icon128.png delete mode 100644 dist/icon16.png delete mode 100644 dist/icon48.png delete mode 100644 dist/manifest.json delete mode 100644 dist/subadub.css diff --git a/.gitignore b/.gitignore index 646ac51..bf56190 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store node_modules/ +dist/ diff --git a/dist/content_script.js b/dist/content_script.js deleted file mode 100644 index 77162bb..0000000 --- a/dist/content_script.js +++ /dev/null @@ -1,122 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const subadub_1 = __importDefault(__webpack_require__(1)); -(() => { - const styleElem = document.createElement('link'); - styleElem.type = 'text/css'; - styleElem.rel = 'stylesheet'; - styleElem.id = 'subadub-style'; - styleElem.href = chrome.runtime.getURL("subadub.css"); - document.head.insertBefore(styleElem, document.head.firstChild); - const scriptElem = document.createElement('script'); - scriptElem.type = 'text/javascript'; - scriptElem.id = 'subadub-script'; - scriptElem.innerHTML = subadub_1.default; - document.head.insertBefore(scriptElem, document.head.firstChild); -})(); - - -/***/ }), -/* 1 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony default export */ __webpack_exports__["default"] = ("function initializeSubadub() {\n console.info('Initializing Subadub');\n const POLL_INTERVAL_MS = 500;\n const WEBVTT_FMT = 'webvtt-lssdh-ios8';\n const URL_MOVIEID_REGEX = RegExp('/watch/([0-9]+)');\n const SUBS_LIST_ELEM_ID = 'subadub-subs-list';\n const TOGGLE_DISPLAY_BUTTON_ID = 'subadub-toggle-display';\n const TRACK_ELEM_ID = 'subadub-track';\n const DOWNLOAD_BUTTON_ID = 'subadub-download';\n const CUSTOM_SUBS_ELEM_ID = 'subadub-custom-subs';\n const trackListCache = new Map(); // from movie ID to list of available tracks\n const webvttCache = new Map(); // from 'movieID/trackID' to blob\n let urlMovieId;\n let selectedTrackId;\n let showSubsState = true;\n let targetSubsList = null;\n let displayedSubsList = null;\n let targetTrackBlob = null;\n let displayedTrackBlob = null;\n // Convert WebVTT text to plain text plus \"simple\" tags (allowed in SRT)\n const TAG_REGEX = RegExp(']*)>', 'ig');\n function vttTextToSimple(s, netflixRTLFix) {\n let simpleText = s;\n // strip tags except simple ones\n simpleText = simpleText.replace(TAG_REGEX, function (match, p1) {\n return ['i', 'u', 'b'].includes(p1.toLowerCase()) ? match : '';\n });\n if (netflixRTLFix) {\n // For each line, if it starts with lrm or rlm escape, wrap in LRE/RLE/PDF pair.\n // This is weird, but needed for compatibility with Netflix. See issue #1.\n const lines = simpleText.split('\\\\n');\n const newLines = [];\n for (const line of lines) {\n if (line.startsWith('‎')) {\n newLines.push('\\u202a' + line.slice(5) + '\\u202c');\n }\n else if (line.startsWith('‏')) {\n newLines.push('\\u202b' + line.slice(5) + '\\u202c');\n }\n else {\n newLines.push(line);\n }\n }\n simpleText = newLines.join('\\\\n');\n }\n return simpleText;\n }\n function extractMovieTextTracks(movieObj) {\n const movieId = movieObj.movieId;\n const usableTracks = [];\n console.log('timedtexttracks', movieObj.timedtexttracks);\n for (const track of movieObj.timedtexttracks) {\n if (track.isForcedNarrative || track.isNoneTrack) {\n continue; // don't want these\n }\n if (!track.cdnlist || !track.cdnlist.length) {\n continue;\n }\n const firstCdnId = track.cdnlist[0].id;\n if (!track.ttDownloadables) {\n continue;\n }\n const webvttDL = track.ttDownloadables[WEBVTT_FMT];\n if (!webvttDL || !webvttDL.downloadUrls) {\n continue;\n }\n const bestUrl = webvttDL.downloadUrls[firstCdnId];\n if (!bestUrl) {\n continue;\n }\n const isClosedCaptions = track.rawTrackType === 'closedcaptions';\n usableTracks.push({\n id: track.new_track_id,\n language: track.language,\n languageDescription: track.languageDescription,\n bestUrl: bestUrl,\n isClosedCaptions: isClosedCaptions,\n });\n }\n console.log('CACHING MOVIE TRACKS', movieId, usableTracks);\n trackListCache.set(movieId, usableTracks);\n renderAndReconcile();\n }\n function getSelectedTrackInfo() {\n if (!urlMovieId || !selectedTrackId) {\n throw new Error('Internal error, getSelectedTrackInfo called but urlMovieId or selectedTrackId is null');\n }\n const trackList = trackListCache.get(urlMovieId);\n const matchingTracks = trackList.filter(el => el.id === selectedTrackId);\n if (matchingTracks.length !== 1) {\n throw new Error('internal error, no matching track id');\n }\n return matchingTracks[0];\n }\n function handleSubsListSetOrChange(selectElem) {\n const trackId = selectElem.value;\n console.log('selecting track', trackId);\n selectedTrackId = trackId;\n if (!selectedTrackId) {\n return;\n }\n const cacheKey = urlMovieId + '/' + selectedTrackId;\n if (!webvttCache.has(cacheKey)) {\n const trackInfo = getSelectedTrackInfo();\n const url = trackInfo.bestUrl;\n fetch(url).then(function (response) {\n if (response.ok) {\n return response.blob();\n }\n throw new Error('Bad response to WebVTT request');\n }).then(function (blob) {\n webvttCache.set(cacheKey, new Blob([blob], { type: 'text/vtt' })); // set type to avoid warning\n renderAndReconcile();\n }).catch(function (error) {\n console.error('Failed to fetch WebVTT file', error.message);\n });\n }\n // NOTE: We don't call renderAndReconcile here, caller should do it to avoid recursive loop bug\n }\n function enableDownloadButton() {\n const downloadButtonElem = document.getElementById(DOWNLOAD_BUTTON_ID);\n if (downloadButtonElem) {\n downloadButtonElem.style.color = 'black';\n downloadButtonElem.disabled = false;\n }\n }\n function disableDownloadButton() {\n const downloadButtonElem = document.getElementById(DOWNLOAD_BUTTON_ID);\n if (downloadButtonElem) {\n downloadButtonElem.style.color = 'grey';\n downloadButtonElem.disabled = true;\n }\n }\n function downloadSRT() {\n function formatTime(t) {\n const date = new Date(0, 0, 0, 0, 0, 0, t * 1000);\n const hours = date.getHours().toString().padStart(2, '0');\n const minutes = date.getMinutes().toString().padStart(2, '0');\n const seconds = date.getSeconds().toString().padStart(2, '0');\n const ms = date.getMilliseconds().toString().padStart(3, '0');\n return hours + ':' + minutes + ':' + seconds + ',' + ms;\n }\n const trackElem = document.getElementById(TRACK_ELEM_ID);\n if (!trackElem || !trackElem.track || !trackElem.track.cues) {\n return;\n }\n // Figure out video title\n const srtFilenamePieces = [];\n for (const elem of document.querySelectorAll('.video-title *')) {\n if (!elem.firstElementChild && elem.textContent) { // only get 'leaf' elements with text\n srtFilenamePieces.push(elem.textContent);\n }\n }\n let srtFilename;\n if (srtFilenamePieces.length) {\n srtFilename = srtFilenamePieces.join('-');\n }\n else {\n srtFilename = urlMovieId.toString(); // fallback in case UI changes\n }\n srtFilename += '_' + trackElem.track.language; // append language code\n srtFilename += '.srt';\n const srtChunks = [];\n let idx = 1;\n for (const cue of trackElem.track.cues) {\n const cleanedText = vttTextToSimple(cue.text, true);\n srtChunks.push(idx + '\\\\n' + formatTime(cue.startTime) + ' --> ' + formatTime(cue.endTime) + '\\\\n' + cleanedText + '\\\\n\\\\n');\n idx++;\n }\n const srtBlob = new Blob(srtChunks, { type: 'text/srt' });\n const srtUrl = URL.createObjectURL(srtBlob);\n const tmpElem = document.createElement('a');\n tmpElem.setAttribute('href', srtUrl);\n tmpElem.setAttribute('download', srtFilename);\n tmpElem.style.display = 'none';\n document.body.appendChild(tmpElem);\n tmpElem.click();\n document.body.removeChild(tmpElem);\n }\n function updateToggleDisplay() {\n const buttomElem = document.getElementById(TOGGLE_DISPLAY_BUTTON_ID);\n if (buttomElem) {\n if (showSubsState) {\n buttomElem.textContent = 'Hide Subs [S]';\n }\n else {\n buttomElem.textContent = 'Show Subs [S]';\n }\n }\n const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID);\n if (subsElem) {\n if (showSubsState) {\n subsElem.style.visibility = 'visible';\n }\n else {\n subsElem.style.visibility = 'hidden';\n }\n }\n }\n function renderAndReconcile() {\n function addSubsList(tracks) {\n const toggleDisplayButtonElem = document.createElement('button');\n toggleDisplayButtonElem.id = TOGGLE_DISPLAY_BUTTON_ID;\n toggleDisplayButtonElem.style.cssText = 'margin: 5px; border: none; color: black; width: 8em';\n toggleDisplayButtonElem.addEventListener('click', function (e) {\n e.preventDefault();\n showSubsState = !showSubsState;\n updateToggleDisplay();\n }, false);\n const selectElem = document.createElement('select');\n selectElem.style.cssText = 'color: black; margin: 5px';\n selectElem.addEventListener('change', function (e) {\n handleSubsListSetOrChange(e.target);\n renderAndReconcile();\n }, false);\n let firstCCTrackId;\n for (const track of tracks) {\n const optElem = document.createElement('option');\n optElem.value = track.id;\n optElem.textContent = track.languageDescription + (track.isClosedCaptions ? ' [CC]' : '');\n selectElem.appendChild(optElem);\n if (track.isClosedCaptions && !firstCCTrackId) {\n firstCCTrackId = track.id;\n }\n }\n if (firstCCTrackId) {\n selectElem.value = firstCCTrackId;\n }\n const downloadButtonElem = document.createElement('button');\n downloadButtonElem.id = DOWNLOAD_BUTTON_ID;\n downloadButtonElem.textContent = 'Download SRT';\n downloadButtonElem.style.cssText = 'margin: 5px; border: none';\n downloadButtonElem.addEventListener('click', function (e) {\n e.preventDefault();\n console.log('download click');\n downloadSRT();\n }, false);\n const panelElem = document.createElement('div');\n panelElem.style.cssText = 'position: absolute; z-index: 1000; top: 0; right: 0; font-size: 16px; color: white';\n panelElem.appendChild(toggleDisplayButtonElem);\n panelElem.appendChild(selectElem);\n panelElem.appendChild(downloadButtonElem);\n const containerElem = document.createElement('div');\n containerElem.id = SUBS_LIST_ELEM_ID;\n containerElem.style.cssText = 'width: 100%; height: 100%; position: absolute; top: 0; right: 0; bottom: 0; left: 0';\n containerElem.appendChild(panelElem);\n document.body.appendChild(containerElem);\n updateToggleDisplay();\n disableDownloadButton();\n handleSubsListSetOrChange(selectElem);\n }\n function removeSubsList() {\n const el = document.getElementById(SUBS_LIST_ELEM_ID);\n if (el) {\n el.remove();\n }\n }\n function addTrackElem(videoElem, blob, srclang) {\n const trackElem = document.createElement('track');\n trackElem.id = TRACK_ELEM_ID;\n trackElem.src = URL.createObjectURL(blob);\n trackElem.kind = 'subtitles';\n trackElem.default = true;\n trackElem.srclang = srclang;\n videoElem.appendChild(trackElem);\n trackElem.track.mode = 'hidden'; // this can only be set after appending\n trackElem.addEventListener('load', () => {\n enableDownloadButton();\n }, false);\n const customSubsElem = document.createElement('div');\n customSubsElem.id = CUSTOM_SUBS_ELEM_ID;\n customSubsElem.style.cssText = 'position: absolute; bottom: 20vh; left: 0; right: 0; color: white; font-size: 3vw; text-align: center; user-select: text; -moz-user-select: text; z-index: 100; pointer-events: none';\n trackElem.addEventListener('cuechange', (e) => {\n // Remove all children\n while (customSubsElem.firstChild) {\n customSubsElem.removeChild(customSubsElem.firstChild);\n }\n const track = e.target.track;\n console.log('active now', track.activeCues);\n for (const cue of track.activeCues) {\n const cueElem = document.createElement('div');\n cueElem.style.cssText = 'background: rgba(0,0,0,0.8); white-space: pre-wrap; padding: 0.2em 0.3em; margin: 10px auto; width: fit-content; width: -moz-fit-content; pointer-events: auto';\n cueElem.innerHTML = vttTextToSimple(cue.text, true); // may contain simple tags like etc.\n customSubsElem.appendChild(cueElem);\n }\n }, false);\n // Appending this to the player rather than the document fixes some issues:\n // 1) Clicking on subtitle text doesn't take focus (keyboard events) away from player\n // 2) Hover on subtitle prevents the \"sleep\" title screen from coming up, which is nice\n const playerElem = document.querySelector('.NFPlayer');\n if (!playerElem) {\n throw new Error(\"Couldn't find player element to append subtitles to\");\n }\n playerElem.appendChild(customSubsElem);\n updateToggleDisplay();\n }\n function removeTrackElem() {\n const trackElem = document.getElementById(TRACK_ELEM_ID);\n if (trackElem) {\n trackElem.remove();\n }\n const customSubsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID);\n if (customSubsElem) {\n customSubsElem.remove();\n }\n disableDownloadButton();\n }\n // Determine what subs list should be\n if (urlMovieId && (document.readyState === 'complete') && trackListCache.has(urlMovieId)) {\n targetSubsList = trackListCache.get(urlMovieId);\n }\n else {\n targetSubsList = null;\n }\n // Reconcile DOM if necessary\n if (targetSubsList !== displayedSubsList) {\n console.log('updating subs list DOM', targetSubsList, displayedSubsList);\n removeSubsList();\n if (targetSubsList) {\n addSubsList(targetSubsList);\n }\n displayedSubsList = targetSubsList;\n }\n // Determine what subs blob should be\n const videoElem = document.querySelector('video');\n if (urlMovieId && selectedTrackId && videoElem) {\n const cacheKey = urlMovieId + '/' + selectedTrackId;\n if (webvttCache.has(cacheKey)) {\n targetTrackBlob = webvttCache.get(cacheKey);\n }\n else {\n targetTrackBlob = null;\n }\n }\n else {\n targetTrackBlob = null;\n }\n // Reconcile DOM if necessary\n if (targetTrackBlob !== displayedTrackBlob) {\n console.log('need to update track blob', targetTrackBlob, displayedTrackBlob);\n removeTrackElem();\n if (targetTrackBlob) {\n // NOTE: super hacky to get the language code this way\n const languageCode = getSelectedTrackInfo().language;\n addTrackElem(videoElem, targetTrackBlob, languageCode);\n }\n displayedTrackBlob = targetTrackBlob;\n }\n }\n // Poll periodically to see if current movie has changed\n setInterval(function () {\n const movieIdMatch = URL_MOVIEID_REGEX.exec(window.location.pathname);\n let movieId;\n if (movieIdMatch) {\n movieId = +movieIdMatch[1];\n }\n urlMovieId = movieId;\n if (!urlMovieId) {\n selectedTrackId = null;\n }\n renderAndReconcile();\n }, POLL_INTERVAL_MS);\n document.body.addEventListener('keydown', function (e) {\n if ((e.keyCode === 67) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified C key\n console.log('copying subs text to clipboard');\n const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID);\n if (subsElem) {\n const pieces = [];\n for (const child of [...subsElem.children]) {\n pieces.push(child.textContent); // copy as plain text\n }\n const text = pieces.join('\\\\n');\n navigator.clipboard.writeText(text);\n }\n }\n else if ((e.keyCode === 83) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified S key\n const el = document.getElementById(TOGGLE_DISPLAY_BUTTON_ID);\n if (el) {\n el.click();\n }\n }\n }, false);\n let hideSubsListTimeout;\n function hideSubsListTimerFunc() {\n const el = document.getElementById(SUBS_LIST_ELEM_ID);\n if (el) {\n el.style.display = 'none';\n }\n hideSubsListTimeout = null;\n }\n document.body.addEventListener('mousemove', function (e) {\n // If there are any popups, make sure our subs don't block mouse events\n const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID);\n if (subsElem) {\n const popup = document.querySelector('.popup-content');\n if (popup) {\n subsElem.style.display = 'none';\n }\n else {\n subsElem.style.display = 'block';\n }\n }\n // Show subs list and update timer to hide it\n const subsListElem = document.getElementById(SUBS_LIST_ELEM_ID);\n if (subsListElem) {\n subsListElem.style.display = 'block';\n }\n if (hideSubsListTimeout) {\n clearTimeout(hideSubsListTimeout);\n }\n hideSubsListTimeout = setTimeout(hideSubsListTimerFunc, 3000);\n }, false);\n}\ninitializeSubadub();\n"); - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/dist/icon128.png b/dist/icon128.png deleted file mode 100644 index 42b127a94b96ce92257babbbaf0b1edbd0b1775c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4425 zcmaKwS2WxWw8j53hUh^Uz4tEqAbOW*37=k~jUds3WEhuJQ9{?x;9d(sw0iYdg5>Jx>`rFe#^GT2awmcp#ZX{&1eFd+o$#B}DiDqAT zW;VI}WMbkFF7H?Fzg1|0zSrbSt?MGtNg(h}Zq`&Vp(wB5Lj*-2oG=g>)3dJ)*4f=` z`7-bAt+V{~4431x`_;u|30;t@q^hA{}_0ZmGXYFFBxn?$m? zJjn7?T@5?xMMVx|c`YaT`ocr3Y)@p1H%rUA7!K>>P>YR*aF?o9Mj_ zKN_O}%%bPFhcMypzqDj)sN`iSnB7@en8ONhJ*lLyT zH`yM5nCF)+;?%g9i)|dGu#pd?D4E8rNw%}1T{NUw3N-UMdyghqQsc$rS6WwJC;FdJ zqSF}i2m-$!=WV#skd}hUpt|G8PgbF6CT(jo8S)sd&w?UriZFxIc2oC18g50$ z{5!1jABd^#_mh-dlCXXehSXYh-E8E|z^ zMC@C1@9)8->9?0nisy`)c@^xm!aK4yjvN2cgp>;kgR;ho_^ zUgrHZ1c3K+vb?S?dFGC&JmY;D3rR;TeuynF7w6ElFXfq7!w?4#rOs9p%VzY*k?wDA z0sjiAkYil~77GR?8T>kmGAH1hb^E!ashTfsBN#YQdy5TK3-2j6{AHO!sFXRv=yH`?{=TMSQ4S3@Wmhsm~acvv_wV9=( ztno8tD6QPdv;81T{N*r1Vx-8i?BR)CaqZ?s&5N~9o0L{}JeVAb=s5(oQ#(1^=D&;@ zW1x1!s^G&HGq@8_;SkGeFb{xz2*JE(WS3nKf#oGco}@0QTi`{%GW{lLdgSE$rJrY; zH2L=OYXRn^Lbh62C91kvpklyI3P%W-NtL{|Z<*)){M*Q$q{&5Gn_&K4;1*krLvS%Q z;2xX!J_ApK$c)4)FJ?N=QFr{B$E^(&t~q)Bfi)uw#5O54tjOm&3qFDeN;-{e6WdV1 zh4A1l)3J`Jd4={d@O;*f8%*k*iD%{~7RYc1Cr;&+6ep_~xdy@~St};mlADmX74W&Y zI+9*aOwgZ-W895(QSO|`AVgF%Wn**>KB7<WKZvx>jCQ zTrfY+PTkA(-<4`HHkpu8xfb%mjoPRnGv)H1=< z&MvrkIK8K(f`IzV;m_>06#=&Vq4{pfLuB>aK(_*TQALKZ^xZx3-_6NsR-{3A`&~nQ zx&9ReJCe+6z~@1kLHvmUYvG|yN3tI1F5cxUOa&xzkJp=36$Uug9bwY_vXA);^a<5< zXXI)3q4KFUOz*q(B(*OD#G|run}9rGSeL!lzM>3Cb-0W)rFYr6Et7ReQfNF)?0CjB z7zkYckN0%g!NkXpPmU5!MT)v6yw$<)>UJj4HGa}6nntb9yj;|i01ov?eM26rn25@K zQF)yfU{_TeCDl7m)%eVU!|`F=^YEn3`HzKOk0y5C4di!b!|u3vM*{k91f)~3p2Ux^ z{0WV-fH5Dj0N>(N$5rxE)ix#DiLv`@AfedvLYxK__k8?0p@=&fqlB9Ap&Z52@rbrtn!%|()t zCPWuc4@;H@lE#y%g^l}vXmyZ6n%h*f+-9E!-LIA2*Qb^c9Q4JCo|K5YhYV8}t1j;f+6~D>M z{VnRILnF>h4SWOpgzDU?rZt6mare3UrpP5kHjCmt$Ei2s>IM9I!E8bS@O;;iFOc4g zjT#t8MFpQzHfq;v6KYr&e8SS-sq9e5Q04vq4jA1mRqVyR32?90YxNI}m_p97O< zjk;pOHVWuXg4m4Ny>r3i8e)V*ghcU0t|E|0w7IpMeh}~pqyiA`+6rxHo;gZCNP%6Q zGhZg4T;11&bKa1rgjh$VDGjDbXY&*T6wsfzXiaDjejb6V)>_ghHRzGl?OE_L zjk=3mLd$}atTIY_bu^?vPHeYIC>9-@bj?na4bF+L6;vQcRs3G?^) zYj@Qm3w1JouSap+MC@?eXTK(2Np@H@`83&PtDl&;3P|F$+zVA|FKy{|1YKg>lNA4s zkeiAg86#tA$K~;CA#y>*+b}N9r>AW;w!yK@U}a}v^lv6u_6YlG`)V)#y8B^x%z`-> zc#`_kewL==Qn(u>1_oOCZWba*#F;2W#`hbJ`|Rx(uB)*(V%AE=TPb=<_YdztA5o*B zbp^TKrSHKk@aU|PdYTa2EMzmx$L*DNh-XqUR z6k>eb2Lp!6;8}Rk#6Vbxi|D1{k2*Gq+dPu-Gm6y3oy^?Nj?bQvX!!-OlKV=S%nC0PW(Y z5Dq>7`HH^6{wDmk&zsc?ZIM^WAbgY%kPky%*r@f;{1sEw%(%-uH)hdy$_UKlm8lb4 z{i~wI?$vL7%~8q%eX@sYe8jaMQYMq$Q|7}xeyHP+24XWW;>cmmHo19qAw{}$G8`0t zTfIB~DUqurDe9aUsJT18i(X8G8N8%Tok3*gHv_Y*3m#S~WJ{t^_!@|Emnty60Xux5V96ldA{Vq@8_)wGPxN_X? z#1`F|zDAz68rnE58|*RXA&b!=a^cmyOo>vhb~-evcD83A z<=VSs^&<`>59bu5*Ntcb1@VxMgHO8NGn&Dkleh_<<_v6Djm|HXvO@eX##89)t2dkE z1Xi!6=El;g#+$LCq~F@FpKGkt?LYaZ^%P_3T#GU4cuEXh=uN$BoHg=VDZu=SqlzZD z-nX@USHkVZwIdU23}BdknA&Kze=WXQU&ptYM7j^RKKSc93%(wlmUTjPi^=1%J+=Qv z#pa7?>8xQ*&CiV`hCytx1V41xEmHHJO&&Ald|clwKgq)f2H-)t@rqTMbI*#=iJNM- ztd~I)?XgR$?f&N>i(i%!x;(%dw-KXpn(Tq>jj{i$2 z@%LH2^Rve(P)yt5tQj6g#aEB>t`Uaf+nwfC7N1(v%={upV!Nd;2sjd~!GjXDbGY{& z(V_@e)3J%`rZ1HPx!R}?(39lA5CggzYyA0Y*+s(7*w{b?dMgxsL4r%lyqH^&O&2MD zc!@oJ)y#|TABn`rKK1ruCb@&Px3-W0_MwDfww@(PA${Wu*AYjLA-VWQXarOuZo+*V zGvp6odKWEj1}ceG6?$sb`Ivqy9FEv_NWYijM?RmO6t#yI?)N5>wPN+=2>GM1;snWKtx6=XC%X_t#VeUJYifJ z=~?swcRf}#hf#argOH=*0RL~%d9Jt$z|NF3(Uox~^hN?+>;nsZ7`Z2ea(-Uofqq2O zo`Q$kfOj?(QNN$$8ciK*0>s?(ZZ%6tJ`Haj2}wV2nW$NOlMYgCoSMerL4&yOTx;tg zk*`LSN;20xR}iWIo3Yp7ewk^E4o)Gh?nUtp3(sM}t5r%SX$)8A^I*$Bj}NDj!9^y} zl~zA6D^+Rin!8~df;ic<8p@7VgKj$2_#%ny&Sa52 z?&xO`lJ)LNz8QN?qNq5FAH!R3-Jp|<^OK>R2LErzPzPTO(Y6aoKb&wj{nw2EIvV=w J)v9)3{{yJ%=P)1v7la#6yYORV*TB=q2No^|VBtk(1e}=9VbZ`;` zhq~6G4!RaZ1XmF^ad8wRgGHo5lNdy?E!CzSL?Mb1?ajTuC*|CmUfev8eBXE8pZlKs z1OK^9QeR>3?k2x4KsXF$y9f>SHACv<2rI=Tf0IF(+_`|@u>{>oqMb#a+sd}{2l)8K z;ht+sWKV}QpS6n(=BvYP4dHl$#*_BF$UyLf2+^FvoGh@~o54G#YyWbhknmK6{vkJ~ zU8AZq$15Nldr#kogVg5BWUooMUx~iUtezt6J7#nb%Jkip=(+=J6{t|=t=bnJ-qT?| z7iFToctr+Pay{!b-v}Cv;mw`I708SiSYC2SbmlxO-@4c`Dqu#gKOCXG>KI4i&nu-p zlyNGFxVF`xmz~If=K3=Be`c?uv%(LgU z%83{-3yS+t^G^LHWNeSsS{~-i2&>QS5E)b%$ou$nx_ajZ?ce`Ob4TCAP4_sXo0#WQ zwS$hsl0A~^&xG8*K(i8E)V-NfgG@H$ff>vs+)TmXFl!AhY zQY{Kv6hSOrNFhE*KnsG#VD&+&f)56%_dbMLD~h$*OHPDOVOpcQ#f)4*$hd4^}cqctU+FM~j7c=17Qh^Jd_L4EK;UpA7!A?$@x1HqD#iy_9XA%9t#4ev3 zo3=uoC|NawnHCya!fB%nvtSVC#~U$rT**x!+GgNyOg_muzdAwQ@skC4lJAFn-{O0i z?-@rWg#a`0tck5F6s!d#Z4GerGbb_8OGDQ!(9m|okPpT#uI(*Wkyhl^5J&@;-GG&6 z*XQ)84Pf9?I~i>TCNNpyK6rqJ9#aJ`omXSv>uhA-&JC>3E*L8>0ldmd-(z;JC>>nu6iBLk0=djTw!KvtIONurBLHbAR?y~`On0tZ z!>P%M=9S2PfScd6lO63wmZ(^XzECCv&oQDok-l`_=KVa%9CTyfRR$6bwIP2;1kqPW zyD^cz6yKaubwTv+x3ldTK-^dx^0xCYZ8vMVc{^XlGNZZCE^VM-)I$CC-fmwK7XDej@iG~@x2qC|kwX%(?$yR3P76Q96QO4`H zT$y+j&(jrjS^-#tGf`)pLeot=wADr-9wr!`y1hRFD*{2BZ&zui3_$+5=|(5fVK>%g zjbipWo^tn-&aL`MLMYZ2 zbUX4ko0#Kux_auWoH4*g4k%UBkFtoRC=0EgS}&^A?5JXho7hpt_zRu4GCN%9#Co=J zm%hhN)5>GuQwB2E+5IDE0mP07qh|?1JEB&H>FzVQM&5GpdQ<->r;rrifQ~U1^FF=m z(sDTZXZ$c;a`K`DAQh|8{~ntrCnM?RbL21j;jh_cun3shO@nt5MFT3!39CX~ysqzKyK|c?m z_;|8ckVyeZ90|GmhS9abfLYCd { // Remove all children @@ -322,10 +332,10 @@ function initializeSubadub() { } const track = (e.target as HTMLTrackElement).track; - console.log('active now', track.activeCues); + // console.log('active now', track.activeCues); for (const cue of track.activeCues) { const cueElem = document.createElement('div'); - cueElem.style.cssText = 'background: rgba(0,0,0,0.8); white-space: pre-wrap; padding: 0.2em 0.3em; margin: 10px auto; width: fit-content; width: -moz-fit-content; pointer-events: auto'; + cueElem.classList.add('subadub-active-cues'); cueElem.innerHTML = vttTextToSimple(cue.text, true); // may contain simple tags like etc. customSubsElem.appendChild(cueElem); } @@ -366,7 +376,7 @@ function initializeSubadub() { // Reconcile DOM if necessary if (targetSubsList !== displayedSubsList) { - console.log('updating subs list DOM', targetSubsList, displayedSubsList); + // console.log('updating subs list DOM', targetSubsList, displayedSubsList); removeSubsList(); if (targetSubsList) { @@ -391,7 +401,7 @@ function initializeSubadub() { // Reconcile DOM if necessary if (targetTrackBlob !== displayedTrackBlob) { - console.log('need to update track blob', targetTrackBlob, displayedTrackBlob); + // console.log('need to update track blob', targetTrackBlob, displayedTrackBlob); removeTrackElem(); if (targetTrackBlob) { @@ -404,6 +414,28 @@ function initializeSubadub() { } } + const originalStringify = JSON.stringify; + JSON.stringify = function(value) { + if (value && value.params && value.params.profiles) { + value.params.profiles.unshift(WEBVTT_FMT); + // console.log('stringify', value); + } + if (value && value.ab && value.ab.profiles) { + value.ab.profiles.unshift(WEBVTT_FMT); + } + return originalStringify.apply(this, arguments); + }; + + const originalParse = JSON.parse; + JSON.parse = function() { + const value = originalParse.apply(this, arguments); + if (value && value.result && value.result.movieId && value.result.timedtexttracks) { + // console.log('parse', value); + extractMovieTextTracks(value.result); + } + return value; + } + // Poll periodically to see if current movie has changed setInterval(function() { const movieIdMatch = URL_MOVIEID_REGEX.exec(window.location.pathname); @@ -421,7 +453,7 @@ function initializeSubadub() { document.body.addEventListener('keydown', function(e) { if ((e.keyCode === 67) && !e.altKey && !e.ctrlKey && !e.metaKey) { // unmodified C key - console.log('copying subs text to clipboard'); + // console.log('copying subs text to clipboard'); const subsElem = document.getElementById(CUSTOM_SUBS_ELEM_ID) as HTMLDivElement; if (subsElem) { const pieces = []; @@ -443,7 +475,7 @@ function initializeSubadub() { function hideSubsListTimerFunc() { const el = document.getElementById(SUBS_LIST_ELEM_ID); if (el) { - el.style.display = 'none'; + el.classList.add('subadub-hidden'); } hideSubsListTimeout = null; } @@ -454,16 +486,16 @@ function initializeSubadub() { if (subsElem) { const popup = document.querySelector('.popup-content'); if (popup) { - subsElem.style.display = 'none'; + subsElem.classList.add('subadub-hidden'); } else { - subsElem.style.display = 'block'; + subsElem.classList.remove('subadub-hidden'); } } // Show subs list and update timer to hide it const subsListElem = document.getElementById(SUBS_LIST_ELEM_ID); if (subsListElem) { - subsListElem.style.display = 'block'; + subsListElem.classList.remove('subadub-hidden'); } if (hideSubsListTimeout) { clearTimeout(hideSubsListTimeout); diff --git a/webpack.config.js b/webpack.config.js index fc60666..db83a4a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,6 +2,8 @@ const webpack = require("webpack"); const path = require('path'); const CopyPlugin = require('copy-webpack-plugin'); +const removeSchema = (b) => JSON.stringify(JSON.parse(b.toString()), (k, v) => k === '$schema' ? undefined : v, 2); + module.exports = { entry: { content_script: path.resolve(__dirname, './src/content_script.ts') @@ -28,7 +30,8 @@ module.exports = { }, plugins: [ new CopyPlugin([ - { from: './res', to: '.' }, + { from: './res/**/*.png', to: '.', flatten: true }, + { from: './res/manifest.json', to: 'manifest.json', transform: removeSchema }, { from: './src/subadub.css', to: 'subadub.css' } ]) ] From 455e54b88cdd3ddc5e6a106741cd914f606b05f5 Mon Sep 17 00:00:00 2001 From: Hans Otto Wirtz Date: Sun, 8 Dec 2019 00:28:34 +0100 Subject: [PATCH 3/4] Fix some typos --- .gitignore | 1 + src/subadub.css | 2 +- src/subadub.ts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index bf56190..ab3d8f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store node_modules/ dist/ +subadub.zip diff --git a/src/subadub.css b/src/subadub.css index 926a753..7901b8e 100644 --- a/src/subadub.css +++ b/src/subadub.css @@ -62,7 +62,7 @@ opacity: 0; } -.subabub-custom-subs { +.subadub-custom-subs { position: absolute; bottom: 20vh; left: 0; diff --git a/src/subadub.ts b/src/subadub.ts index 4f75c29..4360235 100644 --- a/src/subadub.ts +++ b/src/subadub.ts @@ -226,7 +226,7 @@ function initializeSubadub() { if (showSubsState) { subsElem.classList.remove('subadub-invisible'); } else { - subsElem.classList.add('subadub-iinvisible'); + subsElem.classList.add('subadub-invisible'); } } } From d14751f8abd7982e3f5645307e4a576e9b3c83d2 Mon Sep 17 00:00:00 2001 From: Hans Otto Wirtz Date: Sun, 8 Dec 2019 00:32:39 +0100 Subject: [PATCH 4/4] Update readme --- README.md | 10 ++++++---- package-lock.json | 15 --------------- package.json | 6 +++--- res/manifest.json | 2 +- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 1e390c7..734dc33 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,10 @@ Subadub is a browser extension for Chrome and Firefox that enhances Netflix subt ## Process to Publish a New Version -- make changes to dist/content_script.js -- bump version number in dist/manifest.json +- run `npm install` +- make changes to `src/` +- run `npm run build` +- bump version number in `res/manifest.json` - (best to commit+push these changes, but not required) -- run archive.sh to produce new subadub.zip -- upload subadub.zip to Chrome Web Store (https://chrome.google.com/webstore/developer/dashboard) and Firefox Add-on Developer Hub (https://addons.mozilla.org/en-US/developers/) +- run `npm run archive` to produce new `subadub.zip` +- upload `subadub.zip` to Chrome Web Store (https://chrome.google.com/webstore/developer/dashboard) and Firefox Add-on Developer Hub (https://addons.mozilla.org/en-US/developers/) diff --git a/package-lock.json b/package-lock.json index b579161..e1ab027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2762,12 +2762,6 @@ "path-exists": "^3.0.0" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4617,15 +4611,6 @@ "uuid": "^3.3.2" } }, - "webpack-merge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", - "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, "webpack-sources": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", diff --git a/package.json b/package.json index c679b87..03d1c44 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Enhanced Netflix subtitles for foreign language study", "main": "dist/content_script.js", "scripts": { - "build": "webpack" + "build": "webpack", + "archive": "bash ./archive.sh" }, "repository": { "type": "git", @@ -24,7 +25,6 @@ "ts-loader": "^6.2.1", "typescript": "^3.7.3", "webpack": "^4.41.2", - "webpack-cli": "^3.3.10", - "webpack-merge": "^4.2.2" + "webpack-cli": "^3.3.10" } } diff --git a/res/manifest.json b/res/manifest.json index d7c7f2a..96bb1ca 100644 --- a/res/manifest.json +++ b/res/manifest.json @@ -3,7 +3,7 @@ "manifest_version": 2, "name": "Subadub", "description" : "Enhanced Netflix subtitles for foreign language study", - "version": "0.1.4", + "version": "0.1.5", "icons": { "16": "icon16.png", "48": "icon48.png",