+
+ setMode(SIGN_UP_MODE)} label={__('Sign in')} />,
+ }}
+ >
+ Sign up for a sync account. Or %sign_in%.
+
+
+ >
+ }
+ actions={
+
+ }
+ />
+ );
+
+ return (
+
+
+ {mode === DONE_MODE && <>{doneCard}>}
+ {mode === SIGN_IN_MODE && <>{signInCard}>}
+ {mode === SIGN_UP_MODE && <>{signUpCard}>}
+ {mode === MATH_MODE && <>{deriveCard}>}
+ {mode === VERIFY_MODE && <>{verifyCard}>}
+
+
+ );
+}
diff --git a/ui/redux/actions/lbrysync.js b/ui/redux/actions/lbrysync.js
index ec69e3589..f340bd14b 100644
--- a/ui/redux/actions/lbrysync.js
+++ b/ui/redux/actions/lbrysync.js
@@ -1,20 +1,56 @@
// @flow
import * as ACTIONS from 'constants/action_types';
-import Lbrysync from 'lbrysync';
+import { ipcRenderer } from 'electron';
+import { safeStoreEncrypt, safeStoreDecrypt } from 'util/saved-passwords';
+
+import * as Lbrysync from 'lbrysync';
+import Lbry from 'lbry';
+import { Lbryio } from "lbryinc";
+import { selectSyncHash } from '../selectors/sync';
+export const doLbrysyncGetSalt = (email: string) => async (dispatch: Dispatch) => {
+ const { fetchSaltSeed } = Lbrysync;
+ dispatch({
+ type: ACTIONS.LSYNC_GET_SALT_STARTED,
+ });
+ try {
+ const saltOrError = await fetchSaltSeed(email);
+ dispatch({
+ type: ACTIONS.LSYNC_GET_SALT_COMPLETED,
+ data: { email: email, saltSeed: saltOrError},
+ });
+ return saltOrError;
+ } catch (e) {
+ dispatch({
+ type: ACTIONS.LSYNC_GET_SALT_FAILED,
+ data: { email: email, saltError: 'Not Found'},
+ });
+ return 'not found';
+ }
+};
// register an email (eventually username)
-export const doLbrysyncRegister = (email: string, password: string) => async (dispatch: Dispatch) => {
+export const doLbrysyncRegister = (email: string, secrets: any, saltSeed: string) => async (dispatch: Dispatch) => {
const { register } = Lbrysync;
// started
dispatch({
type: ACTIONS.LSYNC_REGISTER_STARTED,
});
- const resultIfError = await register(email, password);
+ const resultIfError = await register(email, secrets.providerPass, saltSeed);
+ const encProviderPass = safeStoreEncrypt(secrets.providerPass);
+ const encHmacKey = safeStoreEncrypt(secrets.hmacKey);
+ const enctyptedRoot = safeStoreEncrypt(secrets.rootPassword);
+ const registerData = {
+ email,
+ saltSeed,
+ providerPass: encProviderPass,
+ hmacKey: encHmacKey,
+ rootPass: enctyptedRoot,
+ };
if (!resultIfError) {
dispatch({
type: ACTIONS.LSYNC_REGISTER_COMPLETED,
- data: email,
+ data: registerData,
});
} else {
dispatch({
@@ -26,13 +62,19 @@ export const doLbrysyncRegister = (email: string, password: string) => async (di
// get token given username/password
export const doLbrysyncAuthenticate =
- (email: string, password: string, deviceId: string) => async (dispatch: Dispatch) => {
- const { getAuthToken } = Lbrysync;
-
- // started
+ () => async (dispatch: Dispatch, getState: GetState) => {
dispatch({
type: ACTIONS.LSYNC_AUTH_STARTED,
});
+ const state = getState();
+ const { lbrysync } = state;
+ const { registeredEmail: email, encryptedProviderPass } = lbrysync;
+ const status = await Lbry.status();
+ const { installation_id: deviceId } = status;
+ const password = safeStoreDecrypt(encryptedProviderPass);
+
+ const { getAuthToken } = Lbrysync;
+
const result: { token?: string, error?: string } = await getAuthToken(email, password, deviceId);
if (result.token) {
@@ -40,10 +82,221 @@ export const doLbrysyncAuthenticate =
type: ACTIONS.LSYNC_AUTH_COMPLETED,
data: result.token,
});
- } else if (result.error) {
+ } else {
dispatch({
type: ACTIONS.LSYNC_AUTH_FAILED,
data: result.error,
});
}
};
+
+export const doGenerateSaltSeed = () => async (dispatch: Dispatch) => {
+ const result = await ipcRenderer.invoke('invoke-get-salt-seed');
+ return result;
+};
+
+export const doDeriveSecrets = (rootPassword: string, email: string, saltSeed: string) => async (dispatch: Dispatch) =>
+ {
+ dispatch({
+ type: ACTIONS.LSYNC_DERIVE_STARTED,
+ });
+ try {
+ const result = await ipcRenderer.invoke('invoke-get-secrets', rootPassword, email, saltSeed);
+
+ const data = {
+ hmacKey: result.hmacKey,
+ rootPassword,
+ providerPass: result.lbryIdPassword,
+ };
+
+ dispatch({
+ type: ACTIONS.LSYNC_DERIVE_COMPLETED,
+ data,
+ });
+ return data;
+ } catch (e) {
+ dispatch({
+ type: ACTIONS.LSYNC_DERIVE_FAILED,
+ data: {
+ error: e,
+ },
+ });
+ return { error: e.message };
+ }
+
+ };
+
+export async function doSetSync() {
+ return (dispatch: Dispatch, getState: GetState) => {
+ const state = getState();
+ const localHash = selectSyncHash(state);
+ const { lbrysync } = state;
+ const { authToken, encryptedRoot } = lbrysync;
+ dispatch({
+ type: ACTIONS.SET_SYNC_STARTED,
+ });
+ let error;
+
+ try {
+ const status = Lbry.wallet_status();
+ if (status.is_locked) {
+ throw new Error('Error parsing i18n messages file: ' + messagesFilePath + ' err: ' + err);
+ }
+ } catch(e) {
+ error = e.message;
+ }
+
+ if (!error) {
+ const syncData = await Lbry.sync_apply({ password: , data: response.data, blocking: true })
+ }
+ // return Lbryio.call('sync', 'set', { old_hash: oldHash, new_hash: newHash, data }, 'post')
+ return pushWallet(authToken)
+ .then((response) => {
+ if (!response.hash) {
+ throw Error('No hash returned for sync/set.');
+ }
+
+ return dispatch({
+ type: ACTIONS.SET_SYNC_COMPLETED,
+ data: { syncHash: response.hash },
+ });
+ })
+ .catch((error) => {
+ dispatch({
+ type: ACTIONS.SET_SYNC_FAILED,
+ data: { error },
+ });
+ });
+ };
+}
+
+export function doGetSync(passedPassword?: string, callback?: (any, ?boolean) => void) {
+
+ const password = passedPassword === null || passedPassword === undefined ? '' : passedPassword;
+
+ function handleCallback(error, hasNewData) {
+ if (callback) {
+ if (typeof callback !== 'function') {
+ throw new Error('Second argument passed to "doGetSync" must be a function');
+ }
+
+ callback(error, hasNewData);
+ }
+ }
+
+ return (dispatch: Dispatch, getState: GetState) => {
+ const state = getState();
+ const localHash = selectSyncHash(state);
+ const { lbrysync } = state;
+ const { authToken, encryptedRoot } = lbrysync;
+ const { pullWallet } = Lbrysync;
+ dispatch({
+ type: ACTIONS.GET_SYNC_STARTED,
+ });
+
+ const data = {};
+
+ Lbry.wallet_status()
+ .then((status) => {
+ if (status.is_locked) {
+ return Lbry.wallet_unlock({ password });
+ }
+
+ // Wallet is already unlocked
+ return true;
+ })
+ .then((isUnlocked) => {
+ if (isUnlocked) {
+ return Lbry.sync_hash(); //unnec
+ }
+ data.unlockFailed = true;
+ throw new Error();
+ })
+ // .then((hash?: string) => Lbryio.call('sync', 'get', { hash }, 'post'))
+ .then((hash?: string) => pullWallet(authToken))
+ .then((response: any) => {
+ // get data, put it in sync apply.
+ const syncHash = response.hash;
+ data.syncHash = syncHash;
+ data.syncData = response.data;
+ data.changed = response.changed || syncHash !== localHash;
+ data.hasSyncedWallet = true;
+
+ if (response.changed) {
+ return Lbry.sync_apply({ password, data: response.data, blocking: true });
+ }
+ })
+ .then((response) => {
+ if (!response) {
+ dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
+ handleCallback(null, data.changed);
+ return;
+ }
+
+ const { hash: walletHash, data: walletData } = response;
+
+ if (walletHash !== data.syncHash) {
+ // different local hash, need to synchronise
+ dispatch(doSetSync(data.syncHash, walletHash, walletData));
+ }
+
+ dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
+ handleCallback(null, data.changed);
+ })
+ .catch((syncAttemptError) => {
+ const badPasswordError =
+ syncAttemptError && syncAttemptError.data && syncAttemptError.data.name === BAD_PASSWORD_ERROR_NAME;
+
+ if (data.unlockFailed) {
+ dispatch({ type: ACTIONS.GET_SYNC_FAILED, data: { error: syncAttemptError } });
+
+ if (badPasswordError) {
+ dispatch({ type: ACTIONS.SYNC_APPLY_BAD_PASSWORD });
+ }
+
+ handleCallback(syncAttemptError);
+ } else if (data.hasSyncedWallet) {
+ const error = (syncAttemptError && syncAttemptError.message) || 'Error getting synced wallet';
+ dispatch({
+ type: ACTIONS.GET_SYNC_FAILED,
+ data: {
+ error,
+ },
+ });
+
+ if (badPasswordError) {
+ dispatch({ type: ACTIONS.SYNC_APPLY_BAD_PASSWORD });
+ }
+
+ handleCallback(error);
+ } else {
+ const noWalletError = syncAttemptError && syncAttemptError.message === NO_WALLET_ERROR;
+
+ dispatch({
+ type: ACTIONS.GET_SYNC_COMPLETED,
+ data: {
+ hasSyncedWallet: false,
+ syncHash: null,
+ // If there was some unknown error, bail
+ fatalError: !noWalletError,
+ },
+ });
+
+ // user doesn't have a synced wallet
+ // call sync_apply to get data to sync
+ // first time sync. use any string for old hash
+ if (noWalletError) {
+ Lbry.sync_apply({ password })
+ .then(({ hash: walletHash, data: syncApplyData }) => {
+ dispatch(doSetSync('', walletHash, syncApplyData));
+ handleCallback();
+ })
+ .catch((syncApplyError) => {
+ handleCallback(syncApplyError);
+ });
+ }
+ }
+ });
+ };
+}
+
diff --git a/ui/redux/actions/sync.js b/ui/redux/actions/sync.js
index d4da1bb60..c3f70f7c5 100644
--- a/ui/redux/actions/sync.js
+++ b/ui/redux/actions/sync.js
@@ -104,7 +104,7 @@ export const doGetSyncDesktop =
const getSyncPending = selectGetSyncIsPending(state);
const setSyncPending = selectSetSyncIsPending(state);
const syncLocked = selectSyncIsLocked(state);
-
+ // here we instead do the new getsync with the derived password
return getSavedPassword().then((savedPassword) => {
const passwordArgument = password || password === '' ? password : savedPassword === null ? '' : savedPassword;
diff --git a/ui/redux/reducers/lbrysync.js b/ui/redux/reducers/lbrysync.js
index 50150164b..fdbda601b 100644
--- a/ui/redux/reducers/lbrysync.js
+++ b/ui/redux/reducers/lbrysync.js
@@ -2,13 +2,24 @@ import * as ACTIONS from 'constants/action_types';
import { handleActions } from 'util/redux-utils';
const defaultState = {
+ syncProvider: null,
+ // reg
registering: false,
registeredEmail: null,
registerError: null,
- syncProvider: null,
+ // authtoken
isAuthenticating: false,
authError: null,
- authToken: null, // store this elsewhere?
+ authToken: null, // store this elsewhere
+ // keys
+ derivingKeys: false,
+ encryptedHmacKey: null,
+ encryptedRoot: null,
+ encryptedProviderPass: null,
+ // salt
+ gettingSalt: false,
+ saltSeed: null,
+ saltError: null,
};
export const lbrysyncReducer = handleActions(
@@ -17,20 +28,27 @@ export const lbrysyncReducer = handleActions(
[ACTIONS.LSYNC_REGISTER_STARTED]: (state) => ({
...state,
registering: true,
+ registerError: null,
}),
[ACTIONS.LSYNC_REGISTER_COMPLETED]: (state, action) => ({
...state,
- registeredEmail: action.data,
+ registeredEmail: action.data.email,
+ encryptedHmacKey: action.data.hmacKey,
+ encryptedProviderPass: action.data.providerPass,
+ encryptedRoot: action.data.rootPass,
+ saltSeed: action.data.saltSeed,
}),
- [ACTIONS.LSYNC_REGISTER_FAILED]: (state) => ({
+ [ACTIONS.LSYNC_REGISTER_FAILED]: (state, action) => ({
...state,
registeredEmail: null,
registering: false,
+ registerError: action.data.error,
}),
// Auth
[ACTIONS.LSYNC_AUTH_STARTED]: (state) => ({
...state,
isAuthenticating: true,
+ authError: null,
}),
[ACTIONS.LSYNC_AUTH_COMPLETED]: (state, action) => ({
...state,
@@ -41,7 +59,36 @@ export const lbrysyncReducer = handleActions(
authError: action.data,
isAuthenticating: false,
}),
- // ...
+ // derive
+ [ACTIONS.LSYNC_DERIVE_STARTED]: (state) => ({
+ ...state,
+ derivingKeys: true,
+ deriveError: null,
+ }),
+ [ACTIONS.LSYNC_DERIVE_COMPLETED]: (state, action) => ({
+ ...state,
+ derivingKeys: false,
+ }),
+ [ACTIONS.LSYNC_DERIVE_FAILED]: (state, action) => ({
+ ...state,
+ deriveError: action.data.error,
+ derivingKeys: false,
+ }),
+ // salt
+ [ACTIONS.LSYNC_GET_SALT_STARTED]: (state) => ({
+ ...state,
+ gettingSalt: true,
+ saltError: null,
+ }),
+ [ACTIONS.LSYNC_GET_SALT_COMPLETED]: (state, action) => ({
+ ...state,
+ gettingSalt: false,
+ }),
+ [ACTIONS.LSYNC_GET_SALT_FAILED]: (state, action) => ({
+ ...state,
+ saltError: action.data.error,
+ gettingSalt: false,
+ }),
},
defaultState
);
diff --git a/ui/redux/selectors/lbrysync.js b/ui/redux/selectors/lbrysync.js
index a344cb3f5..b9f5c7639 100644
--- a/ui/redux/selectors/lbrysync.js
+++ b/ui/redux/selectors/lbrysync.js
@@ -3,14 +3,19 @@ import { createSelector } from 'reselect';
const selectState = (state) => state.lbrysync || {};
export const selectLbrySyncRegistering = createSelector(selectState, (state) => state.registering);
-
export const selectLbrySyncEmail = createSelector(selectState, (state) => state.registeredEmail);
-
export const selectLbrySyncRegisterError = createSelector(selectState, (state) => state.registerError);
-// probably shouldn't store this here.
-export const selectLbrySyncToken = createSelector(selectState, (state) => state.registering);
+export const selectLbrySyncGettingSalt = createSelector(selectState, (state) => state.gettingSalt);
+export const selectLbrySyncSaltError = createSelector(selectState, (state) => state.saltError);
+export const selectLbrySyncSaltSeed = createSelector(selectState, (state) => state.saltSeed);
export const selectLbrySyncIsAuthenticating = createSelector(selectState, (state) => state.isAuthenticating);
export const selectLbrySyncAuthError = createSelector(selectState, (state) => state.authError);
+export const selectLbrySyncToken = createSelector(selectState, (state) => state.authToken);
+
+export const selectLbrySyncDerivingKeys = createSelector(selectState, (state) => state.derivingKeys);
+export const selectLbrySyncEncryptedHmacKey = createSelector(selectState, (state) => state.encryptedHmacKey);
+export const selectLbrySyncEncryptedRoot = createSelector(selectState, (state) => state.encryptedRoot);
+export const selectLbrySyncEncryptedProviderPass = createSelector(selectState, (state) => state.encryptedProviderPass);
diff --git a/ui/util/saved-passwords.js b/ui/util/saved-passwords.js
index ffff63a21..affff9807 100644
--- a/ui/util/saved-passwords.js
+++ b/ui/util/saved-passwords.js
@@ -1,3 +1,5 @@
+const { safeStorage } = require('@electron/remote');
+
const { DOMAIN } = require('../../config.js');
const AUTH_TOKEN = 'auth_token';
const SAVED_PASSWORD = 'saved_password';
@@ -127,6 +129,17 @@ function doAuthTokenRefresh() {
}
}
+function safeStoreEncrypt(ssVal) {
+ const buffer = safeStorage.encryptString(ssVal);
+ console.log('buffer', buffer.toString('base64'));
+ return buffer.toString('base64');
+}
+
+function safeStoreDecrypt(ssVal) {
+ const buffer = safeStorage.decryptString(Buffer.from(ssVal, 'base64'));
+ return buffer.toString();
+}
+
module.exports = {
setSavedPassword,
getSavedPassword,
@@ -137,4 +150,6 @@ module.exports = {
deleteAuthToken,
doSignOutCleanup,
doAuthTokenRefresh,
+ safeStoreEncrypt,
+ safeStoreDecrypt,
};
diff --git a/ui/util/wallet-preferences.js b/ui/util/wallet-preferences.js
new file mode 100644
index 000000000..30385d0ed
--- /dev/null
+++ b/ui/util/wallet-preferences.js
@@ -0,0 +1,32 @@
+export const makeMergedPrefs = (alt, base) => {
+ let finalPrefs = base;
+ let baseData = base.value;
+ let altData = alt.value;
+ if (!altData) {
+ return base;
+ }
+
+ let mergedBlockListSet = new Set(baseData.blocked || []);
+ let mergedSubscriptionsSet = new Set(baseData.subscriptions || []);
+ let mergedTagsSet = new Set(baseData.tags || []);
+
+ const altBlocklist = altData.blocked || [];
+ const altSubscriptions = altData.subscriptions || [];
+ const altTags = altData.tags || [];
+
+ if (altBlocklist.length) {
+ altBlocklist.forEach((el) => mergedBlockListSet.add(el));
+ }
+ if (altSubscriptions.length) {
+ altSubscriptions.forEach((el) => mergedSubscriptionsSet.add(el));
+ }
+ if (altTags.length) {
+ altTags.forEach((el) => mergedTagsSet.add(el));
+ }
+
+ baseData.blocked = Array.from(mergedBlockListSet);
+ baseData.subscriptions = Array.from(mergedSubscriptionsSet);
+ baseData.tags = Array.from(mergedTagsSet);
+ finalPrefs.value = baseData;
+ return finalPrefs;
+};
diff --git a/yarn.lock b/yarn.lock
index 45aa0519f..092e2d130 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3801,6 +3801,18 @@ __metadata:
languageName: node
linkType: hard
+"array.prototype.every@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "array.prototype.every@npm:1.1.3"
+ dependencies:
+ call-bind: ^1.0.2
+ define-properties: ^1.1.3
+ es-abstract: ^1.19.0
+ is-string: ^1.0.7
+ checksum: bbcc864ac1271307043a16262455a6f917d183060a7e5b99c7c710ee611d40c1065f4ec674323b50cf8b987f2d0c9ca9e9ff9cbf4bcc7740f82e731ec2a58d6f
+ languageName: node
+ linkType: hard
+
"array.prototype.flat@npm:^1.2.5":
version: 1.3.0
resolution: "array.prototype.flat@npm:1.3.0"
@@ -3995,6 +4007,13 @@ __metadata:
languageName: node
linkType: hard
+"available-typed-arrays@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "available-typed-arrays@npm:1.0.5"
+ checksum: 20eb47b3cefd7db027b9bbb993c658abd36d4edd3fe1060e83699a03ee275b0c9b216cc076ff3f2db29073225fb70e7613987af14269ac1fe2a19803ccc97f1a
+ languageName: node
+ linkType: hard
+
"aws-sign2@npm:~0.7.0":
version: 0.7.0
resolution: "aws-sign2@npm:0.7.0"
@@ -6471,6 +6490,29 @@ __metadata:
languageName: node
linkType: hard
+"deep-equal@npm:^2.0.5":
+ version: 2.0.5
+ resolution: "deep-equal@npm:2.0.5"
+ dependencies:
+ call-bind: ^1.0.0
+ es-get-iterator: ^1.1.1
+ get-intrinsic: ^1.0.1
+ is-arguments: ^1.0.4
+ is-date-object: ^1.0.2
+ is-regex: ^1.1.1
+ isarray: ^2.0.5
+ object-is: ^1.1.4
+ object-keys: ^1.1.1
+ object.assign: ^4.1.2
+ regexp.prototype.flags: ^1.3.0
+ side-channel: ^1.0.3
+ which-boxed-primitive: ^1.0.1
+ which-collection: ^1.0.1
+ which-typed-array: ^1.1.2
+ checksum: 2bb7332badf589b540184d25098acac750e30fe11c8dce4523d03fc5db15f46881a0105e6bf0b64bb0c57213a95ed964029ff0259026ad6f7f9e0019f8200de5
+ languageName: node
+ linkType: hard
+
"deep-extend@npm:^0.6.0":
version: 0.6.0
resolution: "deep-extend@npm:0.6.0"
@@ -6547,6 +6589,13 @@ __metadata:
languageName: node
linkType: hard
+"defined@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "defined@npm:1.0.0"
+ checksum: 77672997c5001773371c4dbcce98da0b3dc43089d6da2ad87c4b800adb727633cea8723ea3889fe0c2112a2404e2fd07e3bfd0e55f7426aa6441d8992045dbd5
+ languageName: node
+ linkType: hard
+
"del@npm:^3.0.0":
version: 3.0.0
resolution: "del@npm:3.0.0"
@@ -6973,6 +7022,17 @@ __metadata:
languageName: node
linkType: hard
+"dotignore@npm:^0.1.2":
+ version: 0.1.2
+ resolution: "dotignore@npm:0.1.2"
+ dependencies:
+ minimatch: ^3.0.4
+ bin:
+ ignored: bin/ignored
+ checksum: 06bab15e2a2400c6f823a0edbcd73661180f6245a4041a3fe3b9fde4b22ae74b896604df4520a877093f05c656bd080087376c9f605bccdea847664c59910f37
+ languageName: node
+ linkType: hard
+
"duck@npm:^0.1.12":
version: 0.1.12
resolution: "duck@npm:0.1.12"
@@ -7475,7 +7535,7 @@ __metadata:
languageName: node
linkType: hard
-"es-abstract@npm:^1.17.2, es-abstract@npm:^1.19.0, es-abstract@npm:^1.19.1, es-abstract@npm:^1.19.2, es-abstract@npm:^1.19.5, es-abstract@npm:^1.20.1":
+"es-abstract@npm:^1.17.2, es-abstract@npm:^1.19.0, es-abstract@npm:^1.19.1, es-abstract@npm:^1.19.2, es-abstract@npm:^1.19.5, es-abstract@npm:^1.20.0, es-abstract@npm:^1.20.1":
version: 1.20.1
resolution: "es-abstract@npm:1.20.1"
dependencies:
@@ -7513,6 +7573,22 @@ __metadata:
languageName: node
linkType: hard
+"es-get-iterator@npm:^1.1.1":
+ version: 1.1.2
+ resolution: "es-get-iterator@npm:1.1.2"
+ dependencies:
+ call-bind: ^1.0.2
+ get-intrinsic: ^1.1.0
+ has-symbols: ^1.0.1
+ is-arguments: ^1.1.0
+ is-map: ^2.0.2
+ is-set: ^2.0.2
+ is-string: ^1.0.5
+ isarray: ^2.0.5
+ checksum: f75e66acb6a45686fa08b3ade9c9421a70d36a0c43ed4363e67f4d7aab2226cb73dd977cb48abbaf75721b946d3cd810682fcf310c7ad0867802fbf929b17dcf
+ languageName: node
+ linkType: hard
+
"es-shim-unscopables@npm:^1.0.0":
version: 1.0.0
resolution: "es-shim-unscopables@npm:1.0.0"
@@ -8607,6 +8683,15 @@ __metadata:
languageName: node
linkType: hard
+"for-each@npm:^0.3.3":
+ version: 0.3.3
+ resolution: "for-each@npm:0.3.3"
+ dependencies:
+ is-callable: ^1.1.3
+ checksum: 6c48ff2bc63362319c65e2edca4a8e1e3483a2fabc72fbe7feaf8c73db94fc7861bd53bc02c8a66a0c1dd709da6b04eec42e0abdd6b40ce47305ae92a25e5d28
+ languageName: node
+ linkType: hard
+
"for-in@npm:^1.0.2":
version: 1.0.2
resolution: "for-in@npm:1.0.2"
@@ -8884,7 +8969,7 @@ __metadata:
languageName: node
linkType: hard
-"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1":
+"get-intrinsic@npm:^1.0.1, get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1":
version: 1.1.2
resolution: "get-intrinsic@npm:1.1.2"
dependencies:
@@ -8902,6 +8987,13 @@ __metadata:
languageName: node
linkType: hard
+"get-package-type@npm:^0.1.0":
+ version: 0.1.0
+ resolution: "get-package-type@npm:0.1.0"
+ checksum: bba0811116d11e56d702682ddef7c73ba3481f114590e705fc549f4d868972263896af313c57a25c076e3c0d567e11d919a64ba1b30c879be985fc9d44f96148
+ languageName: node
+ linkType: hard
+
"get-stdin@npm:^5.0.1":
version: 5.0.1
resolution: "get-stdin@npm:5.0.1"
@@ -9303,6 +9395,23 @@ __metadata:
languageName: node
linkType: hard
+"has-dynamic-import@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "has-dynamic-import@npm:2.0.1"
+ dependencies:
+ call-bind: ^1.0.2
+ get-intrinsic: ^1.1.1
+ checksum: 1cb60255cdd354a5f53997dd4c8ae0f821706ced3d1047bb810cb74400f28988b08d4d986318cb6610b79e6b9993a6592e678b6cef3ef0b71ab553eaa99b9c4d
+ languageName: node
+ linkType: hard
+
+"has-flag@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "has-flag@npm:2.0.0"
+ checksum: 7d060d142ef6740c79991cb99afe5962b267e6e95538bf8b607026b9b1e7451288927bc8e7b4a9484a8b99935c0af023070f91ee49faef791ecd401dc58b2e8d
+ languageName: node
+ linkType: hard
+
"has-flag@npm:^3.0.0":
version: 3.0.0
resolution: "has-flag@npm:3.0.0"
@@ -10246,7 +10355,7 @@ __metadata:
languageName: node
linkType: hard
-"is-arguments@npm:^1.0.4":
+"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.0":
version: 1.1.1
resolution: "is-arguments@npm:1.1.1"
dependencies:
@@ -10314,7 +10423,7 @@ __metadata:
languageName: node
linkType: hard
-"is-callable@npm:^1.1.4, is-callable@npm:^1.2.4":
+"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.4":
version: 1.2.4
resolution: "is-callable@npm:1.2.4"
checksum: 1a28d57dc435797dae04b173b65d6d1e77d4f16276e9eff973f994eadcfdc30a017e6a597f092752a083c1103cceb56c91e3dadc6692fedb9898dfaba701575f
@@ -10395,7 +10504,7 @@ __metadata:
languageName: node
linkType: hard
-"is-date-object@npm:^1.0.1":
+"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.2":
version: 1.0.5
resolution: "is-date-object@npm:1.0.5"
dependencies:
@@ -10579,6 +10688,13 @@ __metadata:
languageName: node
linkType: hard
+"is-map@npm:^2.0.1, is-map@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "is-map@npm:2.0.2"
+ checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728
+ languageName: node
+ linkType: hard
+
"is-natural-number@npm:^4.0.1":
version: 4.0.1
resolution: "is-natural-number@npm:4.0.1"
@@ -10749,7 +10865,7 @@ __metadata:
languageName: node
linkType: hard
-"is-regex@npm:^1.0.4, is-regex@npm:^1.1.4":
+"is-regex@npm:^1.0.4, is-regex@npm:^1.1.1, is-regex@npm:^1.1.4":
version: 1.1.4
resolution: "is-regex@npm:1.1.4"
dependencies:
@@ -10780,6 +10896,13 @@ __metadata:
languageName: node
linkType: hard
+"is-set@npm:^2.0.1, is-set@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "is-set@npm:2.0.2"
+ checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57
+ languageName: node
+ linkType: hard
+
"is-shared-array-buffer@npm:^1.0.2":
version: 1.0.2
resolution: "is-shared-array-buffer@npm:1.0.2"
@@ -10821,6 +10944,19 @@ __metadata:
languageName: node
linkType: hard
+"is-typed-array@npm:^1.1.9":
+ version: 1.1.9
+ resolution: "is-typed-array@npm:1.1.9"
+ dependencies:
+ available-typed-arrays: ^1.0.5
+ call-bind: ^1.0.2
+ es-abstract: ^1.20.0
+ for-each: ^0.3.3
+ has-tostringtag: ^1.0.0
+ checksum: 11910f1e58755fef43bf0074e52fa5b932bf101ec65d613e0a83d40e8e4c6e3f2ee142d624ebc7624c091d3bbe921131f8db7d36ecbbb71909f2fe310c1faa65
+ languageName: node
+ linkType: hard
+
"is-typedarray@npm:^1.0.0, is-typedarray@npm:~1.0.0":
version: 1.0.0
resolution: "is-typedarray@npm:1.0.0"
@@ -10837,6 +10973,13 @@ __metadata:
languageName: node
linkType: hard
+"is-weakmap@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "is-weakmap@npm:2.0.1"
+ checksum: 1222bb7e90c32bdb949226e66d26cb7bce12e1e28e3e1b40bfa6b390ba3e08192a8664a703dff2a00a84825f4e022f9cd58c4599ff9981ab72b1d69479f4f7f6
+ languageName: node
+ linkType: hard
+
"is-weakref@npm:^1.0.2":
version: 1.0.2
resolution: "is-weakref@npm:1.0.2"
@@ -10846,6 +10989,16 @@ __metadata:
languageName: node
linkType: hard
+"is-weakset@npm:^2.0.1":
+ version: 2.0.2
+ resolution: "is-weakset@npm:2.0.2"
+ dependencies:
+ call-bind: ^1.0.2
+ get-intrinsic: ^1.1.1
+ checksum: 5d8698d1fa599a0635d7ca85be9c26d547b317ed8fd83fc75f03efbe75d50001b5eececb1e9971de85fcde84f69ae6f8346bc92d20d55d46201d328e4c74a367
+ languageName: node
+ linkType: hard
+
"is-whitespace-character@npm:^1.0.0":
version: 1.0.4
resolution: "is-whitespace-character@npm:1.0.4"
@@ -10904,6 +11057,13 @@ __metadata:
languageName: node
linkType: hard
+"isarray@npm:^2.0.5":
+ version: 2.0.5
+ resolution: "isarray@npm:2.0.5"
+ checksum: bd5bbe4104438c4196ba58a54650116007fa0262eccef13a4c55b2e09a5b36b59f1e75b9fcc49883dd9d4953892e6fc007eef9e9155648ceea036e184b0f930a
+ languageName: node
+ linkType: hard
+
"isbinaryfile@npm:^3.0.2":
version: 3.0.3
resolution: "isbinaryfile@npm:3.0.3"
@@ -11500,6 +11660,7 @@ __metadata:
strip-markdown: ^3.0.3
style-loader: ^0.23.1
sudo-prompt: ^9.2.1
+ tape: ^5.6.0
tempy: ^0.6.0
terser-webpack-plugin: ^4.2.3
three-full: ^28.0.2
@@ -13163,14 +13324,14 @@ __metadata:
languageName: node
linkType: hard
-"object-inspect@npm:^1.12.0, object-inspect@npm:^1.9.0":
+"object-inspect@npm:^1.12.0, object-inspect@npm:^1.12.2, object-inspect@npm:^1.9.0":
version: 1.12.2
resolution: "object-inspect@npm:1.12.2"
checksum: a534fc1b8534284ed71f25ce3a496013b7ea030f3d1b77118f6b7b1713829262be9e6243acbcb3ef8c626e2b64186112cb7f6db74e37b2789b9c789ca23048b2
languageName: node
linkType: hard
-"object-is@npm:^1.0.1":
+"object-is@npm:^1.0.1, object-is@npm:^1.1.4, object-is@npm:^1.1.5":
version: 1.1.5
resolution: "object-is@npm:1.1.5"
dependencies:
@@ -13208,6 +13369,18 @@ __metadata:
languageName: node
linkType: hard
+"object.assign@npm:^4.1.3":
+ version: 4.1.4
+ resolution: "object.assign@npm:4.1.4"
+ dependencies:
+ call-bind: ^1.0.2
+ define-properties: ^1.1.4
+ has-symbols: ^1.0.3
+ object-keys: ^1.1.1
+ checksum: 76cab513a5999acbfe0ff355f15a6a125e71805fcf53de4e9d4e082e1989bdb81d1e329291e1e4e0ae7719f0e4ef80e88fb2d367ae60500d79d25a6224ac8864
+ languageName: node
+ linkType: hard
+
"object.entries@npm:^1.1.5":
version: 1.1.5
resolution: "object.entries@npm:1.1.5"
@@ -15513,7 +15686,7 @@ __metadata:
languageName: node
linkType: hard
-"regexp.prototype.flags@npm:^1.2.0, regexp.prototype.flags@npm:^1.4.1, regexp.prototype.flags@npm:^1.4.3":
+"regexp.prototype.flags@npm:^1.2.0, regexp.prototype.flags@npm:^1.3.0, regexp.prototype.flags@npm:^1.4.1, regexp.prototype.flags@npm:^1.4.3":
version: 1.4.3
resolution: "regexp.prototype.flags@npm:1.4.3"
dependencies:
@@ -15959,6 +16132,15 @@ __metadata:
languageName: node
linkType: hard
+"resumer@npm:^0.0.0":
+ version: 0.0.0
+ resolution: "resumer@npm:0.0.0"
+ dependencies:
+ through: ~2.3.4
+ checksum: 21b1c257aac24840643fae9bc99ca6447a71a0039e7c6dcf64d0ead447ce511eff158d529f1b6258ad12668e66ee3e49ff14932d2b88a3bd578f483e79708104
+ languageName: node
+ linkType: hard
+
"ret@npm:~0.1.10":
version: 0.1.15
resolution: "ret@npm:0.1.15"
@@ -16546,7 +16728,7 @@ __metadata:
languageName: node
linkType: hard
-"side-channel@npm:^1.0.4":
+"side-channel@npm:^1.0.3, side-channel@npm:^1.0.4":
version: 1.0.4
resolution: "side-channel@npm:1.0.4"
dependencies:
@@ -17139,6 +17321,17 @@ __metadata:
languageName: node
linkType: hard
+"string.prototype.trim@npm:^1.2.6":
+ version: 1.2.6
+ resolution: "string.prototype.trim@npm:1.2.6"
+ dependencies:
+ call-bind: ^1.0.2
+ define-properties: ^1.1.4
+ es-abstract: ^1.19.5
+ checksum: c5968e023afa9dec6a669c1f427f59aeb74f6f7ee5b0f4b9f0ffcef1d3846aa78b02227448cc874bbfa25dd1f8fd2324041c6cade38d4a986e4ade121ce1ea79
+ languageName: node
+ linkType: hard
+
"string.prototype.trimend@npm:^1.0.5":
version: 1.0.5
resolution: "string.prototype.trimend@npm:1.0.5"
@@ -17464,6 +17657,37 @@ __metadata:
languageName: node
linkType: hard
+"tape@npm:^5.6.0":
+ version: 5.6.0
+ resolution: "tape@npm:5.6.0"
+ dependencies:
+ array.prototype.every: ^1.1.3
+ call-bind: ^1.0.2
+ deep-equal: ^2.0.5
+ defined: ^1.0.0
+ dotignore: ^0.1.2
+ for-each: ^0.3.3
+ get-package-type: ^0.1.0
+ glob: ^7.2.3
+ has: ^1.0.3
+ has-dynamic-import: ^2.0.1
+ inherits: ^2.0.4
+ is-regex: ^1.1.4
+ minimist: ^1.2.6
+ object-inspect: ^1.12.2
+ object-is: ^1.1.5
+ object-keys: ^1.1.1
+ object.assign: ^4.1.3
+ resolve: ^2.0.0-next.3
+ resumer: ^0.0.0
+ string.prototype.trim: ^1.2.6
+ through: ^2.3.8
+ bin:
+ tape: bin/tape
+ checksum: 867b85b6124598c69063548ffb2c4566a63f040d35aee242fd9cc7a0aedc34626feae2ef412d03e2a4817ca9389a4d94006d915b0c163b98e83af52f9258167f
+ languageName: node
+ linkType: hard
+
"tar-stream@npm:^1.5.2":
version: 1.6.2
resolution: "tar-stream@npm:1.6.2"
@@ -17656,7 +17880,7 @@ __metadata:
languageName: node
linkType: hard
-"through@npm:^2.3.6, through@npm:^2.3.8":
+"through@npm:2, through@npm:^2.3.6, through@npm:^2.3.8, through@npm:~2.3, through@npm:~2.3.1, through@npm:~2.3.4":
version: 2.3.8
resolution: "through@npm:2.3.8"
checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd
@@ -19106,7 +19330,7 @@ __metadata:
languageName: node
linkType: hard
-"which-boxed-primitive@npm:^1.0.2":
+"which-boxed-primitive@npm:^1.0.1, which-boxed-primitive@npm:^1.0.2":
version: 1.0.2
resolution: "which-boxed-primitive@npm:1.0.2"
dependencies:
@@ -19119,6 +19343,18 @@ __metadata:
languageName: node
linkType: hard
+"which-collection@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "which-collection@npm:1.0.1"
+ dependencies:
+ is-map: ^2.0.1
+ is-set: ^2.0.1
+ is-weakmap: ^2.0.1
+ is-weakset: ^2.0.1
+ checksum: c815bbd163107ef9cb84f135e6f34453eaf4cca994e7ba85ddb0d27cea724c623fae2a473ceccfd5549c53cc65a5d82692de418166df3f858e1e5dc60818581c
+ languageName: node
+ linkType: hard
+
"which-module@npm:^2.0.0":
version: 2.0.0
resolution: "which-module@npm:2.0.0"
@@ -19126,6 +19362,20 @@ __metadata:
languageName: node
linkType: hard
+"which-typed-array@npm:^1.1.2":
+ version: 1.1.8
+ resolution: "which-typed-array@npm:1.1.8"
+ dependencies:
+ available-typed-arrays: ^1.0.5
+ call-bind: ^1.0.2
+ es-abstract: ^1.20.0
+ for-each: ^0.3.3
+ has-tostringtag: ^1.0.0
+ is-typed-array: ^1.1.9
+ checksum: bedf4d30a738e848404fe67fe0ace33433a7298cf3f5a4d4b2c624ba99c4d25f06a7fd6f3566c3d16af5f8a54f0c6293cbfded5b1208ce11812753990223b45a
+ languageName: node
+ linkType: hard
+
"which@npm:^1.2.10, which@npm:^1.2.14, which@npm:^1.2.9, which@npm:^1.3.1":
version: 1.3.1
resolution: "which@npm:1.3.1"