diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..214388f --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not dead diff --git a/.gitignore b/.gitignore index 20128fc..67a7ab0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,6 @@ crash.log # local env files .env.local .env.*.local -.env # Log files npm-debug.log* @@ -28,10 +27,3 @@ pnpm-debug.log* #Electron-builder output /dist_electron - -#Electron-builder config -electron-builder.yml - -#Window and session states -session.json -window.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 2c0d22c..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,63 +0,0 @@ -stages: - - Build - - Upload - - Release - -build: - stage: Build - tags: - # Use a macos runner to build. - - darwin - before_script: - - yarn - script: - - export VERSION=$(node -e "console.log(require('./package.json').version)") - - echo "VERSION=$VERSION" >> variables.env - - export APPNAME=$(node -e "console.log(require('./package.json').productName)") - - echo "APPNAME=$APPNAME" >> variables.env - - yarn build - artifacts: - reports: - dotenv: variables.env - name: $CI_COMMIT_REF_SLUG - paths: - - dist_electron/*.dmg - - dist_electron/*.zip - - dist_electron/*.yml - when: on_success - only: - - main - -variables: - PACKAGE: '${APPNAME}-${VERSION}.dmg' - PACKAGE_REGISTRY_URL: '${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${APPNAME}/${VERSION}' - -# Upload package to gitlab registry. -upload: - stage: Upload - needs: - - job: build - artifacts: true - rules: - - if: $CI_COMMIT_TAG - when: never # Do not run this job when a tag is created manually - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when when commits are pushed to the default branch - script: - # Take the package we built and place it in the package registry. - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file "dist_electron/${PACKAGE}" "${PACKAGE_REGISTRY_URL}/${PACKAGE}"' - -auto-release-master: - image: registry.gitlab.com/gitlab-org/release-cli - needs: - - job: build - artifacts: true - - job: upload - artifacts: true - stage: Release - rules: - - if: $CI_COMMIT_TAG - when: never # Do not run this job when a tag is created manually - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when when commits are pushed to the default branch - script: - - echo "Release $VERSION" - - release-cli create --name "Release $VERSION" --tag-name v$VERSION --description "Release $CI_COMMIT_TITLE" --ref $CI_COMMIT_SHA --assets-link "{\"name\":\"${APPNAME}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${PACKAGE}\"}" diff --git a/README.md b/README.md index c13a8ab..6fb4b27 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ yarn install ### Compiles and hot-reloads for development ``` -yarn electron:serve +yarn dev ``` ### Compiles and minifies for production @@ -15,7 +15,7 @@ yarn electron:serve yarn electron:build ``` - +``` ### Customize configuration See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/build/config.gypi b/build/config.gypi new file mode 100644 index 0000000..6f84ed7 --- /dev/null +++ b/build/config.gypi @@ -0,0 +1,79 @@ +# Do not edit. File was generated by node-gyp's "configure" step +{ + "target_defaults": { + "cflags": [], + "default_configuration": "Release", + "defines": [], + "include_dirs": [], + "libraries": [] + }, + "variables": { + "asan": 0, + "build_v8_with_gn": "false", + "coverage": "false", + "dcheck_always_on": 0, + "debug_nghttp2": "false", + "debug_node": "false", + "enable_lto": "false", + "enable_pgo_generate": "false", + "enable_pgo_use": "false", + "error_on_warn": "false", + "force_dynamic_crt": 0, + "host_arch": "x64", + "icu_data_in": "../../deps/icu-tmp/icudt67l.dat", + "icu_endianness": "l", + "icu_gyp_path": "tools/icu/icu-generic.gyp", + "icu_path": "deps/icu-small", + "icu_small": "false", + "icu_ver_major": "67", + "is_debug": 0, + "llvm_version": "0.0", + "napi_build_version": "6", + "node_byteorder": "little", + "node_debug_lib": "false", + "node_enable_d8": "false", + "node_install_npm": "true", + "node_module_version": 83, + "node_no_browser_globals": "false", + "node_prefix": "/", + "node_release_urlbase": "https://nodejs.org/download/release/", + "node_shared": "false", + "node_shared_brotli": "false", + "node_shared_cares": "false", + "node_shared_http_parser": "false", + "node_shared_libuv": "false", + "node_shared_nghttp2": "false", + "node_shared_openssl": "false", + "node_shared_zlib": "false", + "node_tag": "", + "node_target_type": "executable", + "node_use_bundled_v8": "true", + "node_use_dtrace": "true", + "node_use_etw": "false", + "node_use_node_code_cache": "true", + "node_use_node_snapshot": "true", + "node_use_openssl": "true", + "node_use_v8_platform": "true", + "node_with_ltcg": "false", + "node_without_node_options": "false", + "openssl_fips": "", + "openssl_is_fips": "false", + "shlib_suffix": "83.dylib", + "target_arch": "x64", + "v8_enable_31bit_smis_on_64bit_arch": 0, + "v8_enable_gdbjit": 0, + "v8_enable_i18n_support": 1, + "v8_enable_inspector": 1, + "v8_enable_pointer_compression": 0, + "v8_no_strict_aliasing": 1, + "v8_optimized_debug": 1, + "v8_promise_internal_field_count": 1, + "v8_random_seed": 0, + "v8_trace_maps": 0, + "v8_use_siphash": 1, + "want_separate_host_toolset": 0, + "xcode_version": "11.0", + "nodedir": "/Users/Enrique/Library/Caches/node-gyp/14.4.0", + "standalone_static_library": 1 + } +} diff --git a/gcloud.json b/gcloud.json new file mode 100644 index 0000000..5c68549 --- /dev/null +++ b/gcloud.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "crimata", + "private_key_id": "3a324fa3fcca4cea589e4b5007f4142db4b3a84d", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCxFJOjhIkYlyhn\nHjtpFC5EOwzNFZem6k6SS7zcgWbNLe9mcBsiTKCjpxItzkIo0pnT32yqw+AKsqpv\n6+LVyzzjfB7vtEUflvg6KgmYMS4ixOTCEbN3e2qj1t2RnITXZR2VGSGdoKKyqZm0\ntWrmexQvSN20cByL1vfxD3E69oYFGhVraa0zmm94WXHAzofT6DkvGdrbK1s1G9jI\nG3mdQ1jN71tghyloeHL+R/1iKQoZFYTkVe6yWvccSNAZelt/5sciCKRTCArXj89X\nLwU6jGOKIsyqx3BeUyWaSS59xpnGX3meSf5Q9U+j45ePUiqO6TTleF+kWiBwjUpp\nfeYcwEIDAgMBAAECggEAElkN9R7p75zV6F1XDYu0QYiWyncmx/o2Gu1zC6vywWa1\ni/korpSe/mX0ub9J1p3/p1balRUHlUQu6brYvYs56140fGTC1sOXQ7uQU+8glySs\niTk5TbOBeKluOsSrdP/6oTTB6Wm4AegVz4YOpgPxsvaLVkNZidnDxfvyIQhjGYsO\nsvRaw48eEmGOa1uvDhgvPOxiDp5YEdxqSue/7ylzjBdKecDyLgTSDDf/p+FwIx5B\n2d/0uRgQBaAk6D/DNOvN8GrYyakFmlDjE72nrBGAJq50UyV6THOSDk+8cK+2QiS1\nEDCFufj+7Dk1EBfBFUFY8ZBB/pphpEWyLoFl7NzGCQKBgQDaj/KOOcj6BkkTj1WM\nRW3KhOE3nhsCQEgQGCflpycEAZj6J7ktBG2/4teDt9sr+Epx8ymnQCZa9pmysdrD\nU0aWku1qUx0IUKTtZbAEbB+AnrWYDYkIWU8kRUUvNHNTBg43VyuohV9wprPih138\nHWMeNac82/XICz2A3rv+Xkx8KwKBgQDPaaEEGWVs3nIhf/p3M3/xWNKt8fhAERpG\n0YpTjgHW3FQFYjiCTTIcuLO3qsDGmfIAB9tL37s2Y3e2wKBGUj/o69Fr7sWVPdsX\nJtUc0+KiG2Bs0hsyZPdk9UQiQX8y2eq1NZW7vEoxWso1bM64WURB5N8ocWePNJJx\nL2Oe75rtiQKBgQDLfQQOiRxmNF3rOSMkAywyRr9NQgXRdbniSiszNQotP7OHDF7q\n29m2suOGfjIv4O6m4wdf8WkEfd4hsleETc9Ft6wVtyYrrLGxWWCk7WnzHVDjLY7s\n2AHIOjostf+9R8EKoz1BnFN8laibev71EQNMiBWZow1VX6m2hymurWs2mwKBgQCb\nuY3n2v14qOb92e1+U89KsEq1yMd/qpeU9jwqEaO14wS+aglNY5ItWEuuqWhFdE3q\n0ftHUzpnUnUOZD+xrI1JXsyEgegc7i0xi7lUBI3S8kUKTxGWW5IXXcKDCbPrxQtg\ndFPweSUnOyg4xnHKnVMPOjyGS+bZ8TnF+zOLoBAtKQKBgF6hAOIwF1DheXT4p8xS\nlSGhl8dBxjsJDVwbnFWQceGzGnq1e3ncy/UItt42UCDVRWTH4r7pQ9eKyd/3foUD\n6KDIcCrYo2KJh6ZNFJ67XF30U+TuEg5U/9jTbWqDOwYVXcMcnzQE4ZiGBxVHL6xr\nNc8FRW5+7xh4zNfzhGUGt5kt\n-----END PRIVATE KEY-----\n", + "client_email": "crimata-service-account@crimata.iam.gserviceaccount.com", + "client_id": "102914612880037864172", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/crimata-service-account%40crimata.iam.gserviceaccount.com" +} diff --git a/login.svg b/login.svg new file mode 100644 index 0000000..a2ccbf3 --- /dev/null +++ b/login.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + Email + Password + + Login + + Submit + Create account + + \ No newline at end of file diff --git a/package.json b/package.json index 24d13b1..5bb4571 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,24 @@ { "name": "Crimata", - "version": "0.9.9", - "private": true, + "productName": "crimata-messenger", "description": "Cross-platform messenger application built with electron, vue3, and TS.", + "version": "0.1.0", + "private": true, "author": { "name": "Enrique Hernandez" }, "scripts": { - "build": "vue-cli-service electron:build", - "dev": "vue-cli-service electron:serve", + "dev": "yarn electron:serve", + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "test:unit": "vue-cli-service test:unit", + "lint": "vue-cli-service lint", + "electron:build": "vue-cli-service electron:build", + "electron:serve": "vue-cli-service electron:serve", "postinstall": "electron-builder install-app-deps", - "postuninstall": "electron-builder install-app-deps" + "postuninstal": "electron-builder install-app-deps" }, - "main": "init.js", + "main": "background.js", "dependencies": { "@google-cloud/speech": "^4.2.0", "@types/animejs": "^3.1.2", @@ -22,15 +28,10 @@ "@types/uuid": "^8.3.0", "@types/ws": "^7.2.7", "animejs": "^3.2.0", - "axios": "^0.21.1", "core-js": "^3.6.5", - "electron-is-dev": "^2.0.0", - "electron-store": "^8.0.0", - "electron-updater": "^4.3.8", "mitt": "^2.1.0", "naudiodon": "^2.3.2", "node-record-lpcm16": "^1.0.1", - "update-electron-app": "^2.0.1", "uuid": "^8.3.2", "vue": "^3.0.0-0", "vue-router": "^4.0.0-0", @@ -38,8 +39,6 @@ "ws": "^7.3.1" }, "devDependencies": { - "@types/axios": "^0.14.0", - "@types/electron-devtools-installer": "^2.2.0", "@types/jest": "^24.0.19", "@typescript-eslint/eslint-plugin": "^2.33.0", "@typescript-eslint/parser": "^2.33.0", @@ -56,36 +55,17 @@ "@wasm-tool/wasm-pack-plugin": "^1.3.1", "electron": "^9.0.0", "electron-devtools-installer": "^3.1.0", - "electron-log": "^4.3.4", "eslint": "^6.7.2", "eslint-plugin-vue": "^7.0.0-0", "lint-staged": "^9.5.0", "node-sass": "^4.12.0", "optimize-wasm-webpack-plugin": "^1.0.12", "sass-loader": "^8.0.2", - "spectron": "11.0.0", + "spectron": "^11.0.0", "typescript": "~3.9.3", - "vue-cli-plugin-electron-builder": "~2.0.0-rc.6", + "vue-cli-plugin-electron-builder": "~2.0.0-rc.4", "vue-jest": "^5.0.0-0" }, - "vue": { - "lintOnSave": false, - "pluginOptions": { - "electronBuilder": { - "mainProcessFile": "./src/init.ts", - "rendererProcessFile": "./src/render/main.ts", - "preload": "./src/render/preload.ts", - "builderOptions": { - "appId": "com.crimata.ElectronUpdaterApp", - "artifactName": "${productName}-${version}.${ext}", - "publish": { - "provider": "generic", - "url": "https://gitlab.com/api/v4/projects/25637892/jobs/artifacts/main/raw/dist_electron?job=build" - } - } - } - } - }, "gitHooks": { "pre-commit": "lint-staged" }, @@ -94,11 +74,5 @@ "vue-cli-service lint", "git add" ] - }, - "productName": "crimata-messenger", - "repository": { - "type": "git", - "url": "https://gitlab.com/crimata/electron-app.git", - "release": "latest" } } diff --git a/public/index.html b/public/index.html index 8f79d27..48809d8 100644 --- a/public/index.html +++ b/public/index.html @@ -11,7 +11,11 @@ -
+ +
diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..165d108 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/src/account.ts b/src/account.ts deleted file mode 100644 index 581da0e..0000000 --- a/src/account.ts +++ /dev/null @@ -1,95 +0,0 @@ - -import { postAuth, postLogin, postLogout } from "@/api/account"; -import { endSession, launchSession } from "@/session"; -import { getToken, setToken, setProfile, getProfile, clearStore } from "./store"; -import { parseAuthRes } from "./auth"; -import { ipcEmit } from "@/composables/useEmitter"; - -export const accountAuth = async (): Promise => { - - /* attempt to get a login token from the store */ - const token = getToken(); - - /* try to login with it, returns platform secret and new token on success */ - if (token) { - try { - - const res = await postAuth(token); - - const parsed = parseAuthRes(res); - - setToken(parsed.token) - setProfile(parsed.profile); - - return { - profile: parsed.profile, - token: parsed.token - }; - - } catch(e) { - console.log('[ACCOUNT]', e); - clearStore(); - throw(new Error('Failed to authenticate.')); - - } - } else { - throw(new Error('Unable to authenticate.')); - } -}; - -export const accountLogin: IpcHandlerCallback = async (payload) => { - const account = payload as AccountCredentials; - try { - - // attempt login with email password - const res = await postLogin(account.email, account.password); - const parsed = parseAuthRes(res); - - // save jwt token and profile - setToken(parsed.token); - setProfile(parsed.profile); - - // launch session - launchSession(parsed.token); - - // return profile to renderer - return parsed.profile; - - } catch(e) { - clearStore(); - throw e; - } -} - - -export const accountLogout = async (): Promise => { - - try { - // post logout to backend - await postLogout(); - - // remove key and crimataId - clearStore(); - - // kill crimata platform session - endSession(); - - return; - - } catch(e) { - console.log('[ACCOUNT]', e); - return (new Error('Failed to logout. Please try again.')); - } - -} - -export const updateAppState = (): void => { - - const profile = getProfile(); - - ipcEmit("set-profile", profile); - - // ipcEmit('messages') etc - -} - diff --git a/src/api/account.ts b/src/api/account.ts deleted file mode 100644 index 45baca2..0000000 --- a/src/api/account.ts +++ /dev/null @@ -1,31 +0,0 @@ - -import useHttp from "@/composables/useHttp"; -import axios from "axios"; -import {config} from "@/config"; - -const { post } = useHttp(); - -export const postAuth = async (token: string) => ( - await axios({ - url: config.BUSINESS_URL + config.BUSINESS_PREFIX + '/account/authenticate', - headers: { - Cookie: `crimataCookie=${token}` - }, - method: 'POST', - }) -); - - -export const postLogin = async (email: string, password: string) => ( - await post('/account/login', { email, password }) -); - - -export const postLogout = - async (): Promise => (await post('/account/logout')); - - - - - - diff --git a/src/assets/crimata.svg b/src/assets/crimata.svg new file mode 100644 index 0000000..8bb28dc --- /dev/null +++ b/src/assets/crimata.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/audio.ts b/src/audio.ts deleted file mode 100644 index 7ae2562..0000000 --- a/src/audio.ts +++ /dev/null @@ -1,187 +0,0 @@ -/* eslint @typescript-eslint/no-var-requires: "off" */ - -"use strict"; - -// where the audio goes -let buffer: ArrayBuffer[] = []; - -// place audio data in buffer -export const collect: IpcListenerCallback = (chunk) => { - if (chunk) buffer.push(chunk); -} - -// return audio and clear buffer -export const flush = async () => { - const bufferCopy = buffer; - buffer = []; - return bufferCopy; -} - -// import { backgroundMitt } from '@/modules/emitter'; -// const portAudio = require('naudiodon'); - -// // Audio in and out stream objects. -// let ai: typeof portAudio.AudioIO | boolean = false; -// let ao: typeof portAudio.AudioIO | boolean = false; - -// // Whether activly recording. -// let record = false; - -// const audioContainer = { -// input: '', -// } - -// const audioOptions = { -// channelCount: 1, -// sampleFormat: 16, -// sampleRate: 16000, -// deviceId: -1, -// closeOnError: false, -// } - -// export const toggleRecord = (): void => { record = !record }; - - -// export const fetchAudioInput = (): Promise => ( - -// new Promise((resolve, reject) => { - -// try { -// resolve(audioContainer.input); -// toggleRecord(); -// } catch (e) { -// reject(new Error('Failed to fetch the audio.')) -// } - -// }) -// ) - - -// // Main audio function run by run.ts module. -// export function initAudioIO(): void { -// console.log("AUDIO:Starting io streams.") - -// if (!ai) { - -// // Initialize and start input stream. -// ai = new portAudio.AudioIO({ inOptions: audioOptions }); -// ai.setEncoding("hex"); -// ai.start(); - -// // On each data chunk... -// ai.on('data', (chunk: string) => { - -// // If recording, we capture the data. -// if (record) { -// console.log('AUDIO:Recording...') -// audioContainer.input += chunk; -// } - -// // Else, we don't capture and also clear audioContainer. -// else { -// if (audioContainer.input.length) { -// audioContainer.input = ""; -// } -// } - -// }); -// } - -// if (!ao) { - -// // Initialize and start input stream. -// ao = new portAudio.AudioIO({ outOptions: audioOptions }); -// ao.start(); - -// } -// } - - -// // ---Audio playback-------------------------------------------- - -// // Split Buffer into an array of len-sized Buffers. -// function bufSplit(buf: Buffer, len: number): Array { -// const chunks = []; -// let i = 0; -// let L = len; - -// while(i < buf.byteLength) { -// chunks.push(buf.slice(i, L)); -// i = L; -// L += len; -// } - -// return chunks; -// } - -// // Audio playback. -// export function play(input: string): void { - -// // Format the audio. -// const audio = bufSplit( -// Buffer.from(input as string, 'hex'), -// 8192 -// ); - -// // Called on end of write. -// const callback = () => { - -// // We stop audio playback anim. -// backgroundMitt.emit('ipc-renderer', { -// endpoint: 'stop-playback-anim' -// }); - -// } - -// write(); - -// // Iterate through audio array and write buffers to portAudio writable. -// function write() { -// let chunk: Buffer; -// let ok = true; -// let i = 0; - -// do { -// chunk = audio[i]; -// if (i === audio.length - 1) { -// // write last chunk. -// ao.write(chunk, null, callback); -// } else { -// // check for backpreassure. -// ok = ao.write(chunk, null); -// } -// i++; -// } while (i < audio.length && ok); - -// if (i < audio.length) { -// // Had to stop early! -// // Write some more once it drains. -// ao.once('drain', write); -// } -// } -// } - -// // ------------------------------------------------------------- - -// // Get's called on window close. -// export async function stopStream() { -// console.log("AUDIO:Stopping audio stream.") -// if (ai) { -// try { -// await ai.quit() -// } catch(e){ -// console.log('AUDIO: Failed to shutdown audio input.'); -// throw e; -// } -// } -// if (ao) { -// try { -// await ao.quit() -// } catch(e){ -// console.log('AUDIO: Failed to shutdown audio output.'); -// throw e; -// } -// } -// } - - diff --git a/src/auth.ts b/src/auth.ts deleted file mode 100644 index 14ed36a..0000000 --- a/src/auth.ts +++ /dev/null @@ -1,13 +0,0 @@ - -export const parseAuthRes = (authRes: any) => { - const token = authRes.headers['set-cookie'][0].split(";")[0].split("=")[1] as string; - const profile = authRes.data as Profile; - return { - token, - profile - } -}; - - - - diff --git a/src/background.ts b/src/background.ts new file mode 100644 index 0000000..065b4ec --- /dev/null +++ b/src/background.ts @@ -0,0 +1,25 @@ +/* + * Entry point for Crimata electron app. + * "Look on my Works, ye Mighty, and despair!" + */ + +"use strict"; + +import { protocol } from "electron"; +import { initApp } from './background/init'; + +// Scheme must be registered before the app is ready +protocol.registerSchemesAsPrivileged([ + { scheme: "app", privileges: { secure: true, standard: true } } +]); + +// Load environment variable +const isDevelopment = process.env.NODE_ENV !== "production"; + +// NOTE Program Begins Here +(async () => { + + console.log('Starting Crimata electron app.'); + initApp(isDevelopment); + +})(); diff --git a/src/background/audio.ts b/src/background/audio.ts new file mode 100644 index 0000000..5b0ef12 --- /dev/null +++ b/src/background/audio.ts @@ -0,0 +1,135 @@ +/* eslint @typescript-eslint/no-var-requires: "off" */ + +"use strict"; + +import { sendAudio } from './session' +import { ipcMain } from "electron"; +import { backgroundMitt } from './emitter'; + +const portAudio = require('naudiodon'); + +let ai: typeof portAudio.AudioIO | null = null; +let ao: typeof portAudio.AudioIO | null = null; +let record = false; +const audioContainer = { + input: '', +} +const encoding = "hex"; +const audioOptions = { + channelCount: 1, + sampleFormat: 16, + sampleRate: 16000, + deviceId: -1, + closeOnError: false, +} + +// callback run on space bar key up and down. +const updateRecorder = (_event, payload: { + isRecording: boolean; + uid: string | null; +}): void => { + record = payload.isRecording; + if (!record) { + if (payload.uid) sendAudio(audioContainer.input, payload.uid); + } +}; + +// listen for space key up/down event. +ipcMain.removeAllListeners('update-recorder'); +ipcMain.on('update-recorder', updateRecorder); + +// Split Buffer into an array of len-sized Buffers. +function bufSplit(buf: Buffer, len: number): Array { + const chunks = []; + let i = 0; + let L = len; + + while(i < buf.byteLength) { + chunks.push(buf.slice(i, L)); + i = L; + L += len; + } + + return chunks; +} + +// main audio function run by run.ts module. +export function initAudioIO(): void { + + if (!ai) { + ai = new portAudio.AudioIO({ inOptions: audioOptions }); + + // base64 encoding needed for google speech to text. + ai.setEncoding(encoding); + ai.start(); + + ai.on('data', (chunk: string) => { + if (record) { + console.log('recording...') + audioContainer.input += chunk; + } else { + if (audioContainer.input.length) audioContainer.input = ""; + } + }); + } + + if (!ao) { + ao = new portAudio.AudioIO({ outOptions: audioOptions }); + ao.start(); + } +} + +// play audio buffers. +export function play(input: Buffer): void { + let i = 0; + + const audio = bufSplit(input, 8192); + + // Called on end of write. + const callback = () => { + + // We stop audio playback anim. + backgroundMitt.emit('ipc-renderer', { + endpoint: 'stop-playback-anim' + }); + + } + + write(); + + // Iterate through audio array and write buffers to portAudio writable. + function write() { + let chunk: Buffer; + let ok = true; + + do { + chunk = audio[i]; + if (i === audio.length - 1) { + // write last chunk. + ao.write(chunk, null, callback); + } else { + // check for backpreassure. + ok = ao.write(chunk, null); + } + i++; + } while (i < audio.length && ok); + + if (i < audio.length) { + // Had to stop early! + // Write some more once it drains. + ao.once('drain', write); + } + } +} + +export function stopStream() { + if(ai != null) { + ai.quit(); + ai = null; + } + if (ao != null) { + ao.quit(); + ao = null; + } +} + diff --git a/src/background/emitter.ts b/src/background/emitter.ts new file mode 100644 index 0000000..14aa77f --- /dev/null +++ b/src/background/emitter.ts @@ -0,0 +1,6 @@ +/* eslint-disable */ +const EventEmitter = require('events'); + +class BackgroundMitt extends EventEmitter { } + +export const backgroundMitt = new BackgroundMitt(); diff --git a/src/background/init.ts b/src/background/init.ts new file mode 100644 index 0000000..0f60068 --- /dev/null +++ b/src/background/init.ts @@ -0,0 +1,50 @@ + +"use strict"; + +import { app } from "electron"; +import { main } from './run'; +import { backgroundMitt } from './emitter'; +import { stopStream } from './audio'; + +let winActive: boolean; + +backgroundMitt.on('window-active', (state: boolean) => { + winActive = state; +}); + +export function initApp(dev: boolean): void { + + app.on("ready", () => { + main(); + }); + + // Quit when all windows are closed. + app.on("window-all-closed", () => { + if (process.platform !== "darwin") { + stopStream(); + app.quit(); + } + }); + + app.on("activate", () => { + if (winActive === false) { + main(); + } + }); + + // Exit cleanly on request from parent process in development mode. + if (dev) { + if (process.platform === "win32") { + process.on("message", data => { + if (data === "graceful-exit") { + app.quit(); + } + }); + } else { + process.on("SIGTERM", () => { + app.quit(); + }); + } + } +} + diff --git a/src/background/run.ts b/src/background/run.ts new file mode 100644 index 0000000..55aad46 --- /dev/null +++ b/src/background/run.ts @@ -0,0 +1,28 @@ +"use strict"; + +import { createWindow } from './window'; +import { initSession } from './session'; +import { initAudioIO } from './audio'; + +let socket = false; + +/* + * The main function will be run after electron app is ready. + */ +export async function main() { + + // create main window. + await createWindow({ + width: 600, + height: 500, + resizable: true + }); + + // Instantiate socket session with crimata-platorm. + if (!socket) initSession(); + socket = true; + + // Begin audio stream. + initAudioIO(); + +} diff --git a/src/background/session.ts b/src/background/session.ts new file mode 100644 index 0000000..861eaea --- /dev/null +++ b/src/background/session.ts @@ -0,0 +1,159 @@ +"use strict"; + +import WebSocket from 'ws'; +import { backgroundMitt } from './emitter'; +import { ipcMain } from "electron"; +import { play } from './audio'; +import { UserCreds, ClientMessage, RenderMessage, Annotation } from "@/types/message/index"; +import { clientMessage, initRenderMessageFromString } from '@/modules/message'; +import { v4 as uuidv4 } from 'uuid'; + +const ip = 'ws://127.0.0.1'; +const port = 8760; +const reconnectTimeout = 3000; //ms +let socket: WebSocket; +let success = false; +let auth = false; + +const onAuthSession = async (e: any, payload: string | UserCreds | null): Promise => { + return new Promise((resolve, reject) => { + + console.log('authenticating...'); + + backgroundMitt.once('auth-res', (res: string) => { + + if (res === 'locked') { + reject(res); + } else { + console.log('Success!'); + auth = true; + resolve(res); + } + + }); + + if (!payload) { + socket.send('no-token'); + } else if (payload instanceof String || typeof payload === 'string') { + socket.send(payload); + } else { + socket.send(JSON.stringify(payload)); + } + + }); +}; + +const onMessage = (message_str: string): void => { + + while (!auth) { + backgroundMitt.emit('auth-res', message_str); + return; + } + + // Decode the message. + const m = JSON.parse(message_str) + let message: RenderMessage | Annotation; + + // Check to see if this is a Render Message. + if (m.content) { + message = initRenderMessageFromString(message_str) + + // Play audio if any. + if (message.content.audio) { + const audioBytes = Buffer.from(m.content.audio as string, 'hex'); + m.content.audio = true; + play(audioBytes); + } + + } + + else { + message = m // Annotation + } + + // Send it to the frontend. + backgroundMitt.emit('ipc-renderer', { + endpoint: 'render-message', + message: message + }); + +}; + +const onClientMessage = (e: any, payload: ClientMessage): void => { + console.log('sending message'); + socket.send(JSON.stringify(payload)); +} + +const restart = () => { + auth = false; + initSession(); +} + +// Run every time we want to connect to backend. +export function initSession(): void { + + // Close existing sockets. + if (socket) { + socket.removeAllListeners(); + socket.terminate(); + socket.close(); + success = false; + } + + // Init new socket. + socket = new WebSocket(`${ip}:${port}`); + socket.binaryType = 'arraybuffer'; + + // handle renderer auth-token event + ipcMain.removeHandler('auth-session'); // avoid setting duplicate handlers + ipcMain.handle('auth-session', onAuthSession); + + // handle user message event + ipcMain.removeAllListeners('client-message'); + ipcMain.on('client-message', onClientMessage); + + // handle renderer logout event + ipcMain.removeAllListeners('logout'); + ipcMain.on('logout', (_event, _payload: string) => restart()); + + // Connect to the backend. + socket.on('open', () => { + console.log('Connected to Crimata Servers.'); + + // call auth renderer event on connection + backgroundMitt.emit('ipc-renderer', { + endpoint: 'auth', + message: null + }); + + success = true; + + }); + + // Handle for failed connect, try again. + socket.on('error', (_e) => { + console.log('ERROR: Failed to connect.'); + socket.removeAllListeners(); + socket.close(); + setTimeout(() => { + if (!success) { + console.log('Reconnecting...'); + initSession(); + } + }, reconnectTimeout); + + }); + + socket.on('close', () => { + console.log('Connection droped! Restarting...'); + restart(); + }); + + socket.on("message", onMessage); +} + + +export function sendAudio(audio: string, uid: string): void { + const m = clientMessage("", audio, uid); + socket.send(JSON.stringify(m)); +} \ No newline at end of file diff --git a/src/background/window.ts b/src/background/window.ts new file mode 100644 index 0000000..27aac38 --- /dev/null +++ b/src/background/window.ts @@ -0,0 +1,109 @@ +"use strict"; + +import { BrowserWindow, ipcMain } from "electron"; +import { createProtocol } from "vue-cli-plugin-electron-builder/lib"; +import { backgroundMitt } from './emitter'; +import { RenderMessage } from "@/types/message/index"; +import * as path from "path"; + +interface WindowSettings { + width: number; + height: number; + resizable: boolean; +} + +interface IpcRendererPayload { + endpoint: string; + message: RenderMessage | null; +} + +let win: BrowserWindow | null; + +// Util function to handle window close & minimize. +const navBarHandler = (_event, action: string): void => { + switch(action) { + case 'close': + if (win) win.close(); + break; + case 'min': + if (win) win.minimize(); + break; + } +} + +// Util function to render message on ipc-renderer event. +const renderMessage = (payload: IpcRendererPayload): void => { + if (win) { + win.webContents.send(payload.endpoint, { + message: payload.message + }); + } +} + +// Do this on window mount. +const windowMount = (): void => { + backgroundMitt.emit('window-active', true); + // handle win nav-bar event. + ipcMain.removeHandler('nav-bar'); // avoid setting duplicate handlers + ipcMain.handle('nav-bar', navBarHandler); + // render messages through ipc-renderer. + backgroundMitt.on('ipc-renderer', renderMessage); +} + +// do this on window dismount. +const windowDismount = (): void => { + win = null; + backgroundMitt.emit('window-active', false); +} + +// function used by run.ts to create the main window. +export async function createWindow(options: WindowSettings): Promise { + return new Promise((resolve, _reject) => { + + // avoid creating duplicate windows. + if (win) resolve(); + + win = new BrowserWindow({ + width: options.width, + height: options.height, + resizable: options.resizable, + backgroundColor: '#EBEBEB', + frame: false, + minWidth: 350, + minHeight: 500, + webPreferences: { + // Use pluginOptions.nodeIntegration, leave this alone + // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info + nodeIntegration: (process.env + .ELECTRON_NODE_INTEGRATION as unknown) as boolean, + preload: path.join(__dirname, "preload.js") + } + }); + + + if (process.env.WEBPACK_DEV_SERVER_URL) { + // Load the url of the dev server if in development mode + win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string); + } else { + createProtocol("app"); + // Load the index.html when not in development + win.loadURL("app://./index.html"); + } + + // Handle window close. + win.on("closed", windowDismount); + + win.once('ready-to-show', () => { + if (win) win.show() + }) + + win.webContents.on('did-finish-load', () => { + if (win) win.webContents.send('window-ready', { + message: true + }); + windowMount(); + resolve(); + }); + + }); +} diff --git a/src/components/inputItem/inputController.ts b/src/components/inputItem/inputController.ts new file mode 100644 index 0000000..3b23dd2 --- /dev/null +++ b/src/components/inputItem/inputController.ts @@ -0,0 +1,150 @@ +/* +* Main logic used by inputItem component. +* Will visualize text input by default as user types. +* If user holds space bar down, input audio stream will +* be recorded and sent to the backend for analysis. +*/ + +import { ref, watch, onUnmounted, onMounted } from "vue"; +import useMitt from "@/modules/mitt"; +import { useIpc } from '@/modules/ipc'; +import keyboardNameMap from "./keyBoardMaps/keyboardNameMap"; +import keyboardCharMap from "./keyBoardMaps/keyboardCharMap"; +import {clientMessage, initRenderMessage} from '@/modules/message'; + +let textInput: HTMLInputElement | null; + +export default function useInputController() { + + const { emitter } = useMitt(); + const { post } = useIpc(); + const isRecording = ref(false); + const isTyping = ref(false); + const input = ref(""); + + // send message on ENTER. + const onEnter = () => { + + if (input.value) { + // remove first character of input. + const text = input.value.substring(1); + + // Render the message immediately. + const message = initRenderMessage(text, "", "", "sf"); + emitter.emit("self-message", message); + + // Then send it to the backend for processing. + const clientM = clientMessage(text, false, message.uid); + post('client-message', clientM); + + // Reset the text input. + if (textInput) textInput.value = ''; + input.value = " "; + } + + } + + // update input on keydown event & listen for special commands. + const onKeyDown = (e: KeyboardEvent) => { + + if (textInput) textInput.focus(); + + // keyboardCharMap is an array of arrays, with each inner + // array having 2 columns - un-shifted, and shifted values. + // iCol = 0 is the un-shifted value, while iCol=1 is the shifted value. + // See the "keyboardCharMap" module for possible keys. + // MODIFY keyboardCharMap to suit your needs if you want + // more/less/different characters to be considered "printable". + let iCol = 0; + if (e.shiftKey) { + iCol = 1; + } + + const ch = keyboardCharMap[e.keyCode][iCol]; + + // Optionally do things with non-printables, + // like CR, ESC, Backspace, LF, Tab, Arrows, F1-F24, etc. + // See the arrary "keyboardNameMap" module for possible keys. + const cmd = keyboardNameMap[e.keyCode]; + + switch (cmd) { + case "ENTER": + onEnter(); + break; + case "BACK_SPACE": + input.value = input.value.slice(0, -1); + break; + case "ESCAPE": + if (textInput) textInput.value = '' + input.value = ""; + break; + default: + input.value += ch; + } + + } + + // stop stream recording and render audio message on space key up event. + const onKeyUp = (e: KeyboardEvent) => { + if (e.key === " " && isRecording.value) { + + isRecording.value = false; + + // Render the message immediately. + const audioMessage = initRenderMessage("", "", "", "sf") + emitter.emit("self-message", audioMessage); + + // Notify backend to stop recording and send audio to python backend for audio processing. + post('update-recorder', { + isRecording: isRecording.value, + uid: audioMessage.uid + }); + + // Reset input. + input.value = '' + } + } + + onMounted(() => { + textInput = document.getElementById('textInput') as HTMLInputElement; + // add window event keyboard listeners + window.addEventListener("keydown", onKeyDown); + window.addEventListener('keyup', onKeyUp); + }) + + onUnmounted(() => { + window.removeEventListener("keydown", onKeyDown); + window.removeEventListener("keyup", onKeyUp); + }); + + // watch keyboard input & update current state. + watch(input, (input, prevInput) => { + + if (prevInput !== "" || prevInput.length > 0) { + if (!isRecording.value) { + isTyping.value = true; + } + return; + } + + if (input === " " && isRecording.value === false) { + isTyping.value = false; + isRecording.value = true; + post('update-recorder', { + isRecording: isRecording.value, + uid: null + }); + return; + } + + isTyping.value = true; + + }); + + return { + input, + isRecording, + isTyping + } + +} diff --git a/src/render/components/inputItem.vue b/src/components/inputItem/inputItem.vue similarity index 63% rename from src/render/components/inputItem.vue rename to src/components/inputItem/inputItem.vue index edd844f..803b6a7 100644 --- a/src/render/components/inputItem.vue +++ b/src/components/inputItem/inputItem.vue @@ -2,24 +2,18 @@
-
{{ initials }}
- - - - + + + +
+
- - - - +
@@ -27,36 +21,25 @@ @@ -136,7 +133,6 @@ margin: 2px; border-radius: 2.5px; background-color: #9B9B9B; - } .settingsOption { @@ -149,11 +145,6 @@ border: none; outline: none; text-decoration: none; - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - z-index: 5; } .settingsOption:hover { diff --git a/src/render/components/splash.vue b/src/components/splash.vue similarity index 100% rename from src/render/components/splash.vue rename to src/components/splash.vue diff --git a/src/composables/autoUpdate.ts b/src/composables/autoUpdate.ts deleted file mode 100644 index 1a6b780..0000000 --- a/src/composables/autoUpdate.ts +++ /dev/null @@ -1,31 +0,0 @@ -const { autoUpdater } = require('electron-updater'); - -let win: boolean; - -// Listen for window creation. -backgroundMitt.on('window-active', (state: boolean) => { - win = state; -}); - -// Auto updating. -autoUpdater.requestHeaders = { 'PRIVATE-TOKEN': 'mvvgWYwWnot4bisiQMh_' } - -autoUpdater.on('update-available', (info: any) => { - console.log(`Update available: ${info.version}`) -}) - -autoUpdater.on('update-downloaded', (info: any) => { - - const updateDialog = { - type: 'info', - buttons: ['Restart', 'Later'], - title: 'Application Update', - message: info.version, - detail: 'A new version has been downloaded. Restart the application to apply the updates.' - } - - dialog.showMessageBox(updateDialog).then((returnValue) => { - if (returnValue.response === 0) autoUpdater.quitAndInstall() - }) - -}) \ No newline at end of file diff --git a/src/composables/useEmitter.ts b/src/composables/useEmitter.ts deleted file mode 100644 index f95f328..0000000 --- a/src/composables/useEmitter.ts +++ /dev/null @@ -1,16 +0,0 @@ - -// Backend emitter -// -const EventEmitter = require('events'); -class BackgroundMitt extends EventEmitter { } - -export const backgroundMitt = new BackgroundMitt(); - -export const ipcEmit = (channel: string, payload: T) => { - backgroundMitt.emit('ipc-renderer', { - channel, - payload - }); -}; - - diff --git a/src/composables/useHttp.ts b/src/composables/useHttp.ts deleted file mode 100644 index 6b9ee56..0000000 --- a/src/composables/useHttp.ts +++ /dev/null @@ -1,51 +0,0 @@ - -import axios, { AxiosRequestConfig } from 'axios'; -import {config} from "@/config"; - -const baseURL = config.BUSINESS_URL + config.BUSINESS_PREFIX; - -interface Request { - endpoint: string; - query?: Record; - config?: Record; -} - -const makeQuery = (reqQuery: Record) => { - - let result = ''; - - result = '?' + Object.entries(reqQuery) - .map(([ key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) - .join('&') - - return result; -}; - - -export default function useHttp() { - - const api = axios.create({ - baseURL, - withCredentials: true, - }); - - - const post = async (endpoint: string, payload?: Record): Promise => ( - await api.post(endpoint, payload) - ) - - - const get = async (req: Request) => { - - if (req.query) { - req.endpoint += makeQuery(req.query); - } - - const res = await api.get(req.endpoint, req.config); - return res; - }; - - return { - get, post - } -} diff --git a/src/composables/useIpcMain.ts b/src/composables/useIpcMain.ts deleted file mode 100644 index ebfc4bc..0000000 --- a/src/composables/useIpcMain.ts +++ /dev/null @@ -1,82 +0,0 @@ - -import { ipcMain, IpcMainInvokeEvent, IpcMainEvent } from "electron"; - -export class IpcHandler implements IIpcHandler { - - readonly channel: string; - - readonly _handlerCallback: IpcHandlerCallback; - - constructor(options: { - channel: string; - handlerCallback: IpcHandlerCallback; - }) { - this.channel = options.channel; - this._handlerCallback = options.handlerCallback; - } - - handle() { - this.remove(); - ipcMain.handle(this.channel, this._onInvoke); - } - - remove() { - ipcMain.removeHandler(this.channel); - } - - private _onInvoke = (_e: IpcMainInvokeEvent, payload?: string | null): Promise => { - - return new Promise(async (resolve, reject) => { - - console.log(`[IPC] Handle:${this.channel}`); - - try { - - const params = payload ? JSON.parse(payload) : null; - - const res = await this._handlerCallback(params); - - resolve(res as unknown as ReturnType); - - } catch(e) { - console.log(`[IPC] Error:${this.channel}`); - reject(e); - } - }); - } - -} - - -export class IpcListener implements IIpcListener { - - readonly channel: string; - - readonly _listenerCallback: IpcListenerCallback; - - constructor(options: { - channel: string; - listenerCallback: IpcListenerCallback; - }) { - this.channel = options.channel; - this._listenerCallback = options.listenerCallback; - } - - listen() { - this.remove(); - ipcMain.on(this.channel, this._onPost); - } - - remove() { - ipcMain.removeAllListeners(this.channel); - } - - private _onPost = (_e: IpcMainEvent, payload?: string | null): void => { - - console.log(`[IPC] Post: ${this.channel}`); - - const params = payload ? JSON.parse(payload) : null; - this._listenerCallback(params); - } - -} diff --git a/src/composables/useMessageCanvas.ts b/src/composables/useMessageCanvas.ts deleted file mode 100644 index c85f7ed..0000000 --- a/src/composables/useMessageCanvas.ts +++ /dev/null @@ -1,36 +0,0 @@ - - - -export default class Canvas { - - messages: Message[]; - - /* seed canvas with messages on init */ - constructor(messages: Message[]) { - this.messages = messages; - ipcEmit("seed-view", this.messages); - } - - /* add a new message to the canvas */ - add(message: Message) { - this.messages.push(message); - ipcEmit("update-view", message); - } - - /* update an existing message */ - update(message: Message) { - - /* get the target message */ - let target_message = this.messages.filter((m: Message) => { - return m.uid = message.uid; - })[0]; - - /* replace the target message */ - if (target_message) { - target_message = message; - ipcEmit("update-view", message); - } - - } - -} diff --git a/src/composables/useSaveToJSON.ts b/src/composables/useSaveToJSON.ts deleted file mode 100644 index 06ab4b9..0000000 --- a/src/composables/useSaveToJSON.ts +++ /dev/null @@ -1,13 +0,0 @@ - -import {config} from "@/config"; -import fs from 'fs'; - -export const saveToJson = (fileName: string, data: any) => { - - fs.writeFile(config.configPath + fileName, JSON.stringify(data), (err) => { - if (err) { - console.log("Error when saving to json.") - } - }) - -} diff --git a/src/composables/useWebsockets.ts b/src/composables/useWebsockets.ts deleted file mode 100644 index d1cfc02..0000000 --- a/src/composables/useWebsockets.ts +++ /dev/null @@ -1,89 +0,0 @@ - -"use strict"; - -import WebSocket from 'ws'; - - -const _connectionCheckTimeout = 4000; -const _reconnectTimeout = 1000; -let _connectionCheckInterval: ReturnType; - - -export default function useWebSockets( - messageCallback: (message: string) => void, - connectionStatusCallback: (alive: boolean) => void, -) { - - let socket: WebSocket; - - const send = async (data: Record): Promise => { - return new Promise((resolve, reject) => { - if (socket) { - if (socket.readyState === WebSocket.OPEN) { - socket.send(JSON.stringify(data)); - resolve(true); - } - } - reject(false); - }); - } - - const connect = (socketUrl: string, secret: string) => { - - // avoid setting multiple interval; - if (_connectionCheckInterval) clearInterval(_connectionCheckInterval); - - /* create a new socket */ - socket = new WebSocket(socketUrl); - - /* add event listeners */ - socket.on("open", () => { - - socket.send(JSON.stringify({key: secret})); - - // ping server - _connectionCheckInterval = setInterval(() => { - - socket.ping(null, true, (e: Error) => { - if (e) { - socket.close(); - connectionStatusCallback(false); - setTimeout(() => connect(socketUrl, secret), _reconnectTimeout); - } - }); - - }, _connectionCheckTimeout); - - }); - - socket.on("message", (event: WebSocket.MessageEvent) => { - console.log("message received", event); - messageCallback(event.toString()) - }); - - socket.on("close", (event: WebSocket.CloseEvent) => { - connectionStatusCallback(false); - clearInterval(_connectionCheckInterval); - if (!event.wasClean) { - setTimeout(() => connect(socketUrl, secret), _reconnectTimeout); - } - - }); - - socket.on("pong", () => connectionStatusCallback(true)); - - } - - const close = () => { - if (socket) { - socket.close(); - } - } - - return { - connect, - send, - close - }; - -} diff --git a/src/config.ts b/src/config.ts deleted file mode 100644 index 855b1b2..0000000 --- a/src/config.ts +++ /dev/null @@ -1,17 +0,0 @@ - -import { app } from "electron"; - -const env = process.env; - -const PLATFORM_PORT = env.PLATFORM_PORT || 8760; -const PLATFORM_IP = env.PLATFORM_IP || 'http://127.0.0.1'; - -const BUSINESS_PORT = env.BUSINESS_PORT || 3000; -const BUSINESS_IP = env.BUSINESS_IP || 'http://127.0.0.1'; - -export const config = { - PLATFORM_URL: `${PLATFORM_IP}:${PLATFORM_PORT}`, - BUSINESS_URL: `${BUSINESS_IP}:${BUSINESS_PORT}`, - BUSINESS_PREFIX: '/api', - configPath: app.getPath('userData') -} diff --git a/src/init.ts b/src/init.ts deleted file mode 100644 index 9a0fdf6..0000000 --- a/src/init.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Entry point for Crimata electron app. - * "Look on my Works, ye Mighty, and despair!" - */ - -"use strict"; - -import { app, protocol } from "electron"; -import createWindow from "./window"; -import main from "./main"; -import { backgroundMitt } from '@/composables/useEmitter'; - -console.log('Starting Crimata electron app.'); - -// Scheme must be registered before the app is ready -protocol.registerSchemesAsPrivileged([ - { scheme: "app", privileges: { secure: true, standard: true } } -]); - -const isDev = require('electron-is-dev'); - -let win: boolean; - -// Listen for window creation. -backgroundMitt.on('window-active', (state: boolean) => { - win = state; -}); - -/* Start main process on ready */ -app.on("ready", async () => { - await main(); -}); - -// Must keep to ensure app doesn't quit on close. -app.on("before-quit", async () => { -}); - -// Must keep to ensure app doesn't quit on close. -app.on("window-all-closed", () => { -}); - -// When user clicks app icon (re-open) -app.on("activate", () => { - if (!win) createWindow(); -}); - -// Exit cleanly on request from parent process in development mode. -if (isDev) { - process.on("SIGTERM", () => { - app.quit(); - }); -} diff --git a/src/ipc/handlers.ts b/src/ipc/handlers.ts deleted file mode 100644 index 5529662..0000000 --- a/src/ipc/handlers.ts +++ /dev/null @@ -1,28 +0,0 @@ - -"use strict"; - -import { accountLogin, accountLogout, accountProfile } from "@/account"; -import { IpcHandler } from "@/composables/useIpcMain"; -import { flush } from "@/audio"; - - -const LOGIN_CHANNEL = "invoke-account-login"; -const LOGOUT_CHANNEL = "invoke-account-logout"; -const GET_AUDIO_CHANNEL = "invoke-audio-flush"; - -export const loginHandler = new IpcHandler({ - channel: LOGIN_CHANNEL, - handlerCallback: accountLogin -}); - -export const logoutHandler = new IpcHandler({ - channel: LOGOUT_CHANNEL, - handlerCallback: accountLogout -}); - -export const getAudioHandler = new IpcHandler({ - channel: GET_AUDIO_CHANNEL, - handlerCallback: flush -}); - - diff --git a/src/ipc/index.ts b/src/ipc/index.ts deleted file mode 100644 index e6eb90a..0000000 --- a/src/ipc/index.ts +++ /dev/null @@ -1,33 +0,0 @@ - -"use strict"; - -import * as handlers from "./handlers"; -import * as listeners from "./listeners"; - -const ipcHandlers: IPCHandlers = {}; -const ipcListeners: IPCListeners = {}; - -const _initHandlers = (): void => { - for (const [key, handler] of Object.entries(handlers)) { - if (!(key in ipcHandlers)) { - ipcHandlers[key] = handler; - handler.handle(); - } - } -}; - -const _initListeners = (): void => { - for (const [key, listener] of Object.entries(listeners)) { - if (!(key in ipcListeners)) { - ipcListeners[key] = listener; - listener.listen(); - } - } -}; - -export default function initIpcMain(): void { - _initHandlers(); - _initListeners(); -} - - diff --git a/src/ipc/listeners.ts b/src/ipc/listeners.ts deleted file mode 100644 index 8ef5d45..0000000 --- a/src/ipc/listeners.ts +++ /dev/null @@ -1,24 +0,0 @@ - -import { IpcListener } from "@/composables/useIpcMain" -import { sendMessage } from '@/session'; -import { collect } from "@/audio"; -import { updateAppState } from "@/account"; - -const CLIENT_MESSAGE_CHANNEL = "post-session-send" -const GET_AUDIO_CHANNEL = "post-audio-collect"; -const APP_MOUNT_CHANNEL = "post-app-mount"; - -export const messageListener = new IpcListener({ - channel: CLIENT_MESSAGE_CHANNEL, - listenerCallback: sendMessage -}); - -export const audioChunkListener = new IpcListener({ - channel: GET_AUDIO_CHANNEL, - listenerCallback: collect -}); - -export const appMountListener = new IpcListener({ - channel: APP_MOUNT_CHANNEL, - listenerCallback: updateAppState -}); diff --git a/src/main.ts b/src/main.ts index a360835..e1965fd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,39 +1,19 @@ -/** - * Where the background logic really begins, gets called by app.onReady(). - * - * Handles authentication. If profile is set, we launch a session, which consis - * of opening a connection with the platform, initializing the audio streams. - * - * The session is primarily an interface between the frontend and the platform, - * relaying messages from one to the other. - * - */ +// src/main.ts -import initIpcMain from "@/ipc/index"; -import { accountAuth, updateAppState } from "./account"; -import { launchSession } from "./session"; -import createWindow from "./window"; +import App from "./App.vue"; +import router from "./router"; -let authState: AuthState | null; +import mitt from "mitt"; +import anime from "animejs"; +import { createApp } from "vue"; -export default async function main() { - /* initiate controls for frontend to use when needed */ - initIpcMain(); +// Handle events. +const emitter = mitt(); - /* launch browser window */ - await createWindow(); +const app = createApp(App) - try { - authState = await accountAuth() as AuthState; - } catch(e) { - console.log('AUTH:', e); - authState = null; - } finally { - if (authState) { - launchSession(authState.token as string); - } - updateAppState(); - } - -} +app.use(router) +app.provide("animejs", anime) +app.provide("mitt", emitter) +app.mount("#app"); diff --git a/src/modules/auth.ts b/src/modules/auth.ts new file mode 100644 index 0000000..04ce66a --- /dev/null +++ b/src/modules/auth.ts @@ -0,0 +1,63 @@ +import { reactive, toRefs } from 'vue'; +import { useIpc } from './ipc'; + +interface AuthState { + accessToken: string | null; + error?: Error; +} + +const state = reactive({ + accessToken: null, + error: undefined, +}); + +const AUTH_KEY = 'crimata_token'; + +let token: string | null; + +token = window.localStorage.getItem(AUTH_KEY); +if (token) { + state.accessToken = token; + window.localStorage.setItem(AUTH_KEY, token); +} + +const authToken = async () => { + const { invoke } = useIpc(); + try { + token = window.localStorage.getItem(AUTH_KEY); + const res = await invoke('auth-session', token); + window.localStorage.setItem(AUTH_KEY, res); + state.accessToken = res; + } + catch(e) { + state.error = e; + console.log('ERROR: failed authentication'); + window.localStorage.removeItem(AUTH_KEY); + state.accessToken = null; + } +} + +// authenticate on auth event +window.ipcRenderer.on("auth", async (_event, _arg) => { + await authToken(); +}); + +export const useAuth = () => { + + const setToken = (token: string) => { + window.localStorage.setItem(AUTH_KEY, token); + state.accessToken = token; + state.error = undefined; + } + + const logout = (): Promise => { + window.localStorage.removeItem(AUTH_KEY); + return Promise.resolve(state.accessToken = null); + } + + return { + setToken, + logout, + ...toRefs(state), // accessToken, error + } +} diff --git a/src/render/composables/useDraggify.ts b/src/modules/draggify.ts similarity index 55% rename from src/render/composables/useDraggify.ts rename to src/modules/draggify.ts index f3d8978..b357ddf 100644 --- a/src/render/composables/useDraggify.ts +++ b/src/modules/draggify.ts @@ -2,27 +2,24 @@ import { onMounted, ref, onUnmounted } from "vue"; //---Dragabble Helper Funcs-------------------------------------- -// Calculate distance to nearest side. +// Update xShort or yShort value. function calcSideProximity (elementX: number, winW: number) { + let short = winW - elementX - // Calc right short. - let short = winW - elementX - 40; + if (short > winW / 2) { + short = elementX + } - // See if it's left short. - if (elementX + 20 < winW / 2) { - short = elementX - } - - return short + return short } -// Update elementX or elementY value on window resize +// Update elementX or elementY value. function calcPosition (elementPosition: number, percent: number, short: number, win: number) { - // Is it close to the right/bottom side? + // Is it close to the right/left side? if (percent > 0.75) { - elementPosition = win - short - 40; + elementPosition = win - short } // Is it not close to a side? @@ -33,8 +30,7 @@ function calcPosition (elementPosition: number, percent: number, return elementPosition } -export default function draggify(elementId: string, xStart: number, - yStart: number, margin: number) { +export default function draggify(input: { elementId: string }) { let element: HTMLElement | null; @@ -50,33 +46,11 @@ export default function draggify(elementId: string, xStart: number, let xShort: number; let yShort: number; - // Keep track of window size; - let winW = window.innerWidth; - let winH = window.innerHeight; - - //---Reposition Anime----------------------------------------------- - - // Move element to target smoothly. - const repositionAnime = (xChange: number, yChange: number) => { - const xStep = xChange / 6000; - const yStep = yChange / 6000; - - for (let i = 1; i <= 6000; i++) { - - setTimeout(() => { - elementX.value += xStep; - elementY.value += yStep; - }, 16) // 60fps - - } - } - //---Event Handlers----------------------------------------------- // Update the position of inputItem on mouse dragging. const onMouseMove = (e: any) => { - e.preventDefault() - element = document.getElementById(elementId); + element = document.getElementById(input.elementId); if (element) { const inputItemRect = element.getBoundingClientRect(); @@ -88,7 +62,6 @@ export default function draggify(elementId: string, xStart: number, // Add an event listener for dragging. const onMouseDown = (_e: any) => { - _e.preventDefault() window.addEventListener('mousemove', onMouseMove, true); } @@ -96,53 +69,21 @@ export default function draggify(elementId: string, xStart: number, const onMouseUp = (_e: any) => { window.removeEventListener('mousemove', onMouseMove, true); - // See if and calculate reposition. - let x = 0; // vector change - let y = 0; - - if (elementX.value < 0) { - x = (elementX.value - margin)*-1 - } - - if (elementX.value > winW - 40) { - const b = winW - 40 - margin; - x = (elementX.value - b)*-1 - } - - // Reposition y - if (elementY.value < 0) { - y = (elementY.value - margin)*-1 - } - - if (elementY.value > winH - 40) { - const d = winH - 40 - margin; - y = (elementY.value - d)*-1 - } - - // Reposition if needed. - if (x !== 0 || y !== 0) repositionAnime(x, y); + const winW = window.innerWidth; + const winH = window.innerHeight; xShort = calcSideProximity(elementX.value, winW); yShort = calcSideProximity(elementY.value, winH); - // Update percentages. percentX = elementX.value / winW; percentY = elementY.value / winH; - // Save position. - const position = { - x: elementX.value, - y: elementY.value - } - window.localStorage.setItem("inputItem_position", JSON.stringify(position)); } // Update position of targetEl on windowResize. const onWindowResize = (_e: any) => { - - // Update window dimensions. - winW = window.innerWidth; - winH = window.innerHeight; + const winW = window.innerWidth; + const winH = window.innerHeight; elementX.value = calcPosition(elementX.value, percentX, xShort, winW); elementY.value = calcPosition(elementY.value, percentY, yShort, winH); @@ -152,7 +93,7 @@ export default function draggify(elementId: string, xStart: number, //--------------------------------------------------------------- onMounted(() => { - element = document.getElementById(elementId); + element = document.getElementById(input.elementId); if (element) { element.addEventListener('mousedown', onMouseDown, false); @@ -171,18 +112,9 @@ export default function draggify(elementId: string, xStart: number, window.addEventListener('resize', onWindowResize, false); }); - // Try loading initPosition, otherwise set default values - let initPosition: any; - const rawData = window.localStorage.getItem("inputItem_position") - - if (rawData) { - initPosition = JSON.parse(rawData) - } else { - initPosition = {x: xStart, y: yStart} - } - - elementX.value = initPosition.x; - elementY.value = initPosition.y; + // Initialize the coordinants. + elementX.value = 20; + elementY.value = 200 - 38 - 20; // remove event listeners on component dismount. onUnmounted(() => { diff --git a/src/modules/ipc.ts b/src/modules/ipc.ts new file mode 100644 index 0000000..f333d6a --- /dev/null +++ b/src/modules/ipc.ts @@ -0,0 +1,23 @@ + +export const useIpc = () => { + const invoke = async (endpoint: string, payload: any) => { + try { + const res = await window.ipcRenderer.invoke(endpoint, payload); + return res; + } catch (e) { + throw e; + } + } + + const post = (endpoint: string, payload: any) => { + window.postMessage({ + endpoint: endpoint, + content: payload + }, '*') + }; + + return { + invoke, + post + } +} diff --git a/src/modules/message.ts b/src/modules/message.ts new file mode 100644 index 0000000..069ef9d --- /dev/null +++ b/src/modules/message.ts @@ -0,0 +1,52 @@ +import { RenderMessage, ClientMessage } from "@/types/message/index"; +import { v4 as uuidv4 } from 'uuid'; + +// Create a RenderMessage object directly from json string. +export function initRenderMessageFromString(messageStr: string) { + + // Parse the string. + const m = JSON.parse(messageStr); + + // Auto set uid and time. + const currentdate = new Date(); + + const message: RenderMessage = { + content: m.content, + context: m.context, + modifier: m.modifier, + time: currentdate.getTime(), + uid: uuidv4(), + isChild: "none" + } + + return message +} + +// Create a RenderMessage object. +export function initRenderMessage(text: string, audio: string, context: string, modifier: string) { + + // Auto set uid and time. + const currentdate = new Date(); + + const message: RenderMessage = { + content: { + text: text, + audio: audio + }, + context: context, + modifier: modifier, + time: currentdate.getTime(), + uid: uuidv4(), + isChild: "none" + } + + return message +} + +export const clientMessage = (text: string, audio: string | boolean, uid: string): ClientMessage => ( + { + audio, + text, + uid + } +) \ No newline at end of file diff --git a/src/modules/messages.ts b/src/modules/messages.ts new file mode 100644 index 0000000..654ca59 --- /dev/null +++ b/src/modules/messages.ts @@ -0,0 +1,112 @@ +import { ref } from 'vue'; +import { RenderMessage, Annotation } from "@/types/message/index"; + +const messagesKey = "CRIMATA_MESSAGES"; +const sizeLimit = 200; + +// list of messages where the first item is the oldest message. +const messages = ref(new Map()); + +// get stored messages. +const messagesString = window.localStorage.getItem(messagesKey); + +if (messagesString) { + // parse stored messages. + const parsed = JSON.parse(messagesString); + // set messages. + messages.value = new Map(Object.entries(parsed)); +} + +// utility function to remove oldest message from the messages map. +function deleteOldest() { + // create array of map keys and get the key of the oldest message. + const lastKey = Array.from(messages.value.keys()).shift(); + + messages.value.delete(lastKey); +} + + + + + + +// Is the message div scrolled to the bottom? +let isScrolledToBottom: boolean; + +// Update isScrolledToBottom +const updateScrollRef = () => { + const e = document.getElementById("messenger") + + if (e) { + isScrolledToBottom = e.scrollHeight - e.clientHeight <= e.scrollTop + 1 + } + +} + +// Adjust scroll after we add content to the messenger. +const adjustScroll = () => { + const e = document.getElementById("messenger") + + if (e) { + + console.log(`Bottom? : ${isScrolledToBottom}`) + console.log(e.scrollHeight) + console.log(e.clientHeight) + console.log(e.scrollTop) + + // // Scroll to bottom if isScrolledToBottom is true + if (isScrolledToBottom) { + e.scrollTop = e.scrollHeight - e.clientHeight + } + + } + +} + + + + + +export default function useMessages() { + + const addMessage = (m: RenderMessage) => { + updateScrollRef() // must update before we add new elements. + + console.log(`Adding message: ${m.content.text}`) + + // check for message limit before setting a new message. + if (messages.value.size >= sizeLimit) deleteOldest(); + + messages.value.set(m.uid, m); + + adjustScroll() + } + + const updateMessage = (a: Annotation) => { + updateScrollRef() + + console.log(`Updating message...`) + + // update message if in the map. + const m = messages.value.get(a.uid) + m.context = a.context + m.text = a.text + + adjustScroll() + + return m + } + + const saveMessages = () => { + // de-reactivate message data before saving. + const messageData = Object.fromEntries(messages.value); + window.localStorage.setItem(messagesKey, JSON.stringify(messageData)); + } + + return { + messages, + saveMessages, + addMessage, + updateMessage + } +} \ No newline at end of file diff --git a/src/modules/mitt.ts b/src/modules/mitt.ts new file mode 100644 index 0000000..3ec8a92 --- /dev/null +++ b/src/modules/mitt.ts @@ -0,0 +1,17 @@ +import { inject } from "vue"; +import { Mitt } from "@/types/mitt/index"; + +let emitter: Mitt; + +export default function useMitt() { + + const emitterInject: Mitt | undefined = inject("mitt"); + if (emitterInject) { + emitter = emitterInject; + } + return { + emitter + } +} + + diff --git a/src/render/preload.ts b/src/preload.ts similarity index 100% rename from src/render/preload.ts rename to src/preload.ts diff --git a/src/render/App.vue b/src/render/App.vue deleted file mode 100644 index 686591b..0000000 --- a/src/render/App.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - - - diff --git a/src/render/components/controllers/bubble.control.ts b/src/render/components/controllers/bubble.control.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/render/components/controllers/helpers.ts b/src/render/components/controllers/helpers.ts deleted file mode 100644 index 23976a8..0000000 --- a/src/render/components/controllers/helpers.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ref } from "vue"; -import anime from "animejs"; -import { v4 as uuidv4 } from 'uuid'; - - -export function animateTextInput () { - - const side = ref("right"); - - function show () { - const t1 = (side.value === "right") ? 50 : -70; - const t2 = (side.value === "right") ? 110 : -130; - - anime({ - targets: '#textInput', - opacity: [0, 1], - translateX: [t1, t2], - scale: [0.3, 1], - duration: 500, - easing: 'easeOutExpo', - }) - - } - - function hide () { - const t = (side.value === "right") ? 50 : -80; - - anime({ - targets: '#textInput', - opacity: [1, 0], - translateX: t, - scale: 0.3, - duration: 500, - easing: 'easeOutExpo', - }) - - } - - function switchSide () { - const t = (side.value === "right") ? -130 : 110; - - anime({ - targets: '#textInput', - translateX: t, - duration: 500, - easing: 'easeOutExpo', - }) - - } - - return { - side, - show, - hide, - switchSide - }; - -} - -export function animateAudioInput () { - - function show () { - anime({ - targets: '#recIcon', - opacity: [0, 0.75], - scale: [0.0, 1], - duration: 250, - easing: 'linear', - }) - } - - function hide () { - anime({ - targets: '#recIcon', - opacity: [0.75, 0], - scale: [1, 0], - duration: 250, - easing: 'linear', - }) - } - - return { - show, - hide - }; - -} - - -export function newMessage ({ - text=false, - audio=false, - context=false, - uid=uuidv4() -}) { - return { - text: text, - audio: audio, - context: context, - uid: uid - }; -} diff --git a/src/render/components/controllers/inputItem.control.audio.ts b/src/render/components/controllers/inputItem.control.audio.ts deleted file mode 100644 index facf30c..0000000 --- a/src/render/components/controllers/inputItem.control.audio.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { onMounted, onUnmounted, ref, Ref } from "vue"; -import { postMessage } from "@/render/ipc"; -import { newMessage, animateAudioInput } from "./helpers"; -import { invokeReturnAudio, postAudioChunk } from "@/render/ipc"; - -export default function useAudioInputController (typing: Ref) { - - const recording = ref(false); - let mediaRecorder: MediaRecorder; - - const { show, hide } = animateAudioInput(); - - // initialize audio - const conf = {audio: true, video: false} - navigator.mediaDevices.getUserMedia(conf).then((stream: MediaStream) => { - - const options = {mimeType: 'audio/webm'}; - mediaRecorder = new MediaRecorder(stream, options); - - // post any mew audio to backend - mediaRecorder.addEventListener('dataavailable', (e: BlobEvent) => { - e.data.arrayBuffer().then((buff: ArrayBuffer) => { - postAudioChunk(buff); - }); - }); - - // get audio and post new message to backend - mediaRecorder.addEventListener('stop', (_e: Event) => { - invokeReturnAudio().then((audio: ArrayBuffer[] | Error) => { - console.log(audio); - // postMessage(newMessage({audio: audio})); - }); - }); - - }); - - // start recording on space bar - const record = () => { - console.log("INPT:Capturing audio...") - mediaRecorder.start(); - recording.value = true; - show() - } - - // stop recording and send on release - const stop = () => { - console.log("INPT:Stopping record.") - mediaRecorder.stop(); - recording.value = false; - hide(); - } - - const onKeyDown = (e: KeyboardEvent) => { - if (e.keyCode == 32 && !typing.value) record(); - } - - const onKeyUp = (e: KeyboardEvent) => { - if (e.keyCode == 32 && recording.value) stop(); - } - - //----------------------------------------------------------- - - onMounted(() => { - window.addEventListener("keydown", onKeyDown); - window.addEventListener("keyup", onKeyUp); - }); - - onUnmounted(() => { - window.removeEventListener("keydown", onKeyDown); - window.removeEventListener("keyup", onKeyUp); - }) - - return { - recording - } - -} diff --git a/src/render/components/controllers/inputItem.control.text.ts b/src/render/components/controllers/inputItem.control.text.ts deleted file mode 100644 index 941ae89..0000000 --- a/src/render/components/controllers/inputItem.control.text.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { Ref, ref, watch, onMounted, onUnmounted } from "vue"; -import { postMessage } from "@/render/ipc"; -import { newMessage, animateTextInput } from "./helpers"; - - -export default function useTextInputController(elementX: Ref) { - - let textInput: HTMLInputElement | null; - - const { side, show, hide, switchSide } = animateTextInput(); - - let firstKey = true; - const typing = ref(false); - - // Prep inputItem for typing. - const prepInput = () => { - show() - typing.value = true - } - - // Clear and hide inputItem after done typing. - const clearInput = () => { - - if (textInput) { - textInput.value = ""; - textInput.blur(); - } - - hide() - firstKey = true; - typing.value = false; - } - - // Send a message and clean up after. - const sendMessage = () => { - if (textInput) { - - // Send it to the backend for processing. - const message = newMessage({ - text: false - }); - - // postMessage(message); - - clearInput() - } - } - - // Keys that are capable of opening the text input (numbers and letters). - const isHotKey = (key: number) => { - if (key >= 47 && key <= 91) { // a letter - return true - } - } - - //---Callbacks----------------------------------------------- - - const onKeyDown = (e: KeyboardEvent) => { - const key = e.keyCode; - - if (textInput) { - - // Only runs on firstKey. - if (firstKey) { - - if (!isHotKey(key)) { - return - } - - prepInput() - } - - textInput.focus(); - - // Close input when no text or on ESC. - if ((textInput.value == "") && (!firstKey) && (key === 8)) { // backspace - clearInput() - return - } - - if (key === 27) { // escape - clearInput() - return - } - - // Close and send on enter. - if (key === 13) { - if (textInput.value) { - sendMessage() - return - } - } - - if (firstKey) firstKey = false - } - } - - //----------------------------------------------------------- - - // Watch parent position and update side. - watch(elementX, (elementX, _previous) => { - const winW = window.innerWidth - - // Logic depends on the side we are on. - if (side.value === "right") { - if (winW - elementX < 230) { - switchSide() - side.value = "left" - } - } - - else { - if (winW - elementX > 230) { - switchSide() - side.value = "right" - } - } - - }); - - onMounted(() => { - textInput = document.getElementById("textInput") as HTMLInputElement; - window.addEventListener("keydown", onKeyDown); - }) - - onUnmounted(() => { - window.removeEventListener("keydown", onKeyDown); - }); - - return { - typing - } - -} diff --git a/src/render/components/controllers/messenger.control.ts b/src/render/components/controllers/messenger.control.ts deleted file mode 100644 index b9c3a96..0000000 --- a/src/render/components/controllers/messenger.control.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ref } from 'vue'; -import useScroll from "@/render/composables/useScroll"; - -const messagesRef = ref(); - -/* seed the canvas with messages */ -const seedCanvas = (messages: Message[]) => { - messagesRef.value = messages; -} - -const addMessage = (message: Message) => { - messagesRef.value.push(message); -} - -const updateMessage = (message: Message) => { - - let target_message = messagesRef.value.filter((m: Message) => { - return m.uid = message.uid; - })[0]; - - if (target_message) { - target_message = message; - } - -} - -export default function useMessages() { - - const { updateScrollRef, adjustScroll } = useScroll("messenger"); - - return { - messagesRef, - seedCanvas, - addMessage, - updateMessage - }; - -} diff --git a/src/render/components/header.vue b/src/render/components/header.vue deleted file mode 100644 index 63716c8..0000000 --- a/src/render/components/header.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - - - diff --git a/src/render/components/messenger.vue b/src/render/components/messenger.vue deleted file mode 100644 index ee56549..0000000 --- a/src/render/components/messenger.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - - - diff --git a/src/render/composables/useIpcRend.ts b/src/render/composables/useIpcRend.ts deleted file mode 100644 index 9ba7f73..0000000 --- a/src/render/composables/useIpcRend.ts +++ /dev/null @@ -1,54 +0,0 @@ - -import { IpcRendererEvent } from "electron"; - -export class IpcRendererListener implements IIpcListener { - - readonly channel: string; - - readonly _listenerCallback: IpcListenerCallback; - - constructor(options: { - channel: string; - listenerCallback: IpcListenerCallback; - }) { - this.channel = options.channel; - this._listenerCallback = options.listenerCallback; - } - - listen() { - this.remove(); - window.ipcRenderer.on(this.channel, this._onPost); - } - - remove() { - window.ipcRenderer.removeAllListeners(this.channel); - } - - private _onPost = (_e: IpcRendererEvent, payload: InputParam): void => { - console.log(`[IPC] Post: ${this.channel}`); - this._listenerCallback(payload); - } - -} - - -export default function useIpcRenderer () { - - const invoke = async (endpoint: string, payload: any) => { - try { - const res = await window.ipcRenderer.invoke(endpoint, payload); - return res; - } catch (e) { - throw e; - } - } - - const post = (endpoint: string, payload: any) => { - window.ipcRenderer.send(endpoint, payload); - }; - - return { - invoke, - post, - } -} diff --git a/src/render/composables/useMessages.ts b/src/render/composables/useMessages.ts deleted file mode 100644 index f731584..0000000 --- a/src/render/composables/useMessages.ts +++ /dev/null @@ -1,33 +0,0 @@ -// shared -import { ref, Ref } from "vue"; -import useScroll from "@/render/composables/useScroll"; - -export const messages: Ref> = ref([]); - -export const setMessages: IpcListenerCallback> = (payload) => { - messages.value = payload as Array; -} - -export const addMessage: IpcListenerCallback = (payload) => { - messages.value.push(payload as Message); -} - -export const updateMessage: IpcListenerCallback = (payload) => { - const message = payload as Message; - - let targetMessage = messages.value.filter((m: Message) => { - return m.uid = message.uid; - })[0]; - - if (targetMessage) { - targetMessage = message; - } - -} - -export default { - messages, - setMessages, - addMessage, - updateMessage -}; diff --git a/src/render/composables/useProfile.ts b/src/render/composables/useProfile.ts deleted file mode 100644 index 3575de7..0000000 --- a/src/render/composables/useProfile.ts +++ /dev/null @@ -1,27 +0,0 @@ -// shared -import { ref } from "vue"; - -export const profile = ref(); - -export const authComplete = ref(false); - -export const setProfile: IpcListenerCallback = (payload) => { - payload ? profile.value = payload : clearProfile(); - showRender(); -}; - -export const clearProfile = () => { - profile.value = null; -}; - -export const showRender = () => { - authComplete.value = true; -}; - -export default { - setProfile, - clearProfile, - profile, - showRender, - authComplete, -}; diff --git a/src/render/composables/useScroll.ts b/src/render/composables/useScroll.ts deleted file mode 100644 index 811e7fc..0000000 --- a/src/render/composables/useScroll.ts +++ /dev/null @@ -1,29 +0,0 @@ - - -export default function useScroll(element: string) { - - let isScrolledToBottom: boolean; - const view = document.getElementById(element) - - // Update isScrolledToBottom - const updateScrollRef = () => { - if (view) isScrolledToBottom = view.scrollHeight - view.clientHeight <= view.scrollTop + 1; - return isScrolledToBottom; - } - - // Adjust scroll after we add content to the messenger. - const adjustScroll = () => { - if (view) { - view.scrollTo({ - top: view.scrollHeight - view.clientHeight, - behavior: 'smooth' - }); - } - } - - return { - updateScrollRef, - adjustScroll, - }; - -} \ No newline at end of file diff --git a/src/render/ipc.ts b/src/render/ipc.ts deleted file mode 100644 index bc68049..0000000 --- a/src/render/ipc.ts +++ /dev/null @@ -1,80 +0,0 @@ - -import useIpc from "@/render/composables/useIpcRend"; -import * as rendererListeners from "./listeners"; - -const { post, invoke } = useIpc(); - -/** - * - * Account and auth related endpoints - * - */ - - -export const invokeLogin = async ( - payload: LoginPayload -): Promise => ( - await invoke('invoke-account-login', JSON.stringify(payload)) -); - -export const invokeLogout = async (): Promise => ( - await invoke("invoke-account-logout", null) -); - -/** - * - * Audio endpoints - * - */ - -export const postAudioChunk = (chunk: ArrayBuffer): void => ( - post("post-audio-collect", chunk) -); - -export const invokeReturnAudio = async (): Promise => ( - await invoke("invoke-audio-flush", null) -); - -/** - * - * Crimata Platform (session) endpoints - * - */ - -export const invokeSession = async (cid: string): Promise => ( - await invoke("messenger-init", cid) -); - -export const postMessage = (payload: Message): void => ( - post('post-session-send', payload) -); - -export const postAppMount = (): void => ( - post('post-app-mount', null) -); - - -/** - * - * Ipc Renderer Listeners - * - */ - -let ipcListeners: IPCListeners = {}; - -export const initIpcRendererListeners = () => { - for (const [key, listener] of Object.entries(rendererListeners)) { - if (!(key in ipcListeners)) { - ipcListeners[key] = listener; - listener.listen(); - } - } -}; - -export const removeListeners = () => { - for (const [key, listener] of Object.entries(rendererListeners)) { - listener.remove(); - } - ipcListeners = {}; -}; - diff --git a/src/render/listeners.ts b/src/render/listeners.ts deleted file mode 100644 index 876d206..0000000 --- a/src/render/listeners.ts +++ /dev/null @@ -1,32 +0,0 @@ - -import { IpcRendererListener } from "./composables/useIpcRend" -import { setProfile } from "./composables/useProfile"; -import { setMessages, addMessage, updateMessage } from "./composables/useMessages"; - -const SET_PROFILE_CHANNEL = "set-profile"; - -const INIT_MESSAGES_CHANNEL = "init-messages"; -const ADD_MESSAGE_CHANNEL = "add-message"; -const UPDATE_MESSAGE_CHANNEL = "update-message"; - -export const setProfileListener = new IpcRendererListener({ - channel: SET_PROFILE_CHANNEL, - listenerCallback: setProfile -}); - -export const initMessagesListener = new IpcRendererListener({ - channel: INIT_MESSAGES_CHANNEL, - listenerCallback: setMessages -}); - - -export const addMessagesListener = new IpcRendererListener({ - channel: ADD_MESSAGE_CHANNEL, - listenerCallback: addMessage -}); - -export const updateMessagesListener = new IpcRendererListener({ - channel: UPDATE_MESSAGE_CHANNEL, - listenerCallback: updateMessage -}); - diff --git a/src/render/main.ts b/src/render/main.ts deleted file mode 100644 index 5375889..0000000 --- a/src/render/main.ts +++ /dev/null @@ -1,21 +0,0 @@ - -// src/main.ts - -import App from "./App.vue"; - -import mitt from "mitt"; -import { createApp } from "vue"; - -import { initIpcRendererListeners } from "./ipc" - - -// Handle ipcMain events. -initIpcRendererListeners(); - -// Handle events. -const emitter = mitt(); - -const app = createApp(App); - -app.provide("mitt", emitter); -app.mount("#app"); diff --git a/src/router.ts b/src/router.ts new file mode 100644 index 0000000..ee94a61 --- /dev/null +++ b/src/router.ts @@ -0,0 +1,55 @@ +import { + createRouter, + createWebHistory, + createWebHashHistory, + RouteRecordRaw +} from "vue-router"; +import Home from "@/views/messenger.vue"; +import { useAuth } from '@/modules/auth'; + +// Define the routes (/*) for the app here. +const routes: Array = [ + { + path: "/", + name: "home", + component: Home, + meta: { requiresAuth: true }, + }, + { + path: "/login", + name: "login", + component: () => import("@/views/login.vue"), + meta: { requiresAuth: false }, + }, + { + path: "/register", + name: "register", + component: () => import("@/views/register.vue"), + meta: { requiresAuth: false }, + }, +]; + +const router = createRouter({ + history: process.env.IS_ELECTRON ? createWebHashHistory() : createWebHistory(process.env.BASE_URL), + routes +}); + +// route auth check +router.beforeEach((to, from, next) => { + const { accessToken } = useAuth(); + + // Not logged into a guarded route? + if (to.meta.requiresAuth && !accessToken.value) { + next({ name: 'login' }) + } + + // Logged in for an auth route + else if ((to.name == 'login' || to.name == 'register') && accessToken.value){ + next({ name: 'home' }); + } + + // Carry On... + else next(); +}) + +export default router; diff --git a/src/session.ts b/src/session.ts deleted file mode 100644 index cde1df3..0000000 --- a/src/session.ts +++ /dev/null @@ -1,101 +0,0 @@ - - - - -// import useAudio from "@/audio"; -import { ipcEmit } from "@/composables/useEmitter"; -import useWebsockets from "./composables/useWebsockets"; -import {config} from "@/config"; - -/* data structure of messages that's tied to the UI */ -const uiState: any | null = null; - -/* start and stop audio functionality */ -// const { initAudio, closeAudio } = useAudio(); - -const isInitMessage = (message: any): boolean => { - return true; -}; - -const deauthenticate = (): void => { - console.log('deauthenticating') -}; - -const isAddMessage = (message: any): boolean => { - return true; -}; - -/** - * Controls for interfacing with the platform. - * Takes an onMessage callback which we define below. - */ - - -const onMessageCallback = (payload: string) => { - - const message = JSON.parse(payload); - console.log(typeof message); - - /* if the platform fails to authenticate, we must back down */ - if (message === "CLOSE_AUTH_FAIL") { - deauthenticate(); - return; - } - - ipcEmit("add-message", message) - return - - /* on init, platform sends state, used to init canvas */ - if (isInitMessage(message)) { - ipcEmit("init-messages", message) - } - - - else if (isAddMessage(message)) { - ipcEmit("add-messages", message) - } - - else { - ipcEmit("update-messages", message) - } - -} - -const onConnectionStatusCallback = (alive: boolean) => { - // console.log('[Session]: Connection Alive: ', alive); - // ipcEmit('connection-state', alive); -} - -const { connect, send, close } = useWebsockets( - onMessageCallback, - onConnectionStatusCallback -); - -/* send a message to the platform */ -export function sendMessage(message: Message): void { - - /* socket send */ - send(message); - -} - - -/* launch a new session (the main process for authenticated users) */ -export function launchSession(platformKey: string) { - - /* connect to the platform */ - connect(config.PLATFORM_URL, platformKey); - - /* initialize the audio streams */ - // initAudio(); - -} - - -export function endSession() { - - // closeAudio(); - - close(); - -} diff --git a/src/render/shims-vue.d.ts b/src/shims-vue.d.ts similarity index 100% rename from src/render/shims-vue.d.ts rename to src/shims-vue.d.ts diff --git a/src/store.ts b/src/store.ts deleted file mode 100644 index e532625..0000000 --- a/src/store.ts +++ /dev/null @@ -1,31 +0,0 @@ -const Store = require('electron-store'); - -const schema = { - token: { - type: 'string', - }, - profile: {} -}; - -const store = new Store({ - schema, - encryptionKey: "super user test" -}); - -export const getToken = (): string | undefined => (store.get("token")); - -export const clearToken = (): void => (store.delete("token")); - -export const setToken = (token: string): void => (store.set('token', token)); - -export const setProfile = (profile: Profile): Profile => (store.set('profile', profile)); - -export const getProfile = (): Profile => (store.get('profile')); - -export const clearProfile = (): void => (store.delete('profile')); - -export const clearStore = (): void => { - clearToken(); - clearProfile(); -} - diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index 450cb77..0000000 --- a/src/types.ts +++ /dev/null @@ -1,77 +0,0 @@ - -interface Message { - text: boolean | string; - context: boolean | string; - audio: boolean | string; - type: 1 | 2 | 3; - uid: string; -} - -interface ViewMessage extends Message { - child: string; -} - -interface WindowState { - width: number; - height: number; - x: number | null; - y: number | null; -} - -interface Profile { - crimataId: string; - alias: string; - initials: string; -} - -interface LoginPayload { - email: string; - password: string; -} - -interface AuthState { - profile: Profile | null; - token: string | null; -} - -interface AccountCredentials { - email: string; - password: string; -} - -/* - * Electron Ipc - */ -interface IpcHandlerCallback { - (payload: I | null): Promise; -} - -interface IpcListenerCallback { - (payload: T | null): void; -} - -interface IIpcHandler { - handle(): void; - remove(): void; - readonly _handlerCallback: IpcHandlerCallback; -} - -interface IIpcListener { - listen(): void; - remove(): void; - readonly _listenerCallback: IpcListenerCallback; -} - -interface IPCHandlers { - [handler: string]: IIpcHandler; -} - -interface IPCListeners { - [listener: string]: IIpcListener | null; -} - -interface IpcRendererEvent { - channel: string; - payload: T | null; -} - diff --git a/src/types/animejs/index.ts b/src/types/animejs/index.ts new file mode 100644 index 0000000..9a2c0e7 --- /dev/null +++ b/src/types/animejs/index.ts @@ -0,0 +1,18 @@ + +interface AnimeFuncParams { + targets: Element | HTMLElement | SVGGElement | SVGElement; + translateY?: number; + translateX?: number | any[] | undefined; + transform?: string; + easing?: string; + duration?: number; + offset?: number; + begin?: () => void; + complete?: () => void; + stroke?: string; + opacity?: number; +} + +export default interface AnimeFunc { + (params: AnimeFuncParams): void | undefined; +} diff --git a/src/types/message/index.ts b/src/types/message/index.ts new file mode 100644 index 0000000..4002396 --- /dev/null +++ b/src/types/message/index.ts @@ -0,0 +1,28 @@ +export interface UserCreds { + email: string; + password: string; +} + +export interface RenderMessage { + content: { + text: string; + audio: boolean | string; + }; + context: string; + modifier: string; + time: number; + uid: string; + isChild: string; +} + +export interface ClientMessage { + text: string; + audio: boolean | string; + uid: string; +} + +export interface Annotation { + text: string; + context: string; + uid: string; +} \ No newline at end of file diff --git a/src/types/mitt/index.ts b/src/types/mitt/index.ts new file mode 100644 index 0000000..a1ba637 --- /dev/null +++ b/src/types/mitt/index.ts @@ -0,0 +1,3 @@ +import { Emitter } from "mitt"; + +export type Mitt = Emitter; diff --git a/src/types/vue3/vueTransitionCallback/index.ts b/src/types/vue3/vueTransitionCallback/index.ts new file mode 100644 index 0000000..8c631d4 --- /dev/null +++ b/src/types/vue3/vueTransitionCallback/index.ts @@ -0,0 +1,3 @@ +export type VueTransitionCallback = { + (el?: SVGGElement | null): void; +} diff --git a/src/types/vueRef/index.ts b/src/types/vueRef/index.ts new file mode 100644 index 0000000..0acebab --- /dev/null +++ b/src/types/vueRef/index.ts @@ -0,0 +1,3 @@ +export interface Ref { + value: A; +} \ No newline at end of file diff --git a/src/render/components/login.vue b/src/views/login.vue similarity index 62% rename from src/render/components/login.vue rename to src/views/login.vue index bece6ea..fe49927 100644 --- a/src/render/components/login.vue +++ b/src/views/login.vue @@ -1,5 +1,5 @@ diff --git a/src/views/register.vue b/src/views/register.vue new file mode 100644 index 0000000..7081ca8 --- /dev/null +++ b/src/views/register.vue @@ -0,0 +1,197 @@ + + + + + diff --git a/src/window.ts b/src/window.ts deleted file mode 100644 index 21ebbca..0000000 --- a/src/window.ts +++ /dev/null @@ -1,161 +0,0 @@ -"use strict"; - -import { BrowserWindow, ipcMain, app } from "electron"; -import { createProtocol } from "vue-cli-plugin-electron-builder/lib"; -import { backgroundMitt } from './composables/useEmitter'; -import { saveToJson } from "./composables/useSaveToJSON"; -import * as path from "path"; -import fs from 'fs'; -import { config } from "@/config"; -const { autoUpdater } = require('electron-updater'); - -let win: BrowserWindow | null; -let winState: WindowState; - -const loadWinState = (fileName: string): WindowState => { - let state: WindowState; - - try { - state = JSON.parse(fs.readFileSync(config.configPath + fileName).toString()); - } - - catch (error) { - state = { - width: 600, - height: 500, - x: null, - y: null, - } - } - - return state - -} - -// Called when a NavBar button is pressed. -const onNavBar = (_event: any, action: string): void => { - if (win) { - if (action === "close") { - win.close() - } else { - win.minimize() - } - } -} - -// Util function to render message on ipc-renderer event. -const postToWindow = (event: IpcRendererEvent): void => { - if (win) { - win.webContents.send(event.channel, event.payload); - } -} - -// Write a json with position and size of window. -const saveWindowState = () => { - if (win) { - const bounds = win.getBounds(); - const position = win.getPosition(); - - if (winState) { - - winState.width = bounds.width; - winState.height = bounds.height; - winState.x = position[0]; - winState.y = position[1] - - saveToJson("window.json", winState) - - } - } -} - -// Do this on window mount. -const onWindowMount = (): void => { - - // Must tell initApp that window exists. - backgroundMitt.emit('window-active', true); - - // Handle win nav-bar event. - ipcMain.removeAllListeners("nav-bar") // avoid setting duplicate handlers - ipcMain.on("nav-bar", onNavBar); - - // Gateway for messages to the frontend. - backgroundMitt.removeAllListeners("ipc-renderer") - backgroundMitt.on("ipc-renderer", postToWindow); - -} - -// Do this on window dismount (close). -const onWindowDismount = (): void => { - win = null; - backgroundMitt.emit('window-active', false); -} - -// function used by run.ts to create the main window. -export default async function createWindow(): Promise { - return new Promise((resolve, _reject) => { - - // avoid creating duplicate windows. - if (win) resolve(); - - // Load the saved window state. - winState = loadWinState("window.json") - - // Define the browser window. - win = new BrowserWindow({ - width: winState.width, - height: winState.height, - x: winState.x as number, - y: winState.y as number, - resizable: true, - backgroundColor: '#EBEBEB', - frame: false, - minWidth: 350, - minHeight: 500, - webPreferences: { - nodeIntegration: (process.env.ELECTRON_NODE_INTEGRATION as unknown) as boolean, preload: path.join(__dirname, "preload.js") - } - }); - - // Load the URL. - if (process.env.WEBPACK_DEV_SERVER_URL) { - win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string); // dev - } - - else { - createProtocol("app"); - win.loadURL("app://./index.html"); // prod - } - - // Handle window close. - win.on("closed", onWindowDismount); - - // Save window state on resize and move. - win.on("moved", saveWindowState); - win.on("resize", saveWindowState); - - win.once('ready-to-show', () => { - autoUpdater.checkForUpdatesAndNotify(); - if (win) win.show() - }) - - // For showing/hiding the splash screen. - win.webContents.on('did-finish-load', () => { - if (win) win.webContents.send('window-ready', { - message: true - }); - - onWindowMount(); - resolve(); - }); - - }); -} - -autoUpdater.on('update-available', () => { - if (win) win.webContents.send('update_available'); -}); - -autoUpdater.on('update-downloaded', () => { - if (win) win.webContents.send('update_downloaded'); -}); diff --git a/tests/audio.js b/tests/audio.js index b8ab22f..d0f3595 100644 --- a/tests/audio.js +++ b/tests/audio.js @@ -86,7 +86,7 @@ function testCallback() { } function splitArrayIntoChunksOfLen(buf, len) { - const chunks = []; + let chunks = []; let i = 0; let L = len; console.log(buf.byteLength) diff --git a/tests/server.js b/tests/server.js index 9616e8a..6731be9 100644 --- a/tests/server.js +++ b/tests/server.js @@ -6,7 +6,6 @@ const wss = new WebSocket.Server({ let auth = false; wss.on("connection", function connection(ws, req) { - ws.on("message", function incoming(message) { console.log(message) @@ -20,13 +19,13 @@ wss.on("connection", function connection(ws, req) { auth = true; } else { const parsed = JSON.parse(message); - console.log('got a message', message); + console.log('got a message', message) } } else { const parsed = JSON.parse(message); - console.log('parsed', parsed); + console.log('parsed', parsed) } }); diff --git a/tests/unit/electron.spec.js b/tests/unit/electron.spec.js index ddd262c..049759d 100644 --- a/tests/unit/electron.spec.js +++ b/tests/unit/electron.spec.js @@ -24,7 +24,7 @@ test('Window Loads Properly', async () => { // App is loaded properly expect( /Welcome to Your Vue\.js (\+ TypeScript )?App/.test( - await (await app.client.$('#app')).getHTML() + await client.getHTML('#app') ) ).toBe(true) diff --git a/tsconfig.json b/tsconfig.json index 5a01f4d..307539b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,7 +32,6 @@ ] }, "include": [ - "**/*.ts", "src/*.ts", "src/**/*.ts", "src/**/*.tsx", diff --git a/vue.config.js b/vue.config.js new file mode 100644 index 0000000..8a7dde9 --- /dev/null +++ b/vue.config.js @@ -0,0 +1,29 @@ +// NOTE needed imports for rust wasm +// const path = require("path"); +// const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin"); +// const OptimizeWasmPlugin = require("optimize-wasm-webpack-plugin"); + +module.exports = { + lintOnSave: false, + configureWebpack: { + // NOTE uncomment to use rust wasm + // optimization: { + // minimizer: [new OptimizeWasmPlugin()] + // }, + // plugins: [ + // new WasmPackPlugin({ + // crateDirectory: path.resolve(__dirname, "crate") + // }) + // ] + }, + pluginOptions: { + electronBuilder: { + builderOptions: { + // TODO electron-builder config https://www.electron.build/configuration/configuration + appId: "com.crimata.messenger", + productName: "Crimata-Messenger" + }, + preload: "src/preload.ts" + } + } +}; diff --git a/yarn.lock b/yarn.lock index 465adc9..619e71a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1243,6 +1243,11 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sindresorhus/is@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" + integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ== + "@soda/friendly-errors-webpack-plugin@^1.7.1": version "1.7.1" resolved "https://registry.yarnpkg.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz#706f64bcb4a8b9642b48ae3ace444c70334d615d" @@ -1264,6 +1269,13 @@ dependencies: defer-to-connect "^1.0.1" +"@szmarczak/http-timer@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" + integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + dependencies: + defer-to-connect "^2.0.0" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -1279,12 +1291,17 @@ resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== -"@types/axios@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@types/axios/-/axios-0.14.0.tgz#ec2300fbe7d7dddd7eb9d3abf87999964cafce46" - integrity sha1-7CMA++fX3d1+udOr+HmZlkyvzkY= +"@types/archiver@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/archiver/-/archiver-3.1.1.tgz#10cc1be44af8911e57484342c7b3b32a5f178a1a" + integrity sha512-TzVZ9204sH1TuFylfr1cw/AA/3/VldAAXswEwKLXUOzA9mDg+m6gHF9EaqKNlozcjc6knX5m1KAqJzksPLSEfw== dependencies: - axios "*" + "@types/glob" "*" + +"@types/atob@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@types/atob/-/atob-2.1.2.tgz#157eb0cc46264a8c55f2273a836c7a1a644fb820" + integrity sha512-8GAYQ1jDRUQkSpHzJUqXwAkYFOxuWAOGLhIR4aPd/Y/yL12Q/9m7LsKpHKlfKdNE/362Hc9wPI1Yh6opDfxVJg== "@types/babel__core@^7.1.0": version "7.1.12" @@ -1332,6 +1349,16 @@ "@types/connect" "*" "@types/node" "*" +"@types/cacheable-request@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" + integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + "@types/connect-history-api-fallback@*": version "1.3.3" resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz#4772b79b8b53185f0f4c9deab09236baf76ee3b4" @@ -1364,11 +1391,6 @@ dependencies: "@types/node" "*" -"@types/electron-devtools-installer@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@types/electron-devtools-installer/-/electron-devtools-installer-2.2.0.tgz#32ee4ebbe99b3daf9847a6d2097dc00b5de94f10" - integrity sha512-HJNxpaOXuykCK4rQ6FOMxAA0NLFYsf7FiPFGmab0iQmtVBHSAfxzy3MRFpLTTDDWbV0yD2YsHOQvdu8yCqtCfw== - "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -1393,14 +1415,14 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/fs-extra@^9.0.1": +"@types/fs-extra@^9.0.1", "@types/fs-extra@^9.0.2": version "9.0.3" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.3.tgz#9996e5cce993508c32325380b429f04a1327523e" integrity sha512-NKdGoXLTFTRED3ENcfCsH8+ekV4gbsysanx2OPbstXVV6fZMgUCqTxubs6I9r7pbOJbFgVq1rpFtLURjKCZWUw== dependencies: "@types/node" "*" -"@types/glob@^7.1.1": +"@types/glob@*", "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== @@ -1408,6 +1430,11 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/http-cache-semantics@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" + integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + "@types/http-proxy-middleware@*": version "0.19.3" resolved "https://registry.yarnpkg.com/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz#b2eb96fbc0f9ac7250b5d9c4c53aade049497d03" @@ -1456,6 +1483,39 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== +"@types/keyv@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" + integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + dependencies: + "@types/node" "*" + +"@types/lodash.clonedeep@^4.5.6": + version "4.5.6" + resolved "https://registry.yarnpkg.com/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.6.tgz#3b6c40a0affe0799a2ce823b440a6cf33571d32b" + integrity sha512-cE1jYr2dEg1wBImvXlNtp0xDoS79rfEdGozQVgliDZj1uERH4k+rmEMTudP9b4VQ8O6nRb5gPqft0QzEQGMQgA== + dependencies: + "@types/lodash" "*" + +"@types/lodash.isplainobject@^4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#757d2dcdecbb32f4452018b285a586776092efd1" + integrity sha512-8G41YFhmOl8Ck6NrwLK5hhnbz6ADfuDJP+zusDnX3PoYhfC60+H/rQE6zmdO4yFzPCPJPY4oGZK2spbXm6gYEA== + dependencies: + "@types/lodash" "*" + +"@types/lodash.merge@^4.6.6": + version "4.6.6" + resolved "https://registry.yarnpkg.com/@types/lodash.merge/-/lodash.merge-4.6.6.tgz#b84b403c1d31bc42d51772d1cd5557fa008cd3d6" + integrity sha512-IB90krzMf7YpfgP3u/EvZEdXVvm4e3gJbUvh5ieuI+o+XqiNEt6fCzqNRaiLlPVScLI59RxIGZMQ3+Ko/DJ8vQ== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.165" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.165.tgz#74d55d947452e2de0742bad65270433b63a8c30f" + integrity sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg== + "@types/long@^4.0.0", "@types/long@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" @@ -1519,6 +1579,20 @@ "@types/duplexify" "*" "@types/node" "*" +"@types/puppeteer-core@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/puppeteer-core/-/puppeteer-core-2.0.0.tgz#3b7fbbac53d56b566f5ef096116e1d60d504aa45" + integrity sha512-JvoEb7KgEkUet009ZDrtpUER3hheXoHgQByuYpJZ5WWT7LWwMH+0NTqGQXGgoOKzs+G5NA1T4DZwXK79Bhnejw== + dependencies: + "@types/puppeteer" "*" + +"@types/puppeteer@*": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-5.4.0.tgz#1ef860bd7a9dcf0c4633aac8c0ec21f75b431868" + integrity sha512-zTYDLjnHjgzokrwKt7N0rgn7oZPYo1J0m8Ghu+gXqzLCEn8RWbELa2uprE2UFJ0jU/Sk0x9jXXdOH/5QQLFHhQ== + dependencies: + "@types/node" "*" + "@types/q@^1.5.1": version "1.5.4" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" @@ -1534,10 +1608,12 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== -"@types/semver@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb" - integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ== +"@types/responselike@*", "@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" "@types/serve-static@*": version "1.13.6" @@ -1584,13 +1660,6 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f" integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ== -"@types/webdriverio@^4.8.0": - version "4.13.3" - resolved "https://registry.yarnpkg.com/@types/webdriverio/-/webdriverio-4.13.3.tgz#c1571c4e62724135c0b11e7d7e36b07af5168856" - integrity sha512-AfSQM1xTO9Ax+u9uSQPDuw69DQ0qA2RMoKHn86jCgWNcwKVUjGMSP4sfSl3JOfcZN8X/gWvn7znVPp2/g9zcJA== - dependencies: - "@types/node" "*" - "@types/webpack-dev-server@^3.11.0": version "3.11.1" resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#f8f4dac1da226d530bd15a1d5dc34b23ba766ccb" @@ -2112,6 +2181,44 @@ command-exists "^1.2.7" watchpack "^1.6.0" +"@wdio/config@6.6.3": + version "6.6.3" + resolved "https://registry.yarnpkg.com/@wdio/config/-/config-6.6.3.tgz#035012ea0d1d02eb72bd181e857e893713ad9ade" + integrity sha512-zJjPpjJu05els9A2ZzOVMAYccaHSXmmqQ2h+ftelXmFgO4mYDlKufx0HaCZDdn+O0SCG0ASqv+u1KNuqmNhjDw== + dependencies: + "@wdio/logger" "6.6.0" + deepmerge "^4.0.0" + glob "^7.1.2" + +"@wdio/logger@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@wdio/logger/-/logger-6.6.0.tgz#69375d6cf373ee8e7db7cd05085e6a325fccfdf7" + integrity sha512-BAvXcnlWdQC93MLWObetpcjHUEGR8niW2mH2KAwLPQhXwJkKxXjhlMKH/DmUn5uQ4/S7iySLlMq9EEEg9KuCwA== + dependencies: + chalk "^4.0.0" + loglevel "^1.6.0" + loglevel-plugin-prefix "^0.8.4" + strip-ansi "^6.0.0" + +"@wdio/protocols@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@wdio/protocols/-/protocols-6.6.0.tgz#3a5fcc7bc15b8138e6e523836984f0746530e6e1" + integrity sha512-0wWSZTB4sBzr9HG3hT9a0jaO+xPhz+eFdE/qMLvM8b1yPOOgHieGPSoTXPjkBaks0CZpqeimbT4myYoim2JK1w== + +"@wdio/repl@6.7.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@wdio/repl/-/repl-6.7.1.tgz#8e8df570b9b1ba00e02197122b4bc08b0392af40" + integrity sha512-Ty69x6HTU/dl+xO2cLiHnYqxnf9ydylgKXiqktEvnGgft47+UEcXmnz18qWwPcqX10bu6lhr8J33hEk1A4kjIQ== + dependencies: + "@wdio/utils" "6.7.0" + +"@wdio/utils@6.7.0": + version "6.7.0" + resolved "https://registry.yarnpkg.com/@wdio/utils/-/utils-6.7.0.tgz#2106584ea075d2625ebc32a37f77839fceeac861" + integrity sha512-YhbExE89Ya5d1XIh4QIOuU1UjG30fB7iiFGgldu9ZfdUusIgjTwL4vMHhK30e+5+jdqzV6jMkTAf5a6OvH+02g== + dependencies: + "@wdio/logger" "6.6.0" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -2335,6 +2442,11 @@ address@^1.1.2: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== +agent-base@5: + version "5.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" + integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -2355,13 +2467,6 @@ ajv-errors@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-formats@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.0.tgz#96eaf83e38d32108b66d82a9cb0cfa24886cdfeb" - integrity sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q== - dependencies: - ajv "^8.0.0" - ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" @@ -2377,16 +2482,6 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.12.3, ajv json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.1.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" - integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -2539,31 +2634,34 @@ arch@^2.1.1: resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== -archiver-utils@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174" - integrity sha1-5QtMCccL89aA4y/xt5lOn52JUXQ= +archiver-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" + integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== dependencies: - glob "^7.0.0" - graceful-fs "^4.1.0" + glob "^7.1.4" + graceful-fs "^4.2.0" lazystream "^1.0.0" - lodash "^4.8.0" - normalize-path "^2.0.0" + lodash.defaults "^4.2.0" + lodash.difference "^4.5.0" + lodash.flatten "^4.4.0" + lodash.isplainobject "^4.0.6" + lodash.union "^4.6.0" + normalize-path "^3.0.0" readable-stream "^2.0.0" -archiver@~2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-2.1.1.tgz#ff662b4a78201494a3ee544d3a33fe7496509ebc" - integrity sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw= +archiver@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.0.2.tgz#b2c435823499b1f46eb07aa18e7bcb332f6ca3fc" + integrity sha512-Tq3yV/T4wxBsD2Wign8W9VQKhaUxzzRmjEiSoOK0SLqPgDP/N1TKdYyBeIEu56T4I9iO4fKTTR0mN9NWkBA0sg== dependencies: - archiver-utils "^1.3.0" - async "^2.0.0" + archiver-utils "^2.1.0" + async "^3.2.0" buffer-crc32 "^0.2.1" - glob "^7.0.0" - lodash "^4.8.0" - readable-stream "^2.0.0" - tar-stream "^1.5.0" - zip-stream "^1.2.0" + readable-stream "^3.6.0" + readdir-glob "^1.0.0" + tar-stream "^2.1.4" + zip-stream "^4.0.0" are-we-there-yet@~1.1.2: version "1.1.5" @@ -2580,11 +2678,6 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -2712,13 +2805,18 @@ async@0.9.x: resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= -async@^2.0.0, async@^2.6.2: +async@^2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== dependencies: lodash "^4.17.14" +async@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" + integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -2734,11 +2832,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -atomically@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/atomically/-/atomically-1.7.0.tgz#c07a0458432ea6dbc9a3506fffa424b48bccaafe" - integrity sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w== - autoprefixer@^9.8.6: version "9.8.6" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" @@ -2762,13 +2855,6 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axios@*, axios@^0.21.1: - version "0.21.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" - integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== - dependencies: - follow-redirects "^1.10.0" - babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -3000,13 +3086,14 @@ bindings@^1.2.1, bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bl@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" - integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== +bl@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" + integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" block-stream@*: version "0.0.9" @@ -3222,20 +3309,7 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-crc32@^0.2.1, buffer-crc32@~0.2.3: +buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= @@ -3245,11 +3319,6 @@ buffer-equal-constant-time@1.0.1: resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= - buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -3279,7 +3348,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.1.0: +buffer@^5.1.0, buffer@^5.2.1, buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -3295,14 +3364,6 @@ builder-util-runtime@8.7.2: debug "^4.1.1" sax "^1.2.4" -builder-util-runtime@8.7.3: - version "8.7.3" - resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.7.3.tgz#0aaafa52d25295c939496f62231ca9ff06c30e40" - integrity sha512-1Q2ReBqFblimF5g/TLg2+0M5Xzv0Ih5LxJ/BMWXvEy/e6pQKeeEpbkPMGsN6OiQgkygaZo5VXCXIjOkOQG5EoQ== - dependencies: - debug "^4.3.2" - sax "^1.2.4" - builder-util@22.9.1: version "22.9.1" resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.9.1.tgz#b7087a5cde477f90d718ca5d7fafb6ae261b16af" @@ -3438,6 +3499,11 @@ cache-loader@^4.1.0: neo-async "^2.6.1" schema-utils "^2.0.0" +cacheable-lookup@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3" + integrity sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w== + cacheable-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" @@ -3451,6 +3517,19 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" +cacheable-request@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" + integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^2.0.0" + call-bind@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" @@ -3584,7 +3663,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.1.0: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== @@ -3592,11 +3671,6 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -3651,6 +3725,18 @@ chownr@^2.0.0: resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +chrome-launcher@^0.13.1: + version "0.13.4" + resolved "https://registry.yarnpkg.com/chrome-launcher/-/chrome-launcher-0.13.4.tgz#4c7d81333c98282899c4e38256da23e00ed32f73" + integrity sha512-nnzXiDbGKjDSK6t2I+35OAPBy5Pw/39bgkb/ZAFwMhwJbdYBp6aH+vW28ZgtjdU890Q7D+3wN/tB8N66q5Gi2A== + dependencies: + "@types/node" "*" + escape-string-regexp "^1.0.5" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + mkdirp "^0.5.3" + rimraf "^3.0.2" + chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -3747,11 +3833,6 @@ cli-truncate@^0.2.1: slice-ansi "0.0.4" string-width "^1.0.1" -cli-width@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" - integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== - cli-width@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" @@ -3928,15 +4009,15 @@ component-emitter@^1.2.1: resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== -compress-commons@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f" - integrity sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8= +compress-commons@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.0.1.tgz#c5fa908a791a0c71329fba211d73cd2a32005ea8" + integrity sha512-xZm9o6iikekkI0GnXCmAl3LQGZj5TBDj0zLowsqi7tJtEa3FMGSEcHcqrSJIrOAk1UG/NBbDn/F1q+MG/p/EsA== dependencies: - buffer-crc32 "^0.2.1" - crc32-stream "^2.0.0" - normalize-path "^2.0.0" - readable-stream "^2.0.0" + buffer-crc32 "^0.2.13" + crc32-stream "^4.0.0" + normalize-path "^3.0.0" + readable-stream "^3.6.0" compressible@~2.0.16: version "2.0.18" @@ -3982,22 +4063,6 @@ condense-newlines@^0.2.1: is-whitespace "^0.3.0" kind-of "^3.0.2" -conf@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/conf/-/conf-10.0.1.tgz#038093e5cbddc0e59bc14f63382c4ce732a4781d" - integrity sha512-QClEoNcruwBL84QgMEPHibL3ERxWIrRKhbjJKG1VsFBadm5QpS0jsu4QjY/maxUvhyAKXeyrs+ws+lC6PajnEg== - dependencies: - ajv "^8.1.0" - ajv-formats "^2.0.2" - atomically "^1.7.0" - debounce-fn "^4.0.0" - dot-prop "^6.0.1" - env-paths "^2.2.1" - json-schema-typed "^7.0.3" - onetime "^5.1.2" - pkg-up "^3.1.0" - semver "^7.3.5" - config-chain@^1.1.11, config-chain@^1.1.12: version "1.1.12" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" @@ -4160,13 +4225,13 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" -crc32-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" - integrity sha1-483TtN8xaN10494/u8t7KX/pCPQ= +crc32-stream@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.0.tgz#05b7ca047d831e98c215538666f372b756d91893" + integrity sha512-tyMw2IeUX6t9jhgXI6um0eKfWq4EIDpfv5m7GX4Jzp7eVelQ360xd8EPXJhp2mHwLQIkqlnMLjzqSZI3a+0wRw== dependencies: crc "^3.4.4" - readable-stream "^2.0.0" + readable-stream "^3.4.0" crc@^3.4.4: version "3.8.0" @@ -4234,7 +4299,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.3: +cross-spawn@^7.0.0: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -4297,13 +4362,6 @@ css-loader@^3.5.3: schema-utils "^2.7.0" semver "^6.3.0" -css-parse@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-2.0.0.tgz#a468ee667c16d81ccf05c58c38d2a97c780dbfd4" - integrity sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q= - dependencies: - css "^2.0.0" - css-select-base-adapter@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" @@ -4345,7 +4403,7 @@ css-tree@^1.0.0: mdn-data "2.0.12" source-map "^0.6.1" -css-value@~0.0.1: +css-value@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/css-value/-/css-value-0.0.1.tgz#5efd6c2eea5ea1fd6b6ac57ec0427b18452424ea" integrity sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo= @@ -4360,7 +4418,7 @@ css-what@^3.2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== -css@^2.0.0, css@^2.1.0: +css@^2.1.0: version "2.2.4" resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== @@ -4520,13 +4578,6 @@ deasync@^0.1.15: bindings "^1.5.0" node-addon-api "^1.7.1" -debounce-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/debounce-fn/-/debounce-fn-4.0.0.tgz#ed76d206d8a50e60de0dd66d494d82835ffe61c7" - integrity sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ== - dependencies: - mimic-fn "^3.0.0" - debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -4555,13 +4606,6 @@ debug@^4.3.0: dependencies: ms "2.1.2" -debug@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -4579,6 +4623,13 @@ decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -4611,16 +4662,11 @@ deepmerge@^1.5.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== -deepmerge@^4.2.2: +deepmerge@^4.0.0, deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== -deepmerge@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.0.1.tgz#25c1c24f110fb914f80001b925264dd77f3f4312" - integrity sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ== - default-gateway@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" @@ -4648,6 +4694,11 @@ defer-to-connect@^1.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== +defer-to-connect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" + integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== + define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -4747,6 +4798,26 @@ dev-null@^0.1.1: resolved "https://registry.yarnpkg.com/dev-null/-/dev-null-0.1.1.tgz#5a205ce3c2b2ef77b6238d6ba179eb74c6a0e818" integrity sha1-WiBc48Ky73e2I41roXnrdMag6Bg= +devtools-protocol@0.0.809251: + version "0.0.809251" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.809251.tgz#300b3366be107d5c46114ecb85274173e3999518" + integrity sha512-pf+2OY6ghMDPjKkzSWxHMq+McD+9Ojmq5XVRYpv/kPd9sTMQxzEt21592a31API8qRjro0iYYOc3ag46qF/1FA== + +devtools@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/devtools/-/devtools-6.7.0.tgz#e5b9ecd30eb731d33ff9bd49d78d67e22f1c53a5" + integrity sha512-RkmIy2tX+XS0HM/6XGDmBHCv92jSbNKBdRcmwxHHBqYuSuVxYhLlhNwNjjA+2LZHe92xnaxW5+oGH27wyPs8Ew== + dependencies: + "@wdio/config" "6.6.3" + "@wdio/logger" "6.6.0" + "@wdio/protocols" "6.6.0" + "@wdio/utils" "6.7.0" + chrome-launcher "^0.13.1" + edge-paths "^2.1.0" + puppeteer-core "^5.1.0" + ua-parser-js "^0.7.21" + uuid "^8.0.0" + diff-sequences@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" @@ -4886,23 +4957,11 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" -dot-prop@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" - integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== - dependencies: - is-obj "^2.0.0" - dotenv-expand@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== -dotenv@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== - dotenv@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" @@ -4958,6 +5017,11 @@ ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: dependencies: safe-buffer "^5.0.1" +edge-paths@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/edge-paths/-/edge-paths-2.1.0.tgz#f273f3a0fe022422048bb78f83eb61aca29977ef" + integrity sha512-ZpIN1Vm5hlo9dkkST/1s8QqPNne2uwk3Plf6HcVUhnpfal0WnDRLdNj/wdQo3xRc+wnN3C25wPpPlV2E6aOunQ== + editorconfig@^0.15.3: version "0.15.3" resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" @@ -4985,11 +5049,6 @@ ejs@^3.1.5: dependencies: jake "^10.6.1" -ejs@~2.5.6: - version "2.5.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.9.tgz#7ba254582a560d267437109a68354112475b0ce5" - integrity sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ== - electron-builder@^22.2.0: version "22.9.1" resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.9.1.tgz#a2962db6f2757bc01d02489f38fafe0809f68f60" @@ -5027,21 +5086,6 @@ electron-devtools-installer@^3.1.0: semver "^7.2.1" unzip-crx-3 "^0.2.0" -electron-is-dev@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-0.3.0.tgz#14e6fda5c68e9e4ecbeff9ccf037cbd7c05c5afe" - integrity sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4= - -electron-is-dev@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-2.0.0.tgz#833487a069b8dad21425c67a19847d9064ab19bd" - integrity sha512-3X99K852Yoqu9AcW50qz3ibYBWY79/pBhlMCab8ToEWS48R0T9tyxRiQhwylE7zQdXrMnx2JKqUJyMPmt5FBqA== - -electron-log@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-4.3.4.tgz#97e991dcd653e759e14eb2ae5d6ba4440f50afd8" - integrity sha512-Cd6xZ9if2J4NG+PNoi3cARAYoanbM4ddpod0faaL5LIhmwuSdxP9XH95C9SgTpHMqklbg8u3CFh1yqiaqo2Bng== - electron-publish@22.9.1: version "22.9.1" resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.9.1.tgz#7cc76ac4cc53efd29ee31c1e5facb9724329068e" @@ -5056,32 +5100,11 @@ electron-publish@22.9.1: lazy-val "^1.0.4" mime "^2.4.6" -electron-store@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-8.0.0.tgz#81a4e687958e2dae1c5c84cc099a8148be776337" - integrity sha512-ZgRPUZkfrrjWSqxZeaxu7lEvmYf6tgl49dLMqxXGnEmliSiwv3u4rJPG+mH3fBQP9PBqgSh4TCuxHZImMMUgWg== - dependencies: - conf "^10.0.0" - type-fest "^1.0.2" - electron-to-chromium@^1.3.585: version "1.3.589" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.589.tgz#bd26183ed8697dde6ac19acbc16a3bf33b1f8220" integrity sha512-rQItBTFnol20HaaLm26UgSUduX7iGerwW7pEYX17MB1tI6LzFajiLV7iZ7LVcUcsN/7HrZUoCLrBauChy/IqEg== -electron-updater@^4.3.8: - version "4.3.8" - resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.8.tgz#94f1731682a756385726183e2b04b959cb319456" - integrity sha512-/tB82Ogb2LqaXrUzAD8waJC+TZV52Pr0Znfj7w+i4D+jA2GgrKFI3Pxjp+36y9FcBMQz7kYsMHcB6c5zBJao+A== - dependencies: - "@types/semver" "^7.3.4" - builder-util-runtime "8.7.3" - fs-extra "^9.1.0" - js-yaml "^4.0.0" - lazy-val "^1.0.4" - lodash.isequal "^4.5.0" - semver "^7.3.4" - electron@^9.0.0: version "9.3.3" resolved "https://registry.yarnpkg.com/electron/-/electron-9.3.3.tgz#99a6619d5df68f97697a5d1d82ef3a8a63fcdf36" @@ -5170,11 +5193,6 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== -env-paths@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -5531,19 +5549,19 @@ execa@^3.3.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" -execa@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== +execa@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" is-stream "^2.0.0" merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" strip-final-newline "^2.0.0" exit@^0.1.2: @@ -5632,15 +5650,6 @@ extend@^3.0.2, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^2.0.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" - integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -5702,6 +5711,11 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -5955,11 +5969,6 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== -follow-redirects@^1.10.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" - integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== - for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -6077,16 +6086,6 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^1.0.0" -fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -6172,7 +6171,7 @@ gaxios@^4.0.0: is-stream "^2.0.0" node-fetch "^2.3.0" -gaze@^1.0.0, gaze@~1.1.2: +gaze@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== @@ -6218,6 +6217,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-port@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -6242,11 +6246,6 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" -get-stream@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" - integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== - get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -6259,13 +6258,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -github-url-to-object@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/github-url-to-object/-/github-url-to-object-4.0.4.tgz#a9797b7026e18d53b50b07f45b7e169b55fd90ee" - integrity sha512-1Ri1pR8XTfzLpbtPz5MlW/amGNdNReuExPsbF9rxLsBfO1GH9RtDBamhJikd0knMWq3RTTQDbTtw0GGvvEAJEA== - dependencies: - is-url "^1.1.0" - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -6451,6 +6443,23 @@ google-p12-pem@^3.0.3: dependencies: node-forge "^0.10.0" +got@^11.0.2: + version "11.8.0" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.0.tgz#be0920c3586b07fd94add3b5b27cb28f49e6545f" + integrity sha512-k9noyoIIY9EejuhaBNLyZ31D5328LeqnyPNXJQb2XlJZcKakLqN5m6O/ikhq/0lw56kUYS54fVm+D1x57YC9oQ== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.1" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -6468,11 +6477,6 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.0: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== - graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" @@ -6530,11 +6534,6 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -6840,11 +6839,27 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.0-beta.5.2" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz#8b923deb90144aea65cf834b016a340fc98556f3" + integrity sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" + integrity sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg== + dependencies: + agent-base "5" + debug "4" + https-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -6858,12 +6873,7 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -7046,26 +7056,6 @@ inquirer@^7.0.0, inquirer@^7.1.0: strip-ansi "^6.0.0" through "^2.3.6" -inquirer@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" - integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - internal-ip@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" @@ -7436,11 +7426,6 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-url@^1.1.0, is-url@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" - integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== - is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" @@ -7461,7 +7446,7 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= -is-wsl@^2.1.1: +is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -8019,13 +8004,6 @@ js-yaml@^3.13.1, js-yaml@^3.14.0: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" - integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== - dependencies: - argparse "^2.0.1" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -8117,6 +8095,11 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -8132,16 +8115,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema-typed@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-7.0.3.tgz#23ff481b8b4eebcd2ca123b4fa0409e66469a2d9" - integrity sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A== - json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -8241,6 +8214,13 @@ keyv@^3.0.0: dependencies: json-buffer "3.0.0" +keyv@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" + integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== + dependencies: + json-buffer "3.0.1" + killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -8334,6 +8314,14 @@ lie@~3.3.0: dependencies: immediate "~3.0.5" +lighthouse-logger@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.2.0.tgz#b76d56935e9c137e86a04741f6bb9b2776e886ca" + integrity sha512-wzUvdIeJZhRsG6gpZfmSCfysaxNEr43i+QT+Hie94wvHDKFLi4n7C2GqZ4sTC+PH5b5iktmXJvU87rWvhP3lHw== + dependencies: + debug "^2.6.8" + marky "^1.2.0" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -8485,15 +8473,40 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + lodash.defaultsdeep@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== -lodash.isequal@^4.5.0: +lodash.difference@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" + integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= + +lodash.flatten@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.isobject@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" + integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= lodash.kebabcase@^4.1.1: version "4.1.1" @@ -8525,21 +8538,26 @@ lodash.transform@^4.6.0: resolved "https://registry.yarnpkg.com/lodash.transform/-/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0" integrity sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A= +lodash.union@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= +lodash.zip@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" + integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= + lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.3, lodash@^4.17.4, lodash@~4.17.10: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== -lodash@^4.3.0, lodash@^4.8.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" @@ -8570,7 +8588,12 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -loglevel@^1.6.8: +loglevel-plugin-prefix@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz#2fe0e05f1a820317d98d8c123e634c1bd84ff644" + integrity sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g== + +loglevel@^1.6.0, loglevel@^1.6.8: version "1.7.0" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.0.tgz#728166855a740d59d38db01cf46f042caa041bb0" integrity sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ== @@ -8683,6 +8706,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +marky@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.1.tgz#a3fcf82ffd357756b8b8affec9fdbf3a30dc1b02" + integrity sha512-md9k+Gxa3qLH6sUKpeC2CNkJK/Ld+bEz5X96nYwloqphQE0CKCVEKco/6jxEZixinqNdz5RFi/KaCyfbMDMAXQ== + matcher@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca" @@ -8857,16 +8885,16 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-fn@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" - integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== - mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + mini-css-extract-plugin@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" @@ -8899,11 +8927,6 @@ minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= - minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -8969,6 +8992,11 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@0.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -9021,11 +9049,6 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - mute-stream@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" @@ -9261,7 +9284,7 @@ normalize-path@^1.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= -normalize-path@^2.0.0, normalize-path@^2.1.1: +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -9306,11 +9329,6 @@ npm-conf@^1.1.3: config-chain "^1.1.11" pify "^3.0.0" -npm-install-package@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/npm-install-package/-/npm-install-package-2.1.0.tgz#d7efe3cfcd7ab00614b896ea53119dc9ab259125" - integrity sha1-1+/jz816sAYUuJbqUxGdyaslkSU= - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -9325,7 +9343,7 @@ npm-run-path@^3.0.0: dependencies: path-key "^3.0.0" -npm-run-path@^4.0.0, npm-run-path@^4.0.1: +npm-run-path@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -9479,7 +9497,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -onetime@^5.1.0, onetime@^5.1.2: +onetime@^5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -9505,14 +9523,6 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" -optimist@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - optimize-wasm-webpack-plugin@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/optimize-wasm-webpack-plugin/-/optimize-wasm-webpack-plugin-1.0.12.tgz#7252da00e356822aea9089f8ca73afcac36319a8" @@ -9580,6 +9590,11 @@ p-cancelable@^1.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== +p-cancelable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" + integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== + p-each-series@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" @@ -9919,20 +9934,13 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-dir@^4.1.0: +pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== - dependencies: - find-up "^3.0.0" - please-upgrade-node@^3.1.1: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -10374,7 +10382,7 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -progress@^2.0.0, progress@^2.0.3: +progress@^2.0.0, progress@^2.0.1, progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -10424,6 +10432,11 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.1" +proxy-from-env@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -10507,7 +10520,25 @@ pupa@^2.0.1: dependencies: escape-goat "^2.0.0" -q@^1.1.2, q@~1.5.0: +puppeteer-core@^5.1.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-5.4.1.tgz#68b85c1aae2dcde8e41df1d12aad8852768a88bd" + integrity sha512-JfPCQgLvyBlpwQTbdnEwCEvD2KiRB2Hv+J1YCwz9o0PxlTqVSuzSQ4XeLhPmy6fZpBFynyQ+r4FSn6RUywawqA== + dependencies: + debug "^4.1.0" + devtools-protocol "0.0.809251" + extract-zip "^2.0.0" + https-proxy-agent "^4.0.0" + node-fetch "^2.6.1" + pkg-dir "^4.2.0" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^3.0.2" + tar-fs "^2.0.0" + unbzip2-stream "^1.3.3" + ws "^7.2.3" + +q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= @@ -10545,6 +10576,11 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -10645,7 +10681,7 @@ read-pkg@^5.1.1: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -10658,7 +10694,7 @@ read-pkg@^5.1.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: +readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -10667,6 +10703,13 @@ readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.1.1, readable string_decoder "^1.1.1" util-deprecate "^1.0.1" +readdir-glob@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.1.tgz#f0e10bb7bf7bfa7e0add8baffdc54c3f7dbee6c4" + integrity sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA== + dependencies: + minimatch "^3.0.4" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -10845,7 +10888,7 @@ request-promise-native@^1.0.5, request-promise-native@^1.0.7: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.83.0, request@^2.87.0, request@^2.88.0, request@^2.88.2: +request@^2.87.0, request@^2.88.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -10876,11 +10919,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -10891,6 +10929,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +resolve-alpn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" + integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -10933,6 +10976,20 @@ responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" +responselike@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" + integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== + dependencies: + lowercase-keys "^2.0.0" + +resq@^1.9.1: + version "1.9.2" + resolved "https://registry.yarnpkg.com/resq/-/resq-1.9.2.tgz#f674b061b22b415225edb4d0b20c33a85f949fc1" + integrity sha512-Y+fprJ9wQY64gh+vJRNatiG61G+9XD5jJe4kI/Rqw6gmOa5ihZvgrxZVydqyM96xj75jwaRCPVYPU3RwsEk6ug== + dependencies: + fast-deep-equal "^2.0.1" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -10976,10 +11033,10 @@ rgb-regex@^1.0.1: resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= -rgb2hex@^0.1.9: - version "0.1.10" - resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.1.10.tgz#4fdd432665273e2d5900434940ceba0a04c8a8a8" - integrity sha512-vKz+kzolWbL3rke/xeTE2+6vHmZnNxGyDnaVW4OckntAIcc7DcZzWkQSfxMDwqHS8vhgySnIFyBUH7lIk6PxvQ== +rgb2hex@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.2.0.tgz#801b4887127181d1e691f610df2cecdb77330265" + integrity sha512-cHdNTwmTMPu/TpP1bJfdApd6MbD+Kzi4GNnM6h35mdFChhQPSi9cAI8J7DMn5kQDKX8NuBaQXAyo360Oa7tOEA== rgba-regex@^1.0.0: version "1.0.0" @@ -11032,7 +11089,7 @@ rsvp@^4.8.4: resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== -run-async@^2.2.0, run-async@^2.4.0: +run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== @@ -11049,18 +11106,6 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= - rxjs@^6.3.3, rxjs@^6.6.0: version "6.6.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" @@ -11232,13 +11277,6 @@ semver@^7.2.1, semver@^7.3.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== -semver@^7.3.4, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -11263,7 +11301,7 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" -serialize-error@^7.0.1: +serialize-error@^7.0.0, serialize-error@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18" integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== @@ -11394,7 +11432,7 @@ sigmund@^1.0.1: resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== @@ -11603,17 +11641,16 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -spectron@11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/spectron/-/spectron-11.0.0.tgz#79d785e6b8898638e77b5186711e3910ed4ca09b" - integrity sha512-YRiB0TTpJa8ofNML/k1fJShe+m7U/E2HnFZsdZK57ekWIzlTHF+Lq7ZvuKGxMbpooU/OZkLObZfitemxhBVH4w== +spectron@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/spectron/-/spectron-11.1.0.tgz#ee4f11c9057f6d79094f2d444eba555ccbe63965" + integrity sha512-gL5mQZrh2Afv5vfUX7Llf61NI9zzS139BP0vivNU9kbl92O1AoGk7KwOEg+Cf6Pb2/G/s/81wYWqo/WOhYi6jQ== dependencies: - "@types/webdriverio" "^4.8.0" dev-null "^0.1.1" electron-chromedriver "^9.0.0" request "^2.87.0" split "^1.0.0" - webdriverio "^4.13.0" + webdriverio "^6.1.20" split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -11807,7 +11844,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -11991,13 +12028,6 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@~5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.0.1.tgz#1c5331f22250c84202805b2f17adf16699f3a39a" - integrity sha512-7FQGOlSQ+AQxBNXJpVDj8efTA/FtyB5wcNE1omXXJ0cq6jm1jjDwuROlYDbnzHqdNPqliWFhcioCWSyav+xBnA== - dependencies: - has-flag "^2.0.0" - svg-tags@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" @@ -12047,18 +12077,26 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== +tar-fs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.0.tgz#d1cdd121ab465ee0eb9ccde2d35049d3f3daf0d5" + integrity sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg== dependencies: - bl "^1.0.0" - buffer-alloc "^1.2.0" - end-of-stream "^1.0.0" + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.0.0" + +tar-stream@^2.0.0, tar-stream@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.4.tgz#c4fb1a11eb0da29b893a5b25476397ba2d053bfa" + integrity sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.1" - xtend "^4.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" tar@^2.0.0: version "2.2.2" @@ -12226,7 +12264,7 @@ through2@^2.0.0, through2@~2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through@2, through@^2.3.6: +through@2, through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -12265,11 +12303,6 @@ to-arraybuffer@^1.0.0: resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= -to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" @@ -12504,11 +12537,6 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-fest@^1.0.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.1.3.tgz#ea1a602e98e5a968a56a289886a52f04c686fc81" - integrity sha512-CsiQeFMR1jZEq8R+H59qe+bBevnjoV5N2WZTTdlyqxeoODQOOepN2+msQOywcieDq5sBjabKzTn3U+sfHZlMdw== - type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -12534,6 +12562,11 @@ typescript@~3.9.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== +ua-parser-js@^0.7.21: + version "0.7.22" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.22.tgz#960df60a5f911ea8f1c818f3747b99c6e177eae3" + integrity sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q== + uglify-js@3.4.x: version "3.4.10" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" @@ -12542,6 +12575,14 @@ uglify-js@3.4.x: commander "~2.19.0" source-map "~0.6.1" +unbzip2-stream@^1.3.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -12662,16 +12703,6 @@ upath@^1.1.1: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-electron-app@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/update-electron-app/-/update-electron-app-2.0.1.tgz#229dbeb4534f51ec949e6a46ae1ac32f68a17eed" - integrity sha512-e4xEner89UZZaBGYJbYlMdL1uUrC0VjOsTAL2N4opPjzFtn+j7mdsJJsnyXZzUVeLY+8tuCX4XEsUM98oBHmZg== - dependencies: - electron-is-dev "^0.3.0" - github-url-to-object "^4.0.4" - is-url "^1.2.4" - ms "^2.1.1" - update-notifier@^4.1.1: version "4.1.3" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" @@ -12732,7 +12763,7 @@ url-parse@^1.4.3: querystringify "^2.1.1" requires-port "^1.0.0" -url@^0.11.0, url@~0.11.0: +url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= @@ -12849,15 +12880,15 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vue-cli-plugin-electron-builder@~2.0.0-rc.6: - version "2.0.0-rc.6" - resolved "https://registry.yarnpkg.com/vue-cli-plugin-electron-builder/-/vue-cli-plugin-electron-builder-2.0.0-rc.6.tgz#2c0df46167ef50c71923cf47836bb7e4f6685c29" - integrity sha512-VDpPwdGZ5qoEZe5DuPmyvDB8Ip/CyarpA9cWnEWNJcZ/2NajnglirMCa6cbLrwt9vsv6HFa28IsmVtaVu4dFqw== +vue-cli-plugin-electron-builder@~2.0.0-rc.4: + version "2.0.0-rc.5" + resolved "https://registry.yarnpkg.com/vue-cli-plugin-electron-builder/-/vue-cli-plugin-electron-builder-2.0.0-rc.5.tgz#87cd8d09877f5f3ae339abc0bedc47d7d2b733ac" + integrity sha512-l1/BkwxMDgDSz3fW+KPM3mdVu6ItR6jGhqR6xGhTHxre3dH9XCEfpT+esZp6wxex9trUJzlL+wMmzm79dYKl0A== dependencies: "@vue/cli-shared-utils" "^4.5.6" chokidar "^3.0.2" electron-builder "^22.2.0" - execa "^5.0.0" + execa "^4.0.0" friendly-errors-webpack-plugin "^1.7.0" fs-extra "^9.0.1" lodash.merge "^4.6.1" @@ -13027,38 +13058,51 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -wdio-dot-reporter@~0.0.8: - version "0.0.10" - resolved "https://registry.yarnpkg.com/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz#facfb7c9c5984149951f59cbc3cd0752101cf0e0" - integrity sha512-A0TCk2JdZEn3M1DSG9YYbNRcGdx/YRw19lTiRpgwzH4qqWkO/oRDZRmi3Snn4L2j54KKTfPalBhlOtc8fojVgg== - -webdriverio@^4.13.0: - version "4.14.4" - resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-4.14.4.tgz#f7a94e9a6530819796088f42b009833d83de0386" - integrity sha512-Knp2vzuzP5c5ybgLu+zTwy/l1Gh0bRP4zAr8NWcrStbuomm9Krn9oRF0rZucT6AyORpXinETzmeowFwIoo7mNA== +webdriver@6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-6.7.1.tgz#5333eb4094c719b6ad16246012b30c51dfed5f30" + integrity sha512-WaOq/fvQrsRkPK0Fs6utC9FNVc8llm74QLLaYiMzotKR/BKug4R0Z7JIJ65zY/PYNQj2a6px389LYdHQnPJOtQ== dependencies: - archiver "~2.1.0" - babel-runtime "^6.26.0" - css-parse "^2.0.0" - css-value "~0.0.1" - deepmerge "~2.0.1" - ejs "~2.5.6" - gaze "~1.1.2" - glob "~7.1.1" + "@types/lodash.merge" "^4.6.6" + "@wdio/config" "6.6.3" + "@wdio/logger" "6.6.0" + "@wdio/protocols" "6.6.0" + "@wdio/utils" "6.7.0" + got "^11.0.2" + lodash.merge "^4.6.1" + +webdriverio@^6.1.20: + version "6.7.2" + resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-6.7.2.tgz#60715ebc4b621f999da42fc1e80957fc3fee76f7" + integrity sha512-+ZHkwYTV6G/8+osxq4mUUHqplaOviQ4XpTRfO5RRMXEV3RfMhoC1Fxkr772JFqrtQZ/iY2b90ZyZxfSjZrbrzw== + dependencies: + "@types/archiver" "^3.1.1" + "@types/atob" "^2.1.2" + "@types/fs-extra" "^9.0.2" + "@types/lodash.clonedeep" "^4.5.6" + "@types/lodash.isplainobject" "^4.0.6" + "@types/puppeteer-core" "^2.0.0" + "@wdio/config" "6.6.3" + "@wdio/logger" "6.6.0" + "@wdio/repl" "6.7.1" + "@wdio/utils" "6.7.0" + archiver "^5.0.0" + atob "^2.1.2" + css-value "^0.0.1" + devtools "6.7.0" + fs-extra "^9.0.1" + get-port "^5.1.1" grapheme-splitter "^1.0.2" - inquirer "~3.3.0" - json-stringify-safe "~5.0.1" - mkdirp "~0.5.1" - npm-install-package "~2.1.0" - optimist "~0.6.1" - q "~1.5.0" - request "^2.83.0" - rgb2hex "^0.1.9" - safe-buffer "~5.1.1" - supports-color "~5.0.0" - url "~0.11.0" - wdio-dot-reporter "~0.0.8" - wgxpath "~1.0.0" + lodash.clonedeep "^4.5.0" + lodash.isobject "^3.0.2" + lodash.isplainobject "^4.0.6" + lodash.zip "^4.2.0" + minimatch "^3.0.4" + puppeteer-core "^5.1.0" + resq "^1.9.1" + rgb2hex "^0.2.0" + serialize-error "^7.0.0" + webdriver "6.7.1" webidl-conversions@^4.0.2: version "4.0.2" @@ -13215,11 +13259,6 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -wgxpath@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wgxpath/-/wgxpath-1.0.0.tgz#eef8a4b9d558cc495ad3a9a2b751597ecd9af690" - integrity sha1-7vikudVYzEla06mit1FZfs2a9pA= - whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" @@ -13288,11 +13327,6 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -13387,7 +13421,7 @@ ws@^6.0.0, ws@^6.2.1: dependencies: async-limiter "~1.0.0" -ws@^7.0.0, ws@^7.3.1: +ws@^7.0.0, ws@^7.2.3, ws@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== @@ -13539,12 +13573,11 @@ yorkie@^2.0.0: normalize-path "^1.0.0" strip-indent "^2.0.0" -zip-stream@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.2.0.tgz#a8bc45f4c1b49699c6b90198baacaacdbcd4ba04" - integrity sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ= +zip-stream@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.0.2.tgz#3a20f1bd7729c2b59fd4efa04df5eb7a5a217d2e" + integrity sha512-TGxB2g+1ur6MHkvM644DuZr8Uzyz0k0OYWtS3YlpfWBEmK4woaC2t3+pozEL3dBfIPmpgmClR5B2QRcMgGt22g== dependencies: - archiver-utils "^1.3.0" - compress-commons "^1.2.0" - lodash "^4.8.0" - readable-stream "^2.0.0" + archiver-utils "^2.1.0" + compress-commons "^4.0.0" + readable-stream "^3.6.0"