fix copayers
This commit is contained in:
parent
6dba17937f
commit
9e70821c4c
11 changed files with 392 additions and 315 deletions
|
|
@ -1,9 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('copayersController',
|
||||
function($scope, $rootScope, $timeout, $log, $ionicModal, profileService, go, notification, platformInfo, gettext, gettextCatalog) {
|
||||
function($scope, $rootScope, $timeout, $log, $ionicModal, profileService, go, notification, platformInfo, gettext, gettextCatalog, $stateParams, $state) {
|
||||
var self = this;
|
||||
var isCordova = platformInfo.isCordova;
|
||||
$scope.isCordova = platformInfo.isCordova;
|
||||
var isWP = platformInfo.isWP;
|
||||
var isAndroid = platformInfo.isAndroid;
|
||||
|
||||
|
|
@ -12,20 +12,6 @@ angular.module('copayApp.controllers').controller('copayersController',
|
|||
var cancel_msg = gettextCatalog.getString('Cancel');
|
||||
var confirm_msg = gettextCatalog.getString('Confirm');
|
||||
|
||||
// Note that this is ONLY triggered when the page is opened
|
||||
// IF a wallet is incomplete and copay is at /#copayers
|
||||
// and the user switch to an other complete wallet
|
||||
// THIS IS NOT TRIGGERED.
|
||||
//
|
||||
self.init = function() {
|
||||
var fc = profileService.focusedClient;
|
||||
if (fc.isComplete()) {
|
||||
$log.debug('Wallet Complete...redirecting')
|
||||
go.walletHome();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
var _modalDeleteWallet = function() {
|
||||
$scope.title = delete_msg;
|
||||
$scope.accept_msg = accept_msg;
|
||||
|
|
@ -66,9 +52,9 @@ angular.module('copayApp.controllers').controller('copayersController',
|
|||
});
|
||||
};
|
||||
|
||||
self.deleteWallet = function() {
|
||||
$scope.deleteWallet = function() {
|
||||
var fc = profileService.focusedClient;
|
||||
if (isCordova) {
|
||||
if ($scope.isCordova) {
|
||||
navigator.notification.confirm(
|
||||
delete_msg,
|
||||
function(buttonIndex) {
|
||||
|
|
@ -83,15 +69,15 @@ angular.module('copayApp.controllers').controller('copayersController',
|
|||
}
|
||||
};
|
||||
|
||||
self.copySecret = function(secret) {
|
||||
if (isCordova) {
|
||||
$scope.copySecret = function() {
|
||||
if ($scope.isCordova) {
|
||||
window.cordova.plugins.clipboard.copy(secret);
|
||||
window.plugins.toast.showShortCenter(gettextCatalog.getString('Copied to clipboard'));
|
||||
}
|
||||
};
|
||||
|
||||
self.shareSecret = function(secret) {
|
||||
if (isCordova) {
|
||||
$scope.shareSecret = function() {
|
||||
if ($scope.isCordova) {
|
||||
var message = gettextCatalog.getString('Join my Copay wallet. Here is the invitation code: {{secret}} You can download Copay for your phone or desktop at https://copay.io', {
|
||||
secret: secret
|
||||
});
|
||||
|
|
@ -99,4 +85,19 @@ angular.module('copayApp.controllers').controller('copayersController',
|
|||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
if (!$stateParams.walletId) {
|
||||
$log.debug('No wallet provided...back to home');
|
||||
return $state.transitionTo('tabs.home')
|
||||
}
|
||||
|
||||
var wallet = profileService.getWallet($stateParams.walletId);
|
||||
var secret = wallet.status.wallet.secret;
|
||||
try {
|
||||
secret = wallet.status.wallet.secret;
|
||||
} catch (e) {};
|
||||
|
||||
|
||||
$scope.wallet = wallet;
|
||||
$scope.secret = secret;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('createController',
|
||||
function($scope, $rootScope, $timeout, $log, lodash, go, profileService, configService, gettext, ledger, trezor, platformInfo, derivationPathHelper, ongoingProcess) {
|
||||
function($scope, $rootScope, $timeout, $log, lodash, go, profileService, configService, gettext, ledger, trezor, platformInfo, derivationPathHelper, ongoingProcess, walletService) {
|
||||
|
||||
var isChromeApp = platformInfo.isChromeApp;
|
||||
var isCordova = platformInfo.isCordova;
|
||||
|
|
@ -166,7 +166,7 @@ angular.module('copayApp.controllers').controller('createController',
|
|||
ongoingProcess.set('creatingWallet', true);
|
||||
$timeout(function() {
|
||||
|
||||
profileService.createWallet(opts, function(err) {
|
||||
profileService.createWallet(opts, function(err, wallet) {
|
||||
ongoingProcess.set('creatingWallet', false);
|
||||
if (err) {
|
||||
$log.warn(err);
|
||||
|
|
@ -176,13 +176,19 @@ angular.module('copayApp.controllers').controller('createController',
|
|||
});
|
||||
return;
|
||||
}
|
||||
|
||||
walletService.updateRemotePreferences(wallet, {}, function() {
|
||||
$log.debug('Remote preferences saved for:' + wallet.walletId)
|
||||
});
|
||||
|
||||
|
||||
if (self.seedSourceId == 'set') {
|
||||
$timeout(function() {
|
||||
$rootScope.$emit('Local/BackupDone');
|
||||
}, 1);
|
||||
}
|
||||
go.walletHome();
|
||||
|
||||
go.walletHome();
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,15 +95,21 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
opts.password = null;
|
||||
|
||||
$timeout(function() {
|
||||
profileService.importWallet(str2, opts, function(err, walletId) {
|
||||
profileService.importWallet(str2, opts, function(err, wallet) {
|
||||
ongoingProcess.set('importingWallet', false);
|
||||
if (err) {
|
||||
$scope.error = err;
|
||||
} else {
|
||||
$rootScope.$emit('Local/WalletImported', walletId);
|
||||
notification.success(gettext('Success'), gettext('Your wallet has been imported correctly'));
|
||||
go.walletHome();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
walletService.updateRemotePreferences(wallet, {}, function() {
|
||||
$log.debug('Remote preferences saved for:' + wallet.walletId)
|
||||
});
|
||||
|
||||
$rootScope.$emit('Local/WalletImported', wallet.walletId);
|
||||
notification.success(gettext('Success'), gettext('Your wallet has been imported correctly'));
|
||||
go.walletHome();
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
|
@ -111,7 +117,7 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
var _importExtendedPrivateKey = function(xPrivKey, opts) {
|
||||
ongoingProcess.set('importingWallet', true);
|
||||
$timeout(function() {
|
||||
profileService.importExtendedPrivateKey(xPrivKey, opts, function(err, walletId) {
|
||||
profileService.importExtendedPrivateKey(xPrivKey, opts, function(err, wallet) {
|
||||
ongoingProcess.set('importingWallet', false);
|
||||
if (err) {
|
||||
if (err instanceof errors.NOT_AUTHORIZED) {
|
||||
|
|
@ -124,7 +130,12 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
});
|
||||
}
|
||||
|
||||
$rootScope.$emit('Local/WalletImported', walletId);
|
||||
|
||||
walletService.updateRemotePreferences(wallet, {}, function() {
|
||||
$log.debug('Remote preferences saved for:' + wallet.walletId)
|
||||
});
|
||||
|
||||
$rootScope.$emit('Local/WalletImported', wallet.walletId);
|
||||
notification.success(gettext('Success'), gettext('Your wallet has been imported correctly'));
|
||||
go.walletHome();
|
||||
});
|
||||
|
|
@ -157,7 +168,7 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
ongoingProcess.set('importingWallet', true);
|
||||
|
||||
$timeout(function() {
|
||||
profileService.importMnemonic(words, opts, function(err, walletId) {
|
||||
profileService.importMnemonic(words, opts, function(err, wallet) {
|
||||
ongoingProcess.set('importingWallet', false);
|
||||
|
||||
if (err) {
|
||||
|
|
@ -171,7 +182,11 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
});
|
||||
}
|
||||
|
||||
$rootScope.$emit('Local/WalletImported', walletId);
|
||||
walletService.updateRemotePreferences(wallet, {}, function() {
|
||||
$log.debug('Remote preferences saved for:' + wallet.walletId)
|
||||
});
|
||||
|
||||
$rootScope.$emit('Local/WalletImported', wallet.walletId);
|
||||
notification.success(gettext('Success'), gettext('Your wallet has been imported correctly'));
|
||||
go.walletHome();
|
||||
});
|
||||
|
|
@ -293,7 +308,7 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
ongoingProcess.set('importingWallet', true);
|
||||
$log.debug('Import opts', lopts);
|
||||
|
||||
profileService.importExtendedPublicKey(lopts, function(err, walletId) {
|
||||
profileService.importExtendedPublicKey(lopts, function(err, wallet) {
|
||||
ongoingProcess.set('importingWallet', false);
|
||||
if (err) {
|
||||
$scope.error = err;
|
||||
|
|
@ -301,7 +316,12 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
$scope.$apply();
|
||||
});
|
||||
}
|
||||
$rootScope.$emit('Local/WalletImported', walletId);
|
||||
|
||||
|
||||
walletService.updateRemotePreferences(wallet, {}, function() {
|
||||
$log.debug('Remote preferences saved for:' + wallet.walletId)
|
||||
});
|
||||
$rootScope.$emit('Local/WalletImported', wallet.walletId);
|
||||
notification.success(gettext('Success'), gettext('Your wallet has been imported correctly'));
|
||||
go.walletHome();
|
||||
});
|
||||
|
|
@ -366,7 +386,7 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
ongoingProcess.set('importingWallet', true);
|
||||
$log.debug('Import opts', lopts);
|
||||
|
||||
profileService.importExtendedPublicKey(lopts, function(err, walletId) {
|
||||
profileService.importExtendedPublicKey(lopts, function(err, wallet) {
|
||||
ongoingProcess.set('importingWallet', false);
|
||||
if (err) {
|
||||
$scope.error = err;
|
||||
|
|
@ -374,7 +394,12 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
$scope.$apply();
|
||||
});
|
||||
}
|
||||
$rootScope.$emit('Local/WalletImported', walletId);
|
||||
|
||||
|
||||
walletService.updateRemotePreferences(wallet, {}, function() {
|
||||
$log.debug('Remote preferences saved for:' + wallet.walletId)
|
||||
});
|
||||
$rootScope.$emit('Local/WalletImported', wallet.walletId);
|
||||
notification.success(gettext('Success'), gettext('Your wallet has been imported correctly'));
|
||||
go.walletHome();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -128,13 +128,18 @@ angular.module('copayApp.controllers').controller('joinController',
|
|||
this._join = function(opts) {
|
||||
ongoingProcess.set('joiningWallet', true);
|
||||
$timeout(function() {
|
||||
profileService.joinWallet(opts, function(err) {
|
||||
profileService.joinWallet(opts, function(err, wallet) {
|
||||
ongoingProcess.set('joiningWallet', false);
|
||||
if (err) {
|
||||
self.error = err;
|
||||
$rootScope.$apply();
|
||||
return;
|
||||
}
|
||||
|
||||
walletService.updateRemotePreferences(wallet, {}, function() {
|
||||
$log.debug('Remote preferences saved for:' + wallet.walletId)
|
||||
});
|
||||
|
||||
go.walletHome();
|
||||
});
|
||||
}, 100);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $stateParams, profileService, lodash, configService, gettext, gettextCatalog, platformInfo, go, walletService ) {
|
||||
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, profileService, lodash, configService, gettext, gettextCatalog, platformInfo, go, walletService) {
|
||||
|
||||
|
||||
console.log('[walletDetails.js.5]', $stateParams); //TODO
|
||||
var isCordova = platformInfo.isCordova;
|
||||
var isWP = platformInfo.isWP;
|
||||
var isAndroid = platformInfo.isAndroid;
|
||||
|
|
@ -32,7 +31,7 @@ console.log('[walletDetails.js.5]', $stateParams); //TODO
|
|||
ret.countDown = null;
|
||||
ret.sendMaxInfo = {};
|
||||
ret.showAlternative = false;
|
||||
|
||||
|
||||
$scope.openSearchModal = function() {
|
||||
var fc = profileService.focusedClient;
|
||||
$scope.color = fc.backgroundColor;
|
||||
|
|
@ -63,14 +62,32 @@ console.log('[walletDetails.js.5]', $stateParams); //TODO
|
|||
};
|
||||
|
||||
$scope.update = function() {
|
||||
console.log('[walletDetails.js.65:update:] TODO'); //TODO
|
||||
// {triggerTxUpdate: true}
|
||||
walletService.updateStatus(wallet, {
|
||||
force: true
|
||||
}, function(err, status) {
|
||||
if (err) {} // TODO
|
||||
});
|
||||
};
|
||||
|
||||
$scope.hideToggle = function() {
|
||||
console.log('[walletDetails.js.70:hideToogle:] TODO'); //TODO
|
||||
console.log('[walletDetails.js.70:hideToogle:] TODO'); //TODO
|
||||
};
|
||||
$scope.wallet = profileService.getWallet($stateParams.walletId);
|
||||
|
||||
console.log('[walletDetails.js.66]',$scope.wallet); //TODO
|
||||
if (!$stateParams.walletId) {
|
||||
$log.debug('No wallet provided... using the first one');
|
||||
$stateParams.walletId = profileService.getWallets({
|
||||
onlyComplete: true
|
||||
})[0].id;
|
||||
}
|
||||
|
||||
|
||||
var wallet = profileService.getWallet($stateParams.walletId);
|
||||
$scope.wallet = wallet;
|
||||
|
||||
|
||||
if (wallet) {
|
||||
walletService.updateStatus(wallet, {}, function(err, status) {
|
||||
if (err) {} // TODO
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -161,8 +161,8 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.state('unsupported', {
|
||||
url: '/unsupported',
|
||||
|
|
@ -223,11 +223,15 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
.state('copayers', {
|
||||
url: '/copayers',
|
||||
needProfile: true,
|
||||
cache: false,
|
||||
views: {
|
||||
'main': {
|
||||
templateUrl: 'views/copayers.html'
|
||||
},
|
||||
}
|
||||
},
|
||||
params: {
|
||||
walletId: null,
|
||||
},
|
||||
})
|
||||
.state('preferences', {
|
||||
url: '/preferences',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
angular.module('copayApp.services')
|
||||
.factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, notificationService, pushNotificationsService, gettext, gettextCatalog, bwcError, uxLanguage, bitcore, platformInfo, walletService) {
|
||||
.factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, notificationService, pushNotificationsService, gettext, gettextCatalog, bwcError, uxLanguage, bitcore, platformInfo, $ionicHistory) {
|
||||
|
||||
|
||||
var isChromeApp = platformInfo.isChromeApp;
|
||||
|
|
@ -95,6 +95,9 @@ angular.module('copayApp.services')
|
|||
|
||||
client.on('notification', function(n) {
|
||||
$log.debug('BWC Notification:', n);
|
||||
|
||||
$ionicHistory.clearCache();
|
||||
|
||||
notificationService.newBWCNotification(n,
|
||||
walletId, client.credentials.walletName);
|
||||
|
||||
|
|
@ -401,7 +404,7 @@ angular.module('copayApp.services')
|
|||
doCreateWallet(opts, function(err, walletClient, secret) {
|
||||
if (err) return cb(err);
|
||||
|
||||
root.addAndBindWalletClient(walletClient, {
|
||||
addAndBindWalletClient(walletClient, {
|
||||
bwsurl: opts.bwsurl
|
||||
}, cb);
|
||||
});
|
||||
|
|
@ -433,7 +436,7 @@ angular.module('copayApp.services')
|
|||
|
||||
walletClient.joinWallet(opts.secret, opts.myName || 'me', {}, function(err) {
|
||||
if (err) return bwcError.cb(err, gettext('Could not join wallet'), cb);
|
||||
root.addAndBindWalletClient(walletClient, {
|
||||
addAndBindWalletClient(walletClient, {
|
||||
bwsurl: opts.bwsurl
|
||||
}, cb);
|
||||
});
|
||||
|
|
@ -496,7 +499,7 @@ angular.module('copayApp.services')
|
|||
}
|
||||
|
||||
// Adds and bind a new client to the profile
|
||||
root.addAndBindWalletClient = function(client, opts, cb) {
|
||||
var addAndBindWalletClient = function(client, opts, cb) {
|
||||
if (!client || !client.credentials)
|
||||
return cb(gettext('Could not access wallet'));
|
||||
|
||||
|
|
@ -530,19 +533,14 @@ angular.module('copayApp.services')
|
|||
});
|
||||
};
|
||||
|
||||
walletService.updateRemotePreferences(client, {}, function() {
|
||||
$log.debug('Remote preferences saved for:' + walletId)
|
||||
});
|
||||
|
||||
saveBwsUrl(function() {
|
||||
root.setAndStoreFocus(walletId, function() {
|
||||
storageService.storeProfile(root.profile, function(err) {
|
||||
var config = configService.getSync();
|
||||
if (config.pushNotifications.enabled)
|
||||
pushNotificationsService.enableNotifications(root.wallet);
|
||||
return cb(err, walletId);
|
||||
return cb(err, walletClient);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -584,13 +582,13 @@ angular.module('copayApp.services')
|
|||
|
||||
var addressBook = str.addressBook || {};
|
||||
|
||||
root.addAndBindWalletClient(walletClient, {
|
||||
addAndBindWalletClient(walletClient, {
|
||||
bwsurl: opts.bwsurl
|
||||
}, function(err, walletId) {
|
||||
if (err) return cb(err);
|
||||
root.setMetaData(walletClient, addressBook, function(error) {
|
||||
if (error) $log.warn(error);
|
||||
return cb(err, walletId);
|
||||
return cb(err, walletClient);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -607,7 +605,7 @@ angular.module('copayApp.services')
|
|||
return bwcError.cb(err, gettext('Could not import'), cb);
|
||||
}
|
||||
|
||||
root.addAndBindWalletClient(walletClient, {
|
||||
addAndBindWalletClient(walletClient, {
|
||||
bwsurl: opts.bwsurl
|
||||
}, cb);
|
||||
});
|
||||
|
|
@ -638,7 +636,7 @@ angular.module('copayApp.services')
|
|||
return bwcError.cb(err, gettext('Could not import'), cb);
|
||||
}
|
||||
|
||||
root.addAndBindWalletClient(walletClient, {
|
||||
addAndBindWalletClient(walletClient, {
|
||||
bwsurl: opts.bwsurl
|
||||
}, cb);
|
||||
});
|
||||
|
|
@ -661,7 +659,7 @@ angular.module('copayApp.services')
|
|||
return bwcError.cb(err, gettext('Could not import'), cb);
|
||||
}
|
||||
|
||||
root.addAndBindWalletClient(walletClient, {
|
||||
addAndBindWalletClient(walletClient, {
|
||||
bwsurl: opts.bwsurl
|
||||
}, cb);
|
||||
});
|
||||
|
|
@ -745,28 +743,5 @@ angular.module('copayApp.services')
|
|||
return lodash.sortBy(ret, 'name');
|
||||
};
|
||||
|
||||
root.needsBackup = function(client, cb) {
|
||||
|
||||
if (!walletService.needsBackup(client))
|
||||
return cb(false);
|
||||
|
||||
storageService.getBackupFlag(client.credentials.walletId, function(err, val) {
|
||||
if (err) $log.error(err);
|
||||
if (val) return cb(false);
|
||||
return cb(true);
|
||||
});
|
||||
};
|
||||
|
||||
root.isReady = function(client, cb) {
|
||||
if (!client.isComplete())
|
||||
return cb('WALLET_NOT_COMPLETE');
|
||||
|
||||
root.needsBackup(client, function(needsBackup) {
|
||||
if (needsBackup)
|
||||
return cb('WALLET_NEEDS_BACKUP');
|
||||
return cb();
|
||||
});
|
||||
};
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
root.needsBackup = function(wallet) {
|
||||
root.requiresBackup = function(wallet) {
|
||||
if (wallet.isPrivKeyExternal()) return false;
|
||||
if (!wallet.credentials.mnemonic) return false;
|
||||
if (wallet.credentials.network == 'testnet') return false;
|
||||
|
|
@ -69,6 +69,18 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
return true;
|
||||
};
|
||||
|
||||
root.needsBackup = function(wallet, cb) {
|
||||
|
||||
if (!walletService.requiresBackup(wallet))
|
||||
return cb(false);
|
||||
|
||||
storageService.getBackupFlag(wallet.credentials.walletId, function(err, val) {
|
||||
if (err) $log.error(err);
|
||||
if (val) return cb(false);
|
||||
return cb(true);
|
||||
});
|
||||
};
|
||||
|
||||
var _walletStatusHash = function(walletStatus) {
|
||||
var bal;
|
||||
if (walletStatus) {
|
||||
|
|
@ -90,6 +102,9 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
$log.warn('TODO');
|
||||
return; // TODO!!!
|
||||
if (err instanceof errors.NOT_AUTHORIZED) {
|
||||
|
||||
console.log('[walletService.js.93] TODO NOT AUTH'); //TODO
|
||||
// TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
self.notAuthorized = true;
|
||||
go.walletHome();
|
||||
} else if (err instanceof errors.NOT_FOUND) {
|
||||
|
|
@ -815,5 +830,18 @@ console.log('[walletService.js.786:wallet:]',wallet, forceNew); //TODO
|
|||
};
|
||||
|
||||
|
||||
root.isReady = function(wallet, cb) {
|
||||
if (!wallet.isComplete())
|
||||
return cb('WALLET_NOT_COMPLETE');
|
||||
|
||||
root.needsBackup(wallet, function(needsBackup) {
|
||||
if (needsBackup)
|
||||
return cb('WALLET_NEEDS_BACKUP');
|
||||
return cb();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue