From 057c1dc7c8e655742f0d300290a876037ab0d7bd Mon Sep 17 00:00:00 2001
From: "Mr. Stallion" <mrstallion@nobody.nowhere.fauxdomain.ext>
Date: Sun, 3 Sep 2023 20:05:46 -0700
Subject: [PATCH] fix broken tabs

---
 CHANGELOG.md             |   3 +
 PRIVACY.md               |   3 +-
 docs/_config.yml         |   2 +-
 electron/Index.vue       |  10 +--
 electron/Window.vue      |  26 +++++-
 electron/chat.ts         |   9 +++
 electron/common.ts       |  17 ++--
 electron/index.html      |   5 +-
 electron/package.json    |   2 +-
 electron/secure-store.ts |  30 +++----
 electron/window.ts       |   2 +
 package.json             |   4 +-
 yarn.lock                | 169 ++++++++++++---------------------------
 13 files changed, 121 insertions(+), 161 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index bcf81a4..bad2650 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
 # Changelog
 
+## 1.24.0
+* Hotfix to address issue with multiple tabs
+
 ## 1.24.0
 * Channel owners can now add `[ads: 30min]` in the channel description to limit how often Rising auto-posts ads on the channel
 * Neko/mimi species are now considered human, not anthro
diff --git a/PRIVACY.md b/PRIVACY.md
index 9b8b51c..a4242e5 100644
--- a/PRIVACY.md
+++ b/PRIVACY.md
@@ -36,4 +36,5 @@ information such as custom dictionary words. By default, the data is stored in:
 | MacOS                | `~/Library/Application Support/fchat` |
 | Linux                | `~/.config/fchat`                     |
 
-F-List account usernames and passwords are stored in a secure datastore provided by your operating system. For more information, see [electron-store](https://www.npmjs.com/package/electron-store).
+F-List account usernames and passwords are stored in a secure datastore provided by your operating system.
+For more information, see [electron safeStorage](https://www.electronjs.org/docs/latest/api/safe-storage).
diff --git a/docs/_config.yml b/docs/_config.yml
index 61ce7ee..02f941f 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -51,7 +51,7 @@ changelog: https://github.com/hearmeneigh/fchat-rising/blob/master/CHANGELOG.md
 installurl: https://github.com/hearmeneigh/fchat-rising/wiki
 
 download:
-  version: 1.24.0
+  version: 1.24.1
 
   url: https://github.com/hearmeneigh/fchat-rising/releases/latest/download/F-Chat-Rising-%PLATFORM_TAIL%
 
diff --git a/electron/Index.vue b/electron/Index.vue
index a9fa551..9bcaf6c 100644
--- a/electron/Index.vue
+++ b/electron/Index.vue
@@ -201,7 +201,7 @@
     //   }
     // >('keytar/build/Release/keytar.node');
 
-    const keyStore = new SecureStore('fchat-rising-accounts', 'DKhjsLIUD#sdfiHNav9SjenWMeF');
+    const keyStore = new SecureStore('fchat-rising-accounts');
 
     // const keyStore = import('keytar');
     //
@@ -263,7 +263,7 @@
 
             log.debug('init.chat.cache.done');
 
-            void EIconStore.getSharedStore();
+            void EIconStore.getSharedStore(); // intentionally background
 
             log.debug('init.eicons.update.done');
 
@@ -317,7 +317,7 @@
 
             if(this.settings.account.length > 0) this.saveLogin = true;
 
-            this.password = keyStore.getPassword('f-list.net', this.settings.account) || '';
+            this.password = (await keyStore.getPassword('f-list.net', this.settings.account)) || '';
 
             log.debug('init.chat.keystore.get.done');
 
@@ -400,7 +400,7 @@
             this.loggingIn = true;
             try {
                 if(!this.saveLogin) {
-                  keyStore.deletePassword('f-list.net', this.settings.account);
+                  await keyStore.deletePassword('f-list.net', this.settings.account);
                 }
 
                 core.siteSession.setCredentials(this.settings.account, this.password);
@@ -416,7 +416,7 @@
                 }
                 if(this.saveLogin) {
                     electron.ipcRenderer.send('save-login', this.settings.account, this.settings.host);
-                    keyStore.setPassword('f-list.net', this.settings.account, this.password);
+                    await keyStore.setPassword('f-list.net', this.settings.account, this.password);
                 }
                 Socket.host = this.settings.host;
 
diff --git a/electron/Window.vue b/electron/Window.vue
index 0fe2388..e28b8e0 100644
--- a/electron/Window.vue
+++ b/electron/Window.vue
@@ -302,11 +302,15 @@
         }
 
         async addTab(): Promise<void> {
+            log.debug('init.window.tab.add.start');
+
             if(this.lockTab) return;
             const tray = new remote.Tray(trayIcon);
             tray.setToolTip(l('title'));
             tray.on('click', (_e) => this.trayClicked(tab));
 
+            log.debug('init.window.tab.add.tray');
+
             const view = new remote.BrowserView(
               {
                 webPreferences: {
@@ -320,9 +324,13 @@
               }
             );
 
+            log.debug('init.window.tab.add.view');
+
             const remoteMain = require("@electron/remote/main");
             remoteMain.enable(view.webContents);
 
+            log.debug('init.window.tab.add.remote');
+
             // tab devtools
             // view.webContents.openDevTools();
 
@@ -330,19 +338,29 @@
               view.webContents.openDevTools({ mode: 'detach' });
             }
 
+            log.debug('init.window.tab.add.devtools');
+
             // console.log('ADD TAB LANGUAGES', getSafeLanguages(this.settings.spellcheckLang), this.settings.spellcheckLang);
             view.webContents.session.setSpellCheckerLanguages(getSafeLanguages(this.settings.spellcheckLang));
 
+            log.debug('init.window.tab.add.spellcheck');
+
             view.setAutoResize({width: true, height: true});
             electron.ipcRenderer.send('tab-added', view.webContents.id);
+
+            log.debug('init.window.tab.add.notify');
+
             const tab = {active: false, view, user: undefined, hasNew: false, tray};
             tray.setContextMenu(remote.Menu.buildFromTemplate(this.createTrayMenu(tab)));
             this.tabs.push(tab);
             this.tabMap[view.webContents.id] = tab;
+
+            log.debug('init.window.tab.add.context');
+
             this.show(tab);
             this.lockTab = true;
 
-            log.debug('init.window.tab.load');
+            log.debug('init.window.tab.add.show');
 
             const indexUrl = url.format({
                 pathname: path.join(__dirname, 'index.html'),
@@ -351,12 +369,16 @@
                 query: {settings: JSON.stringify(this.settings), hasCompletedUpgrades: JSON.stringify(this.hasCompletedUpgrades)}
             });
 
+            log.debug('init.window.tab.add.load-index.start', indexUrl);
+
             await view.webContents.loadURL(indexUrl);
 
-            log.debug('init.window.tab.load.complete', indexUrl);
+            log.debug('init.window.tab.add.load-index.complete', indexUrl);
 
             tab.view.setBounds(getWindowBounds());
             this.lockTab = false;
+
+            log.debug('init.window.tab.add.done');
         }
 
         show(tab: Tab): void {
diff --git a/electron/chat.ts b/electron/chat.ts
index 40b3f4b..b8e5e74 100644
--- a/electron/chat.ts
+++ b/electron/chat.ts
@@ -1,3 +1,4 @@
+console.log('CHAT FIRST');
 /**
  * @license
  * MIT License
@@ -36,12 +37,18 @@
 
 import * as electron from 'electron';
 
+console.log('CHAT GOT HERE');
+
 import * as remote from '@electron/remote';
 const webContents = remote.getCurrentWebContents();
 
+console.log('CHAT GOT HERE 2');
+
 // tslint:disable-next-line:no-require-imports no-submodule-imports
 require('@electron/remote/main').enable(webContents);
 
+console.log('CHAT GOT HERE 3');
+
 import Axios from 'axios';
 import {exec, execSync} from 'child_process';
 import * as path from 'path';
@@ -265,3 +272,5 @@ new Index({
         hasCompletedUpgrades: JSON.parse(params['hasCompletedUpgrades']!)
     }
 });
+
+log.debug('init.chat.vue.done');
diff --git a/electron/common.ts b/electron/common.ts
index 22e75a2..0425a81 100644
--- a/electron/common.ts
+++ b/electron/common.ts
@@ -3,6 +3,8 @@ import * as path from 'path';
 
 import log from 'electron-log'; //tslint:disable-line:match-default-export-name
 
+log.debug('init.common');
+
 export const defaultHost = 'wss://chat.f-list.net/chat2';
 
 function getDefaultLanguage(): string {
@@ -31,11 +33,14 @@ export class GeneralSettings {
     risingDisableWindowsHighContrast =  false;
 }
 
-//tslint:disable
-const Module = require('module');
+// //tslint:disable
+// const Module = require('module');
+//
+// export function nativeRequire<T>(module: string): T {
+//     return Module.prototype.require.call({paths: Module._nodeModulePaths(__dirname)}, module);
+// }
+//
+// //tslint:enable
 
-export function nativeRequire<T>(module: string): T {
-    return Module.prototype.require.call({paths: Module._nodeModulePaths(__dirname)}, module);
-}
+log.debug('init.common.done');
 
-//tslint:enable
diff --git a/electron/index.html b/electron/index.html
index 39523e5..1659e23 100644
--- a/electron/index.html
+++ b/electron/index.html
@@ -7,10 +7,9 @@
 	<link href="fa.css" rel="stylesheet">
 </head>
 <body>
-<div id="app">
-    <div style="color: #ffffff; font-size: 25pt; text-align: center; opacity: 0.4; margin-top: 5em;">Loading F-Chat Rising...</div>
-</div>
+<div id="app"></div>
 <script type="text/javascript" src="common.js"></script>
 <script type="text/javascript" src="chat.js"></script>
 </body>
 </html>
+<!-- <div style="color: #ffffff; font-size: 25pt; text-align: center; opacity: 0.4; margin-top: 5em;">Loading F-Chat Rising...</div> -->
diff --git a/electron/package.json b/electron/package.json
index 0b28e7d..1f29e4d 100644
--- a/electron/package.json
+++ b/electron/package.json
@@ -1,6 +1,6 @@
 {
   "name": "fchat",
-  "version": "1.24.0",
+  "version": "1.24.1",
   "author": "The F-List Team and Mister Stallion (Esq.)",
   "description": "F-List.net Chat Client",
   "main": "main.js",
diff --git a/electron/secure-store.ts b/electron/secure-store.ts
index 4638c88..0b65f0b 100644
--- a/electron/secure-store.ts
+++ b/electron/secure-store.ts
@@ -1,54 +1,44 @@
 import * as electronRemote from '@electron/remote';
-import Store from 'electron-store';
+import settings from 'electron-settings';
 
 export class SecureStore {
-  private store: Store<Record<string, string>>;
-
-  constructor(storeName: string, obfuscationKey: string) {
-    this.store = new Store<Record<string, string>>({
-      accessPropertiesByDotNotation: true,
-      clearInvalidConfig: true,
-      name: storeName,
-      projectName: storeName,
-      watch: true,
-      encryptionKey: obfuscationKey // obfuscation only
-    } as any);
+  constructor(protected storeName: string) {
   }
 
   private getKey(domain: string, account: string): string {
-    return `${domain}__${account}`;
+    return `${this.storeName}__${domain}__${account}`.replace(/[^a-zA-Z0-9_]/g, '__');
   }
 
-  setPassword(domain: string, account: string, password: string): void {
+  async setPassword(domain: string, account: string, password: string): Promise<void> {
     if ((electronRemote as any).safeStorage.isEncryptionAvailable() === false) {
       return;
     }
 
     const buffer = (electronRemote as any).safeStorage.encryptString(password);
 
-    this.store.set(this.getKey(domain, account), buffer.toString('binary'));
+    await settings.set(this.getKey(domain, account), buffer.toString('binary'));
   }
 
-  deletePassword(domain: string, account: string): void {
+  async deletePassword(domain: string, account: string): Promise<void> {
     if ((electronRemote as any).safeStorage.isEncryptionAvailable() === false) {
       return;
     }
 
-    this.store.delete(this.getKey(domain, account));
+    await settings.unset(this.getKey(domain, account));
   }
 
-  getPassword(domain: string, account: string): string | null {
+  async getPassword(domain: string, account: string): Promise<string | null> {
     if ((electronRemote as any).safeStorage.isEncryptionAvailable() === false) {
       return null;
     }
 
-    const pw = this.store.get(this.getKey(domain, account));
+    const pw = await settings.get(this.getKey(domain, account));
 
     if (!pw) {
       return null;
     }
 
-    const buffer = Buffer.from(pw, 'binary');
+    const buffer = Buffer.from(pw.toString(), 'binary');
     const decrypted = (electronRemote as any).safeStorage.decryptString(buffer);
 
     return decrypted;
diff --git a/electron/window.ts b/electron/window.ts
index 4f043aa..f9ee9c0 100644
--- a/electron/window.ts
+++ b/electron/window.ts
@@ -22,3 +22,5 @@ export default new Window({
     el: '#app',
     data: {settings}
 });
+
+log.debug('init.window.vue.done');
diff --git a/package.json b/package.json
index 79a88ab..8ea7524 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "f-list-rising",
-  "version": "1.24.0",
+  "version": "1.24.1",
   "author": "The F-List Team and and Mister Stallion (Esq.)",
   "description": "A heavily modded F-Chat 3.0 client for F-List",
   "license": "MIT",
@@ -30,7 +30,7 @@
     "electron-log": "^4.4.3",
     "electron-packager": "^15.4.0",
     "electron-rebuild": "^3.2.7",
-    "electron-store": "^7.0.0",
+    "electron-settings": "~4.0.2",
     "extract-loader": "^5.1.0",
     "file-loader": "^6.2.0",
     "lodash": "^4.17.20",
diff --git a/yarn.lock b/yarn.lock
index 6a2e885..988821e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -758,13 +758,6 @@ aggregate-error@^3.0.0:
     clean-stack "^2.0.0"
     indent-string "^4.0.0"
 
-ajv-formats@^1.5.1:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-1.6.1.tgz#35c7cdcd2a12d509171c37bac32f2e8eb010a536"
-  integrity sha512-4CjkH20If1lhR5CGtqkrVg3bbOtFEG80X9v6jDOIUhbzzbB+UzPBGy8GQhUNVZ0yvMHdMpawCOcy5ydGMsagGQ==
-  dependencies:
-    ajv "^7.0.0"
-
 ajv-keywords@^3.5.2:
   version "3.5.2"
   resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
@@ -780,16 +773,6 @@ ajv@^6.12.3, ajv@^6.12.5:
     json-schema-traverse "^0.4.1"
     uri-js "^4.2.2"
 
-ajv@^7.0.0, ajv@^7.0.3:
-  version "7.2.4"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-7.2.4.tgz#8e239d4d56cf884bccca8cca362f508446dc160f"
-  integrity sha512-nBeQgg/ZZA3u3SYxyaDvpvDtgZ/EZPF547ARgZBrG9Bhu1vKDwAIjtIf+sDtJUKa2zOcEbmRLBRSyMraS/Oy1A==
-  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"
@@ -995,11 +978,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==
-
 author-regex@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450"
@@ -2136,23 +2114,6 @@ concat-stream@^1.6.2:
     readable-stream "^2.2.2"
     typedarray "^0.0.6"
 
-conf@^9.0.0:
-  version "9.0.2"
-  resolved "https://registry.yarnpkg.com/conf/-/conf-9.0.2.tgz#943589602b1ce274d9234265314336a698972bc5"
-  integrity sha512-rLSiilO85qHgaTBIIHQpsv8z+NnVfZq3cKuYNCXN1AOqPzced0GWZEe/A517VldRLyQYXUMyV+vszavE2jSAqw==
-  dependencies:
-    ajv "^7.0.3"
-    ajv-formats "^1.5.1"
-    atomically "^1.7.0"
-    debounce-fn "^4.0.0"
-    dot-prop "^6.0.1"
-    env-paths "^2.2.0"
-    json-schema-typed "^7.0.3"
-    make-dir "^3.1.0"
-    onetime "^5.1.2"
-    pkg-up "^3.1.0"
-    semver "^7.3.4"
-
 config-chain@^1.1.11:
   version "1.1.13"
   resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
@@ -2451,13 +2412,6 @@ de-indent@^1.0.2:
   resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
   integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
 
-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"
@@ -2648,13 +2602,6 @@ 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"
-
 ds-store@^0.1.5:
   version "0.1.6"
   resolved "https://registry.yarnpkg.com/ds-store/-/ds-store-0.1.6.tgz#d1024ef746ed0c13f0f7fec85c7e858e8c4b7ca7"
@@ -2752,6 +2699,18 @@ electron-rebuild@^3.2.7:
     tar "^6.0.5"
     yargs "^17.0.1"
 
+electron-settings@~4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/electron-settings/-/electron-settings-4.0.2.tgz#26ef242397393e0e69119f6fb879fc2287d0f508"
+  integrity sha512-WnUlrnBsO784oXcag0ym+A3ySoIwonz5GhYFsWroMHVzslzmsP+81f/Fof41T9UrRUxuPPKiZPZMwGO+yvWChg==
+  dependencies:
+    lodash.get "^4.4.2"
+    lodash.has "^4.5.2"
+    lodash.set "^4.3.2"
+    lodash.unset "^4.5.2"
+    mkdirp "^1.0.4"
+    write-file-atomic "^3.0.3"
+
 electron-squirrel-startup@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/electron-squirrel-startup/-/electron-squirrel-startup-1.0.0.tgz#19b4e55933fa0ef8f556784b9c660f772546a0b8"
@@ -2759,14 +2718,6 @@ electron-squirrel-startup@^1.0.0:
   dependencies:
     debug "^2.2.0"
 
-electron-store@^7.0.0:
-  version "7.0.3"
-  resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-7.0.3.tgz#56d78284454018ed50ffc7645da49f828ae5ff19"
-  integrity sha512-wIbw4GHt4djs4dVrlRLCD/SpdpDUiRsQc212jagGA6zJ8xt1iwx3KZIzXY8gmwvgVCOcVxi3iyCXZoBBWwBXpQ==
-  dependencies:
-    conf "^9.0.0"
-    type-fest "^0.20.2"
-
 electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.284:
   version "1.4.402"
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.402.tgz#9aa7bbb63081513127870af6d22f829344c5ba57"
@@ -3290,13 +3241,6 @@ find-up@^2.0.0:
   dependencies:
     locate-path "^2.0.0"
 
-find-up@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
-  integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
-  dependencies:
-    locate-path "^3.0.0"
-
 find-up@^4.0.0, find-up@^4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
@@ -4380,7 +4324,7 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.9:
     gopd "^1.0.1"
     has-tostringtag "^1.0.0"
 
-is-typedarray@~1.0.0:
+is-typedarray@^1.0.0, is-typedarray@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
   integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
@@ -4525,16 +4469,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.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
@@ -4695,14 +4629,6 @@ locate-path@^2.0.0:
     p-locate "^2.0.0"
     path-exists "^3.0.0"
 
-locate-path@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
-  integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
-  dependencies:
-    p-locate "^3.0.0"
-    path-exists "^3.0.0"
-
 locate-path@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
@@ -4715,16 +4641,26 @@ lodash._reinterpolate@^3.0.0:
   resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
   integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==
 
-lodash.get@^4.0.0:
+lodash.get@^4.0.0, lodash.get@^4.4.2:
   version "4.4.2"
   resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
   integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
 
+lodash.has@^4.5.2:
+  version "4.5.2"
+  resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862"
+  integrity sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==
+
 lodash.memoize@^4.1.2:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
   integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==
 
+lodash.set@^4.3.2:
+  version "4.3.2"
+  resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
+  integrity sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==
+
 lodash.template@^4.2.2:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
@@ -4745,6 +4681,11 @@ lodash.uniq@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
   integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
 
+lodash.unset@^4.5.2:
+  version "4.5.2"
+  resolved "https://registry.yarnpkg.com/lodash.unset/-/lodash.unset-4.5.2.tgz#370d1d3e85b72a7e1b0cdf2d272121306f23e4ed"
+  integrity sha512-bwKX88k2JhCV9D1vtE8+naDKlLiGrSmf8zi/Y9ivFHwbmRfA8RxS/aVJ+sIht2XOwqoNr4xUPUkGZpc1sHFEKg==
+
 lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5:
   version "4.17.21"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@@ -4811,7 +4752,7 @@ macos-alias@~0.2.5:
   dependencies:
     nan "^2.4.0"
 
-make-dir@^3.0.2, make-dir@^3.1.0:
+make-dir@^3.0.2:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
   integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
@@ -5013,11 +4954,6 @@ 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"
@@ -5496,7 +5432,7 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
   dependencies:
     wrappy "1"
 
-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==
@@ -5558,7 +5494,7 @@ p-limit@^1.1.0:
   dependencies:
     p-try "^1.0.0"
 
-p-limit@^2.0.0, p-limit@^2.2.0:
+p-limit@^2.2.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
   integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
@@ -5579,13 +5515,6 @@ p-locate@^2.0.0:
   dependencies:
     p-limit "^1.1.0"
 
-p-locate@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
-  integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
-  dependencies:
-    p-limit "^2.0.0"
-
 p-locate@^4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
@@ -5748,13 +5677,6 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0:
   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"
-
 plist@^3.0.0, plist@^3.0.1, plist@^3.0.4:
   version "3.0.6"
   resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.6.tgz#7cfb68a856a7834bca6dbfe3218eb9c7740145d3"
@@ -6449,11 +6371,6 @@ require-directory@^2.1.1:
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
   integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
 
-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==
-
 resolve-alpn@^1.0.0:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
@@ -7457,11 +7374,6 @@ type-fest@^0.18.0:
   resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f"
   integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==
 
-type-fest@^0.20.2:
-  version "0.20.2"
-  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
-  integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
-
 type-fest@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
@@ -7489,6 +7401,13 @@ typed-array-length@^1.0.4:
     for-each "^0.3.3"
     is-typed-array "^1.1.9"
 
+typedarray-to-buffer@^3.1.5:
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
+  integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
+  dependencies:
+    is-typedarray "^1.0.0"
+
 typedarray@^0.0.6:
   version "0.0.6"
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
@@ -7886,6 +7805,16 @@ wrappy@1:
   resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
   integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
 
+write-file-atomic@^3.0.3:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
+  integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
+  dependencies:
+    imurmurhash "^0.1.4"
+    is-typedarray "^1.0.0"
+    signal-exit "^3.0.2"
+    typedarray-to-buffer "^3.1.5"
+
 ws@~8.11.0:
   version "8.11.0"
   resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"