diff --git a/.gitignore b/.gitignore index 66fd13c..48d1600 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,14 @@ # Dependency directories (remove the comment below to include it) # vendor/ + +# Electron. +electron/release +electron/.cache +electron/.electron_cache +electron/node_modules +electron/.gox_output +electron/server + +# dependencies +**/node_modules diff --git a/.travis.yml b/.travis.yml index 45f52df..7a29ce6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,14 @@ matrix: if: type != pull_request osx_image: xcode8 +before_install: + - nvm install 10.16 + install: - go get -u github.com/FiloSottile/vendorcheck - make install-linters + - make install-deps-ui script: - - make check \ No newline at end of file + - make lint-ui + - make build-ui diff --git a/Makefile b/Makefile index b9eff06..16e6a54 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,9 @@ DEFAULT_GOAL := help OPTS?=GO111MODULE=on TEST_OPTS?=-race -tags no_ci -cover -timeout=10m +# Static files directory +GUI_STATIC_DIR = src/gui/static + check: lint test ## Run linters and tests lint: ## Run linters. Use make install-linters first @@ -32,5 +35,14 @@ dep: ## Sorts dependencies ${OPTS} go mod download ${OPTS} go mod tidy -v +install-deps-ui: ## Install the UI dependencies + cd $(GUI_STATIC_DIR) && npm ci + +lint-ui: ## Lint the UI code + cd $(GUI_STATIC_DIR) && npm run lint + +build-ui: ## Builds the UI + cd $(GUI_STATIC_DIR) && npm run build + help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/electron/README.md b/electron/README.md new file mode 100644 index 0000000..086934e --- /dev/null +++ b/electron/README.md @@ -0,0 +1,48 @@ +# Build system + +The GUI client is an Electron (http://electron.atom.io/) app. + +It cross compiles for osx, linux and windows 64 bit systems. + +## Requirements + +The Skycoin repository must be cloned in the parent directory. + +gox (go cross compiler), node and npm. + +### gox + +To install gox: + +```sh +go get github.com/gz-c/gox +``` + +### NPM + +Node and npm installation is system dependent. + +## Make sure that the wallet dist is up to date + +Recompile the wallet frontend. See [Wallet GUI Development README](../src/gui/static/README.md) for instructions. + +## Use electron-builder to pack and create app installer + +Use this command for preparing the build process. + +```sh +./perpare-build.sh +``` + +Then you can compile the version for the OS you need with any of these commands: + +```sh +npm run dist-win32 +npm run dist-win64 +npm run dist-win +npm run dist-linux +npm run dist-mac +npm run dist-mac +``` + +Final results are placed in the `release` folder. diff --git a/electron/app/.snyk b/electron/app/.snyk new file mode 100644 index 0000000..4747845 --- /dev/null +++ b/electron/app/.snyk @@ -0,0 +1,9 @@ +# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. +version: v1.13.1 +# ignores vulnerabilities until expiry date; change duration by modifying expiry date +ignore: + 'npm:chownr:20180731': + - '*': + reason: No fix available + expires: '2019-06-25T15:35:33.473Z' +patch: {} diff --git a/electron/app/electron-api.js b/electron/app/electron-api.js new file mode 100644 index 0000000..7aa0990 --- /dev/null +++ b/electron/app/electron-api.js @@ -0,0 +1,10 @@ +const { contextBridge, ipcRenderer } = require('electron') + +// Allows to check the URL of the local node while using Electron, as the port number +// is selected randomly. + +contextBridge.exposeInMainWorld('electron', { + getLocalServerUrl: () => { + return ipcRenderer.sendSync('localNodeUrl'); + } +}); diff --git a/electron/app/electron-main.js b/electron/app/electron-main.js new file mode 100644 index 0000000..72d340a --- /dev/null +++ b/electron/app/electron-main.js @@ -0,0 +1,557 @@ +'use strict' + +const { app, Menu, BrowserWindow, shell, session, ipcMain } = require('electron'); +const path = require('path'); +const childProcess = require('child_process'); +const url = require('url'); +const axios = require('axios'); + +// This adds refresh and devtools console keybindings +// Page can refresh with cmd+r, ctrl+r, F5 +// Devtools can be toggled with cmd+alt+i, ctrl+shift+i, F12 +require('electron-debug')({enabled: true, showDevTools: false}); +require('electron-context-menu')({}); + +global.eval = function() { throw new Error('bad!!'); } + +let splashLoaded = false + +// Session of the current window. +let currentSession; +// Folder in which the local node saves the wallet files. +let walletsFolder = null; + +// URLs for accessing the local node and the app contents. +let currentLocalNodeURL; +let currentLocalNodeHost; +let guiURL; +ipcMain.on('localNodeUrl', (event) => { + event.returnValue = currentLocalNodeURL; +}) + +// Detect if the code is running with the "dev" arg. The "dev" arg is added when running npm +// start. If this is true, a local node will not be started, but one is expected to be running +// in 127.0.0.1:6420; also, the local web server will not be started, the contents served in +// http://localhost:4200 will be displayed and it will be allowed to reload the URLs using the +// Electron window, so that it is easier to test the changes made to the UI using npm start. +let dev = process.argv.find(arg => arg === 'dev') ? true : false; + +// Basic settings. +app.commandLine.appendSwitch('ssl-version-fallback-min', 'tls1.2'); +app.commandLine.appendSwitch('--no-proxy-server'); +app.setAsDefaultProtocolClient('skycoin'); +app.allowRendererProcessReuse = true; + +// Keep a global reference of the window object, if you don't, the window will +// be closed automatically when the JavaScript object is garbage collected. +let win; + +// Local node and web server. +var skycoin = null; +let server = null; +const serverPort= 8412; + +// It is only possible to make connections to hosts that are in this list. +var allowedHosts = new Map(); +// Local server. +allowedHosts.set('127.0.0.1:' + serverPort, true); +// Skywallet daemon. +allowedHosts.set('127.0.0.1:9510', true); +// Price service. +allowedHosts.set('api.coinpaprika.com', true); +// For multiple operations. +allowedHosts.set('version.skycoin.com', true); +allowedHosts.set('downloads.skycoin.com', true); +if (dev) { + // Local server while testing. + allowedHosts.set('localhost:4200', true); +} + +// Starts the local node. +function startSkycoin() { + if (!dev) { + console.log('Starting local node from Electron'); + + if (skycoin) { + console.log('Local node already running'); + app.emit('skycoin-ready'); + return; + } + + // Resolve the local node binary location. + var appPath = app.getPath('exe'); + var exe = (() => { + switch (process.platform) { + case 'darwin': + return path.join(appPath, '../../Resources/app/skycoin'); + case 'win32': + // Use only the relative path on windows due to short path length + // limits + return './resources/app/skycoin.exe'; + case 'linux': + return path.join(path.dirname(appPath), './resources/app/skycoin'); + default: + return './resources/app/skycoin'; + } + })() + + // Start the local node. + var args = [ + '-launch-browser=false', + '-color-log=false', // must be disabled for web interface detection + '-logtofile=true', + '-download-peerlist=true', + '-enable-all-api-sets=true', + '-enable-api-sets=INSECURE_WALLET_SEED', + '-disable-csrf=false', + '-reset-corrupt-db=true', + '-enable-gui=false', + '-web-interface-port=0' // random port assignment + // will break + // broken (automatically generated certs do not work): + // '-web-interface-https=true', + ] + skycoin = childProcess.spawn(exe, args); + + createWindow(); + + // Print the local node messages and check for the local node URL. + skycoin.stdout.on('data', (data) => { + console.log(data.toString()); + if (currentLocalNodeURL) { + return; + } + + // String which is expected to precede the local node URL. + const marker = 'Full address: '; + // Get the local node URL. + data.toString().split('\n').forEach(line => { + if (line.indexOf(marker) !== -1) { + setLocalNodeUrl(line.split(marker)[1].trim()); + + var id = setInterval(function() { + // Wait till the splash page loading is finished. + if (splashLoaded) { + app.emit('skycoin-ready', { url: currentLocalNodeURL }); + clearInterval(id); + } + }, 500); + } + }); + }); + skycoin.stderr.on('data', (data) => { + console.log(data.toString()); + }); + + // Close the app if there is a problem. + skycoin.on('error', (e) => { + console.log('Error starting the local node: ' + e); + app.quit(); + }); + skycoin.on('close', (code) => { + console.log('Local node closed'); + app.quit(); + }); + skycoin.on('exit', (code) => { + console.log('Local node exited'); + app.quit(); + }); + } else { + // If in dev mode, use 127.0.0.1:6420 as the local node. It must have been started before. + setLocalNodeUrl('http://127.0.0.1:6420'); + app.emit('skycoin-ready', { url: currentLocalNodeURL }); + } +} + +// Starts the local web server. +function startLocalServer() { + if (!dev) { + console.log('Starting the local server'); + + if (server) { + console.log('Server already running'); + return + } + + // Resolve the server binary location. + var appPath = app.getPath('exe'); + var exe = (() => { + switch (process.platform) { + case 'darwin': + return path.join(appPath, '../../Resources/app/server') + case 'win32': + // User only the relative path on windows due to short path length + // limits + return './resources/app/server.exe'; + case 'linux': + return path.join(path.dirname(appPath), './resources/app/server'); + default: + return './resources/app/server'; + } + })() + + // Get the path to the app files. + var contentsPath = (() => { + switch (process.platform) { + case 'darwin': + return path.join(appPath, '../../Resources/app/dist/') + case 'win32': + return path.join(path.dirname(appPath), './resources/app/dist/'); + case 'linux': + return path.join(path.dirname(appPath), './resources/app/dist/'); + default: + return './resources/app/dist/'; + } + })() + + // Start the server + server = childProcess.spawn(exe, ['-port=' + serverPort, '-path=' + contentsPath]); + + // Close the app if there is a problem. + server.on('error', (e) => { + console.log('Failed to start the local server: ' + e); + app.quit(); + }); + server.on('close', (code) => { + console.log('Local server closed'); + app.quit(); + }); + server.on('exit', (code) => { + console.log('Local server exited'); + app.quit(); + }); + + // Load the contents. + guiURL = 'http://127.0.0.1:' + serverPort; + win.loadURL(guiURL); + } else { + // If in dev mode, simply open the dev server URL. It must have been started before. + guiURL = 'http://localhost:4200/'; + createWindow(guiURL); + } +} + +// Creates and configures the main app window. +function createWindow(urltoOpen) { + // To fix appImage doesn't show icon in dock issue. + var appPath = app.getPath('exe'); + var iconPath = (() => { + switch (process.platform) { + case 'linux': + return path.join(path.dirname(appPath), './resources/icon512x512.png'); + } + })() + + // Create the browser window. + win = new BrowserWindow({ + width: 1200, + height: 900, + backgroundColor: '#000000', + title: 'Skycoin Multicoin Wallet', + icon: iconPath, + nodeIntegration: false, + webPreferences: { + webgl: false, + webaudio: false, + contextIsolation: true, + webviewTag: false, + nodeIntegration: false, + nodeIntegrationInWorker: false, + allowRunningInsecureContent: false, + webSecurity: true, + plugins: false, + enableRemoteModule: false, + preload: __dirname + '/electron-api.js', + }, + }); + + win.webContents.on('did-finish-load', function() { + if (!splashLoaded) { + splashLoaded = true; + } + }); + + // patch out eval + win.eval = global.eval; + win.webContents.executeJavaScript('window.eval = 0;'); + + currentSession = win.webContents.session +/* + currentSession.clearCache().then(response => { + console.log('Cleared the caching of the skycoin wallet.'); + }); + */ + + // When an options request to a swaplab https endpoint is detected, asume that it is a cors + // request and redirect it to an invalid endpoint on the node API. + currentSession.protocol.registerHttpProtocol('https', (request, callback) => { + if (request.method.toLowerCase().includes('options') && request.url.toLowerCase().includes('swaplab.cc')) { + callback({ url: currentLocalNodeURL + '/api/v1/unused', method: 'get' }); + } else { + callback({ url:request.url }); + } + }); + + // Block the connection if the URL is not in allowedHosts. + currentSession.webRequest.onBeforeRequest((details, callback) => { + // This if is needed for allowing the devtools to work. + if (!details.url.startsWith('devtools://devtools')) { + let requestUrl = details.url; + if (details.url.startsWith('blob:')) { + requestUrl = requestUrl.substr('blob:'.length, requestUrl.length - 'blob:'.length); + } + + let requestHost = url.parse(requestUrl).host; + if (!allowedHosts.has(requestHost)) { + callback({cancel: true}) + return; + } + } + callback({cancel: false}) + }); + + // Configure some filters for special cases. + configureFilters(); + + // Open the url if it is already known. If not, open the loading page. + if (urltoOpen) { + win.loadURL(urltoOpen); + } else { + win.loadURL('file://' + __dirname + '/splash/index.html'); + } + + // Emitted when the window is closed. + win.on('closed', () => { + win = null; + }); + + // If in dev mode, allow to open URLs. + if (!dev) { + win.webContents.on('will-navigate', function(e, destinationUrl) { + const requestHost = url.parse(destinationUrl).host; + if (requestHost !== '127.0.0.1:' + serverPort) { + e.preventDefault(); + require('electron').shell.openExternal(destinationUrl); + } + }); + } + + // Open links with target='_blank' in the default browser. + win.webContents.on('new-window', function(e, url) { + e.preventDefault(); + require('electron').shell.openExternal(url); + }); + + // Create the main menu. + var template = [{ + label: 'Skycoin', + submenu: [ + { label: 'Quit', accelerator: 'Command+Q', click: function() { app.quit(); } } + ] + }, { + label: 'Edit', + submenu: [ + { label: 'Undo', accelerator: 'CmdOrCtrl+Z', role: 'undo' }, + { label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo' }, + { type: 'separator' }, + { label: 'Cut', accelerator: 'CmdOrCtrl+X', role: 'cut' }, + { label: 'Copy', accelerator: 'CmdOrCtrl+C', role: 'copy' }, + { label: 'Paste', accelerator: 'CmdOrCtrl+V', role: 'paste' }, + { label: 'Select All', accelerator: 'CmdOrCtrl+A', role: 'selectall' } + ] + }, { + label: 'Show', + submenu: [ + { + label: 'Wallets folder', + click: () => { + if (walletsFolder) { + shell.showItemInFolder(walletsFolder) + } else { + shell.showItemInFolder(path.join(app.getPath("home"), '.skycoin', 'wallets')); + } + }, + }, + { + label: 'Logs folder', + click: () => { + if (walletsFolder) { + shell.showItemInFolder(walletsFolder.replace('wallets', 'logs')) + } else { + shell.showItemInFolder(path.join(app.getPath("home"), '.skycoin', 'logs')); + } + }, + }, + { + label: 'DevTools', + accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I', + click: (item, focusedWindow) => { + if (focusedWindow) { + focusedWindow.toggleDevTools(); + } + } + }, + ] + }]; + + Menu.setApplicationMenu(Menu.buildFromTemplate(template)); + + session + .fromPartition('') + .setPermissionRequestHandler((webContents, permission, callback) => { + return callback(false); + }); +} + +// Makes the window correctly manage some special cases. +function configureFilters() { + if (!currentSession) { + return; + } + + // URLs to check. + const urls = ['https://swaplab.cc/*']; + if (currentLocalNodeURL) { + urls.push(currentLocalNodeURL + '/*'); + } + + // Use the origin headers expected by Swaplab and the local node. + currentSession.webRequest.onBeforeSendHeaders({ + urls: urls + }, (details, callback) => { + if (details.url.indexOf('swaplab.cc') !== -1) { + details.requestHeaders['origin'] = null; + details.requestHeaders['referer'] = null; + details.requestHeaders['host'] = null; + details.requestHeaders['Origin'] = null; + details.requestHeaders['Referer'] = null; + details.requestHeaders['Host'] = null; + } else { + details.requestHeaders['origin'] = currentLocalNodeURL; + details.requestHeaders['referer'] = currentLocalNodeURL; + details.requestHeaders['host'] = currentLocalNodeHost; + } + + callback({ requestHeaders: details.requestHeaders }); + }) + + // Add the CORS headers needed for accessing Swaplab and the local node. + currentSession.webRequest.onHeadersReceived({ + urls: urls + }, (details, callback) => { + const headers = details.responseHeaders; + if (headers) { + headers['Access-Control-Allow-Origin'] = '*'; + headers['Access-Control-Allow-Headers'] = '*'; + } + const response = { responseHeaders: headers }; + + // Options request are redirected in other part of this code to an invalid url, so the + // status must be changed to 200 to simulate a good response. + if (details.method.toLowerCase().includes('options')) { + response['statusLine'] = '200'; + } + + callback(response); + }); +} + +// Allow only one window. +const singleInstanceLockObtained = app.requestSingleInstanceLock() +if (!singleInstanceLockObtained) { + app.quit() + return; +} else { + app.on('second-instance', (event, commandLine, workingDirectory) => { + // Someone tried to run a second instance, we should focus our window. + if (win) { + if (win.isMinimized()) { + win.restore(); + } + win.focus(); + } else { + createWindow(guiURL); + } + }); +} + +// This method will be called when Electron has finished +// initialization and is ready to create browser windows. +// Some APIs can only be used after this event occurs. +app.on('ready', startSkycoin); + +// Called when the local node is running and ready. +app.on('skycoin-ready', (e) => { + // Start the local web server. + startLocalServer(); + + // Get the folder in which the local node saves the wallet files. + axios + .get(e.url + '/api/v1/wallets/folderName') + .then(response => { + walletsFolder = response.data.address; + }) + .catch(() => {}); +}); + +// Quit when all windows are closed. +app.on('window-all-closed', () => { + // On OS X it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('activate', () => { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (win === null) { + createWindow(guiURL); + } +}); + +app.on('will-quit', () => { + if (skycoin) { + skycoin.kill('SIGINT'); + } +}); + +app.on('web-contents-created', (event, contents) => { + contents.on('will-attach-webview', (event, webPreferences, params) => { + // Strip away preload scripts if unused or verify their location is legitimate + delete webPreferences.preload + delete webPreferences.preloadURL + + // Disable Node.js integration + webPreferences.nodeIntegration = false + + // Verify URL being loaded + if (!params.src.startsWith(url)) { + event.preventDefault(); + } + }); +}); + +// Populates currentLocalNodeURL and currentLocalNodeHost. It cleans the URL if needed and adds +// it to the list of allowed URLs (it also removes the previous value from the list, if needed). +// After finishing, configureFilters() is called, to make sure the new URL is processed correctly. +function setLocalNodeUrl(url) { + if (currentLocalNodeHost) { + allowedHosts.delete(currentLocalNodeHost); + } + + currentLocalNodeURL = url; + if (currentLocalNodeURL.endsWith('/')) { + currentLocalNodeURL = currentLocalNodeURL.substr(0, currentLocalNodeURL.length - 1); + } + + if (currentLocalNodeURL.startsWith('https://')) { + currentLocalNodeHost = currentLocalNodeURL.substr(8); + } else { + currentLocalNodeHost = currentLocalNodeURL.substr(7); + } + + allowedHosts.set(currentLocalNodeHost, true); + configureFilters(); +} diff --git a/electron/app/package-lock.json b/electron/app/package-lock.json new file mode 100644 index 0000000..c516d4f --- /dev/null +++ b/electron/app/package-lock.json @@ -0,0 +1,186 @@ +{ + "name": "skycoin-multicoin-electron", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "axios": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", + "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "electron-context-menu": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/electron-context-menu/-/electron-context-menu-0.9.1.tgz", + "integrity": "sha1-7U3yDAgEkcPJlqv8s2MVmUajgFg=", + "requires": { + "electron-dl": "^1.2.0", + "electron-is-dev": "^0.1.1" + } + }, + "electron-debug": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/electron-debug/-/electron-debug-1.5.0.tgz", + "integrity": "sha512-23CLHQXW+gMgdlJbeW1EinPX7DpwuLtfdzSuFL0OnsqEhKGJVJufAZTyq2hc3sr+R53rr3P+mJiYoR5VzAHKJQ==", + "requires": { + "electron-is-dev": "^0.3.0", + "electron-localshortcut": "^3.0.0" + }, + "dependencies": { + "electron-is-dev": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz", + "integrity": "sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=" + } + } + }, + "electron-dl": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-1.12.0.tgz", + "integrity": "sha512-UMc2CL45Ybpvu66LDPYzwmDRmYK4Ivz+wdnTM0eXcNMztvQwhixAk2UPme1c7McqG8bAlKEkQpZn3epmQy4EWg==", + "requires": { + "ext-name": "^5.0.0", + "pupa": "^1.0.0", + "unused-filename": "^1.0.0" + } + }, + "electron-is-accelerator": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz", + "integrity": "sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=" + }, + "electron-is-dev": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.1.2.tgz", + "integrity": "sha1-ihBD4ys6HaHD9VPc4oznZCRhZ+M=" + }, + "electron-localshortcut": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-3.1.0.tgz", + "integrity": "sha512-MgL/j5jdjW7iA0R6cI7S045B0GlKXWM1FjjujVPjlrmyXRa6yH0bGSaIAfxXAF9tpJm3pLEiQzerYHkRh9JG/A==", + "requires": { + "debug": "^2.6.8", + "electron-is-accelerator": "^0.1.0", + "keyboardevent-from-electron-accelerator": "^1.1.0", + "keyboardevents-areequal": "^0.2.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "requires": { + "mime-db": "^1.28.0" + } + }, + "ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "requires": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "keyboardevent-from-electron-accelerator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-1.1.0.tgz", + "integrity": "sha512-VDC4vKWGrR3VgIKCE4CsXnvObGgP8C2idnTKEMUkuEuvDGE1GEBX9FtNdJzrD00iQlhI3xFxRaeItsUmlERVng==" + }, + "keyboardevents-areequal": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz", + "integrity": "sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==" + }, + "mime-db": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==" + }, + "modify-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz", + "integrity": "sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "pupa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-1.0.0.tgz", + "integrity": "sha1-mpVopa9+ZXuEYqbp1TKHQ1YM7/Y=" + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", + "requires": { + "sort-keys": "^1.0.0" + } + }, + "unused-filename": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-1.0.0.tgz", + "integrity": "sha1-00CID3GuIRXrqhMlvvBcxmhEacY=", + "requires": { + "modify-filename": "^1.1.0", + "path-exists": "^3.0.0" + } + } + } +} diff --git a/electron/app/package.json b/electron/app/package.json new file mode 100644 index 0000000..9ba20b3 --- /dev/null +++ b/electron/app/package.json @@ -0,0 +1,14 @@ +{ + "name": "skycoin-multicoin-electron", + "author": "skycoin", + "main": "electron-main.js", + "version": "0.1.0", + "license": "MIT", + "description": "Specific Electron code for the Skycoin multicoin wallet", + "private": true, + "dependencies": { + "axios": "^0.18.1", + "electron-context-menu": "^0.9.1", + "electron-debug": "^1.5.0" + } +} diff --git a/electron/app/splash/index.html b/electron/app/splash/index.html new file mode 100644 index 0000000..546f99e --- /dev/null +++ b/electron/app/splash/index.html @@ -0,0 +1,44 @@ + + + + + + + + +
+
+ +
+ +
+
+
+ + diff --git a/electron/assets/osx/Info.plist b/electron/assets/osx/Info.plist new file mode 100644 index 0000000..7307840 --- /dev/null +++ b/electron/assets/osx/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleExecutable + Skycoin Multicoin Wallet + CFBundleIdentifier + org.skycoin.Skycoin-Multicoin + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Skycoin Multicoin Wallet + CFBundlePackageType + APPL + LSMinimumSystemVersion + 10.10.0 + NSPrincipalClass + NSApplication + CFBundleSignature + ???? + CFBundleIconFile + appIcon.icns + LSUIElement + + CFBundleURLTypes + + + CFBundleURLName + Skycoin Multicoin Wallet + CFBundleURLSchemes + + skycoin + + + + + diff --git a/electron/assets/osx/appIcon.icns b/electron/assets/osx/appIcon.icns new file mode 100644 index 0000000..69e608f Binary files /dev/null and b/electron/assets/osx/appIcon.icns differ diff --git a/electron/assets/windows/favicon.ico b/electron/assets/windows/favicon.ico new file mode 100644 index 0000000..4af3f72 Binary files /dev/null and b/electron/assets/windows/favicon.ico differ diff --git a/electron/build-server.sh b/electron/build-server.sh new file mode 100644 index 0000000..af5ffba --- /dev/null +++ b/electron/build-server.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +if [[ -n "$1" ]]; then + OSARCH="$@" +else + OSARCH="linux/amd64 windows/amd64 windows/386 darwin/amd64" +fi + +if [[ "$OSARCH" == *"windows/386"* ]]; then + echo "Compiling for win_ia32" + env GOOS=windows GOARCH=386 go build -o ./server/win_ia32/server.exe +fi + +if [[ "$OSARCH" == *"windows/amd64"* ]]; then + echo "Compiling for win_x64" + env GOOS=windows GOARCH=amd64 go build -o ./server/win_x64/server.exe +fi + +if [[ "$OSARCH" == *"linux/amd64"* ]]; then + echo "Compiling for linux_x64" + env GOOS=linux GOARCH=amd64 go build -o ./server/linux_x64/server +fi + +if [[ "$OSARCH" == *"darwin/amd64"* ]]; then + echo "Compiling for mac_x64" + env GOOS=darwin GOARCH=amd64 go build -o ./server/mac_x64/server +fi diff --git a/electron/build/icon.icns b/electron/build/icon.icns new file mode 100644 index 0000000..69e608f Binary files /dev/null and b/electron/build/icon.icns differ diff --git a/electron/build/icon.ico b/electron/build/icon.ico new file mode 100644 index 0000000..4af3f72 Binary files /dev/null and b/electron/build/icon.ico differ diff --git a/electron/build/icons/icon512x512.png b/electron/build/icons/icon512x512.png new file mode 100644 index 0000000..8eabd21 Binary files /dev/null and b/electron/build/icons/icon512x512.png differ diff --git a/electron/package-lock.json b/electron/package-lock.json new file mode 100644 index 0000000..e0349c6 --- /dev/null +++ b/electron/package-lock.json @@ -0,0 +1,2189 @@ +{ + "name": "skycoin-multicoin-wallet", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "7zip-bin": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.0.3.tgz", + "integrity": "sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA==", + "dev": true + }, + "@develar/schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } + }, + "@electron/get": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.2.tgz", + "integrity": "sha512-vAuHUbfvBQpYTJ5wB7uVIDq5c/Ry0fiTBMs7lnEYAo/qXXppIVcWdfBr57u6eRnKdVso7KSiH6p/LbQAG6Izrg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "global-agent": "^2.0.2", + "global-tunnel-ng": "^2.7.1", + "got": "^9.6.0", + "progress": "^2.0.3", + "sanitize-filename": "^1.6.2", + "sumchecker": "^3.0.1" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/debug": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", + "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", + "dev": true + }, + "@types/fs-extra": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.2.tgz", + "integrity": "sha512-jp0RI6xfZpi5JL8v7WQwpBEQTq63RqW2kxwTZt+m27LcJqQdPVU1yGnT1ZI4EtCDynQQJtIGyQahkiCGCS7e+A==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "12.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.3.tgz", + "integrity": "sha512-8Jduo8wvvwDzEVJCOvS/G6sgilOLvvhn1eMmK3TW8/T217O7u1jdrK6ImKLv80tVryaPSVeKu6sjDEiFjd4/eg==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.9.tgz", + "integrity": "sha512-HmU8SeIRhZCWcnRskCs36Q1Q00KBV6Cqh/ora8WN1+22dY07AZdn6Gel8QZ3t26XYPImtcL8WV/eqjhVmMEw4g==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "app-builder-bin": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.10.tgz", + "integrity": "sha512-Jd+GW68lR0NeetgZDo47PdWBEPdnD+p0jEa7XaxjRC8u6Oo/wgJsfKUkORRgr2NpkD19IFKN50P6JYy04XHFLQ==", + "dev": true + }, + "app-builder-lib": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.9.1.tgz", + "integrity": "sha512-KfXim/fiNwFW2SKffsjEMdAU7RbbEXn62x5YyXle1b4j9X/wEHW9iwox8De6y0hJdR+/kCC/49lI+VgNwLhV7A==", + "dev": true, + "requires": { + "7zip-bin": "~5.0.3", + "@develar/schema-utils": "~2.6.5", + "async-exit-hook": "^2.0.1", + "bluebird-lst": "^1.0.9", + "builder-util": "22.9.1", + "builder-util-runtime": "8.7.2", + "chromium-pickle-js": "^0.2.0", + "debug": "^4.3.0", + "ejs": "^3.1.5", + "electron-publish": "22.9.1", + "fs-extra": "^9.0.1", + "hosted-git-info": "^3.0.5", + "is-ci": "^2.0.0", + "isbinaryfile": "^4.0.6", + "js-yaml": "^3.14.0", + "lazy-val": "^1.0.4", + "minimatch": "^3.0.4", + "normalize-package-data": "^2.5.0", + "read-config-file": "6.0.0", + "sanitize-filename": "^1.6.3", + "semver": "^7.3.2", + "temp-file": "^3.3.7" + }, + "dependencies": { + "debug": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.0.tgz", + "integrity": "sha512-jjO6JD2rKfiZQnBoRzhRTbXjHLGLfH+UtGkWLc/UXAh/rzZMyjbgn0NcfFpqT8nd1kTtFnDiJcrIFkq4UKeJVg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } + } + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, + "async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bluebird-lst": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", + "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5" + } + }, + "boolean": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.1.tgz", + "integrity": "sha512-HRZPIjPcbwAVQvOTxR4YE3o8Xs98NqbbL1iEZDCz7CL8ql0Lt5iOyJFxfnAB0oFs8Oh02F/lLlg30Mexv46LjA==", + "dev": true, + "optional": true + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "builder-util": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.9.1.tgz", + "integrity": "sha512-5hN/XOaYu4ZQUS6F+5CXE6jTo+NAnVqAxDuKGSaHWb9bejfv/rluChTLoY3/nJh7RFjkoyVjvFJv7zQDB1QmHw==", + "dev": true, + "requires": { + "7zip-bin": "~5.0.3", + "@types/debug": "^4.1.5", + "@types/fs-extra": "^9.0.1", + "app-builder-bin": "3.5.10", + "bluebird-lst": "^1.0.9", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "debug": "^4.3.0", + "fs-extra": "^9.0.1", + "is-ci": "^2.0.0", + "js-yaml": "^3.14.0", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.3.7" + }, + "dependencies": { + "debug": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.0.tgz", + "integrity": "sha512-jjO6JD2rKfiZQnBoRzhRTbXjHLGLfH+UtGkWLc/UXAh/rzZMyjbgn0NcfFpqT8nd1kTtFnDiJcrIFkq4UKeJVg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + } + } + }, + "builder-util-runtime": { + "version": "8.7.2", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz", + "integrity": "sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "sax": "^1.2.4" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "cliui": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.3.tgz", + "integrity": "sha512-Gj3QHTkVMPKqwP3f7B4KPkBZRMR9r4rfi5bXFpg1a+Svvj8l7q5CnkBkVQzfxT5DFSsGk2+PascOgL0JYkL2kw==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "dev": true, + "optional": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "optional": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true, + "optional": true + }, + "dmg-builder": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.9.1.tgz", + "integrity": "sha512-jc+DAirqmQrNT6KbDHdfEp8D1kD0DBTnsLhwUR3MX+hMBun5bT134LQzpdK0GKvd22GqF8L1Cz/NOgaVjscAXQ==", + "dev": true, + "requires": { + "app-builder-lib": "22.9.1", + "builder-util": "22.9.1", + "fs-extra": "^9.0.1", + "iconv-lite": "^0.6.2", + "js-yaml": "^3.14.0", + "sanitize-filename": "^1.6.3" + }, + "dependencies": { + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + } + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "dev": true + }, + "dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ejs": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz", + "integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==", + "dev": true, + "requires": { + "jake": "^10.6.1" + } + }, + "electron": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/electron/-/electron-10.1.5.tgz", + "integrity": "sha512-fys/KnEfJq05TtMij+lFvLuKkuVH030CHYx03iZrW5DNNLwjE6cW3pysJ420lB0FRSfPjTHBMu2eVCf5TG71zQ==", + "dev": true, + "requires": { + "@electron/get": "^1.0.1", + "@types/node": "^12.0.12", + "extract-zip": "^1.0.3" + } + }, + "electron-builder": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.9.1.tgz", + "integrity": "sha512-GXPt8l5Mxwm1QKYopUM6/Tdh9W3695G6Ax+IFyj5pQ51G4SD5L1uq4/RkPSsOgs3rP7jNSV6g6OfDzdtVufPdA==", + "dev": true, + "requires": { + "@types/yargs": "^15.0.5", + "app-builder-lib": "22.9.1", + "bluebird-lst": "^1.0.9", + "builder-util": "22.9.1", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "dmg-builder": "22.9.1", + "fs-extra": "^9.0.1", + "is-ci": "^2.0.0", + "lazy-val": "^1.0.4", + "read-config-file": "6.0.0", + "sanitize-filename": "^1.6.3", + "update-notifier": "^4.1.1", + "yargs": "^16.0.3" + }, + "dependencies": { + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + } + } + }, + "electron-publish": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.9.1.tgz", + "integrity": "sha512-ducLjRJLEeU87FaTCWaUyDjCoLXHkawkltP2zqS/n2PyGke54ZIql0tBuUheht4EpR8AhFbVJ11spSn1gy8r6w==", + "dev": true, + "requires": { + "@types/fs-extra": "^9.0.1", + "bluebird-lst": "^1.0.9", + "builder-util": "22.9.1", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "fs-extra": "^9.0.1", + "lazy-val": "^1.0.4", + "mime": "^2.4.6" + }, + "dependencies": { + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "optional": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "env-paths": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", + "dev": true + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "optional": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "optional": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "dev": true, + "requires": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "filelist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz", + "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "global-agent": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz", + "integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==", + "dev": true, + "optional": true, + "requires": { + "boolean": "^3.0.1", + "core-js": "^3.6.5", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + } + }, + "global-dirs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "dev": true, + "requires": { + "ini": "^1.3.5" + } + }, + "global-tunnel-ng": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", + "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", + "dev": true, + "optional": true, + "requires": { + "encodeurl": "^1.0.2", + "lodash": "^4.17.10", + "npm-conf": "^1.1.3", + "tunnel": "^0.0.6" + } + }, + "globalthis": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz", + "integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==", + "dev": true, + "optional": true, + "requires": { + "define-properties": "^1.1.3" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "hosted-git-info": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", + "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", + "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isbinaryfile": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", + "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", + "dev": true + }, + "jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "dev": true, + "requires": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true, + "optional": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "lazy-val": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.4.tgz", + "integrity": "sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q==", + "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true, + "optional": true + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "optional": true, + "requires": { + "escape-string-regexp": "^4.0.0" + } + }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "npm-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", + "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "dev": true, + "optional": true, + "requires": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "optional": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true, + "optional": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read-config-file": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.0.0.tgz", + "integrity": "sha512-PHjROSdpceKUmqS06wqwP92VrM46PZSTubmNIMJ5DrMwg1OgenSTSEHIkCa6TiOJ+y/J0xnG1fFwG3M+Oi1aNA==", + "dev": true, + "requires": { + "dotenv": "^8.2.0", + "dotenv-expand": "^5.1.0", + "js-yaml": "^3.13.1", + "json5": "^2.1.2", + "lazy-val": "^1.0.4" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "registry-auth-token": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", + "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "resolve": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "dev": true, + "requires": { + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "optional": true, + "requires": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true, + "optional": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "optional": true, + "requires": { + "type-fest": "^0.13.1" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", + "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "dev": true + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true, + "optional": true + }, + "stat-mode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "requires": { + "debug": "^4.1.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "temp-file": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.3.7.tgz", + "integrity": "sha512-9tBJKt7GZAQt/Rg0QzVWA8Am8c1EFl+CAv04/aBVqlx5oyfQ508sFIABshQ0xbZu6mBrFLWIUXO/bbLYghW70g==", + "dev": true, + "requires": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^8.1.0" + } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "dev": true, + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "optional": true + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "optional": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.0.tgz", + "integrity": "sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.2", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.3.tgz", + "integrity": "sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/electron/package.json b/electron/package.json new file mode 100644 index 0000000..3682340 --- /dev/null +++ b/electron/package.json @@ -0,0 +1,87 @@ +{ + "name": "skycoin-multicoin-wallet", + "productName": "Skycoin multicoin wallet", + "author": "skycoin", + "main": "app/electron-main.js", + "version": "0.1.0", + "description": "Skycoin multicoin wallet", + "license": "MIT", + "private": true, + "build": { + "appId": "org.skycoin.skycoin-multicoin", + "nsis": { + "oneClick": false, + "allowToChangeInstallationDirectory": true + }, + "mac": { + "category": "public.app-category.productivity", + "extraFiles": [ + { + "from": ".gox_output/gui/${os}_${arch}", + "to": "./Resources/app" + }, + { + "from": "./server/${os}_${arch}/", + "to": "./Resources/app" + } + ] + }, + "win": { + "target": "nsis", + "extraFiles": [ + { + "from": ".gox_output/gui/${os}_${arch}", + "to": "./resources/app" + }, + { + "from": "./server/${os}_${arch}/", + "to": "./resources/app" + } + ] + }, + "linux": { + "category": "Network", + "extraFiles": [ + { + "from": ".gox_output/gui/${os}_${arch}", + "to": "./resources/app" + }, + { + "from": "./server/${os}_${arch}/", + "to": "./resources/app" + }, + { + "from": "build/icons/icon512x512.png", + "to": "./Resources" + } + ] + }, + "extraResources": [ + { + "from": "../src/gui/static/dist/", + "to": "./app/dist/", + "filter": [ + "**/*" + ] + } + ], + "directories": { + "output": "release" + } + }, + "scripts": { + "start": "electron ./app/electron-main.js dev", + "dist-win32": "electron-builder -w --ia32 -p=never", + "dist-win64": "electron-builder -w --x64 -p=never", + "dist-win": "electron-builder -w --x64 --ia32 -p=never", + "dist-linux": "electron-builder -l --x64 -p=never", + "dist-mac": "electron-builder -m --x64 -p=never", + "pack-mac": "electron-builder --dir -m -p=never", + "postinstall": "electron-builder install-app-deps" + }, + "devDependencies": { + "electron": "^10.1.5", + "electron-builder": "22.9.1" + }, + "dependencies": {} +} diff --git a/electron/perpare-build.sh b/electron/perpare-build.sh new file mode 100644 index 0000000..685ce31 --- /dev/null +++ b/electron/perpare-build.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Prepares the files needed for building the Electron release using npm. +# The app must have been already built with npm run build. + +echo "Installing node modules" +npm install +cd app/ +npm install +cd .. + +echo +echo "===========================" +echo "Building the local web server" +build-server.sh + +echo +echo "===========================" +echo "Building the local node" +GOX_OSARCH="linux/amd64 linux/arm windows/amd64 windows/386 darwin/amd64" +GOX_OUTPUT_DIR=".gox_output" +GOX_GUI_OUTPUT_DIR="${GOX_OUTPUT_DIR}/gui" +cd ../../skycoin/electron +CONFIG_MODE=STANDALONE_CLIENT ./gox.sh "$GOX_OSARCH" "$GOX_GUI_OUTPUT_DIR" +cp -R .gox_output ../../multicoin-wallet/electron/.gox_output diff --git a/electron/server.go b/electron/server.go new file mode 100644 index 0000000..6d49964 --- /dev/null +++ b/electron/server.go @@ -0,0 +1,67 @@ +/* +Lite wallet backend service. Serves a precompiled angular website. +*/ + +package main + +import ( + "flag" + "net/http" + "time" +) + +const ( + walletHost = "127.0.0.1" + + // https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/ + // timeout for requests + serverReadTimeout = time.Second * 10 + serverWriteTimeout = time.Second * 60 + serverIdleTimeout = time.Second * 120 +) + +var ( + path string + port string +) + +// ContentSecurityPolicy csp header in http response +const ContentSecurityPolicy = "default-src 'self'" + + "; script-src 'self'" + + "; connect-src *" + + "; img-src 'self' 'unsafe-inline' data:" + + "; style-src 'self' 'unsafe-inline'" + + "; object-src 'none'" + + "; form-action 'none'" + + "; frame-ancestors 'none'" + + "; block-all-mixed-content" + + "; base-uri 'self'" + +// CSPHandler enables CSP +func CSPHandler(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Security-Policy", ContentSecurityPolicy) + handler.ServeHTTP(w, r) + }) +} + +func main() { + flag.StringVar(&path, "path", "-1", "contents path") + flag.StringVar(&port, "port", "-1", "server port") + flag.Parse() + + if path != "-1" && port != "-1" { + handler := http.FileServer(http.Dir(path)) + s := &http.Server{ + Addr: walletHost + ":" + port, + Handler: CSPHandler(handler), + ReadTimeout: serverReadTimeout, + WriteTimeout: serverWriteTimeout, + IdleTimeout: serverIdleTimeout, + } + + if err := s.ListenAndServe(); err != nil { + panic(err) + } + } +} diff --git a/src/gui/static/.browserslistrc b/src/gui/static/.browserslistrc new file mode 100644 index 0000000..8084853 --- /dev/null +++ b/src/gui/static/.browserslistrc @@ -0,0 +1,12 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +> 0.5% +last 2 versions +Firefox ESR +not dead +not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/src/gui/static/.editorconfig b/src/gui/static/.editorconfig new file mode 100644 index 0000000..6e87a00 --- /dev/null +++ b/src/gui/static/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/src/gui/static/.gitignore b/src/gui/static/.gitignore new file mode 100644 index 0000000..30c55b6 --- /dev/null +++ b/src/gui/static/.gitignore @@ -0,0 +1,41 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/tmp +/out-tsc + +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +testem.log +/typings + +# e2e +/e2e/*.js +/e2e/*.map + +# System Files +.DS_Store +Thumbs.db diff --git a/src/gui/static/DEVELOPMENT.md b/src/gui/static/DEVELOPMENT.md new file mode 100644 index 0000000..3662117 --- /dev/null +++ b/src/gui/static/DEVELOPMENT.md @@ -0,0 +1,33 @@ +# Development notes + +This file contains notes about the procedures that have been used for performing frequent operations and other general +approaches that have been used in the code, which should be followed to maintain consistency and make the project more maintainable. + +## Form validation + +Normally, Forms are not validated using the prebuild validators Angular provide, but a custom validation function assigned to the form +via the `setValidators`. You can see examples of this in most forms, like in `CreateWalletFormComponent`, were the form is validated +by the `validateForm` function. Please, check the code to have a better idea about how each field is validated inside the function +and what is done when invalid values are found, the process is very similar in all forms. Some relevant things to take into account are: + +- When there is an invalid value, the error message is saved in a var specifically made for that field. +- In the html code those vars are passed to the `appFormFieldError` directive, which takes care of showing the error in the UI. +- If there are errors, the confirm button should be disabled. + +## Working forms + +When the user uses a form to start a procedure and the procedure is not immediate, the confirmation button must be put in loading +state and a var called `working` is normally set to `true`. When the `working` var is `true`, all new request to process the data +must be ignored, which is something important top keep in mind because the procedure can be started by pressing the confirmation button, +pressing the `enter` key while in the last field and other situations. Also, while the `working` var is true all fields must be disabled. + +## Submit forms + +The user must be able to submit any form by pressing the confirmation button and by pressing the `Enter` key while the last field is +focused. The normal behavior of the web browsers when using a form and a submit button is to submit the form if the `Enter` key is +pressed while any field is focused, which is NOT the behavior of this app. + +## Passwords + +Use `DontsavepasswordDirective` in all password fields to prevent the web browser from showing password suggestions and prevent +potential security problems. diff --git a/src/gui/static/README.md b/src/gui/static/README.md new file mode 100644 index 0000000..5636e92 --- /dev/null +++ b/src/gui/static/README.md @@ -0,0 +1,73 @@ +# Skycoin desktop client + +The Skycoin wallet ships with a web interface which can be ran from the browser and/or Electron. + +The project contains both the source (src) and target (dist) files of this web interface. + +## Prerequisites + +The Skycoin web interface requires Node 10.9.0 or higher, together with NPM 6.0 or higher. + +## Installation + +This project is generated using Angular CLI, therefore it is adviced to first run `npm install -g @angular/cli`. + +Dependencies are managed with NPM, to install these run `npm install`. + +You will only have to run this again, if any dependencies have been changed in the `package-lock.json` file. + +## Compiling new target files + +After pulling the latest code, you might first have to update your dependencies, in case someone else has updated them. +You should always do this when compiling new production files: + +``` +rm -rf node_modules +npm install +``` + +This will remove the current dependencies, and install them from the `package-lock.json`. + +To compile new target files, you will have to run: `npm run build`. + +## Development server + +Run `npm start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +Please note that you will most likely receive CORS errors as there's a difference between the port number of the source and destination. + +As a work-around, the development server will create a proxy from `http://localhost:4200/api` to `http://127.0.0.1:6420/`. + +You can route all calls to this address by changing the url property on the FiberApiService class. + +## Swaplab integration + +The wallet has a section for buying coins using the Swaplab service and, during development, it is possible to configure its operation, +in order to test its different parts without having to make a real exchange. The configuration is done by modifying the properties of +the `swaplab` object in [environment.ts](/src/gui/static/src/environment/environment.ts). + +If you set `swaplab.activateTestMode` to `true`, all operations made with the Swaplab integration will be faked. When creating a new +operation or opening an old one using the history, the system will show the operation progressing every few seconds, from the state in +which the user is expected to make the initial deposit to the moment in which the operation is completed. +If `swaplabTests.activateTestMode` is `false`, the integration will work as it should and you will be able to make real exchange transactions. + +Also `swaplab` has a property called `endStatusInError`. If you set it to `true` and `swaplabTests.activateTestMode` is also `true`, +all the faked operations will end in an error, instead of success. + +## Purchase API (teller) + +Please note that at the moment the Purchase API (teller) is both offline and not supporting CORS headers. + +While event.skycoin.com is not working, we will have to run the purchase API locally. + +Similar as the solution for the above CORS issue, you can circumvent CORS issues by changing the url property to '/teller/' + +## Style guide + +As an Angular application, we try to follow the [Angular style guide](https://angular.io/guide/styleguide). + +Some additions notes can be found in [DEVELOPMENT.md](DEVELOPMENT.md). + +## Translations + +You can find information about how to work with translation files in the [Translations README](/src/gui/static/src/assets/i18n/README.md). diff --git a/src/gui/static/angular.json b/src/gui/static/angular.json new file mode 100644 index 0000000..7366e04 --- /dev/null +++ b/src/gui/static/angular.json @@ -0,0 +1,178 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "desktopwallet": { + "root": "", + "sourceRoot": "src", + "projectType": "application", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "aot": true, + "outputPath": "dist", + "index": "src/index.html", + "main": "src/main.ts", + "tsConfig": "src/tsconfig.app.json", + "polyfills": "src/polyfills.ts", + "deleteOutputPath": false, + "assets": [ + "src/assets", + "src/favicon.ico", + "src/app/current-skycoin.json" + ], + "styles": [ + "node_modules/font-awesome/css/font-awesome.css", + "src/assets/fonts/material-icons/material-icons.css", + "src/styles.scss" + ], + "scripts": [ + "src/assets/scripts/qrcode.min.js" + ], + "allowedCommonJsDependencies": [ + "bignumber.js", + "base-x", + "safe-buffer" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ] + }, + "e2e": { + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.e2e.ts" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "desktopwallet:build", + "proxyConfig": "proxy.config.js", + "aot": false + }, + "configurations": { + "production": { + "browserTarget": "desktopwallet:build:production" + } + } + }, + "serve-e2e": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "desktopwallet:build:e2e", + "proxyConfig": "proxy.config.js" + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "desktopwallet:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "karmaConfig": "./karma.conf.js", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.spec.json", + "scripts": [ + "src/assets/scripts/qrcode.min.js" + ], + "styles": [ + "node_modules/font-awesome/css/font-awesome.css", + "src/assets/fonts/material-icons/material-icons.css", + "src/styles.scss" + ], + "assets": [ + "src/assets", + "src/favicon.ico", + "src/app/current-skycoin.json" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "src/tsconfig.app.json", + "src/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "desktopwallet-e2e": { + "root": "e2e", + "sourceRoot": "e2e", + "projectType": "application", + "architect": { + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "./protractor.conf.js", + "devServerTarget": "desktopwallet:serve-e2e" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "e2e/tsconfig.e2e.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + } + }, + "defaultProject": "desktopwallet", + "schematics": { + "@schematics/angular:component": { + "prefix": "app", + "style": "sass" + }, + "@schematics/angular:directive": { + "prefix": "app" + } + } +} \ No newline at end of file diff --git a/src/gui/static/debug.log b/src/gui/static/debug.log new file mode 100644 index 0000000..fe35c92 --- /dev/null +++ b/src/gui/static/debug.log @@ -0,0 +1,1097 @@ +[0630/200327.795:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/200327.798:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/200327.798:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/200327.798:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/200327.798:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/200327.798:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/200327.798:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/200327.798:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0630/200327.810:ERROR:exception_snapshot_win.cc(88)] thread ID 7064 not found in process +[0630/202029.420:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202029.431:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202029.431:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202029.431:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202029.431:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202029.431:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202029.431:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0630/202029.432:ERROR:exception_snapshot_win.cc(88)] thread ID 11052 not found in process +[0630/202118.810:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202118.822:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202118.822:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202118.822:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202118.822:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202118.822:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202118.822:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202118.822:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0630/202118.823:ERROR:exception_snapshot_win.cc(88)] thread ID 9648 not found in process +[0630/202509.175:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202509.176:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202509.176:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202509.176:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202509.176:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202509.176:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202509.176:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0630/202509.176:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0630/202509.176:ERROR:exception_snapshot_win.cc(88)] thread ID 9404 not found in process +[0810/133835.051:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0810/133835.075:ERROR:exception_snapshot_win.cc(88)] thread ID 9952 not found in process +[0810/133835.089:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0810/133835.089:ERROR:exception_snapshot_win.cc(88)] thread ID 10064 not found in process +[0706/082719.413:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/082719.426:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/082719.426:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/082719.426:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/082719.426:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/082719.426:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/082719.426:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/082719.426:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/082719.426:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0706/082719.431:ERROR:exception_snapshot_win.cc(98)] thread ID 7008 not found in process +[0706/083129.256:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0706/083129.258:ERROR:exception_snapshot_win.cc(98)] thread ID 3640 not found in process +[0706/083402.859:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083402.863:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083402.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083402.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083402.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083402.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083402.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083402.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083402.864:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0706/083402.866:ERROR:exception_snapshot_win.cc(98)] thread ID 10468 not found in process +[0706/083715.013:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/083715.014:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0706/083715.015:ERROR:exception_snapshot_win.cc(98)] thread ID 14112 not found in process +[0706/085438.287:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085438.288:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085438.288:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085438.288:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085438.288:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085438.288:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085438.288:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085438.288:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0706/085438.289:ERROR:exception_snapshot_win.cc(98)] thread ID 10704 not found in process +[0706/085827.843:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085827.844:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085827.844:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085827.844:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085827.844:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085827.844:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085827.844:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085827.844:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/085827.844:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0706/085827.845:ERROR:exception_snapshot_win.cc(98)] thread ID 10120 not found in process +[0706/090102.987:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/090102.989:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/090102.989:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/090102.989:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/090102.989:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/090102.989:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/090102.989:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/090102.989:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0706/090102.989:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0706/090102.994:ERROR:exception_snapshot_win.cc(98)] thread ID 10480 not found in process +[1215/185605.427:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.429:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[1215/185605.430:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[1215/185605.430:ERROR:exception_snapshot_win.cc(98)] thread ID 4624 not found in process +[0108/112729.585:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0108/112729.586:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0108/112729.586:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0108/112729.586:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0108/112729.586:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0108/112729.587:ERROR:exception_snapshot_win.cc(98)] thread ID 13264 not found in process +[0124/082028.696:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.697:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0124/082028.698:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0124/082028.699:ERROR:exception_snapshot_win.cc(98)] thread ID 14904 not found in process +[0129/203735.498:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.501:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.502:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.502:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/203735.502:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/203735.502:ERROR:exception_snapshot_win.cc(98)] thread ID 796 not found in process +[0129/204022.098:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/204022.099:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/204022.099:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/204022.099:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/204022.099:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/204022.099:ERROR:exception_snapshot_win.cc(98)] thread ID 8164 not found in process +[0129/204432.216:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/204432.218:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/204432.218:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/204432.218:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/204432.218:ERROR:exception_snapshot_win.cc(98)] thread ID 2164 not found in process +[0129/205014.313:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205014.316:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205014.316:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205014.316:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205014.316:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/205014.317:ERROR:exception_snapshot_win.cc(98)] thread ID 10568 not found in process +[0129/205311.627:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205311.628:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205311.628:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205311.628:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205311.628:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/205311.629:ERROR:exception_snapshot_win.cc(98)] thread ID 10556 not found in process +[0129/205509.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205509.462:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205509.462:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205509.462:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205509.462:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/205509.462:ERROR:exception_snapshot_win.cc(98)] thread ID 2524 not found in process +[0129/205735.200:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205735.201:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205735.201:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205735.201:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/205735.201:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/205735.202:ERROR:exception_snapshot_win.cc(98)] thread ID 9068 not found in process +[0129/210307.769:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.770:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210307.771:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/210307.771:ERROR:exception_snapshot_win.cc(98)] thread ID 7456 not found in process +[0129/210750.705:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.706:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.706:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.706:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.706:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.706:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.706:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.706:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.706:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/210750.707:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/210750.707:ERROR:exception_snapshot_win.cc(98)] thread ID 6164 not found in process +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/211847.786:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/211847.787:ERROR:exception_snapshot_win.cc(98)] thread ID 4476 not found in process +[0129/212138.475:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212138.476:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/212138.477:ERROR:exception_snapshot_win.cc(98)] thread ID 9264 not found in process +[0129/212638.897:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.898:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/212638.899:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/212638.899:ERROR:exception_snapshot_win.cc(98)] thread ID 3036 not found in process +[0129/214231.895:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.903:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214231.904:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/214231.907:ERROR:exception_snapshot_win.cc(98)] thread ID 12628 not found in process +[0129/214636.455:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214636.456:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214636.456:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214636.456:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/214636.456:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/214636.457:ERROR:exception_snapshot_win.cc(98)] thread ID 10236 not found in process +[0129/215406.402:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.403:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.404:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.404:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.404:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.404:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.404:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.404:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215406.404:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/215406.404:ERROR:exception_snapshot_win.cc(98)] thread ID 11940 not found in process +[0129/215841.641:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.642:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.643:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/215841.643:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/215841.643:ERROR:exception_snapshot_win.cc(98)] thread ID 10956 not found in process +[0129/220152.292:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.293:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.293:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.293:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.293:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/220152.294:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/220152.295:ERROR:exception_snapshot_win.cc(98)] thread ID 11680 not found in process +[0129/221809.099:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/221809.100:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/221809.100:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/221809.100:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/221809.100:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/221809.100:ERROR:exception_snapshot_win.cc(98)] thread ID 5884 not found in process +[0129/222010.316:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/222010.317:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/222010.317:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/222010.317:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/222010.317:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/222010.318:ERROR:exception_snapshot_win.cc(98)] thread ID 13088 not found in process +[0129/222210.925:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/222210.926:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/222210.926:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/222210.926:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0129/222210.926:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0129/222210.927:ERROR:exception_snapshot_win.cc(98)] thread ID 5264 not found in process +[0320/111531.425:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.428:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111531.430:ERROR:exception_snapshot_win.cc(98)] thread ID 5156 not found in process +[0320/111531.438:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.438:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.438:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111531.438:ERROR:exception_snapshot_win.cc(98)] thread ID 5784 not found in process +[0320/111531.459:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.459:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.459:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111531.459:ERROR:exception_snapshot_win.cc(98)] thread ID 1256 not found in process +[0320/111531.475:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111531.475:ERROR:exception_snapshot_win.cc(98)] thread ID 676 not found in process +[0320/111531.500:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.500:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.500:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111531.500:ERROR:exception_snapshot_win.cc(98)] thread ID 11368 not found in process +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.766:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111531.767:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111531.767:ERROR:exception_snapshot_win.cc(98)] thread ID 10180 not found in process +[0320/111805.368:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.369:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.370:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111805.370:ERROR:exception_snapshot_win.cc(98)] thread ID 14040 not found in process +[0320/111805.382:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.383:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111805.383:ERROR:exception_snapshot_win.cc(98)] thread ID 14036 not found in process +[0320/111805.406:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.406:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.406:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111805.406:ERROR:exception_snapshot_win.cc(98)] thread ID 14024 not found in process +[0320/111805.421:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111805.421:ERROR:exception_snapshot_win.cc(98)] thread ID 14032 not found in process +[0320/111805.427:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.427:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.427:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111805.427:ERROR:exception_snapshot_win.cc(98)] thread ID 14028 not found in process +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/111805.830:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/111805.830:ERROR:exception_snapshot_win.cc(98)] thread ID 14020 not found in process +[0320/112315.863:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.864:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.865:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.865:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.865:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.865:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.865:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.865:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112315.865:ERROR:exception_snapshot_win.cc(98)] thread ID 4520 not found in process +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.876:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112315.876:ERROR:exception_snapshot_win.cc(98)] thread ID 3100 not found in process +[0320/112315.894:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.894:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112315.894:ERROR:exception_snapshot_win.cc(98)] thread ID 12104 not found in process +[0320/112315.915:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.915:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.915:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112315.915:ERROR:exception_snapshot_win.cc(98)] thread ID 3148 not found in process +[0320/112315.924:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.924:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112315.924:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112315.924:ERROR:exception_snapshot_win.cc(98)] thread ID 5508 not found in process +[0320/112315.941:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112315.943:ERROR:exception_snapshot_win.cc(98)] thread ID 12408 not found in process +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112316.461:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112316.461:ERROR:exception_snapshot_win.cc(98)] thread ID 13688 not found in process +[0320/112808.910:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.912:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112808.913:ERROR:exception_snapshot_win.cc(98)] thread ID 12904 not found in process +[0320/112808.923:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.923:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.923:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112808.923:ERROR:exception_snapshot_win.cc(98)] thread ID 2028 not found in process +[0320/112808.948:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.948:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.948:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112808.948:ERROR:exception_snapshot_win.cc(98)] thread ID 9896 not found in process +[0320/112808.971:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112808.971:ERROR:exception_snapshot_win.cc(98)] thread ID 11808 not found in process +[0320/112808.988:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.988:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112808.988:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112808.988:ERROR:exception_snapshot_win.cc(98)] thread ID 13980 not found in process +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0320/112809.296:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0320/112809.296:ERROR:exception_snapshot_win.cc(98)] thread ID 8556 not found in process +[0331/130849.945:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.949:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.949:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.949:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.950:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/130849.953:ERROR:exception_snapshot_win.cc(98)] thread ID 5716 not found in process +[0331/130849.962:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.962:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.962:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/130849.963:ERROR:exception_snapshot_win.cc(98)] thread ID 420 not found in process +[0331/130849.982:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.983:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.983:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130849.983:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/130849.983:ERROR:exception_snapshot_win.cc(98)] thread ID 6352 not found in process +[0331/130849.997:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/130849.997:ERROR:exception_snapshot_win.cc(98)] thread ID 13792 not found in process +[0331/130850.003:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.003:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.003:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.003:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/130850.003:ERROR:exception_snapshot_win.cc(98)] thread ID 11412 not found in process +[0331/130850.487:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.487:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/130850.488:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/130850.488:ERROR:exception_snapshot_win.cc(98)] thread ID 9896 not found in process +[0331/131250.664:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.665:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131250.666:ERROR:exception_snapshot_win.cc(98)] thread ID 1560 not found in process +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.678:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131250.678:ERROR:exception_snapshot_win.cc(98)] thread ID 12152 not found in process +[0331/131250.699:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.699:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.699:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.699:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131250.699:ERROR:exception_snapshot_win.cc(98)] thread ID 12100 not found in process +[0331/131250.708:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.708:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131250.708:ERROR:exception_snapshot_win.cc(98)] thread ID 3928 not found in process +[0331/131250.721:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.722:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.722:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131250.722:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131250.722:ERROR:exception_snapshot_win.cc(98)] thread ID 13748 not found in process +[0331/131250.754:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131250.754:ERROR:exception_snapshot_win.cc(98)] thread ID 15012 not found in process +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131251.233:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131251.233:ERROR:exception_snapshot_win.cc(98)] thread ID 6472 not found in process +[0331/131557.738:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.738:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.738:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.738:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.738:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.738:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.739:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131557.739:ERROR:exception_snapshot_win.cc(98)] thread ID 15208 not found in process +[0331/131557.749:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.749:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.750:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131557.750:ERROR:exception_snapshot_win.cc(98)] thread ID 7148 not found in process +[0331/131557.776:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.776:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.776:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.776:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131557.776:ERROR:exception_snapshot_win.cc(98)] thread ID 4948 not found in process +[0331/131557.785:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.785:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131557.785:ERROR:exception_snapshot_win.cc(98)] thread ID 1320 not found in process +[0331/131557.797:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.797:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.797:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131557.797:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131557.797:ERROR:exception_snapshot_win.cc(98)] thread ID 10728 not found in process +[0331/131557.826:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131557.826:ERROR:exception_snapshot_win.cc(98)] thread ID 7332 not found in process +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0331/131558.246:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0331/131558.246:ERROR:exception_snapshot_win.cc(98)] thread ID 12020 not found in process +[0403/183359.654:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.656:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.656:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.656:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.656:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.656:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.656:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.656:ERROR:process_reader_win.cc(123)] NtOpenThread: Se ha especificado un identificador de cliente no válido. (0xc000000b) +[0403/183359.657:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.657:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.657:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.657:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.657:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.657:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.657:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0403/183359.657:ERROR:exception_snapshot_win.cc(98)] thread ID 9200 not found in process +[0403/183359.669:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.670:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.670:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.670:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0403/183359.670:ERROR:exception_snapshot_win.cc(98)] thread ID 1028 not found in process +[0403/183359.689:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.689:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.689:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.689:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0403/183359.689:ERROR:exception_snapshot_win.cc(98)] thread ID 8936 not found in process +[0403/183359.708:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.709:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0403/183359.709:ERROR:exception_snapshot_win.cc(98)] thread ID 13276 not found in process +[0403/183359.726:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0403/183359.727:ERROR:exception_snapshot_win.cc(98)] thread ID 13920 not found in process +[0403/183359.731:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183359.731:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0403/183359.731:ERROR:exception_snapshot_win.cc(98)] thread ID 8356 not found in process +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(151)] SuspendThread: Acceso denegado. (0x5) +[0403/183400.081:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022) +[0403/183400.081:ERROR:exception_snapshot_win.cc(98)] thread ID 1080 not found in process diff --git a/src/gui/static/dist.zip b/src/gui/static/dist.zip new file mode 100644 index 0000000..f8af4c8 Binary files /dev/null and b/src/gui/static/dist.zip differ diff --git a/src/gui/static/dist/0.d5967d50848818a3b5b3.chunk.js b/src/gui/static/dist/0.d5967d50848818a3b5b3.chunk.js new file mode 100644 index 0000000..228c54d --- /dev/null +++ b/src/gui/static/dist/0.d5967d50848818a3b5b3.chunk.js @@ -0,0 +1 @@ +webpackJsonp([0],{dXVM:function(e,t){e.exports={common:{"coin-id":"SKY","coin-hours":"Coin Hours",usd:"USD",loading:"Loading...",new:"New",load:"Load"},errors:{error:"Error","fetch-version":"Unable to fetch latest release version from Github","incorrect-password":"Incorrect password","error-decrypting":"Error decrypting the wallet","api-disabled":"API disabled","no-wallet":"Wallet does not exist","no-outputs":"No unspent outputs","window-size":"The window is too narrow for the content"},title:{language:"Select Language",wallets:"Wallets",send:"Send",history:"History","buy-coin":"Buy Skycoin",network:"Networking",blockchain:"Blockchain",outputs:"Outputs",transactions:"Transactions","pending-txs":"Pending Transactions",backup:"Backup Wallet",explorer:"Skycoin Explorer",seed:"Wallet Seed",qrcode:"QR Code",reset:"Reset Password",exchange:"Exchange","select-address":"Select Address","order-history":"Order history"},header:{"syncing-blocks":"Syncing blocks",update1:"Wallet update",update2:"available.",synchronizing:"The wallet is synchronizing. Data you see may not be updated.","pending-txs1":"There are some","pending-txs2":"pending transactions.","pending-txs3":"Data you see may not be updated.",errors:{"no-connections":"No connections active, your client is not connected to any other nodes!","no-backend1":"Cannot reach backend. Please restart the app and/or seek help on our","no-backend2":"Telegram.","no-backend3":"",csrf:"Security vulnerability: CSRF is not working, please exit immediately."}},password:{title:"Enter Password",label:"Password","confirm-label":"Confirm password",button:"Proceed","reset-link":"I forgot my password"},buy:{"deposit-address":"Choose an address to generate a BTC deposit link for:","select-address":"Select address",generate:"Generate","deposit-location":"Deposit Location","deposit-location-desc":"Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.","make-choice":"Make a choice","wallets-desc":"Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.",send:"Send Bitcoin","send-desc":"Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.","fraction-warning":"Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!",receive:"Receive Sky","receive-desc":"After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.","status-button":"Status:","check-status-button":"Check Status","new-order-button":"New Order"},wizard:{"wallet-desc":'If you don\'t have a Skycoin wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to "Load Wallet" and enter your seed.',"encrypt-desc":"Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.","hardware-wallet-link":"Using a hardware wallet?","finish-button":"Finish","back-button":"Back",confirm:{title:"Safeguard your seed!",desc:"We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your Skycoin wallet!",checkbox:"It\u2019s safe, I swear.",button:"Continue"}},wallet:{"new-address":"New Address","new-addresses":"New Addresses","show-empty":"Show Empty","hide-empty":"Hide Empty",encrypt:"Encrypt Wallet",decrypt:"Decrypt Wallet","decrypt-warning":"Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.",delete:"Delete Wallet",edit:"Edit Wallet",add:"Add Wallet",load:"Load Wallet","encryption-enabled":"Encryption enabled","encryption-disabled":"Encryption disabled","hw-security-warning":'Possible security risk. Access the hardware wallet options (by pressing the "Hardware Wallet" button below the wallets list) while the device is connected for more information.',wallet:"Wallet","hardware-wallet":"Hardware Wallet","delete-confirmation":'WARNING: The wallet "{{ name }}" will be removed from the list. To add it again, you will have to reconnect the device and open the hardware wallet options (by pressing the "Hardware Wallet" button below the wallets list). Do you want to continue?',"delete-confirmation-check":"Yeah, I want to delete the wallet.","max-hardware-wallets-error":"You have already reached the max number of addresses that can be added to the hardware wallet.","add-many-confirmation":"WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?",new:{"create-title":"Create Wallet","load-title":"Load Wallet","encrypt-title":"Encrypt Wallet","name-label":"Name","seed-label":"Seed","confirm-seed-label":"Confirm seed","seed-warning":"Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!","create-button":"Create","load-button":"Load","cancel-button":"Cancel","12-words":"12 words","24-words":"24 words","generate-12-seed":"Generate 12 word seed","generate-24-seed":"Generate 24 word seed",encrypt:"Encrypt wallet","encrypt-warning":"We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.","unconventional-seed-title":"Possible error","unconventional-seed-text":"You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.","unconventional-seed-check":"Continue with the unconventional seed."},rename:{title:"Rename Wallet","name-label":"Name","cancel-button":"Cancel","rename-button":"Rename"},"add-addresses":{title:"Select quantity","name-quantity":"How many addresses to create","cancel-button":"Cancel","create-button":"Create"},address:{show:"Press to show",copy:"Copy","copy-address":"Copy address",copied:"Copied!",confirm:"Confirm address",outputs:"Unspent outputs",history:"History"}},send:{"synchronizing-warning":"The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?","from-label":"Send from","to-label":"Send to","amount-label":"Amount","notes-label":"Notes","wallet-label":"Wallet","addresses-label":"Addresses","invalid-amount":"Please enter a valid amount","addresses-help":"Limit the addresses from where the coins and hours could be sent","all-addresses":"All the addresses of the selected wallet","outputs-label":"Unspent outputs","outputs-help":"Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown","all-outputs":"All the outputs of the selected addresses","available-msg-part1":"With your current selection you can send up to","available-msg-part2":"and","available-msg-part3":"(at least","available-msg-part4":"must be used for the transaction fee).","change-address-label":"Custom change address","change-address-select":"Select","change-address-help":'Address to receive change. If it\'s not provided, it will be chosen automatically. Click on the "Select" link to choose an address from one of your wallets',"destinations-label":"Destinations","destinations-help1":"Destination addresses and their coins","destinations-help2":"Destination addresses, their coins and coin hours","hours-allocation-label":"Automatic coin hours allocation","options-label":"Options","value-label":"Coin hours share factor","value-help":"The higher the value, the more coin hours will be sent to outputs","preview-button":"Preview","send-button":"Send","back-button":"Back",simple:"Simple",advanced:"Advanced","select-wallet":"Select Wallet"},reset:{"wallet-label":"Wallet","seed-label":"Wallet seed","password-label":"New password (leave empty if you want the wallet not to be encrypted)","confirm-label":"Confirm new password","reset-button":"Reset"},tx:{transaction:"Transaction","confirm-transaction":"Confirm Transaction",from:"From",to:"To",date:"Date",status:"Status",coins:"Coins",hours:"Hours",id:"Tx ID","show-more":"Show more","hours-moved":"moved","hours-sent":"sent","hours-received":"received","hours-burned":"burned",inputs:"Inputs",outputs:"Outputs",confirmed:"Confirmed",pending:"Pending","current-rate":"Calculated at the current rate"},backup:{"wallet-directory":"Wallet Directory:","seed-warning":"BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.",desc:"Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.","close-button":"Close",wallet:"Wallet Label",filename:"Filename",seed:"Seed","show-seed":"Show seed","no-wallets":"No encrypted wallets"},blockchain:{blocks:"Number of blocks",time:"Timestamp of last block",hash:"Hash of last block","current-supply":"Current SKY supply","total-supply":"Total SKY supply","current-coinhour-supply":"Current Coin Hours supply","total-coinhour-supply":"Total Coin Hours supply"},network:{peer:"Peer",source:"Source","block-height":"Block height","block-height-short":"Block","last-seen":"Last seen","last-received":"Last received","last-sent":"Last sent",in:"Incoming",out:"Outgoing",sources:{default:"Default peer",exchange:"Peer exchange"}},"pending-txs":{timestamp:"Timestamp",txid:"Transaction ID",none:"No pending transactions",my:"Mine",all:"All"},history:{"tx-detail":"Transaction Detail",moving:"Internally moving",moved:"Internally moved",sending:"Sending",sent:"Sent",received:"Received",receiving:"Receiving",pending:"Pending","no-txs":"You have no transaction history","no-txs-filter":"There are no transactions matching the current filter criteria","no-filter":"No filter active (press to select wallets/addresses)",filter:"Active filter: ",filters:"Active filters: ","all-addresses":"All addresses"},teller:{done:"Completed","waiting-confirm":"Waiting for confirmation","waiting-deposit":"Waiting for Bitcoin deposit","waiting-send":"Waiting to send Skycoin",unknown:"Unknown"},confirmation:{"header-text":"Confirmation","confirm-button":"Yes","cancel-button":"No",close:"Close"},service:{api:{"server-error":"Server error"},wallet:{"not-enough-hours":"Not enough available Coin Hours to perform the transaction!"}},"hardware-wallet":{general:{"default-wallet-name":"New hardware wallet","error-disconnected":"Unable to perform the operation. The hardware wallet is not connected.","simple-error":"Error, Unable to perform the operation.","generic-error":"Unable to perform the operation. Make sure you have connected a valid hardware wallet and that it is not waiting for input.","generic-error-internet":"Unable to perform the operation. Make sure you have connected a valid hardware wallet that is not waiting for input and that you have a connection to the internet/node.","error-incorrect-wallet":"Unable to perform the operation. The connected hardware wallet is different from the expected one.","error-incorrect-pin":"Unable to perform the operation. The PIN you have entered is not correct.",confirm:"Please, confirm the operation in the hardware wallet.","confirm-and-more":"Please, confirm the operation in the hardware wallet and follow the instructions.",close:"Close",cancel:"Cancel",continue:"Continue",completed:"Operation completed successfully.",refused:"The operation failed or was canceled."},errors:{"too-many-inputs":"The transaction has too many inputs and can not be processed. Please contact technical support.","too-many-outputs":"The transaction has too many outputs and can not be processed. Please contact technical support."},"security-warning":{title:"Security warning",text:'The last time this hardware wallet was connected, one or more security warnings were found. We recommend you to open the hardware wallet options (by pressing the "Hardware Wallet" button below the wallets list) while the device is connected and solve the security problems before continuing.',check:"I understand the risks and want to continue",continue:"Continue",cancel:"Cancel"},options:{connecting:"Connecting...",disconnected:"No hardware wallet detected. Please connect a hardware wallet to use this option.","unconfigured-detected-title":"Unconfigured hardware wallet","unconfigured-detected":'A seedless hardware wallet has been detected. Select "Configure automatically" if you want to configure it as a brand new wallet and start using it immediately, or select "Restore backup" if you want to configure it with a previously created seed backup and thus be able to access your funds again.',"configured-detected":"Hardware wallet detected. The device is identified in the wallets list as:","security-warnings-title":"Security warnings","security-warning-title":"Security warning","backup-warning":'You should backup the hardware wallet seed or you could lose access to the funds in case of problems. To do this, select the "Create a backup" option.',"pin-warning":'The connected hardware wallet does not have a PIN. The PIN code protects the hardware wallet in case of loss, theft and hacks. To create a PIN code, select the "Create PIN code" option.',options:"Options:","configure-automatically":"Configure automatically","restore-backup":"Restore backup","create-backup":"Create a backup",wipe:"Wipe the device","confirm-seed":"Confirm seed","create-pin":"Create PIN code","change-pin":"Change PIN code","forgotten-pin1":"If you can not access the wallet because you have forgotten the PIN, you can wipe the hardware wallet and then restore it with the seed by clicking","forgotten-pin2":"here."},"generate-seed":{text:"Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.",configuring:"Configuring..."},"restore-seed":{text:"Before proceeding, please select the number of words that the seed you want to recover has.","check-text":"You can use this option to enter a seed and check if it is equal to the one in the hardware wallet. Before start, select the number of words the seed you want to check has.",warning:"WARNING: to avoid potential problems, use only seeds created with a hardware wallet from the same brand/model.","error-wrong-word":"Error: The retyped word does not match the one requested by the hardware wallet.","error-invalid-seed":"Error: The seed is not valid. Please be sure to enter the correct words in the correct order.","error-wrong-seed":"Error: The seed is valid but does not match the one in the device."},added:{title:"New Hardware Wallet",configuring:"New hardware wallet detected. Configuring...",done:"Done",added1:"The connected hardware wallet has been added to the wallets list with the following name:",added2:"Now you can check the balance and the addresses of the hardware wallet even when it is not connected. Additionally, you can change the name of the wallet or remove it from the wallets list, if you wish."},wipe:{warning:"WARNING: All the data in the hardware wallet will be deleted. If you do not have a backup, you will not be able to access your funds again.","confirm-delete":"Also remove from the wallets list"},"create-backup":{warning:'WARNING: You can only use this option to backup your hardware wallet seed once. If you decide to continue, you will have to write down a group of words (it is recommended to do it on paper and not on a computer) that will appear on the screen of the hardware wallet and store the list in a safe place. Anyone with access to the word list (the "seed") will be able access the wallet balance, so extreme caution is advised.',instructions:"Write down the word list that appear on the screen of the hardware wallet. Make sure you respect the order and write each word correctly."},"seed-word":{title:"Enter word",info1:"Enter the word indicated in the device",info2:"You will be asked to enter the words of your backup seed in random order, plus a few additional words.",word:"Requested word","error-invalid-word":"The entered word is not valid.","error-loading-words":"Loading the word list. Please wait."},"change-pin":{"pin-mismatch":"Unable to perform the operation. Two PINs you have entered do not match."},"enter-pin":{title:"Enter PIN","title-change-current":"Enter the current PIN","title-change-new":"Enter the new PIN","title-change-confirm":"Confirm the new PIN",instructions:"The PIN layout is displayed on the hardware wallet screen.","instructions-tx":"Enter the PIN to confirm and sign the transaction.","instructions-change":"Please enter a hard-to-guess PIN of between 4 and 8 numbers.",help:"Need help?"},"pin-help":{title:"Help",part1:"When it is necessary to enter the PIN to continue, the hardware wallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol #.",part2:'To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the hardware wallet and press the corresponding buttons in the software wallet. For example, if the PIN is "23" and the number 2 is in the upper left, number 3 in the middle of the hardware wallet numbers matrix, press the upper left and middle button in that order in the software wallet.',part3:'If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is "23", you can not simply type "23" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the hardware wallet.'},"create-tx":{title:"Create transaction"},"confirm-address":{title:"Confirm address",instructions:"Please confirm on the hardware wallet if the address is:","short-confirmation":"Address confirmed.",confirmation:'Address confirmed. For security, you can re-show the address in the hardware wallet using the "Confirm address" option, in the menu that you can display by pressing the button at the right of the address balance.'}},"time-from-now":{"few-seconds":"a few seconds ago",minute:"one minute ago",minutes:"{{time}} minutes ago",hour:"one hour ago",hours:"{{time}} hours ago",day:"one day ago",days:"{{time}} days ago"},exchange:{"you-send":"You send","you-get":"You get (approx.)","to-address":"To {{coin}} address",price:"Exchange rate","time-15":"Exchange time","exchange-button":"Exchange","min-amount":"Minimum amount:","max-amount":"Maximum amount:","agree-1":"I agree with","agree-2":"Terms of Use","agree-3":"and","agree-4":"Privacy Policy","powered-by":"Powered by","need-help":"Need help?","support-portal":"Support portal",history:"Order history","order-not-found":"Order not found",status:"Status",exchanging:"Exchanging {{from}} for {{to}}",select:"Select",offline:"Exchange is temporarily offline","problem-connecting":"Unable to connect with the service. Please check your Internet connection and try again later.","invalid-address":"Invalid address.",statuses:{"user-waiting":"Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below","user-waiting-info":"The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.","market-waiting-confirmations":"Waiting for transaction confirmations","market-waiting-confirmations-info":"The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.","market-confirmed":"Transaction accepted","market-confirmed-info":"The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.","market-exchanged":"Traded {{from}} for {{to}}","market-exchanged-info":"The exchange has been made. The funds will be transferred to your address in a moment.","market-withdraw-waiting":"Sending {{to}} to your address","market-withdraw-waiting-info":"The process for sending the coins to your address has been initiated.",complete:"Exchange completed!","complete-info":"The funds have been successfully sent to your address.",error:"Error occurred","error-info":"There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page."},"history-window":{address:"Address",date:"Date"},details:{"exchange-addr":"Exchange address","exchange-addr-tag":"Payment ID or Destination Tag which must be used for the transaction","tx-id":"Transaction ID","order-id":"Order ID","initial-price":"Initial exchange rate","error-msg":"Error message",details:"Details","start-date":"Start date",back:"Back","back-alert":'The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the "Order history" button'}}}}}); \ No newline at end of file diff --git a/src/gui/static/dist/1.bf6ae8acc706c3217da3.chunk.js b/src/gui/static/dist/1.bf6ae8acc706c3217da3.chunk.js new file mode 100644 index 0000000..8d077f5 --- /dev/null +++ b/src/gui/static/dist/1.bf6ae8acc706c3217da3.chunk.js @@ -0,0 +1 @@ +webpackJsonp([1],{ODm5:function(e,t){e.exports={common:{"coin-id":"SKY","coin-hours":"\u5e01\u65f6",usd:"\u7f8e\u5143",loading:"\u52a0\u8f7d\u4e2d...",new:"\u65b0",load:"\u52a0\u8f7d"},errors:{error:"\u9519\u8bef","fetch-version":"\u65e0\u6cd5\u4eceGithub\u83b7\u53d6\u6700\u65b0\u7248\u672c","incorrect-password":"\u5bc6\u7801\u9519\u8bef","error-decrypting":"\u89e3\u5bc6\u94b1\u5305\u65f6\u51fa\u9519","api-disabled":"API\u7981\u7528","no-wallet":"\u65e0\u53ef\u652f\u4ed8\u94b1\u5305","no-outputs":"\u65e0\u672a\u4ea4\u6613\u8f93\u51fa","window-size":"\u7a97\u53e3\u592a\u7a84\uff0c\u5185\u5bb9\u653e\u4e0d\u4e0b"},title:{language:"\u9009\u62e9\u8bed\u8a00",wallets:"\u94b1\u5305",send:"\u53d1\u9001",history:"\u5386\u53f2","buy-coin":"\u4e70 Skycoin",network:"\u7f51\u7edc",blockchain:"\u533a\u5757\u94fe",outputs:"\u672a\u4ea4\u6613\u8f93\u51fa",transactions:"\u4ea4\u6613","pending-txs":"\u5f85\u5904\u7406\u4ea4\u6613",backup:"\u5907\u4efd\u94b1\u5305",explorer:"Skycoin Explorer",seed:"\u94b1\u5305\u79cd\u5b50",qrcode:"QR\u4ee3\u7801",reset:"\u91cd\u7f6e\u5bc6\u7801",exchange:"\u4ea4\u6613","select-address":"\u9009\u62e9\u5730\u5740","order-history":"\u8ba2\u5355\u5386\u53f2"},header:{"syncing-blocks":"\u533a\u5757\u540c\u6b65\u4e2d",update1:"\u94b1\u5305\u66f4\u65b0",update2:"\u53ef\u83b7\u53d6",synchronizing:"\u94b1\u5305\u6b63\u5728\u540c\u6b65\u3002\u4f60\u770b\u5230\u7684\u6570\u636e\u53ef\u80fd\u4e0d\u662f\u6700\u65b0\u7684\u3002","pending-txs1":"\u8fd9\u91cc\u6709\u4e00\u4e9b","pending-txs2":"\u5f85\u5904\u7406\u4ea4\u6613.","pending-txs3":"\u4f60\u770b\u5230\u7684\u6570\u636e\u53ef\u80fd\u4e0d\u662f\u6700\u65b0\u7684\u3002",errors:{"no-connections":"\u6ca1\u6709\u8fde\u63a5\uff0c\u4f60\u7684\u5ba2\u6237\u7aef\u6ca1\u6709\u8fde\u63a5\u5230\u4efb\u4f55\u5176\u4ed6\u8282\u70b9","no-backend1":"\u4e0d\u80fd\u5230\u8fbe\u540e\u7aef\u3002\u8bf7\u91cd\u65b0\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u6216\u5bfb\u6c42\u6211\u4eec\u7684\u5e2e\u52a9","no-backend2":"Telegram","no-backend3":"",csrf:"\u5b89\u5168\u6f0f\u6d1e: CSRF\u672a\u5de5\u4f5c\uff0c\u8bf7\u7acb\u5373\u9000\u51fa\u3002"}},password:{title:"\u8f93\u5165\u5bc6\u7801",label:"\u5bc6\u7801","confirm-label":"\u786e\u8ba4\u5bc6\u7801",button:"\u7ee7\u7eed","reset-link":"\u6211\u5fd8\u8bb0\u4e86\u5bc6\u7801"},buy:{"deposit-address":"\u9009\u62e9\u4e00\u4e2a\u5730\u5740\u6765\u751f\u6210BTC\u5145\u503c\u94fe\u63a5\uff0c\u7528\u4e8e:","select-address":"\u9009\u62e9\u5730\u5740",generate:"\u751f\u6210","deposit-location":"\u5145\u503c\u4f4d\u7f6e","deposit-location-desc":"\u9009\u62e9\u4e00\u4e2a\u94b1\u5305\uff0c\u4ee5\u5728\u6211\u4eec\u6536\u5230\u4f60\u7684\u6bd4\u7279\u5e01\u540e\u5145\u503cSkycoin\u5230\u8be5\u94b1\u5305","make-choice":"\u505a\u9009\u62e9","wallets-desc":"\u6bcf\u5f53\u9009\u62e9\u4e00\u4e2a\u65b0\u7684\u94b1\u5305\u548c\u5730\u5740\uff0c\u4e00\u4e2a\u65b0\u7684BTC\u5730\u5740\u5c06\u4f1a\u751f\u6210\u3002\u4e00\u4e2a\u72ec\u7acb\u7684Skycoin\u5730\u5740\u6700\u591a\u53ef\u7ed1\u5b9a5\u4e2aBTC\u5730\u5740\u3002",send:"\u53d1\u9001Bitcoin","send-desc":"\u53d1\u9001Bitcoin\u81f3\u5982\u4e0b\u5730\u5740\u3002\u4e00\u65e6\u6536\u5230\uff0c\u6211\u4eec\u5c06\u4f1a\u6309\u5f53\u524d\u6c47\u7387: {{ rate }} SKY/BTC\u5145\u503cSkycoin\u5230\u9009\u4e2d\u94b1\u5305\u7684\u4e00\u4e2a\u65b0\u5730\u5740\u3002","fraction-warning":"\u8bf7\u6309SKY/BTC\u6c47\u7387\u7684\u500d\u6570\u53d1\u9001BTC! Skycoin\u662f\u4ee5\u6574\u6570\u53d1\u9001; SKY\u7684\u5c0f\u6570\u4f4d\u5c06\u4e0d\u4f1a\u53d1\u9001",receive:"\u63a5\u6536Sky","receive-desc":"\u6536\u5230\u4f60\u7684\u6bd4\u7279\u5e01\u540e\uff0c\u6211\u4eec\u5c06\u53d1\u9001Skycoin\u7ed9\u4f60\u3002\u4f60\u53ef\u80fd\u9700\u898120\u5206\u949f\u5230\u4e00\u4e2a\u5c0f\u65f6\u624d\u80fd\u6536\u5230\u8fd9\u4e9bSKY\u3002","status-button":"\u72b6\u6001:","check-status-button":"\u67e5\u770b\u72b6\u6001","new-order-button":"\u65b0\u8ba2\u5355"},wizard:{"wallet-desc":'\u5982\u679c\u4f60\u6ca1\u6709Skycoin\u94b1\u5305\uff0c\u8bf7\u4f7f\u7528\u751f\u6210\u7684\u79cd\u5b50\u6765\u521b\u5efa\u4e00\u4e2a\u65b0\u94b1\u5305\u3002\u5982\u679c\u4f60\u5df2\u7ecf\u6709\u4e00\u4e2a\u94b1\u5305\uff0c\u5207\u6362\u5230"\u52a0\u8f7d\u94b1\u5305"\u5e76\u8f93\u5165\u4f60\u7684\u79cd\u5b50\u3002',"encrypt-desc":"\u901a\u8fc7\u52a0\u5bc6\u6765\u589e\u52a0\u94b1\u5305\u7684\u5b89\u5168\u6027\u3002\u8f93\u5165\u5bc6\u7801\u540e\uff0c\u4f60\u7684\u94b1\u5305\u4f1a\u88ab\u52a0\u5bc6\u3002\u53ea\u6709\u8f93\u5165\u5bc6\u7801\u624d\u53ef\u4ee5\u8bbf\u95ee\u7684\u94b1\u5305\u6216\u79fb\u52a8\u8d44\u91d1\u3002","hardware-wallet-link":"\u4f7f\u7528\u786c\u4ef6\u94b1\u5305\uff1f","finish-button":"\u5b8c\u6210","back-button":"\u540e\u9000",confirm:{title:"\u4fdd\u62a4\u4f60\u7684\u79cd\u5b50!",desc:"\u8bf7\u786e\u4fdd\u4f60\u5df2\u7ecf\u5199\u4e0b\u4f60\u7684\u79cd\u5b50\u5e76\u5c06\u5b83\u50a8\u5b58\u5728\u4e86\u4e00\u4e2a\u5b89\u5168\u7684\u5730\u65b9\u3002\u5982\u679c\u4f60\u5fd8\u8bb0\u4e86\u79cd\u5b50\uff0c\u4f60\u5c06\u65e0\u6cd5\u6062\u590d\u4f60\u7684Skycoin\u94b1\u5305",checkbox:"\u5b83\u5f88\u5b89\u5168\uff0c\u6211\u53d1\u8a93\u3002",button:"\u7ee7\u7eed"}},wallet:{"new-address":"\u65b0\u5730\u5740","new-addresses":"\u65b0\u5730\u5740","show-empty":"\u5c55\u793a\u7a7a\u5730\u5740","hide-empty":"\u9690\u85cf\u7a7a\u5730\u5740",encrypt:"\u52a0\u5bc6\u94b1\u5305",decrypt:"\u89e3\u5bc6\u94b1\u5305","decrypt-warning":"\u8b66\u544a: \u51fa\u4e8e\u5b89\u5168\u8003\u8651\uff0c\u5efa\u8bae\u5c06\u94b1\u5305\u52a0\u5bc6\u3002\u5efa\u8bae\u8c28\u614e\u4e00\u70b9\u3002",delete:"\u5220\u9664\u94b1\u5305",edit:"\u7f16\u8f91\u94b1\u5305",add:"\u6dfb\u52a0\u94b1\u5305",load:"\u52a0\u8f7d\u94b1\u5305","encryption-enabled":"\u52a0\u5bc6\u5df2\u542f\u7528","encryption-disabled":"\u52a0\u5bc6\u5df2\u7981\u7528","hw-security-warning":'\u53ef\u80fd\u7684\u5b89\u5168\u98ce\u9669\u3002\u5f53\u786c\u4ef6\u8bbe\u5907\u5df2\u8fde\u63a5\u65f6(\u70b9\u51fb\u94b1\u5305\u5217\u8868\u4e0b\u7684"\u786c\u4ef6\u94b1\u5305"\u6309\u94ae)\u8bbf\u95ee\u786c\u4ef6\u94b1\u5305\u9009\u9879\u4ee5\u83b7\u53d6\u66f4\u591a\u4fe1\u606f',wallet:"\u94b1\u5305","hardware-wallet":"\u786c\u4ef6\u94b1\u5305","delete-confirmation":'\u8b66\u544a: \u94b1\u5305"{{ name }}"\u5c06\u4ece\u5217\u8868\u4e2d\u5220\u9664\u3002\u82e5\u60f3\u91cd\u65b0\u6dfb\u52a0\uff0c\u9700\u91cd\u65b0\u8fde\u63a5\u8bbe\u5907\u5e76\u6253\u5f00\u786c\u4ef6\u94b1\u5305\u7684\u9009\u9879\u5217\u8868(\u70b9\u51fb\u94b1\u5305\u5217\u8868\u4e0b\u7684"\u786c\u4ef6\u94b1\u5305"\u6309\u94ae)\u3002\u4f60\u60f3\u7ee7\u7eed\u5417\uff1f',"delete-confirmation-check":"\u662f\u7684\uff0c\u6211\u60f3\u8981\u5220\u9664\u94b1\u5305\u3002","max-hardware-wallets-error":"\u4f60\u7684\u786c\u4ef6\u94b1\u5305\u91cc\u7684\u5730\u5740\u5df2\u7ecf\u8fbe\u5230\u5141\u8bb8\u7684\u6700\u5927\u503c\u3002","add-many-confirmation":"\u8b66\u544a: \u5982\u679c\u4f60\u5728\u4e0d\u4f7f\u7528\u524d\u4e00\u4e2a\u5730\u5740\u7684\u60c5\u51b5\u4e0b\u6dfb\u52a0\u592a\u591a\u5730\u5740\uff0c\u6216\u8005\u5982\u679c\u4f60\u4f7f\u7528\u7684\u662f\u6700\u540e\u4e00\u4e2a\u5730\u5740\u800c\u4e0d\u662f\u7b2c\u4e00\u4e2a\u5730\u5740\uff0c\u90a3\u4e48\u5982\u679c\u4f60\u5c1d\u8bd5\u4f7f\u7528\u79cd\u5b50\u6062\u590d\u94b1\u5305\uff0c\u6709\u4e9b\u5730\u5740\u5c06\u53ef\u80fd\u65e0\u6cd5\u81ea\u52a8\u6062\u590d\uff08\u4f60\u5fc5\u987b\u624b\u52a8\u6dfb\u52a0\u5b83\u4eec\uff09\u3002 \u4f60\u60f3\u7ee7\u7eed\u5417\uff1f",new:{"create-title":"\u521b\u5efa\u94b1\u5305","load-title":"\u52a0\u8f7d\u94b1\u5305","encrypt-title":"\u52a0\u5bc6\u94b1\u5305","name-label":"\u540d\u79f0","seed-label":"\u79cd\u5b50","confirm-seed-label":"\u786e\u8ba4\u79cd\u5b50","seed-warning":"\u8bb0\u4f4f\u79cd\u5b50! \u628a\u5b83\u4fdd\u5b58\u5728\u5b89\u5168\u7684\u5730\u65b9\u3002 \u5982\u679c\u4f60\u5fd8\u8bb0\u4e86\u4f60\u7684\u79cd\u5b50\uff0c\u4f60\u5c06\u65e0\u6cd5\u627e\u56de\u4f60\u7684\u94b1\u5305!","create-button":"\u521b\u5efa","load-button":"\u52a0\u8f7d","cancel-button":"\u5220\u9664","12-words":"12\u5b57","24-words":"24\u5b57","generate-12-seed":"\u751f\u621012\u5b57\u79cd\u5b50","generate-24-seed":"\u751f\u621024\u5b57\u79cd\u5b50",encrypt:"\u52a0\u5bc6\u94b1\u5305","encrypt-warning":"\u6211\u4eec\u5efa\u8bae\u4f60\u4e3a\u6bcf\u4e2a\u94b1\u5305\u8bbe\u7f6e\u4e00\u4e2a\u72ec\u7acb\u7684\u5bc6\u7801\u3002\u5982\u679c\u4f60\u5fd8\u8bb0\u5bc6\u7801\uff0c\u4f60\u53ef\u4ee5\u901a\u8fc7\u79cd\u5b50\u91cd\u7f6e\u94b1\u5305\u3002\u5728\u52a0\u5bc6\u4f60\u7684\u94b1\u5305\u4e4b\u524d\uff0c\u786e\u4fdd\u4f60\u7684\u79cd\u5b50\u4fdd\u5b58\u5728\u5b89\u5168\u7684\u5730\u65b9\u3002","unconventional-seed-title":"\u53ef\u80fd\u9519\u8bef","unconventional-seed-text":"\u4f60\u5f15\u8fdb\u4e86\u4e00\u79cd\u975e\u4f20\u7edf\u7684\u79cd\u5b50\u3002\u5982\u679c\u4f60\u51fa\u4e8e\u4efb\u4f55\u7279\u6b8a\u539f\u56e0\u8fd9\u6837\u505a\uff0c\u4f60\u53ef\u4ee5\u7ee7\u7eed(\u53ea\u63a8\u8350\u9ad8\u7ea7\u7528\u6237)\u3002\u4f46\u662f\uff0c\u5982\u679c\u4f60\u6253\u7b97\u4f7f\u7528\u666e\u901a\u7684\u7cfb\u7edf\u79cd\u5b50\uff0c\u5219\u5fc5\u987b\u5220\u9664\u6240\u6709\u9644\u52a0\u6587\u672c\u548c\u7279\u6b8a\u5b57\u7b26\u3002","unconventional-seed-check":"\u7ee7\u7eed\u4f7f\u7528\u975e\u4f20\u7edf\u79cd\u5b50\u3002"},rename:{title:"\u91cd\u547d\u540d\u94b1\u5305","name-label":"\u547d\u540d","cancel-button":"\u53d6\u6d88","rename-button":"\u91cd\u547d\u540d"},"add-addresses":{title:"\u9009\u62e9\u6570\u91cf","name-quantity":"\u521b\u5efa\u591a\u5c11\u5730\u5740","cancel-button":"\u53d6\u6d88","create-button":"\u521b\u5efa"},address:{show:"\u70b9\u51fb\u663e\u793a",copy:"\u590d\u5236","copy-address":"\u590d\u5236\u5730\u5740",copied:"\u5df2\u590d\u5236!",confirm:"\u786e\u8ba4\u5730\u5740",outputs:"\u672a\u4ea4\u6613\u8f93\u51fa",history:"\u5386\u53f2"}},send:{"synchronizing-warning":"\u94b1\u5305\u4ecd\u5728\u540c\u6b65\u6570\u636e\uff0c\u6240\u4ee5\u663e\u793a\u7684\u4f59\u989d\u53ef\u80fd\u4e0d\u6b63\u786e\u3002\u4f60\u786e\u5b9a\u8981\u7ee7\u7eed\u5417\uff1f","from-label":"\u53d1\u9001\u81ea","to-label":"\u53d1\u9001\u81f3","amount-label":"\u603b\u989d","notes-label":"\u6807\u6ce8","wallet-label":"\u94b1\u5305","addresses-label":"\u5730\u5740","invalid-amount":"\u8bf7\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u6570\u503c","addresses-help":"\u9650\u5b9a\u6e90\u53d1\u9001\u5730\u5740","all-addresses":"\u6240\u6709\u5730\u5740(\u6240\u9009\u94b1\u5305\u7684)","outputs-label":"\u672a\u4ea4\u6613\u8f93\u51fa","outputs-help":"\u9650\u5b9a\u672a\u4ea4\u6613\u8f93\u51fa","all-outputs":"\u6240\u6709\u672a\u4ea4\u6613\u8f93\u51fa(\u6240\u9009\u5730\u5740\u7684)","available-msg-part1":"\u6839\u636e\u4f60\u5f53\u524d\u7684\u9009\u62e9\uff0c\u4f60\u6700\u591a\u53ef\u4ee5\u53d1\u9001","available-msg-part2":"\u548c","available-msg-part3":"(\u81f3\u5c11","available-msg-part4":"\u5c06\u4f5c\u4e3a\u5fc5\u987b\u7684\u4ea4\u6613\u624b\u7eed\u8d39)\u3002","change-address-label":"\u81ea\u5b9a\u4e49\u627e\u96f6\u5730\u5740","change-address-select":"\u9009\u62e9","change-address-help":'\u81ea\u5b9a\u4e49\u627e\u96f6\u5730\u5740\u3002\u5982\u679c\u4e0d\u63d0\u4f9b\uff0c\u94b1\u5305\u5c06\u4f1a\u81ea\u52a8\u9009\u62e9\u3002\u70b9\u51fb"\u9009\u62e9" \u6765\u9009\u62e9\u4e00\u4e2a\u5730\u5740',"destinations-label":"\u76ee\u6807\u5730\u5740","destinations-help1":"\u76ee\u6807\u5730\u5740\u548c\u5373\u5c06\u53d1\u9001\u7684\u5e01","destinations-help2":"\u76ee\u6807\u5730\u5740\u548c\u5373\u5c06\u53d1\u9001\u7684\u5e01\u4ee5\u53ca\u5e01\u65f6","hours-allocation-label":"\u81ea\u52a8\u5206\u914d\u5e01\u65f6","options-label":"\u9009\u9879","value-label":"\u5e01\u65f6\u5206\u53d1\u56e0\u5b50","value-help":"\u5206\u53d1\u56e0\u5b50\u503c\u8d8a\u9ad8\uff0c\u8d8a\u591a\u5e01\u65f6\u5c06\u88ab\u53d1\u9001","preview-button":"\u9884\u89c8","send-button":"\u53d1\u9001","back-button":"\u540e\u9000",simple:"\u7b80\u6613",advanced:"\u9ad8\u7ea7\u7684","select-wallet":"\u9009\u62e9\u94b1\u5305"},reset:{"wallet-label":"\u94b1\u5305","seed-label":"\u94b1\u5305\u79cd\u5b50","password-label":"\u65b0\u5bc6\u7801 (\u5982\u679c\u4f60\u4e0d\u5e0c\u671b\u94b1\u5305\u52a0\u5bc6\uff0c\u8bf7\u5c06\u5bc6\u7801\u7559\u7a7a)","confirm-label":"\u786e\u8ba4\u65b0\u5bc6\u7801","reset-button":"\u91cd\u7f6e"},tx:{transaction:"\u4ea4\u6613","confirm-transaction":"\u786e\u8ba4\u4ea4\u6613",from:"\u6765\u81ea",to:"\u5230",date:"\u65e5\u671f",status:"\u72b6\u6001",coins:"\u5e01",hours:"\u5e01\u65f6",id:"\u4ea4\u6613ID","show-more":"\u5c55\u793a\u66f4\u591a","hours-moved":"\u5df2\u8f6c\u79fb","hours-sent":"\u5df2\u53d1\u9001","hours-received":"\u5df2\u63a5\u6536","hours-burned":"\u5df2\u71c3\u70e7",inputs:"\u8f93\u5165",outputs:"\u8f93\u51fa",confirmed:"\u5df2\u786e\u8ba4",pending:"\u5f85\u5904\u7406","current-rate":"\u6309\u5f53\u524d\u6c47\u7387\u8ba1\u7b97"},backup:{"wallet-directory":"\u94b1\u5305\u76ee\u5f55:","seed-warning":"\u5728\u7eb8\u4e0a\u5907\u4efd\u4f60\u7684\u79cd\u5b50\uff0c\u5e76\u4fdd\u5b58\u5728\u4e00\u4e2a\u5b89\u5168\u7684\u5730\u65b9\u3002\u53ea\u8981\u6709\u79cd\u5b50\uff0c\u4f60\u5c31\u53ef\u4ee5\u627e\u56de\u4f60\u7684\u5e01\u3002",desc:"\u4f7f\u7528\u4e0b\u8868\u4ece\u52a0\u5bc6\u7684\u94b1\u5305\u4e2d\u5f97\u5230\u79cd\u5b50\u3002
\u4e3a\u4e86\u4ece\u672a\u52a0\u5bc6\u7684\u94b1\u5305\u4e2d\u83b7\u5f97\u79cd\u5b50\uff0c\u6253\u5f00\u4e0a\u9762\u7684\u6587\u4ef6\u5939,\u5728\u6587\u672c\u7f16\u8f91\u5668\u4e2d\u6253\u5f00.wlt\u6587\u4ef6\u5e76\u6062\u590d\u79cd\u5b50\u3002","close-button":"Close",wallet:"\u94b1\u5305",filename:"\u6587\u4ef6\u540d",seed:"\u79cd\u5b50","show-seed":"\u663e\u793a\u79cd\u5b50","no-wallets":"\u672a\u52a0\u5bc6\u94b1\u5305"},blockchain:{blocks:"\u533a\u5757\u6570\u91cf",time:"\u4e0a\u4e00\u4e2a\u533a\u5757\u7684\u65f6\u95f4\u6233",hash:"\u4e0a\u4e00\u4e2a\u533a\u5757\u7684\u54c8\u5e0c\u503c","current-supply":"\u76ee\u524dSKY\u4f9b\u5e94\u91cf","total-supply":"SKY\u7684\u603b\u4f9b\u5e94\u91cf","current-coinhour-supply":"\u76ee\u524d\u5e01\u65f6\u4f9b\u5e94\u91cf","total-coinhour-supply":"\u5e01\u65f6\u603b\u4f9b\u5e94\u91cf"},network:{peer:"\u8282\u70b9",source:"\u8282\u70b9\u6765\u6e90","block-height":"\u533a\u5757\u9ad8\u5ea6","block-height-short":"\u533a\u5757","last-seen":"\u4e0a\u4e00\u6b21\u51fa\u73b0","last-received":"\u4e0a\u4e00\u6b21\u63a5\u6536","last-sent":"\u4e0a\u4e00\u6b21\u53d1\u9001",in:"\u8fdb\u6765\u7684",out:"\u51fa\u53bb\u7684",sources:{default:"\u9ed8\u8ba4\u8282\u70b9",exchange:"\u4ea4\u6362\u8282\u70b9"}},"pending-txs":{timestamp:"\u65f6\u95f4\u6233",txid:"\u4ea4\u6613ID",none:"\u65e0\u5f85\u5904\u7406\u4ea4\u6613",my:"\u6211\u7684",all:"\u5168\u90e8"},history:{"tx-detail":"\u4ea4\u6613\u660e\u7ec6",moving:"\u5185\u90e8\u8f6c\u8d26\u4e2d",moved:"\u5df2\u5185\u90e8\u8f6c\u8d26",sending:"\u53d1\u9001\u4e2d",sent:"\u5df2\u53d1\u9001",received:"\u5df2\u63a5\u6536",receiving:"\u63a5\u6536\u4e2d",pending:"\u5f85\u5904\u7406","no-txs":"\u4f60\u6ca1\u6709\u5386\u53f2\u4ea4\u6613","no-txs-filter":"\u6ca1\u6709\u4e0e\u5f53\u524d\u7b5b\u9009\u6761\u4ef6\u5339\u914d\u7684\u4ea4\u6613","no-filter":"\u672a\u7ecf\u7b5b\u9009 (\u70b9\u51fb\u9009\u62e9\u94b1\u5305/\u5730\u5740)",filter:"\u5df2\u7b5b\u9009: ",filters:"\u5df2\u7b5b\u9009: ","all-addresses":"\u6240\u6709\u5730\u5740"},teller:{done:"\u5b8c\u6210","waiting-confirm":"\u7b49\u5f85\u786e\u8ba4","waiting-deposit":"\u7b49\u5f85\u6bd4\u7279\u5e01\u5145\u503c","waiting-send":"\u7b49\u5f85\u53d1\u9001Skycoin",unknown:"\u672a\u77e5"},confirmation:{"header-text":"\u786e\u8ba4","confirm-button":"\u662f","cancel-button":"\u5426",close:"\u5173\u95ed"},service:{api:{"server-error":"\u670d\u52a1\u5668\u9519\u8bef"},wallet:{"not-enough-hours":"\u6ca1\u6709\u8db3\u591f\u7684\u5e01\u65f6\u6765\u6267\u884c\u4ea4\u6613"}},"hardware-wallet":{general:{"default-wallet-name":"\u65b0\u786c\u4ef6\u94b1\u5305","error-disconnected":"\u65e0\u6cd5\u6267\u884c\u8be5\u64cd\u4f5c\u3002\u786c\u4ef6\u94b1\u5305\u672a\u8fde\u63a5\u3002","simple-error":"\u9519\u8bef\uff0c\u65e0\u6cd5\u6267\u884c\u64cd\u4f5c\u3002","generic-error":"\u65e0\u6cd5\u6267\u884c\u8be5\u64cd\u4f5c\u3002\u786e\u4fdd\u4f60\u5df2\u7ecf\u8fde\u63a5\u4e86\u4e00\u4e2a\u6709\u6548\u7684\u786c\u4ef6\u94b1\u5305\uff0c\u5e76\u4e14\u5b83\u6ca1\u6709\u5728\u7b49\u5f85\u8f93\u5165\u3002","generic-error-internet":"\u65e0\u6cd5\u6267\u884c\u8be5\u64cd\u4f5c\u3002\u786e\u4fdd\u4f60\u5df2\u7ecf\u8fde\u63a5\u4e86\u4e00\u4e2a\u6709\u6548\u7684\u786c\u4ef6\u94b1\u5305\uff0c\u5b83\u4e0d\u5728\u7b49\u5f85\u8f93\u5165\uff0c\u5e76\u4e14\u4f60\u5df2\u7ecf\u8fde\u63a5\u5230\u7f51\u7edc/\u8282\u70b9","error-incorrect-wallet":"\u65e0\u6cd5\u6267\u884c\u8be5\u64cd\u4f5c\u3002\u6240\u8fde\u63a5\u7684\u786c\u4ef6\u94b1\u5305\u4e0e\u9884\u671f\u4e0d\u540c\u3002","error-incorrect-pin":"\u65e0\u6cd5\u6267\u884c\u8be5\u64cd\u4f5c\u3002\u4f60\u8f93\u5165\u7684\u5bc6\u7801\u4e0d\u6b63\u786e\u3002",confirm:"\u8bf7\u5728\u786c\u4ef6\u94b1\u5305\u4e2d\u786e\u8ba4\u64cd\u4f5c\u3002","confirm-and-more":"\u8bf7\u5728\u786c\u4ef6\u94b1\u5305\u4e2d\u786e\u8ba4\u64cd\u4f5c\u5e76\u6309\u9075\u5faa\u6307\u793a\u3002",close:"\u5173\u95ed",cancel:"\u53d6\u6d88",continue:"\u7ee7\u7eed",completed:"\u64cd\u4f5c\u5b8c\u6210\u3002",refused:"\u64cd\u4f5c\u5931\u8d25\u6216\u88ab\u53d6\u6d88\u3002"},errors:{"too-many-inputs":"\u6b64\u7b14\u4ea4\u6613\u6709\u592a\u591a\u7684\u8f93\u5165\uff0c\u65e0\u6cd5\u5904\u7406\u3002\u8bf7\u8054\u7cfb\u6280\u672f\u652f\u6301\u3002","too-many-outputs":"\u6b64\u7b14\u4ea4\u6613\u6709\u592a\u591a\u7684\u8f93\u51fa\uff0c\u65e0\u6cd5\u5904\u7406\uff0c\u8bf7\u8054\u7cfb\u6280\u672f\u652f\u6301\u3002"},"security-warning":{title:"\u5b89\u5168\u8b66\u544a",text:'\u4e0a\u6b21\u8fde\u63a5\u6b64\u786c\u4ef6\u94b1\u5305\u65f6\uff0c\u53d1\u73b0\u4e00\u4e2a\u6216\u591a\u4e2a\u5b89\u5168\u8b66\u544a\u3002\u6211\u4eec\u5efa\u8bae\u4f60\u6253\u5f00\u786c\u4ef6\u94b1\u5305\u9009\u9879(\u70b9\u51fb\u94b1\u5305\u5217\u8868\u4e0b\u7684"\u786c\u4ef6\u94b1\u5305"\u6309\u94ae)\u5e76\u4fdd\u6301\u8bbe\u5907\u5df2\u8fde\u63a5\uff0c\u5728\u7ee7\u7eed\u4e4b\u524d\uff0c\u89e3\u51b3\u5b89\u5168\u95ee\u9898',check:"\u6211\u660e\u767d\u5176\u4e2d\u7684\u98ce\u9669\uff0c\u5e76\u5e0c\u671b\u7ee7\u7eed\u4e0b\u53bb",continue:"\u7ee7\u7eed",cancel:"\u53d6\u6d88"},options:{connecting:"\u8fde\u63a5...",disconnected:"\u6ca1\u6709\u68c0\u6d4b\u5230\u786c\u4ef6\u94b1\u5305\u3002\u8bf7\u8fde\u63a5\u786c\u4ef6\u94b1\u5305\u540e\u4f7f\u7528\u6b64\u9009\u9879\u3002","unconfigured-detected-title":"\u672a\u914d\u7f6e\u7684\u786c\u4ef6\u94b1\u5305","unconfigured-detected":'\u68c0\u6d4b\u5230\u65e0\u79cd\u5b50\u7684\u786c\u4ef6\u94b1\u5305\u3002\u9009\u62e9"\u81ea\u52a8\u914d\u7f6e"\u5982\u679c\u4f60\u60f3\u5c06\u5176\u914d\u7f6e\u4e3a\u5168\u65b0\u7684\u94b1\u5305\u5e76\u7acb\u5373\u5f00\u59cb\u4f7f\u7528\u5b83\uff0c\u6216\u9009\u62e9"\u6062\u590d\u5907\u4efd"\u5982\u679c\u4f60\u60f3\u4f7f\u7528\u5148\u524d\u521b\u5efa\u7684\u5907\u4efd\u79cd\u5b50\u5bf9\u5176\u8fdb\u884c\u914d\u7f6e\uff0c\u4ece\u800c\u80fd\u591f\u518d\u6b21\u8bbf\u95ee\u4f60\u7684\u8d44\u4ea7\u3002',"configured-detected":"\u68c0\u6d4b\u5230\u786c\u4ef6\u94b1\u5305\u3002\u8be5\u8bbe\u5907\u5728\u94b1\u5305\u5217\u8868\u4e2d\u88ab\u8bc6\u522b\u4e3a:","security-warnings-title":"\u5b89\u5168\u8b66\u544a","security-warning-title":"\u5b89\u5168\u8b66\u544a","backup-warning":'\u4f60\u5e94\u8be5\u5907\u4efd\u786c\u4ef6\u94b1\u5305\u79cd\u5b50\uff0c\u5426\u5219\u4e07\u4e00\u51fa\u73b0\u95ee\u9898\uff0c\u4f60\u53ef\u80fd\u5c06\u65e0\u6cd5\u8bbf\u95ee\u4f60\u7684\u8d44\u91d1\uff0c\u8981\u505a\u5230\u8fd9\u4e00\u70b9\u3002\u9009\u62e9"\u521b\u5efa\u4e00\u4e2a\u5907\u4efd"\u9009\u9879\u3002',"pin-warning":'\u5f53\u524d\u8fde\u63a5\u7684\u786c\u4ef6\u94b1\u5305\u672a\u8bbe\u7f6e\u5bc6\u7801\u3002\u5bc6\u7801\u53ef\u4fdd\u62a4\u786c\u4ef6\u94b1\u5305\uff0c\u4ee5\u9632\u4e22\u5931\u3001\u76d7\u7a83\u548c\u9ed1\u5ba2\u5165\u4fb5\u3002\u8981\u521b\u5efa\u4e00\u4e2a\u5bc6\u7801\uff0c\u9009\u62e9"\u521b\u5efaPIN\u7801"\u9009\u9879\u3002',options:"\u9009\u9879:","configure-automatically":"\u81ea\u52a8\u914d\u7f6e","restore-backup":"\u6062\u590d\u5907\u4efd","create-backup":"\u521b\u5efa\u5907\u4efd",wipe:"\u5220\u9664\u8bbe\u5907","confirm-seed":"\u786e\u8ba4\u79cd\u5b50","create-pin":"\u521b\u5efa\u5bc6\u7801","change-pin":"\u66f4\u6539\u5bc6\u7801","forgotten-pin1":"\u5982\u679c\u4f60\u56e0\u4e3a\u5fd8\u8bb0\u5bc6\u7801\u800c\u65e0\u6cd5\u8fdb\u5165\u94b1\u5305\uff0c\u4f60\u53ef\u4ee5\u5220\u9664\u786c\u4ef6\u94b1\u5305\uff0c\u7136\u540e\u901a\u8fc7\u79cd\u5b50","forgotten-pin2":"\u6062\u590d"},"generate-seed":{text:"\u5728\u7ee7\u7eed\u4e4b\u524d\uff0c\u4f60\u53ef\u4ee5\u9009\u62e9\u751f\u6210\u79cd\u5b50\u7684\u5355\u8bcd\u6570\u3002\u79cd\u5b50\u662f\u4e00\u4e2a\u5355\u8bcd\u5217\u8868\uff0c\u51fa\u73b0\u95ee\u9898\u540e\u53ef\u4ee5\u7528\u6765\u6062\u590d\u8bbf\u95ee\u4f60\u7684\u5e01\u3002\u6240\u6709\u9009\u9879\u90fd\u662f\u5b89\u5168\u7684\uff0c\u5982\u679c\u4f60\u6ca1\u6709\u7279\u6b8a\u539f\u56e0\u5fc5\u987b\u9009\u62e9\u67d0\u4e00\u9879\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528\u9ed8\u8ba4\u503c\u3002",configuring:"\u914d\u7f6e..."},"restore-seed":{text:"\u5728\u7ee7\u7eed\u524d\uff0c\u8bf7\u9009\u62e9\u4f60\u60f3\u8981\u6062\u590d\u79cd\u5b50\u7684\u5355\u8bcd\u6570\u91cf\u3002","check-text":"\u4f60\u53ef\u4ee5\u4f7f\u7528\u6b64\u9009\u9879\u8f93\u5165\u79cd\u5b50\uff0c\u5e76\u68c0\u67e5\u5b83\u662f\u5426\u4e0e\u786c\u4ef6\u94b1\u5305\u4e2d\u7684\u4e00\u81f4\u3002\u5728\u5f00\u59cb\u4e4b\u524d\uff0c\u9009\u62e9\u4f60\u60f3\u8981\u68c0\u67e5\u7684\u79cd\u5b50\u7684\u5355\u8bcd\u6570\u3002",warning:"\u8b66\u544a: \u4e3a\u4e86\u907f\u514d\u53ef\u80fd\u51fa\u73b0\u7684\u95ee\u9898\uff0c\u8bf7\u4ec5\u4f7f\u7528\u540c\u4e00\u54c1\u724c/\u578b\u53f7\u7684\u786c\u4ef6\u94b1\u5305\u521b\u5efa\u79cd\u5b50\u3002","error-wrong-word":"\u9519\u8bef: \u91cd\u65b0\u952e\u5165\u7684\u5355\u8bcd\u4e0e\u786c\u4ef6\u94b1\u5305\u6240\u8bf7\u6c42\u7684\u4e0d\u5339\u914d\u3002","error-invalid-seed":"\u9519\u8bef: \u79cd\u5b50\u65e0\u6548\u3002\u8bf7\u52a1\u5fc5\u6309\u6b63\u786e\u7684\u987a\u5e8f\u8f93\u5165\u6b63\u786e\u7684\u5355\u8bcd\u3002","error-wrong-seed":"\u9519\u8bef: \u79cd\u5b50\u662f\u6709\u6548\u7684\uff0c\u4f46\u4e0e\u8bbe\u5907\u4e2d\u7684\u79cd\u5b50\u4e0d\u5339\u914d\u3002"},added:{title:"\u65b0\u786c\u4ef6\u94b1\u5305",configuring:"\u68c0\u6d4b\u5230\u65b0\u7684\u786c\u4ef6\u94b1\u5305\u3002\u914d\u7f6e...",done:"\u5df2\u5b8c\u6210",added1:"\u5df2\u8fde\u63a5\u7684\u786c\u4ef6\u7684\u94b1\u5305\u5df2\u7ecf\u7528\u5982\u4e0b\u540d\u5b57\u88ab\u6dfb\u52a0\u5230\u94b1\u5305\u5217\u8868:",added2:"\u73b0\u5728\u4f60\u53ef\u4ee5\u67e5\u770b\u786c\u4ef6\u94b1\u5305\u4e2d\u7684\u4f59\u989d\u548c\u5730\u5740\u4e86\uff0c\u5373\u4f7f\u786c\u4ef6\u94b1\u5305\u5e76\u672a\u8fde\u63a5\u3002\u6b64\u5916\u5982\u679c\u4f60\u613f\u610f\uff0c\u4f60\u8fd8\u53ef\u4ee5\u66f4\u6539\u94b1\u5305\u540d\u79f0\u6216\u4ece\u5c06\u5176\u4ece\u94b1\u5305\u5217\u8868\u5220\u9664\u3002"},wipe:{warning:"\u8b66\u544a: \u786c\u4ef6\u94b1\u5305\u4e2d\u7684\u6240\u6709\u6570\u636e\u5c06\u88ab\u5220\u9664\u3002\u5982\u679c\u6ca1\u6709\u5907\u4efd\uff0c\u4f60\u5c06\u65e0\u6cd5\u518d\u6b21\u8bbf\u95ee\u4f60\u7684\u8d44\u91d1\u3002","confirm-delete":"\u8fd8\u662f\u5c06\u5176\u4ece\u94b1\u5305\u5217\u8868\u4e2d\u5220\u9664"},"create-backup":{warning:'\u8b66\u544a: \u4f60\u53ea\u80fd\u4f7f\u7528\u6b64\u9009\u9879\u5907\u4efd\u4f60\u7684\u786c\u4ef6\u94b1\u5305\u79cd\u5b50\u4e00\u6b21\u3002\u5982\u679c\u4f60\u51b3\u5b9a\u7ee7\u7eed\uff0c\u4f60\u5c06\u4e0d\u5f97\u4e0d\u5199\u4e0b\u4e00\u7ec4\u5355\u8bcd(\u5efa\u8bae\u5199\u5728\u7eb8\u4e0a\uff0c\u800c\u4e0d\u662f\u7535\u8111\u4e0a)\uff0c\u8fd9\u4e9b\u5355\u8bcd\u5c06\u51fa\u73b0\u5728\u786c\u4ef6\u94b1\u5305\u7684\u5c4f\u5e55\u4e0a\uff0c\u5e76\u5c06\u5176\u5b58\u50a8\u5728\u4e00\u4e2a\u5b89\u5168\u7684\u5730\u65b9\u3002\u4efb\u4f55\u53ef\u4ee5\u8bbf\u95ee\u5355\u8bcd\u5217\u8868("\u79cd\u5b50")\u7684\u4eba\u90fd\u53ef\u4ee5\u8bbf\u95ee\u94b1\u5305\u4f59\u989d\uff0c\u56e0\u6b64\u5efa\u8bae\u8bf7\u683c\u5916\u8c28\u614e\u3002',instructions:"\u5199\u4e0b\u51fa\u73b0\u5728\u786c\u4ef6\u94b1\u5305\u5c4f\u5e55\u4e0a\u7684\u5355\u8bcd\u5217\u8868\u3002\u4e00\u5b9a\u8981\u6309\u987a\u5e8f\u5e76\u628a\u6bcf\u4e2a\u5355\u8bcd\u90fd\u5199\u5bf9\u3002"},"seed-word":{title:"\u8f93\u5165\u5b57",info1:"\u8f93\u5165\u8bbe\u5907\u4e2d\u663e\u793a\u7684\u5b57",info2:"\u4f60\u5c06\u88ab\u8981\u6c42\u4ee5\u968f\u673a\u7684\u987a\u5e8f\u8f93\u5165\u4f60\u5907\u4efd\u7684\u79cd\u5b50\uff0c\u52a0\u4e0a\u4e00\u4e9b\u989d\u5916\u7684\u5b57\u3002",word:"\u8981\u6c42\u7684\u5b57","error-invalid-word":"\u8f93\u5165\u5b57\u65e0\u6548\u3002","error-loading-words":"\u6b63\u5728\u52a0\u8f7d\u5b57\u5217\u8868\u3002\u8bf7\u7a0d\u7b49\u3002"},"change-pin":{"pin-mismatch":"\u65e0\u6cd5\u6267\u884c\u64cd\u4f5c\u3002\u4f60\u8f93\u5165\u7684\u4e24\u4e2a\u5bc6\u7801\u4e0d\u5339\u914d"},"enter-pin":{title:"\u8f93\u5165\u5bc6\u7801","title-change-current":"\u8f93\u5165\u5f53\u524d\u5bc6\u7801","title-change-new":"\u8f93\u5165\u65b0\u7684\u5bc6\u7801","title-change-confirm":"\u786e\u8ba4\u65b0\u7684\u5bc6\u7801",instructions:" \u5bc6\u7801\u5df2\u663e\u793a\u5728\u786c\u4ef6\u94b1\u5305\u7684\u5c4f\u5e55\u4e0a\u3002","instructions-tx":"\u8fdb\u5165\u5bc6\u7801\u4ee5\u786e\u8ba4\u5e76\u7b7e\u7f72\u4ea4\u6613\u3002","instructions-change":"\u8bf7\u8f93\u5165\u4e00\u4e2a4\u52308\u4e2a\u6570\u5b57\u4e4b\u95f4\u7684\u96be\u4ee5\u88ab\u731c\u4e2d\u7684\u5bc6\u7801\u3002",help:"\u9700\u8981\u5e2e\u52a9\uff1f"},"pin-help":{title:"\u5e2e\u52a9",part1:"\u5f53\u9700\u8981\u8f93\u5165\u5bc6\u7801\u624d\u80fd\u7ee7\u7eed\u65f6\uff0c\u786c\u4ef6\u94b1\u5305\u5c4f\u5e55\u4f1a\u663e\u793a\u4e00\u4e2a\u77e9\u9635\uff0c\u77e9\u9635\u75319\u4e2a\u968f\u673a\u6392\u5217\u7684\u5757\u7ec4\u6210(\u6bcf\u6b21\u987a\u5e8f\u90fd\u4f1a\u6539\u53d8)\uff0c\u4f60\u5c06\u88ab\u8981\u6c42\u5728\u8f6f\u4ef6\u94b1\u5305\u4e2d\u8f93\u5165\u5bc6\u7801\uff0c\u4f7f\u7528\u4e00\u4e2a\u77e9\u9635\uff0c\u6b64\u77e9\u9635\u5305\u542b9\u4e2a\u6309\u94ae\uff0c\u53ea\u663e\u793a\u7b26\u53f7#\u3002",part2:'\u8981\u8f93\u5165\u5bc6\u7801\uff0c\u8bf7\u5728\u786c\u4ef6\u94b1\u5305\u5c4f\u5e55\u4e0a\u4ee5\u6570\u5b57\u77e9\u9635\u67e5\u770b\u5bc6\u7801\u7684\u4f4d\u7f6e\uff0c\u7136\u540e\u70b9\u51fb\u8f6f\u4ef6\u94b1\u5305\u4e2d\u7684\u76f8\u5e94\u6309\u94ae\u3002\u4f8b\u5982\uff0c\u5982\u679c\u5bc6\u7801\u4e3a"23"\u4e14\u6570\u5b572\u4f4d\u4e8e\u786c\u4ef6\u94b1\u5305\u6570\u5b57\u77e9\u9635\u7684\u5de6\u4e0a\u89d2\uff0c\u6570\u5b573\u4f4d\u4e8e\u786c\u4ef6\u94b1\u5305\u6570\u5b57\u77e9\u9635\u7684\u6b63\u4e2d\u95f4\uff0c\u5219\u6309\u987a\u5e8f\u70b9\u51fb\u8f6f\u4ef6\u94b1\u5305\u4e2d\u7684\u5de6\u4e0a\u89d2\u548c\u4e2d\u95f4\u6309\u94ae\u3002',part3:'\u5982\u679c\u4f60\u613f\u610f\uff0c\u8fd8\u53ef\u4ee5\u4f7f\u7528\u952e\u76d8\u4e0a\u7684\u5c0f\u952e\u76d8\u8f93\u5165\u5bc6\u7801\u3002\u4f46\u662f\uff0c\u5982\u4e4b\u524d\u793a\u4f8b\u6240\u793a\uff0c\u5982\u679c\u5bc6\u7801\u662f"23"\uff0c\u4f60\u4e0d\u80fd\u7b80\u5355\u5730\u7528\u5c0f\u952e\u76d8\u952e\u5165"23"\uff0c\u800c\u662f\u5fc5\u987b\u9009\u62e9\u70b9\u51fb\u786c\u4ef6\u94b1\u5305\u5c4f\u5e55\u4e0a2\u548c3\u5bf9\u5e94\u4f4d\u7f6e\u7684\u503c\u3002'},"create-tx":{title:"\u521b\u5efa\u4ea4\u6613"},"confirm-address":{title:"\u786e\u8ba4\u5730\u5740",instructions:"\u8bf7\u5728\u786c\u4ef6\u94b1\u5305\u4e0a\u786e\u8ba4\uff0c\u5982\u679c\u5730\u5740\u4e3a:","short-confirmation":"\u5730\u5740\u5df2\u786e\u8ba4",confirmation:'\u5730\u5740\u5df2\u786e\u8ba4\u3002\u4e3a\u4e86\u5b89\u5168, \u9009\u62e9 "\u786e\u8ba4\u5730\u5740" \u9009\u9879\u53ef\u4ee5\u5728\u786c\u4ef6\u94b1\u5305\u4e0a\u518d\u6b21\u663e\u793a\u5730\u5740\uff0c\u5728\u83dc\u5355\u4e2d\u53ef\u70b9\u51fb\u5730\u5740\u4f59\u989d\u53f3\u4fa7\u7684\u6309\u94ae\u663e\u793a\u3002'}},"time-from-now":{"few-seconds":"\u51e0\u79d2\u949f\u4e4b\u524d",minute:"\u4e00\u5206\u949f\u4e4b\u524d",minutes:"{{time}} \u5206\u949f\u4e4b\u524d",hour:"\u4e00\u5c0f\u65f6\u4e4b\u524d",hours:"{{time}} \u5c0f\u65f6\u4e4b\u524d",day:"\u4e00\u5929\u4e4b\u524d",days:"{{time}} \u5929\u4e4b\u524d"},exchange:{"you-send":"\u4f60\u53d1\u9001","you-get":"\u4f60\u6536\u5230 (\u5927\u7ea6)","to-address":"\u5230 {{coin}} \u5730\u5740",price:"\u4ea4\u6613\u6c47\u7387","time-15":"\u4ea4\u6613\u65f6\u95f4","exchange-button":"\u4ea4\u6613","min-amount":"\u6700\u5c0f\u6570\u989d:","max-amount":"\u6700\u5927\u6570\u989d:","agree-1":"\u6211\u540c\u610f","agree-2":"\u4f7f\u7528\u6761\u6b3e","agree-3":"\u548c","agree-4":"\u9690\u79c1\u653f\u7b56","powered-by":"\u6280\u672f\u652f\u6301","need-help":"\u9700\u8981\u5e2e\u52a9?","support-portal":"\u5e2e\u52a9\u5165\u53e3",history:"\u8ba2\u5355\u5386\u53f2","order-not-found":"\u8ba2\u5355\u672a\u627e\u5230",status:"\u72b6\u6001",exchanging:"{{from}}\u4ea4\u6613{{to}}",select:"\u9009\u62e9",offline:"\u4ea4\u6613\u6682\u65f6\u4e0b\u7ebf","problem-connecting":"\u672a\u80fd\u8fde\u63a5\u5230\u670d\u52a1\u5668\u3002\u8bf7\u68c0\u67e5\u4f60\u7684\u7f51\u7edc\u8fde\u63a5\u5e76\u7a0d\u540e\u518d\u8bd5\u3002","invalid-address":"\u65e0\u6548\u5730\u5740\u3002",statuses:{"user-waiting":"\u7b49\u5f85\u5145\u503c\u3002\u8bf7\u5c06{{amount}} {{from}}\u53d1\u9001\u5230\u4e0b\u9762\u663e\u793a\u7684\u4ea4\u6613\u5730\u5740","user-waiting-info":"\u7cfb\u7edf\u6b63\u5728\u7b49\u5f85\u4f60\u5145\u503c\u5230\u4ea4\u6613\u5730\u5740\u3002\u4ea4\u6613\u5c06\u5728\u7cfb\u7edf\u68c0\u6d4b\u5230\u4f60\u7684\u5145\u503c\u5e76\u5728\u533a\u5757\u94fe\u4e2d\u786e\u8ba4\u540e\u5f00\u59cb\u3002\u5982\u679c\u4f60\u5df2\u7ecf\u5145\u503c\uff0c\u5e94\u8be5\u5f88\u5feb\u5c31\u4f1a\u68c0\u6d4b\u5230\u3002","market-waiting-confirmations":"\u7b49\u5f85\u94fe\u4e0a\u4ea4\u6613\u786e\u8ba4","market-waiting-confirmations-info":"\u5df2\u7ecf\u68c0\u6d4b\u5230\u5145\u503c\uff0c\u7b49\u5f85\u533a\u5757\u94fe\u4e2d\u88ab\u786e\u8ba4\u3002","market-confirmed":"\u94fe\u4e0a\u4ea4\u6613\u5df2\u63a5\u53d7","market-confirmed-info":"\u94fe\u4e0a\u4ea4\u6613\u5df2\u7ecf\u5728\u533a\u5757\u94fe\u4e0a\u786e\u8ba4\u3002\u51c6\u5907\u9a6c\u4e0a\u6267\u884c\u5151\u6362\u3002","market-exchanged":"\u5b8c\u6210{{from}}\u5230{{to}}\u7684\u5151\u6362","market-exchanged-info":"\u5151\u6362\u5df2\u7ecf\u5b8c\u6210\u3002\u8d44\u91d1\u5c06\u5f88\u5feb\u53d1\u9001\u5230\u4f60\u7684\u5730\u5740\u3002","market-withdraw-waiting":"\u6b63\u5728\u53d1\u9001{{to}}\u5230\u4f60\u7684\u5730\u5740","market-withdraw-waiting-info":"\u53d1\u9001{{to}}\u5230\u4f60\u5730\u5740\u7684\u8fdb\u7a0b\u5df2\u542f\u52a8",complete:"\u4ea4\u6613\u5df2\u5b8c\u6210!","complete-info":"\u8d44\u91d1\u5df2\u7ecf\u6210\u529f\u53d1\u9001\u5230\u4f60\u7684\u5730\u5740\u3002",error:"\u53d1\u751f\u9519\u8bef","error-info":"\u8fd0\u8f6c\u8fc7\u7a0b\u4e2d\u51fa\u73b0\u9519\u8bef\uff0c\u4f60\u53ef\u4ee5\u5728\u4e0b\u9762\u627e\u5230\u66f4\u591a\u4fe1\u606f\u3002\u5982\u679c\u4f60\u9700\u8981\u5e2e\u52a9\uff0c\u8bf7\u4fdd\u5b58\u4e0b\u9762\u663e\u793a\u7684\u6240\u6709\u6570\u636e\u5e76\u4f7f\u7528\u9875\u9762\u53f3\u4e0b\u89d2\u7684\u5e2e\u52a9\u94fe\u63a5\u6765\u8054\u7cfb\u6280\u672f\u652f\u6301\u3002"},"history-window":{address:"\u5730\u5740",date:"\u65e5\u671f"},details:{"exchange-addr":"\u4ea4\u6613\u5730\u5740","exchange-addr-tag":"\u652f\u4ed8ID\u6216\u4ea4\u6613\u5fc5\u987b\u7528\u5230\u7684\u76ee\u6807\u6807\u7b7e","tx-id":"\u4ea4\u6613ID","order-id":"\u8ba2\u5355ID","initial-price":"\u521d\u59cb\u6c47\u7387","error-msg":"\u9519\u8bef\u4fe1\u606f ",details:"\u8be6\u60c5","start-date":"\u5f00\u59cb\u65e5\u671f",back:"\u8fd4\u56de","back-alert":'\u64cd\u4f5c\u6b63\u5728\u6267\u884c\u3002\u4f60\u771f\u7684\u60f3\u8981\u8fd4\u56de\u5230\u8868\u683c\u5417\uff1f\u4f60\u53ef\u4ee5\u901a\u8fc7\u70b9\u51fb"\u8ba2\u5355\u5386\u53f2"\u518d\u6b21\u770b\u5230\u6267\u884c\u8fc7\u7a0b'}}}}}); \ No newline at end of file diff --git a/src/gui/static/dist/2.af5e2fa6c65ff6f39739.chunk.js b/src/gui/static/dist/2.af5e2fa6c65ff6f39739.chunk.js new file mode 100644 index 0000000..1c8cc19 --- /dev/null +++ b/src/gui/static/dist/2.af5e2fa6c65ff6f39739.chunk.js @@ -0,0 +1 @@ +webpackJsonp([2],{"P+VX":function(e,n){e.exports={common:{"coin-id":"SKY","coin-hours":"CH",loading:"\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430...",new:"\u041d\u043e\u0432\u044b\u0439",load:"\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c"},errors:{"fetch-version":"\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441 Github","incorrect-password":"\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c","api-disabled":"API \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d","no-wallet":"\u041a\u043e\u0448\u0435\u043b\u0451\u043a \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442","no-outputs":"\u041d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0440\u0435\u0434\u0441\u0442\u0432"},title:{wallets:"\u041a\u043e\u0448\u0435\u043b\u044c\u043a\u0438",send:"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c",history:"\u0418\u0441\u0442\u043e\u0440\u0438\u044f","buy-coin":"\u041a\u0443\u043f\u0438\u0442\u044c Skycoin",network:"\u0421\u0435\u0442\u044c",blockchain:"\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d",outputs:"\u0412\u044b\u0445\u043e\u0434\u044b (Outputs)",transactions:"\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438","pending-txs":"\u041d\u0435\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043d\u043d\u044b\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438",backup:"\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435",explorer:"Skycoin \u044d\u043a\u0441\u043f\u043b\u043e\u0440\u0435\u0440",seed:"\u0424\u0440\u0430\u0437\u0430 \u0432\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f",qrcode:"QR-\u043a\u043e\u0434"},header:{"syncing-blocks":"\u0418\u0434\u0451\u0442 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u043b\u043e\u043a\u043e\u0432...",update1:"\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430",update2:"\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e.","pending-txs1":"\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442","pending-txs2":"\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.","pending-txs3":"\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0441\u0435\u0442\u044c\u044e.",errors:{"no-connections":"\u041d\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439, \u0432\u0430\u0448 \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u0443\u0437\u043b\u0430\u043c!","no-backend1":"\u041d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0443. \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0441\u0435\u044c \u0437\u0430 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432 \u043d\u0430\u0448\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u0435","no-backend2":"\u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c\u043c\u0435.","no-backend3":"",csrf:"\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438: CSRF \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442."}},password:{title:"\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c",label:"\u041f\u0430\u0440\u043e\u043b\u044c","confirm-label":"\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c",button:"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c"},buy:{"deposit-address":"\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043a\u043e\u0448\u0435\u043b\u0451\u043a \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u0435\u043f\u043e\u0437\u0438\u0442\u043d\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430:","select-address":"\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0430\u0434\u0440\u0435\u0441",generate:"\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c","deposit-location":"\u0410\u0434\u0440\u0435\u0441 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f","deposit-location-desc":"\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043a\u043e\u0448\u0435\u043b\u0451\u043a \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f Skycoin, \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u0435\u043f\u043e\u0437\u0438\u0442\u0430.","make-choice":"\u0421\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0432\u044b\u0431\u043e\u0440","wallets-desc":"\u041f\u0440\u0438 \u0432\u044b\u0431\u043e\u0440\u0435 \u0430\u0434\u0440\u0435\u0441\u0430, \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0434\u043b\u044f \u0434\u0435\u043f\u043e\u0437\u0438\u0442\u0430. \u041e\u0434\u0438\u043d \u0430\u0434\u0440\u0435\u0441 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0451\u043d \u043a \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u043c\u0443 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0430\u0434\u0440\u0435\u0441\u043e\u0432.",send:"\u041f\u043e\u0448\u043b\u0438\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0430\u043b\u044e\u0442\u0443","send-desc":"\u041e\u0442\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u0432\u0430\u043c\u0438 \u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0430\u043b\u044e\u0442\u0443 \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u044b\u0439 \u043d\u0438\u0436\u0435. \u041f\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044e \u0438 \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u043e\u0432, \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 Skycoin \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e \u043a\u0443\u0440\u0441\u0443 {{ rate }} Skycoin/Selected Coin.","fraction-warning":"\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u043e \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u0446\u0435\u043b\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.",receive:"\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c Skycoin","receive-desc":"\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043a\u0440\u0438\u043f\u0442\u0430\u0432\u0430\u043b\u044e\u0442\u044b, \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 Skycoin. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u044c \u043e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u043d\u0435\u0439, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u043e\u043f\u043b\u0430\u0442\u044b \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0435\u0442\u0438.","status-button":"\u0421\u0442\u0430\u0442\u0443\u0441:","check-status-button":"\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441","new-order-button":"\u041d\u043e\u0432\u044b\u0439 \u0437\u0430\u043a\u0430\u0437",refresh:"\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c","available-now":"\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e:","choose-preference":"\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u043f\u043b\u0430\u0442\u044b. \u0418\u043c\u0435\u0439\u0442\u0435 \u0432 \u0432\u0438\u0434\u0443, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u044b.",choose:"\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u043b\u044e\u0431\u0438\u043c\u0443\u044e \u043a\u0440\u0438\u043f\u0442\u0443 ;)","send-coin":"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c","send-coin-text-1":"\u043d\u0430 \u0430\u0434\u0440\u0435\u0441 \u043d\u0438\u0436\u0435. \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0439 \u043d\u0430 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u0435, \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 Skycoin \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0432\u0430\u043c\u0438 \u043a\u043e\u0448\u0435\u043b\u0451\u043a \u043f\u043e \u043a\u0443\u0440\u0441\u0443"},wizard:{"wallet-desc":'\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043d\u0435\u0442 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430 Skycoin, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0444\u0440\u0430\u0437\u0443 \u0434\u043b\u044f \u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u0444\u0440\u0430\u0437\u0430 \u0443 \u0432\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 "\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430" \u0438 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u0444\u0440\u0430\u0437\u0443.',"encrypt-desc":"\u0414\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0442\u0438, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0421\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043f\u0430\u0440\u043e\u043b\u044f. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u044b \u0435\u0433\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u0435.","finish-button":"\u0417\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c","back-button":"\u041d\u0430\u0437\u0430\u0434",confirm:{title:"\u0414\u0435\u0440\u0436\u0438\u0442\u0435 \u0441\u0432\u043e\u044e \u0444\u0440\u0430\u0437\u0443 \u0432 \u0441\u043e\u0445\u0440\u0430\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435!",desc:"\u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u044b \u0437\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0444\u0440\u0430\u0437\u0443 \u0432\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0434\u0435\u0440\u0436\u0438\u0442\u0435 \u0435\u0451 \u0432 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435. \u041f\u0440\u0438 \u0443\u0442\u0435\u0440\u0435 \u0444\u0440\u0430\u0437\u044b \u0432\u044b \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u0442\u0435 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0432\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0443 Skycoin!",checkbox:"\u041a\u043b\u044f\u043d\u0443\u0441\u044c. \u042f \u0437\u0430\u043f\u0438\u0441\u0430\u043b.",button:"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c"}},wallet:{"new-address":"\u041d\u043e\u0432\u044b\u0439 \u0430\u0434\u0440\u0435\u0441","show-empty":"\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u0435","hide-empty":"\u0421\u043a\u0440\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u0435",encrypt:"\u0417\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0448\u0435\u043b\u0451\u043a",decrypt:"\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0448\u0435\u043b\u0451\u043a",edit:"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0432\u043e\u0430\u0442\u044c",add:"\u041d\u043e\u0432\u044b\u0439 \u043a\u043e\u0448\u0435\u043b\u0451\u043a",load:"\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c","encryption-enabled":"\u0417\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d","encryption-disabled":"\u0411\u0435\u0437 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f",wallet:"\u041a\u043e\u0448\u0435\u043b\u0451\u043a",new:{"create-title":"\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u0448\u0435\u043b\u0451\u043a","load-title":"\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0448\u0435\u043b\u0451\u043a","encrypt-title":"\u0428\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0448\u0435\u043b\u0451\u043a","name-label":"\u0418\u043c\u044f \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430","seed-label":"\u0424\u0440\u0430\u0437\u0430 \u0432\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f","confirm-seed-label":"\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0444\u0440\u0430\u0437\u0443","seed-warning":"\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u0435 \u044d\u0442\u0430 \u0444\u0440\u0430\u0437\u0443 \u0438\u043b\u0438 \u0437\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0438 \u0434\u0435\u0440\u0436\u0438\u0442\u0435 \u0432 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u0432 \u0434\u0430\u043b\u0438 \u043e\u0442 \u0447\u0443\u0436\u0438\u0445 \u0433\u043b\u0430\u0437. \u041f\u0440\u0438 \u043f\u043e\u0442\u0435\u0440\u0435 \u0444\u0440\u0430\u0437\u044b \u0432\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c Skycoin \u043a\u043e\u0448\u0435\u043b\u0451\u043a!","create-button":"\u0421\u043e\u0437\u0434\u0430\u0442\u044c","load-button":"\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c","cancel-button":"\u041e\u0442\u043c\u0435\u043d\u0430","12-words":"12 \u0441\u043b\u043e\u0432","24-words":"24 \u0441\u043b\u043e\u0432\u0430","generate-12-seed":"\u0421\u0433\u0435\u043d\u0438\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0440\u0430\u0437\u0443 \u0438\u0437 12 \u0441\u043b\u043e\u0432","generate-24-seed":"\u0421\u0433\u0435\u043d\u0438\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0440\u0430\u0437\u0443 \u0438\u0437 24 \u0441\u043b\u043e\u0432",encrypt:"\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435","encrypt-warning":"\u041c\u044b \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0432\u0430\u0448\u0438 \u043a\u0430\u0448\u0435\u043b\u044c\u043a\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u043e\u043b\u044f. \u0422\u0430\u043a \u0436\u0435 \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0444\u0440\u0430\u0437\u0430 \u0432\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435."},rename:{title:"\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430","name-label":"\u0418\u043c\u044f","cancel-button":"\u041e\u0442\u043c\u0435\u043d\u0430","rename-button":"\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c"},address:{copy:"\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c","copy-address":"\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441",copied:"\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043e!",outputs:"\u041d\u0435\u043f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u044b\u0435 \u0432\u044b\u0445\u043e\u0434\u044b (Unspent Outputs)"}},send:{"from-label":"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441","to-label":"\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430","amount-label":"\u0421\u0443\u043c\u043c\u0430","notes-label":"\u0417\u0430\u043c\u0435\u0442\u043a\u0438","wallet-label":"\u041a\u043e\u0448\u0435\u043b\u0451\u043a","addresses-label":"\u0410\u0434\u0440\u0435\u0441","addresses-help":"\u0410\u0434\u0440\u0435\u0441 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f","change-address-label":"\u0410\u0434\u0440\u0435\u0441 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u0442\u043a\u0430","change-address-help":"\u0410\u0434\u0440\u0435\u0441 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438. \u0415\u0441\u043b\u0438 \u0432\u044b \u0435\u0433\u043e \u043d\u0435 \u0443\u043a\u0430\u0436\u0438\u0442\u0435, \u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438","destinations-label":"\u0410\u0434\u0440\u0435\u0441\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439","destinations-help1":"\u0410\u0434\u0440\u0435\u0441\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0441\u0443\u043c\u043c\u0430 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f","destinations-help2":"\u0410\u0434\u0440\u0435\u0441\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439, \u0441\u0443\u043c\u043c\u0430 Skycoin & CH \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f","hours-allocation-label":"\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0447\u0430\u0441\u044b (CH)","options-label":"\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e","value-label":"\u0424\u0430\u043a\u0442\u043e\u0440 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0447\u0430\u0441\u043e\u0432 (CH)","value-help":"\u0427\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u0444\u0430\u043a\u0442\u043e\u0440, \u0442\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 CH \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439","preview-button":"\u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440","send-button":"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c","back-button":"\u041d\u0430\u0437\u0430\u0434",simple:"\u041e\u0431\u044b\u0447\u043d\u044b\u0439",advanced:"\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439"},tx:{transaction:"\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f","confirm-transaction":"\u041f\u043e\u0434\u0442\u0435\u0440\u0434\u0438\u0442\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e",from:"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c",to:"\u041f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c",date:"\u0414\u0430\u0442\u0430",status:"\u0421\u0442\u0430\u0442\u0443\u0441",coins:"\u0421\u0443\u043c\u043c\u0430",hours:"\u0427\u0430\u0441\u044b",id:"TX ID","show-more":"\u0418\u043d\u0444\u043e","hours-sent":"\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c","hours-burned":"\u0441\u0436\u0438\u0433\u0430\u0435\u043c",inputs:"\u0412\u0445\u043e\u0434\u044b",outputs:"\u0412\u044b\u0445\u043e\u0434\u044b",confirmed:"\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0430",pending:"\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435","current-rate":"\u041f\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043a\u0443\u0440\u0441\u0443"},backup:{"wallet-directory":"\u041f\u0430\u043f\u043a\u0430 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430:","seed-warning":"\u0414\u0415\u0420\u0416\u0418\u0422\u0415 \u0424\u0420\u0410\u0417\u0423 \u0412\u041e\u0421\u0422\u0410\u041d\u041e\u0412\u041b\u0415\u041d\u0418\u042f \u0412 \u041d\u0410\u0414\u0401\u0416\u041d\u041e\u041c \u041c\u0415\u0421\u0422\u0415. \u041d\u0410 \u0411\u0423\u041c\u0410\u0413\u0415. \u041e\u0424\u0424\u041b\u0410\u0419\u041d. \u0415\u0441\u043b\u0438 \u0432\u044b \u0434\u0435\u0440\u0436\u0438\u0442\u0435 \u0444\u0440\u0430\u0437\u0443 \u0432 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0441\u043c\u043e\u0433 \u0435\u0451 \u043f\u043e\u0434\u0433\u043b\u044f\u0434\u0435\u0442\u044c - \u0432\u0430\u0448\u044b \u0442\u043e\u043a\u0435\u043d\u044b \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438.",desc:"\u0418\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043d\u0438\u0436\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0444\u0440\u0430\u0437\u044b \u0434\u043b\u044f \u0432\u0430\u0448\u0438\u0445 \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u043e\u0432.
\u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0440\u0430\u0437 \u0432\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430\u0445 \u0431\u0435\u0437 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u0430\u043f\u043a\u0443 \u0443\u043a\u0430\u0437\u0430\u043d\u0443\u044e \u0432\u044b\u0448\u0435 \u0438 \u043d\u0430\u0439\u0434\u0438\u0442\u0435 \u0432 \u043d\u0435\u0439 \u0444\u0430\u0439\u043b\u044b \u0441 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c .wlt. \u0424\u0440\u0430\u0437\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043d\u0438\u0445. \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043b\u044e\u0431\u043e\u0433\u043e (\u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0433\u043e) \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430","close-button":"\u0417\u0430\u043a\u0440\u044b\u0442\u044c",wallet:"\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0430",filename:"\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430",seed:"\u0424\u0440\u0430\u0437\u0430","show-seed":"\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0444\u0440\u0430\u0437\u0443","no-wallets":"\u041a\u043e\u0448\u0435\u043b\u044c\u043a\u043e\u0432 \u0441 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u0442"},blockchain:{blocks:"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u043b\u043e\u043a\u043e\u0432",time:"\u0412\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430",hash:"\u0425\u044d\u0448 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430","current-supply":"\u0412\u0441\u0435\u0433\u043e Skycoin \u0432 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438","total-supply":"\u0412\u0441\u0435\u0433\u043e Skycoin \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442","current-coinhour-supply":"\u0412\u0441\u0435\u0433\u043e CH \u0432 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438","total-coinhour-supply":"\u0412\u0441\u0435\u0433\u043e CH \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442"},network:{peer:"\u041f\u0438\u0440 (Peer)",source:"\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a","block-height":"\u0412\u044b\u0441\u043e\u0442\u0430 \u0431\u043b\u043e\u043a\u0430","last-seen":"\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0431\u043b\u043e\u043a","last-received":"\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b\u0439","last-sent":"\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b\u0439",in:"\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0435",out:"\u0418\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435",sources:{default:"\u041f\u0438\u0440 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e",exchange:"\u041e\u0431\u043c\u0435\u043d\u0430 \u043f\u0438\u0440\u0430\u043c\u0438"}},"pending-txs":{timestamp:"\u041c\u0435\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438",txid:"ID \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438",none:"\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0442\u0440\u0430\u043d\u0430\u0437\u043a\u0446\u0438\u0439 \u0436\u0434\u0443\u0449\u0438\u0445 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0439",my:"\u041c\u043e\u0439",all:"\u0412\u0441\u0435"},history:{"tx-detail":"\u0414\u0435\u0442\u0430\u043b\u0438 \u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438",sending:"\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c",sent:"\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e",received:"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e",receiving:"\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c",pending:"\u041e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f","no-txs":"\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439"},teller:{done:"\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e","waiting-confirm":"\u041e\u0436\u0438\u0434\u0430\u0435\u043c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0439","waiting-deposit":"\u041e\u0436\u0438\u0434\u0430\u0435\u043c \u0434\u0435\u043f\u043e\u0437\u0438\u0442","waiting-send":"\u041f\u043e\u0441\u044b\u043b\u0430\u0435\u043c Skycoin",unknown:"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e"}}}}); \ No newline at end of file diff --git a/src/gui/static/dist/3.b1328f7fc5fe260edda4.chunk.js b/src/gui/static/dist/3.b1328f7fc5fe260edda4.chunk.js new file mode 100644 index 0000000..73fef92 --- /dev/null +++ b/src/gui/static/dist/3.b1328f7fc5fe260edda4.chunk.js @@ -0,0 +1 @@ +webpackJsonp([3],{"0v8u":function(e,t){e.exports={common:{"coin-id":"SKY","coin-hours":"Coin Hours",usd:"USD",loading:"Loading...",new:"New",load:"Load"},errors:{error:"Error","fetch-version":"Unable to fetch latest release version from Github","incorrect-password":"Incorrect password","error-decrypting":"Error decrypting the wallet","api-disabled":"API disabled","no-wallet":"Wallet does not exist","no-outputs":"No unspent outputs","window-size":"The window is too narrow for the content"},title:{language:"Select Language",wallets:"Wallets",send:"Send",history:"History","buy-coin":"Buy Skycoin",network:"Networking",blockchain:"Blockchain",outputs:"Outputs",transactions:"Transactions","pending-txs":"Pending Transactions",backup:"Backup Wallet",explorer:"Skycoin Explorer",seed:"Wallet Seed",qrcode:"QR Code",reset:"Reset Password",exchange:"Exchange","select-address":"Select Address","order-history":"Order history"},header:{"syncing-blocks":"Syncing blocks",update1:"Wallet update",update2:"available.",synchronizing:"The wallet is synchronizing. Data you see may not be updated.","pending-txs1":"There are some","pending-txs2":"pending transactions.","pending-txs3":"Data you see may not be updated.",errors:{"no-connections":"No connections active, your client is not connected to any other nodes!","no-backend1":"Cannot reach backend. Please restart the app and/or seek help on our","no-backend2":"Telegram.","no-backend3":"",csrf:"Security vulnerability: CSRF is not working, please exit immediately."}},password:{title:"Enter Password",label:"Password","confirm-label":"Confirm password",button:"Proceed","reset-link":"I forgot my password"},buy:{"deposit-address":"Choose an address to generate a BTC deposit link for:","select-address":"Select address",generate:"Generate","deposit-location":"Deposit Location","deposit-location-desc":"Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.","make-choice":"Make a choice","wallets-desc":"Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.",send:"Send Bitcoin","send-desc":"Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.","fraction-warning":"Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!",receive:"Receive Sky","receive-desc":"After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.","status-button":"Status:","check-status-button":"Check Status","new-order-button":"New Order"},wizard:{"wallet-desc":'If you don\'t have a Skycoin wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to "Load Wallet" and enter your seed.',"encrypt-desc":"Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.","hardware-wallet-link":"Using a hardware wallet?","finish-button":"Finish","back-button":"Back",confirm:{title:"Safeguard your seed!",desc:"We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your Skycoin wallet!",checkbox:"It\u2019s safe, I swear.",button:"Continue"}},wallet:{"new-address":"New Address","new-addresses":"New Addresses","show-empty":"Show Empty","hide-empty":"Hide Empty",encrypt:"Encrypt Wallet",decrypt:"Decrypt Wallet","decrypt-warning":"Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.",delete:"Delete Wallet",edit:"Edit Wallet",add:"Add Wallet",load:"Load Wallet","encryption-enabled":"Encryption enabled","encryption-disabled":"Encryption disabled","hw-security-warning":'Possible security risk. Access the hardware wallet options (by pressing the "Hardware Wallet" button below the wallets list) while the device is connected for more information.',wallet:"Wallet","hardware-wallet":"Hardware Wallet","delete-confirmation":'WARNING: The wallet "{{ name }}" will be removed from the list. To add it again, you will have to reconnect the device and open the hardware wallet options (by pressing the "Hardware Wallet" button below the wallets list). Do you want to continue?',"delete-confirmation-check":"Yeah, I want to delete the wallet.","max-hardware-wallets-error":"You have already reached the max number of addresses that can be added to the hardware wallet.","add-many-confirmation":"WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?",new:{"create-title":"Create Wallet","load-title":"Load Wallet","encrypt-title":"Encrypt Wallet","name-label":"Name","seed-label":"Seed","confirm-seed-label":"Confirm seed","seed-warning":"Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!","create-button":"Create","load-button":"Load","cancel-button":"Cancel","12-words":"12 words","24-words":"24 words","generate-12-seed":"Generate 12 word seed","generate-24-seed":"Generate 24 word seed",encrypt:"Encrypt wallet","encrypt-warning":"We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.","unconventional-seed-title":"Possible error","unconventional-seed-text":"You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.","unconventional-seed-check":"Continue with the unconventional seed."},rename:{title:"Rename Wallet","name-label":"Name","cancel-button":"Cancel","rename-button":"Rename"},"add-addresses":{title:"Select quantity","name-quantity":"How many addresses to create","cancel-button":"Cancel","create-button":"Create"},address:{show:"Press to show",copy:"Copy","copy-address":"Copy address",copied:"Copied!",confirm:"Confirm address",outputs:"Unspent outputs",history:"History"}},send:{"synchronizing-warning":"The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?","from-label":"Send from","to-label":"Send to","amount-label":"Amount","notes-label":"Notes","wallet-label":"Wallet","addresses-label":"Addresses","invalid-amount":"Please enter a valid amount","addresses-help":"Limit the addresses from where the coins and hours could be sent","all-addresses":"All the addresses of the selected wallet","outputs-label":"Unspent outputs","outputs-help":"Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown","all-outputs":"All the outputs of the selected addresses","available-msg-part1":"With your current selection you can send up to","available-msg-part2":"and","available-msg-part3":"(at least","available-msg-part4":"must be used for the transaction fee).","change-address-label":"Custom change address","change-address-select":"Select","change-address-help":'Address to receive change. If it\'s not provided, it will be chosen automatically. Click on the "Select" link to choose an address from one of your wallets',"destinations-label":"Destinations","destinations-help1":"Destination addresses and their coins","destinations-help2":"Destination addresses, their coins and coin hours","hours-allocation-label":"Automatic coin hours allocation","options-label":"Options","value-label":"Coin hours share factor","value-help":"The higher the value, the more coin hours will be sent to outputs","preview-button":"Preview","send-button":"Send","back-button":"Back",simple:"Simple",advanced:"Advanced","select-wallet":"Select Wallet"},reset:{"wallet-label":"Wallet","seed-label":"Wallet seed","password-label":"New password (leave empty if you want the wallet not to be encrypted)","confirm-label":"Confirm new password","reset-button":"Reset"},tx:{transaction:"Transaction","confirm-transaction":"Confirm Transaction",from:"From",to:"To",date:"Date",status:"Status",coins:"Coins",hours:"Hours",id:"Tx ID","show-more":"Show more","hours-moved":"moved","hours-sent":"sent","hours-received":"received","hours-burned":"burned",inputs:"Inputs",outputs:"Outputs",confirmed:"Confirmed",pending:"Pending","current-rate":"Calculated at the current rate"},backup:{"wallet-directory":"Wallet Directory:","seed-warning":"BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.",desc:"Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.","close-button":"Close",wallet:"Wallet Label",filename:"Filename",seed:"Seed","show-seed":"Show seed","no-wallets":"No encrypted wallets"},blockchain:{blocks:"Number of blocks",time:"Timestamp of last block",hash:"Hash of last block","current-supply":"Current SKY supply","total-supply":"Total SKY supply","current-coinhour-supply":"Current Coin Hours supply","total-coinhour-supply":"Total Coin Hours supply"},network:{peer:"Peer",source:"Source","block-height":"Block height","block-height-short":"Block","last-seen":"Last seen","last-received":"Last received","last-sent":"Last sent",in:"Incoming",out:"Outgoing",sources:{default:"Default peer",exchange:"Peer exchange"}},"pending-txs":{timestamp:"Timestamp",txid:"Transaction ID",none:"No pending transactions",my:"Mine",all:"All"},history:{"tx-detail":"Transaction Detail",moving:"Internally moving",moved:"Internally moved",sending:"Sending",sent:"Sent",received:"Received",receiving:"Receiving",pending:"Pending","no-txs":"You have no transaction history","no-txs-filter":"There are no transactions matching the current filter criteria","no-filter":"No filter active (press to select wallets/addresses)",filter:"Active filter: ",filters:"Active filters: ","all-addresses":"All addresses"},teller:{done:"Completed","waiting-confirm":"Waiting for confirmation","waiting-deposit":"Waiting for Bitcoin deposit","waiting-send":"Waiting to send Skycoin",unknown:"Unknown"},confirmation:{"header-text":"Confirmation","confirm-button":"Yes","cancel-button":"No",close:"Close"},service:{api:{"server-error":"Server error"},wallet:{"not-enough-hours":"Not enough available Coin Hours to perform the transaction!"}},"hardware-wallet":{general:{"default-wallet-name":"New hardware wallet","error-disconnected":"Unable to perform the operation. The hardware wallet is not connected.","simple-error":"Error, Unable to perform the operation.","generic-error":"Unable to perform the operation. Make sure you have connected a valid hardware wallet and that it is not waiting for input.","generic-error-internet":"Unable to perform the operation. Make sure you have connected a valid hardware wallet that is not waiting for input and that you have a connection to the internet/node.","error-incorrect-wallet":"Unable to perform the operation. The connected hardware wallet is different from the expected one.","error-incorrect-pin":"Unable to perform the operation. The PIN you have entered is not correct.",confirm:"Please, confirm the operation in the hardware wallet.","confirm-and-more":"Please, confirm the operation in the hardware wallet and follow the instructions.",close:"Close",cancel:"Cancel",continue:"Continue",completed:"Operation completed successfully.",refused:"The operation failed or was canceled."},errors:{"too-many-inputs":"The transaction has too many inputs and can not be processed. Please contact technical support.","too-many-outputs":"The transaction has too many outputs and can not be processed. Please contact technical support."},"security-warning":{title:"Security warning",text:'The last time this hardware wallet was connected, one or more security warnings were found. We recommend you to open the hardware wallet options (by pressing the "Hardware Wallet" button below the wallets list) while the device is connected and solve the security problems before continuing.',check:"I understand the risks and want to continue",continue:"Continue",cancel:"Cancel"},options:{connecting:"Connecting...",disconnected:"No hardware wallet detected. Please connect a hardware wallet to use this option.","unconfigured-detected-title":"Unconfigured hardware wallet","unconfigured-detected":'A seedless hardware wallet has been detected. Select "Configure automatically" if you want to configure it as a brand new wallet and start using it immediately, or select "Restore backup" if you want to configure it with a previously created seed backup and thus be able to access your funds again.',"configured-detected":"Hardware wallet detected. The device is identified in the wallets list as:","security-warnings-title":"Security warnings","security-warning-title":"Security warning","backup-warning":'You should backup the hardware wallet seed or you could lose access to the funds in case of problems. To do this, select the "Create a backup" option.',"pin-warning":'The connected hardware wallet does not have a PIN. The PIN code protects the hardware wallet in case of loss, theft and hacks. To create a PIN code, select the "Create PIN code" option.',options:"Options:","configure-automatically":"Configure automatically","restore-backup":"Restore backup","create-backup":"Create a backup",wipe:"Wipe the device","confirm-seed":"Confirm seed","create-pin":"Create PIN code","change-pin":"Change PIN code","forgotten-pin1":"If you can not access the wallet because you have forgotten the PIN, you can wipe the hardware wallet and then restore it with the seed by clicking","forgotten-pin2":"here."},"generate-seed":{text:"Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.",configuring:"Configuring..."},"restore-seed":{text:"Before proceeding, please select the number of words that the seed you want to recover has.","check-text":"You can use this option to enter a seed and check if it is equal to the one in the hardware wallet. Before start, select the number of words the seed you want to check has.",warning:"WARNING: to avoid potential problems, use only seeds created with a hardware wallet from the same brand/model.","error-wrong-word":"Error: The retyped word does not match the one requested by the hardware wallet.","error-invalid-seed":"Error: The seed is not valid. Please be sure to enter the correct words in the correct order.","error-wrong-seed":"Error: The seed is valid but does not match the one in the device."},added:{title:"New Hardware Wallet",configuring:"New hardware wallet detected. Configuring...",done:"Done",added1:"The connected hardware wallet has been added to the wallets list with the following name:",added2:"Now you can check the balance and the addresses of the hardware wallet even when it is not connected. Additionally, you can change the name of the wallet or remove it from the wallets list, if you wish."},wipe:{warning:"WARNING: All the data in the hardware wallet will be deleted. If you do not have a backup, you will not be able to access your funds again.","confirm-delete":"Also remove from the wallets list"},"create-backup":{warning:'WARNING: You can only use this option to backup your hardware wallet seed once. If you decide to continue, you will have to write down a group of words (it is recommended to do it on paper and not on a computer) that will appear on the screen of the hardware wallet and store the list in a safe place. Anyone with access to the word list (the "seed") will be able access the wallet balance, so extreme caution is advised.',instructions:"Write down the word list that appear on the screen of the hardware wallet. Make sure you respect the order and write each word correctly."},"seed-word":{title:"Enter word",info1:"Enter the word indicated in the device",info2:"You will be asked to enter the words of your backup seed in random order, plus a few additional words.",word:"Requested word","error-invalid-word":"The entered word is not valid.","error-loading-words":"Loading the word list. Please wait."},"change-pin":{"pin-mismatch":"Unable to perform the operation. Two PINs you have entered do not match."},"enter-pin":{title:"Enter PIN","title-change-current":"Enter the current PIN","title-change-new":"Enter the new PIN","title-change-confirm":"Confirm the new PIN",instructions:"The PIN layout is displayed on the hardware wallet screen.","instructions-tx":"Enter the PIN to confirm and sign the transaction.","instructions-change":"Please enter a hard-to-guess PIN of between 4 and 8 numbers.",help:"Need help?"},"pin-help":{title:"Help",part1:"When it is necessary to enter the PIN to continue, the hardware wallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol #.",part2:'To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the hardware wallet and press the corresponding buttons in the software wallet. For example, if the PIN is "23" and the number 2 is in the upper left, number 3 in the middle of the hardware wallet numbers matrix, press the upper left and middle button in that order in the software wallet.',part3:'If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is "23", you can not simply type "23" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the hardware wallet.'},"create-tx":{title:"Create transaction"},"confirm-address":{title:"Confirm address",instructions:"Please confirm on the hardware wallet if the address is:","short-confirmation":"Address confirmed.",confirmation:'Address confirmed. For security, you can re-show the address in the hardware wallet using the "Confirm address" option, in the menu that you can display by pressing the button at the right of the address balance.'}},"time-from-now":{"few-seconds":"a few seconds ago",minute:"one minute ago",minutes:"{{time}} minutes ago",hour:"one hour ago",hours:"{{time}} hours ago",day:"one day ago",days:"{{time}} days ago"},exchange:{"you-send":"You send","you-get":"You get (approx.)","to-address":"To {{coin}} address",price:"Exchange rate","time-15":"Exchange time","exchange-button":"Exchange","min-amount":"Minimum amount:","max-amount":"Maximum amount:","agree-1":"I agree with","agree-2":"Terms of Use","agree-3":"and","agree-4":"Privacy Policy","powered-by":"Powered by","need-help":"Need help?","support-portal":"Support portal",history:"Order history","order-not-found":"Order not found",status:"Status",exchanging:"Exchanging {{from}} for {{to}}",select:"Select",offline:"Exchange is temporarily offline","problem-connecting":"Unable to connect with the service. Please check your Internet connection and try again later.","invalid-address":"Invalid address.",statuses:{"user-waiting":"Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below","user-waiting-info":"The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.","market-waiting-confirmations":"Waiting for transaction confirmations","market-waiting-confirmations-info":"The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.","market-confirmed":"Transaction accepted","market-confirmed-info":"The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.","market-exchanged":"Traded {{from}} for {{to}}","market-exchanged-info":"The exchange has been made. The funds will be transferred to your address in a moment.","market-withdraw-waiting":"Sending {{to}} to your address","market-withdraw-waiting-info":"The process for sending the coins to your address has been initiated.",complete:"Exchange completed!","complete-info":"The funds have been successfully sent to your address.",error:"Error occurred","error-info":"There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page."},"history-window":{address:"Address",date:"Date"},details:{"exchange-addr":"Exchange address","exchange-addr-tag":"Payment ID or Destination Tag which must be used for the transaction","tx-id":"Transaction ID","order-id":"Order ID","initial-price":"Initial exchange rate","error-msg":"Error message",details:"Details","start-date":"Start date",back:"Back","back-alert":'The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the "Order history" button'}}}}}); \ No newline at end of file diff --git a/src/gui/static/dist/3rdpartylicenses.txt b/src/gui/static/dist/3rdpartylicenses.txt new file mode 100644 index 0000000..4041b94 --- /dev/null +++ b/src/gui/static/dist/3rdpartylicenses.txt @@ -0,0 +1,362 @@ +moment@2.21.0 +MIT +Copyright (c) JS Foundation and other contributors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +webpack@3.11.0 +MIT +Copyright JS Foundation and other contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +base64-js@1.2.3 +MIT +The MIT License (MIT) + +Copyright (c) 2014 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +buffer@4.9.1 +MIT +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh, and other contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +base-x@3.0.5 +MIT +The MIT License (MIT) + +Copyright (c) 2018 base-x contributors +Copyright (c) 2014-2018 The Bitcoin Core developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +@angular/core@5.2.0 +MIT +MIT + +safe-buffer@5.1.1 +MIT +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +@ngx-translate/core@9.1.1 +MIT +MIT + +hammerjs@2.0.8 +MIT +The MIT License (MIT) + +Copyright (C) 2011-2014 by Jorik Tangelder (Eight Media) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +isarray@1.0.0 +MIT +MIT + +ieee754@1.1.8 +BSD-3-Clause +Copyright (c) 2008, Fair Oaks Labs, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +bignumber.js@7.2.1 +MIT +MIT + +@angular/common@5.2.0 +MIT +MIT + +@angular/platform-browser@5.2.0 +MIT +MIT + +@angular/http@5.2.0 +MIT +MIT + +@angular/cdk@5.0.4 +MIT +The MIT License + +Copyright (c) 2017 Google LLC. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +@angular/material@5.0.4 +MIT +The MIT License + +Copyright (c) 2017 Google LLC. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +@angular/forms@5.2.0 +MIT +MIT + +@angular/animations@5.2.0 +MIT +MIT + +@angular/router@5.2.0 +MIT +MIT + +@angular/platform-browser-dynamic@5.2.0 +MIT +MIT + +core-js@2.5.3 +MIT +Copyright (c) 2014-2017 Denis Pushkarev + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +zone.js@0.8.20 +MIT +The MIT License + +Copyright (c) 2016 Google, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +bootstrap@4.0.0-beta.3 +MIT +The MIT License (MIT) + +Copyright (c) 2011-2017 Twitter, Inc. +Copyright (c) 2011-2017 The Bootstrap Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/src/gui/static/dist/4.7f8f58ff3f30291666bf.chunk.js b/src/gui/static/dist/4.7f8f58ff3f30291666bf.chunk.js new file mode 100644 index 0000000..c615150 --- /dev/null +++ b/src/gui/static/dist/4.7f8f58ff3f30291666bf.chunk.js @@ -0,0 +1 @@ +webpackJsonp([4],{"/YBz":function(e,a){e.exports={common:{"coin-id":"SKY","coin-hours":"Coin Hours",usd:"USD",loading:"Cargando...",new:"Nueva",load:"Cargar"},errors:{error:"Error","fetch-version":"No ha sido posible verificar la \xfaltima versi\xf3n desde Github","incorrect-password":"Contrase\xf1a incorrecta","error-decrypting":"Error al desencriptar la billetera","api-disabled":"API desabilitada","no-wallet":"La billetera no existe","no-outputs":"No hay salidas no gastadas","window-size":"La ventana es demasiado estrecha para el contenido"},title:{language:"Seleccionar Lenguaje",wallets:"Billeteras",send:"Enviar",history:"Historial","buy-coin":"Comprar Skycoins",network:"Red",blockchain:"Blockchain",outputs:"Salidas",transactions:"Transacciones","pending-txs":"Transacciones Pendientes",backup:"Respaldar Billetera",explorer:"Explorador de Skycoin",seed:"Semilla de la Billetera",qrcode:"C\xf3digo QR",reset:"Restablecer contrase\xf1a",exchange:"Intercambiar","select-address":"Seleccionar Direcci\xf3n","order-history":"Historial de \xf3rdenes"},header:{"syncing-blocks":"Sincronizando bloques",update1:"La actualizaci\xf3n",update2:"est\xe1 disponible.",synchronizing:"El nodo est\xe1 sincronizando. Los datos mostrados pueden estar desactualizados.","pending-txs1":"Hay una o m\xe1s","pending-txs2":"transacciones pendientes.","pending-txs3":"Los datos mostrados pueden estar desactualizados.",errors:{"no-connections":"Sin conexiones activas, \xa1el cliente no est\xe1 conectado a otros nodos!","no-backend1":"Sin acceso al servidor. Por favor, reinicie la aplicaci\xf3n y/o cont\xe1ctenos v\xeda","no-backend2":"Telegram.","no-backend3":"",csrf:"Vulnerabilidad de seguridad: CSRF no funciona. Por favor, salga de inmediato."}},password:{title:"Introduzca Su Contrase\xf1a",label:"Contrase\xf1a","confirm-label":"Confirmar contrase\xf1a",button:"Continuar","reset-link":"He olvidado mi contrase\xf1a"},buy:{"deposit-address":"Seleccione una direcci\xf3n para la cual generar un enlace de dep\xf3sito BTC:","select-address":"Seleccione una direcci\xf3n",generate:"Generar","deposit-location":"Localizaci\xf3n de Dep\xf3sito","deposit-location-desc":"Seleccione la billetera en la que desea que le depositemos sus Skycoins despu\xe9s de recibir los Bitcoins.","make-choice":"Realice una selecci\xf3n","wallets-desc":"Una nueva direcci\xf3n BTC es generada cada vez que se selecciona una nueva billetera y direcci\xf3n. Una \xfanica direcci\xf3n de Skycoin puede tener asignadas hasta 5 direcciones BTC.",send:"Enviar Bitcoins","send-desc":"Env\xede Bitcoins a la direcci\xf3n abajo indicada. Al recibirlos, le depositaremos los Skycoins en una nueva direcci\xf3n en la billetera seleccionada m\xe1s arriba, a la tasa de cambio actual de {{ rate }} SKY/BTC.","fraction-warning":"\xa1Env\xede s\xf3lo m\xfaltiplos de la tasa SKY/BTC! Los Skycoins son enviados en n\xfameros enteros, \xa1no se env\xedan fracciones de SKY!",receive:"Recibir SKY","receive-desc":"Despu\xe9s de recibir los Bitcoins, le enviaremos sus Skycoins. El tiempo de espera para recibir sus SKY puede ser de entre 20 minutos y una hora.","status-button":"Estatus:","check-status-button":"Revisar Estatus","new-order-button":"Nueva Orden"},wizard:{"wallet-desc":'Si no tiene una billetera, use la semilla generada autom\xe1ticamente para crear una nueva. Si ya tiene una billetera, seleccione "Cargar" e introduzca su semilla.',"encrypt-desc":"Incremente la seguridad de su billetera encript\xe1ndola. Al introducir una contrase\xf1a m\xe1s abajo, su billetera ser\xe1 encriptada. S\xf3lo quien tenga la contrase\xf1a podr\xe1 acceder a la billetera y retirar fondos.","hardware-wallet-link":"\xbfUtilizando una billetera de hardware?","finish-button":"Finalizar","back-button":"Volver",confirm:{title:"\xa1Resguarde su semilla!",desc:"Queremos asegurarnos de que ha anotado su semilla y la ha almacenado en un lugar seguro. \xa1Si olvida su semilla, NO podr\xe1 recuperar su billetera!",checkbox:"Est\xe1 segura, lo garantizo.",button:"Continuar"}},wallet:{"new-address":"Nueva Direcci\xf3n","new-addresses":"Nuevas Direcciones","show-empty":"Mostrar Vac\xedas","hide-empty":"Ocultar Vac\xedas",encrypt:"Encriptar Billetera",decrypt:"Desencriptar Billetera","decrypt-warning":"Advertencia: por razones de seguridad, no se recomienda mantener las carteras desencriptadas. Se aconseja precauci\xf3n.",delete:"Borrar Billetera",edit:"Editar Billetera",add:"Agregar Billetera",load:"Cargar Billetera","encryption-enabled":"Encriptado habilitado","encryption-disabled":"Encriptado deshabilitado","hw-security-warning":'Posible riesgo de seguridad. Acceda a las opciones de la billetera de hardware (presionando el bot\xf3n "Billetera de Hardware" debajo de la lista de billeteras) mientras el dispositivo est\xe1 conectado, para m\xe1s informaci\xf3n.',wallet:"Billetera","hardware-wallet":"Billetera de Hardware","delete-confirmation":'ADVERTENCIA: la billetera "{{ name }}" ser\xe1 removida de la lista. Para agregarla nuevamente, deber\xe1 volver a conectar el dispositivo y abrir las opciones de la billetera del hardware (presionando el bot\xf3n "Billetera de hardware" debajo de la lista de las billeteras). \xbfDesea continuar?',"delete-confirmation-check":"S\xed, quiero borrar la billetera.","max-hardware-wallets-error":"Ya ha alcanzado el n\xfamero m\xe1ximo de direcciones que se puede agregar a la billetera de hardware.","add-many-confirmation":"ADVERTENCIA: si agrega demasiadas direcciones sin usar las anteriores o si usa las \xfaltimas y no las primeras, es posible que algunas direcciones no se recuperen autom\xe1ticamente si intenta restaurar la billetera con la semilla (tendr\xe1 que agregarlas manualmente). \xbfDesea continuar?",new:{"create-title":"Crear Billetera","load-title":"Cargar Billetera","encrypt-title":"Encriptar la billetera","name-label":"Nombre","seed-label":"Semilla","confirm-seed-label":"Confirmar semilla","seed-warning":"\xa1Recuerde esta semilla! Mant\xe9ngala en un lugar seguro. \xa1Si olvida su semilla, no podr\xe1 recuperar la billetera!","create-button":"Crear","load-button":"Cargar","cancel-button":"Cancelar","12-words":"12 palabras","24-words":"24 palabras","generate-12-seed":"Generar una semilla de 12 palabras","generate-24-seed":"Generar una semilla de 24 palabras",encrypt:"Encriptar billetera","encrypt-warning":"Le sugerimos que encripte con una contrase\xf1a cada una de sus billeteras. Si olvida su contrase\xf1a, puede restaurarla con la semilla. Aseg\xfarese de guardar su semilla en un lugar seguro antes de encriptar la billetera.","unconventional-seed-title":"Posible error","unconventional-seed-text":"Usted introdujo una semilla no convencional. Si lo hizo por alguna raz\xf3n en especial, puede continuar (s\xf3lo recomendable para usuarios avanzados). Sin embargo, si su intenci\xf3n es utilizar una semilla normal del sistema, usted debe borrar los textos y/o caracteres especiales adicionales.","unconventional-seed-check":"Continuar con la semilla no convencional."},rename:{title:"Renombrar Billetera","name-label":"Nombre","cancel-button":"Cancelar","rename-button":"Renombrar"},"add-addresses":{title:"Seleccionar cantidad","name-quantity":"Cantidad de direcciones a crear","cancel-button":"Cancelar","create-button":"Crear"},address:{show:"Presione para mostrar",copy:"Copiar","copy-address":"Copiar Direcci\xf3n",copied:"\xa1Copiado!",confirm:"Confirmar Direcci\xf3n",outputs:"Salidas No Gastadas",history:"Historial"}},send:{"synchronizing-warning":"La billetera todav\xeda est\xe1 sincronizando los datos, por lo que el saldo que se muestra puede ser incorrecto. \xbfSeguro de que desea continuar?","from-label":"Enviar desde","to-label":"Enviar a","amount-label":"Cantidad","notes-label":"Notas","wallet-label":"Billetera","addresses-label":"Direcci\xf3n","invalid-amount":"Por favor introduzca una cantidad v\xe1lida","addresses-help":"Limite las direcciones desde donde se podr\xedan enviar las monedas y las horas","all-addresses":"Todas las direcciones de la billetera seleccionada","outputs-label":"Salidas no gastadas","outputs-help":"Limite las salidas no gastadas desde donde se podr\xedan enviar las monedas y las horas. Solo se muestran las salidas de las direcciones seleccionadas.","all-outputs":"Todas las salidas no gastadas de las direcciones seleccionadas","available-msg-part1":"Con su selecci\xf3n actual puede enviar hasta","available-msg-part2":"y","available-msg-part3":"(al menos","available-msg-part4":"deben ser utilizadas para la tarifa de transacci\xf3n).","change-address-label":"Direcci\xf3n de retorno personalizada","change-address-select":"Seleccionar","change-address-help":'Direcci\xf3n para recibir el cambio. Si no se proporciona, ser\xe1 elegida autom\xe1ticamente. Haga clic en el enlace "Seleccionar" para elegir una direcci\xf3n de una de sus billeteras',"destinations-label":"Destinos","destinations-help1":"Direcciones de destino y sus monedas","destinations-help2":"Direcciones de destino, sus monedas y coin hours","hours-allocation-label":"Distribuci\xf3n autom\xe1tica de coin hours","options-label":"Opciones","value-label":"Factor de distribuci\xf3n de las coin hours","value-help":"Mientras mayor sea el valor, m\xe1s coin hours se enviar\xe1n a las salidas","preview-button":"Preview","send-button":"Enviar","back-button":"Volver",simple:"Simple",advanced:"Advanzado","select-wallet":"Seleccionar Billetera"},reset:{"wallet-label":"Billetera","seed-label":"Semilla de la billetera","password-label":"Nueva contrase\xf1a (deje en blanco si desea que la billetera no est\xe9 encriptada)","confirm-label":"Confirme la contrase\xf1a","reset-button":"Restaurar"},tx:{transaction:"Transacci\xf3n","confirm-transaction":"Confirmar Transacci\xf3n",from:"Desde",to:"A",date:"Fecha",status:"Estatus",coins:"Monedas",hours:"Horas",id:"Tx ID","show-more":"Mostrar m\xe1s","hours-moved":"movida(s)","hours-sent":"enviada(s)","hours-received":"recibida(s)","hours-burned":"quemada(s)",inputs:"Entradas",outputs:"Salidas",confirmed:"Confirmada",pending:"Pendiente","current-rate":"Calculado a la tasa actual"},backup:{"wallet-directory":"Directorio de la Billetera:","seed-warning":"RESPALDE SU SEMILLA. EN PAPEL. EN UN LUGAR SEGURO. Mientras tenga su semilla, podr\xe1 recuperar las monedas.",desc:"Use la tabla de m\xe1s abajo para obtener las semillas de sus billeteras encriptadas.
Para obtener las semillas de las billeteras no encriptadas, abra el directorio de m\xe1s arriba, abra los archivos .wlt en un editor de texto y recupere las semillas.","close-button":"Cerrar",wallet:"Nombre de la Billetera",filename:"Archivo",seed:"Semilla","show-seed":"Mostrar semilla","no-wallets":"No hay billeteras encriptadas"},blockchain:{blocks:"Cantidad de bloques",time:"Fecha del \xfaltimo bloque",hash:"Hash del \xfaltimo bloque","current-supply":"Suministro de SKY actual","total-supply":"Suministro de SKY total","current-coinhour-supply":"Suministro de Coin Hours actual","total-coinhour-supply":"Suministro de Coin Hours total"},network:{peer:"Par",source:"Fuente","block-height":"Altura del bloque","block-height-short":"Bloque","last-seen":"\xdaltima vez visto","last-received":"\xdaltima recepci\xf3n","last-sent":"\xdaltimo env\xedo",in:"Entrante",out:"Saliente",sources:{default:"Par por defecto",exchange:"Intercambio de pares"}},"pending-txs":{timestamp:"Fecha",txid:"ID de la transacci\xf3n",none:"Actualmente no hay transacciones pendientes",my:"M\xedas",all:"Todas"},history:{"tx-detail":"Detalles de la Transacci\xf3n",moving:"Moviendo internamente",moved:"Movida internamente",sending:"Enviando",sent:"Enviada",received:"Recibida",receiving:"Recibiendo",pending:"Pendiente","no-txs":"Usted no tiene historial de transacciones","no-txs-filter":"No hay transacciones que coincidan con los criterios de filtro actuales","no-filter":"Sin filtros activos (Presione para seleccionar billeteras/direcciones)",filter:"Filtro activo: ",filters:"Filtros activo: ","all-addresses":"Todas las direcciones"},teller:{done:"Completado","waiting-confirm":"Esperando confirmaci\xf3n","waiting-deposit":"Esperando dep\xf3sito de Bitcoins","waiting-send":"Esperando para env\xedar Skycoins",unknown:"Desconocido"},confirmation:{"header-text":"Confirmaci\xf3n","confirm-button":"S\xed","cancel-button":"No",close:"Cerrar"},service:{api:{"server-error":"Error de servidor"},wallet:{"not-enough-hours":"\xa1No cuenta con suficientes Coin Hours para realizar la operaci\xf3n!"}},"hardware-wallet":{general:{"default-wallet-name":"Nueva billetera de hardware","error-disconnected":"No se puede realizar la operaci\xf3n. La billetera de hardware no est\xe1 conectada.","simple-error":"Error, no se puede realizar la operaci\xf3n.","generic-error":"No se puede realizar la operaci\xf3n. Aseg\xfarese de haber conectado una billetera de hardware v\xe1lida y de que no est\xe9 esperando por alguna confirmaci\xf3n o respuesta.","generic-error-internet":"No se puede realizar la operaci\xf3n. Aseg\xfarese de haber conectado una billetera de hardware v\xe1lida que no est\xe9 esperando por alguna confirmaci\xf3n o respuesta y de que su equipo cuente con conexi\xf3n a internet y al nodo.","error-incorrect-wallet":"No se puede realizar la operaci\xf3n. La billetera de hardware conectada es diferente a la esperada.","error-incorrect-pin":"No se puede realizar la operaci\xf3n. El PIN que ha introducido no es correcto.",confirm:"Por favor, confirme la operaci\xf3n en la billetera de hardware.","confirm-and-more":"Por favor, confirme la operaci\xf3n en la billetera de hardware y siga las instrucciones.",close:"Cerrar",cancel:"Cancelar",continue:"Continuar",completed:"La operaci\xf3n se realiz\xf3 con \xe9xito.",refused:"La operaci\xf3n fall\xf3 o fue cancelada."},errors:{"too-many-inputs":"La transacci\xf3n tiene demasiadas entradas y no se puede procesar. Por favor, p\xf3ngase en contacto con el soporte t\xe9cnico.","too-many-outputs":"La transacci\xf3n tiene demasiadas salidas y no se puede procesar. Por favor, p\xf3ngase en contacto con el soporte t\xe9cnico."},"security-warning":{title:"Advertencia de seguridad",text:'La \xfaltima vez que se conect\xf3 esta billetera de hardware, se encontraron una o m\xe1s advertencias de seguridad. Le recomendamos que abra las opciones de billetera de hardware (presionando el bot\xf3n "Billetera de hardware" debajo de la lista de billeteras) mientras el dispositivo est\xe1 conectado y resuelva los problemas de seguridad antes de continuar.',check:"Entiendo los riesgos y deseo continuar.",continue:"Continuar",cancel:"Cancelar"},options:{connecting:"Conectando...",disconnected:"Billetera de hardware no detectada. Por favor, conecte una billetera de hardware para usar esta opci\xf3n.","unconfigured-detected-title":"Billetera de hardware no configurada","unconfigured-detected":'Se ha detectado una billetera de hardware sin semilla. Seleccione "Configurar autom\xe1ticamente" si desea configurarla como una billetera nueva y comenzar a usarla inmediatamente, o seleccione "Restaurar una copia de seguridad" si desea configurarla con la copia de seguridad de una semilla creada anteriormente y as\xed poder acceder a sus fondos de nuevo.',"configured-detected":"Billetera de hardware detectada. El dispositivo se identifica en la lista de billeteras como:","security-warnings-title":"Advertencias de seguridad","security-warning-title":"Advertencia de seguridad","backup-warning":'Debe hacer una copia de seguridad de la semilla de la billetera de hardware o podr\xeda perder acceso a los fondos en caso de problemas. Para hacer esto, seleccione la opci\xf3n "Crear copia de seguridad".',"pin-warning":'La billetera de hardware conectada no tiene un PIN. El c\xf3digo PIN protege la billetera de hardware en caso de p\xe9rdida, robo y pirateo. Para crear un c\xf3digo PIN, seleccione la opci\xf3n "Crear c\xf3digo PIN".',options:"Opciones:","configure-automatically":"Configurar autom\xe1ticamente","restore-backup":"Restaurar una copia de seguridad","create-backup":"Crear copia de seguridad",wipe:"Borrar el dispositivo","confirm-seed":"Confirmar la semilla","create-pin":"Crear c\xf3digo PIN","change-pin":"Cambiar el c\xf3digo PIN","forgotten-pin1":"Si no puede acceder a la billetera porque ha olvidado el PIN, puede borrar la billetera del hardware y luego restaurarla con la semilla haciendo clic","forgotten-pin2":"aqu\xed."},"generate-seed":{text:"Antes de continuar, puede seleccionar el n\xfamero de palabras que desea que tenga la semilla. La semilla es una lista de palabras que se pueden usar para recuperar el acceso a las monedas en caso de problemas. Ambos valores son seguros, por lo que si no tiene una raz\xf3n especial para seleccionar uno u otro, puede dejar el valor predeterminado.",configuring:"Configurando..."},"restore-seed":{text:"Antes de continuar, por favor seleccione la cantidad de palabras de la semilla que desea recuperar.","check-text":"Puede usar esta opci\xf3n para ingresar una semilla y verificar si es igual a la de la billetera de hardware. Antes de comenzar, seleccione el n\xfamero de palabras de la semilla que desea verificar.",warning:"ADVERTENCIA: para evitar posibles problemas, use solo semillas creadas con una billetera de hardware de la misma marca/modelo.","error-wrong-word":"Error: la palabra introducida no coincide con la solicitada por la billetera de hardware.","error-invalid-seed":"Error: La semilla no es v\xe1lida. Por favor, aseg\xfarese de ingresar las palabras correctas en el orden correcto.","error-wrong-seed":"Error: la semilla es v\xe1lida pero no coincide con la del dispositivo."},added:{title:"Nueva Billetera de Hardware",configuring:"Nueva billetera de hardware detectada. Configurando...",done:"Hecho",added1:"La billetera de hardware conectada se ha agregado a la lista de billeteras con el siguiente nombre:",added2:"Ahora puede consultar el saldo y las direcciones de la billetera de hardware incluso cuando no est\xe1 conectada. Adem\xe1s, puede cambiar el nombre de la billetera o eliminarla de la lista de billeteras, si lo desea."},wipe:{warning:"ADVERTENCIA: Todos los datos en la billetera de hardware ser\xe1n eliminados. Si no tiene una copia de seguridad, no podr\xe1 volver a acceder a sus fondos.","confirm-delete":"Quitar tambi\xe9n de la lista de billeteras."},"create-backup":{warning:'ADVERTENCIA: Solo puede usar esta opci\xf3n para hacer una copia de seguridad de la semilla de su billetera de hardware una vez. Si decide continuar, tendr\xe1 que escribir un grupo de palabras (se recomienda hacerlo en papel y no en una computadora) que aparecer\xe1n en la pantalla de la billetera de hardware y almacenar la lista en un lugar seguro. Cualquier persona con acceso a la lista de palabras (la "semilla") podr\xe1 acceder a los fondos de la cartera, por lo que se recomienda extremar las precauciones.',instructions:"Escriba la lista de palabras que aparecen en la pantalla de la billetera de hardware. Aseg\xfarate de respetar el orden y escribir cada palabra correctamente."},"seed-word":{title:"Ingresar palabra",info1:"Introduzca la palabra indicada en el dispositivo",info2:"Se le pedir\xe1 que ingrese las palabras de su semilla de respaldo en orden aleatorio, m\xe1s algunas palabras adicionales.",word:"Palabra solicitada","error-invalid-word":"La palabra introducida no es v\xe1lida.","error-loading-words":"Cargando la lista de palabras. Por favor espere."},"change-pin":{"pin-mismatch":"No se puede realizar la operaci\xf3n. Los dos PIN que ha introducido no coinciden."},"enter-pin":{title:"Ingresar PIN","title-change-current":"Ingrese el PIN actual","title-change-new":"Ingrese el nuevo PIN","title-change-confirm":"Confirme el nuevo PIN",instructions:"El patr\xf3n de n\xfameros del PIN se muestra en la pantalla de la billetera de hardware.","instructions-tx":"Introduzca el PIN para confirmar y firmar la transacci\xf3n.","instructions-change":"Ingrese un PIN dif\xedcil de adivinar de entre 4 y 8 n\xfameros.",help:"\xbfNecesita ayuda?"},"pin-help":{title:"Ayuda",part1:"Cuando sea necesario ingresar el PIN para continuar, la pantalla de la billetera del hardware mostrar\xe1 una matriz de 9 casillas con n\xfameros en orden aleatorio (el orden cambia cada vez) y se le pedir\xe1 que ingrese el PIN en la billetera de software usando una matriz de 9 botones que simplemente muestran el s\xedmbolo #.",part2:'Para ingresar el PIN, mire la posici\xf3n de los n\xfameros del PIN en la matriz de n\xfameros en la pantalla de la billetera de hardware y presione los botones correspondientes en la billetera de software. Por ejemplo, si el PIN es "23", el n\xfamero 2 est\xe1 en la esquina superior izquierda y el n\xfamero 3 en el centro de la matriz de n\xfameros de billetera de hardware, presione los botones superior izquierdo y central, en ese orden, en la billetera de software.',part3:'Si lo desea, tambi\xe9n puede usar el teclado num\xe9rico para ingresar el PIN. Sin embargo, como en el ejemplo anterior, si el PIN es "23", no puede simplemente escribir "23" con el teclado num\xe9rico, sino que deber\xe1 presionar las teclas que est\xe1n en la posici\xf3n donde est\xe1n los n\xfameros 2 y 3 en la pantalla de la billetera de hardware.'},"create-tx":{title:"Crear transacci\xf3n"},"confirm-address":{title:"Confirmar direcci\xf3n",instructions:"Por favor confirme en la billetera de hardware si la direcci\xf3n es:","short-confirmation":"Direcci\xf3n confirmada.",confirmation:'Direcci\xf3n confirmada. Por seguridad, puede volver a mostrar la direcci\xf3n en la billetera de hardware usando la opci\xf3n "Confirmar direcci\xf3n", en el men\xfa que puede mostrar presionando el bot\xf3n a la derecha del balance de la direccion.'}},"time-from-now":{"few-seconds":"hace pocos segundos",minute:"hace un minuto",minutes:"hace {{time}} minutos",hour:"hace una hora",hours:"hace {{time}} horas",day:"hace un d\xeda",days:"hace {{time}} d\xedas"},exchange:{"you-send":"Usted env\xeda","you-get":"Usted recibe (aprox.)","to-address":"A la direcci\xf3n de {{coin}}",price:"Tasa de cambio","time-15":"Duraci\xf3n del intercambio","exchange-button":"Intercambiar","min-amount":"Monto minimo:","max-amount":"Monto maximo:","agree-1":"Acepto los","agree-2":"T\xe9rminos de Uso","agree-3":"y la ","agree-4":"Pol\xedtica de Privacidad","powered-by":"Manejado por","need-help":"\xbfNecesita ayuda?","support-portal":"Portal de soporte",history:"Historial de \xf3rdenes","order-not-found":"Orden no encontrada",status:"Estado",exchanging:"Intercambiando {{from}} por {{to}}",select:"Seleccionar",offline:"El servicio est\xe1 temporalmente offline","problem-connecting":"No se puede conectar con el servicio. Por favor, compruebe su conexi\xf3n a Internet y vuelva a intentarlo m\xe1s tarde.","invalid-address":"Direcci\xf3n inv\xe1lida.",statuses:{"user-waiting":"Esperando el deposito. Por favor, env\xede {{amount}} {{from}} a la direcci\xf3n de intercambio indicada m\xe1s abajo","user-waiting-info":"El sistema est\xe1 a la espera de que realice el dep\xf3sito en la direcci\xf3n de intercambio. El proceso de intercambio comenzar\xe1 despu\xe9s de que se detecte el dep\xf3sito y sea confirmado en la cadena de bloques. Si ya ha realizado el dep\xf3sito, deber\xeda ser detectado en breve.","market-waiting-confirmations":"Esperando las confirmaciones de la transacci\xf3n","market-waiting-confirmations-info":"El dep\xf3sito ya ha sido detectado y el sistema est\xe1 esperando que sea confirmado en la cadena de bloques.","market-confirmed":"Transacci\xf3n aceptada","market-confirmed-info":"La transacci\xf3n ya ha sido confirmada en la cadena de bloques. Haciendo los preparativos para realizar el intercambio pronto.","market-exchanged":"{{from}} intercambiado por {{to}}","market-exchanged-info":"El intercambio se ha realizado. Los fondos ser\xe1n transferidos a su direcci\xf3n en un momento.","market-withdraw-waiting":"Enviando {{to}} a su direcci\xf3n","market-withdraw-waiting-info":"Se ha iniciado el proceso para enviar las monedas a su direcci\xf3n.",complete:"\xa1Intercambio completado!","complete-info":"Los fondos han sido enviados con \xe9xito a su direcci\xf3n.",error:"Se produjo un error","error-info":"Hubo un error en la operaci\xf3n, puede encontrar m\xe1s informaci\xf3n m\xe1s abajo. Si necesita ayuda, por favor guarde todos los datos de operaci\xf3n que se muestran m\xe1s abajo y comun\xedquese con soporte t\xe9cnico utilizando el enlace que se encuentra en la parte inferior derecha de esta p\xe1gina."},"history-window":{address:"Direcci\xf3n",date:"Fecha"},details:{"exchange-addr":"Direcci\xf3n de intercambio","exchange-addr-tag":"Payment ID o Destination Tag que debe usarse para la transacci\xf3n","tx-id":"ID de la transacci\xf3n","order-id":"ID de la orden","initial-price":"Tasa de cambio inicial","error-msg":"Mensaje de error",details:"Detalles","start-date":"Fecha de inicio",back:"Volver","back-alert":'La operaci\xf3n a\xfan est\xe1 en progreso. \xbfRealmente desea volver al formulario? Puede ver el progreso de esta operaci\xf3n nuevamente presionando el bot\xf3n "Historial de pedidos"'}}}}}); \ No newline at end of file diff --git a/src/gui/static/dist/5.a2cdc3b5d1d15440fa16.chunk.js b/src/gui/static/dist/5.a2cdc3b5d1d15440fa16.chunk.js new file mode 100644 index 0000000..ebd2dda --- /dev/null +++ b/src/gui/static/dist/5.a2cdc3b5d1d15440fa16.chunk.js @@ -0,0 +1 @@ +webpackJsonp([5],{TKku:function(e,t){e.exports={common:{"coin-id":"SKY","coin-hours":"Coin Hours",usd:"USD",loading:"Loading...",new:"New",load:"Load",success:"Success",warning:"Warning","changes-made":"The changes have been made."},errors:{error:"Error","fetch-version":"Unable to fetch latest release version from Github","incorrect-password":"Incorrect password","error-decrypting":"Error decrypting the wallet","api-disabled":"API disabled","no-wallet":"Wallet does not exist","no-outputs":"No unspent outputs","window-size":"The window is too narrow for the content"},title:{language:"Select Language",wallets:"Wallets",send:"Send",history:"History","buy-coin":"Buy Skycoin",network:"Networking",blockchain:"Blockchain",outputs:"Outputs",transactions:"Transactions","pending-txs":"Pending Transactions",backup:"Backup Wallet",explorer:"Skycoin Explorer",seed:"Wallet Seed",reset:"Reset Password",exchange:"Exchange","select-address":"Select Address","order-history":"Order history"},header:{"syncing-blocks":"Syncing blocks",update1:"Wallet update",update2:"available.",synchronizing:"The wallet is synchronizing. Data you see may not be updated.","pending-txs1":"There are some","pending-txs2":"pending transactions.","pending-txs3":"Data you see may not be updated.",errors:{"no-connections":"No connections active, your client is not connected to any other nodes!","no-backend1":"Cannot reach backend. Please restart the app and/or seek help on our","no-backend2":"Telegram.","no-backend3":"",csrf:"Security vulnerability: CSRF is not working, please exit immediately."}},password:{title:"Enter Password",label:"Password","confirm-label":"Confirm password",button:"Proceed","reset-link":"I forgot my password"},buy:{"deposit-address":"Choose an address to generate a BTC deposit link for:","select-address":"Select address",generate:"Generate","deposit-location":"Deposit Location","deposit-location-desc":"Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.","make-choice":"Make a choice","wallets-desc":"Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.",send:"Send Bitcoin","send-desc":"Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.","fraction-warning":"Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!",receive:"Receive Sky","receive-desc":"After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.","status-button":"Status:","check-status-button":"Check Status","new-order-button":"New Order"},wizard:{"wallet-desc":'If you don\'t have a Skycoin wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to "Load Wallet" and enter your seed.',"encrypt-desc":"Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.","hardware-wallet-link":"Using a Skywallet?","finish-button":"Finish","back-button":"Back",confirm:{title:"Safeguard your seed!",desc:"We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your Skycoin wallet!",checkbox:"It\u2019s safe, I swear.",button:"Continue"}},wallet:{"new-address":"New Address","new-addresses":"New Addresses","show-empty":"Show Empty","hide-empty":"Hide Empty",encrypt:"Encrypt Wallet",decrypt:"Decrypt Wallet","decrypt-warning":"Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.",delete:"Delete Wallet",edit:"Edit Wallet",add:"Add Wallet",load:"Load Wallet","encryption-enabled":"Encryption enabled","encryption-disabled":"Encryption disabled","hw-security-warning":'Possible security risk. Access the Skywallet options (by pressing the "Skywallet" button below the wallets list) while the device is connected for more information.',wallet:"Wallet","hardware-wallet":"Skywallet","delete-confirmation":'WARNING: The wallet "{{ name }}" will be removed from the list. To add it again, you will have to reconnect the device and open the Skywallet options (by pressing the "Skywallet" button below the wallets list). Do you want to continue?',"delete-confirmation-check":"Yeah, I want to delete the wallet.","max-hardware-wallets-error":"You have already reached the max number of addresses that can be added to the Skywallet.","add-many-confirmation":"WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?",new:{"create-title":"Create Wallet","load-title":"Load Wallet","encrypt-title":"Encrypt Wallet","name-label":"Name","words-number":"How many word the seed has","seed-label":"Seed","confirm-seed-label":"Confirm seed","seed-warning":"Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!","create-button":"Create","load-button":"Load","cancel-button":"Cancel","12-words":"12 words","24-words":"24 words","generate-12-seed":"Generate 12 word seed","generate-24-seed":"Generate 24 word seed",encrypt:"Encrypt wallet","encrypt-warning":"We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.","unconventional-seed-title":"Possible error","unconventional-seed-text":"You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.","unconventional-seed-check":"Continue with the unconventional seed.","synchronizing-warning-title":"Warning","synchronizing-warning-text":"The wallet is still synchronizing and some addresses may not be restored. If some addresses are not restored, please wait for the wallet to be fully synchronized and add them again manually.","synchronizing-warning-continue":"Continue","synchronizing-warning-cancel":"Cancel","wallet-created":"The wallet has been added to the list.",seed:{"enter-seed":"Press here to enter your seed.","change-seed":"Press to change","confirm-seed":"Press here to confirm your seed.","confirmed-seed":"Seed confirmed.","use-custom-seed":"Press here if you want to enter the seed manually.","use-normal-seed":"Press here if you want to enter the seed using the recommended method.","custom-seed-warning-title":"Warning","custom-seed-warning-text":"This option is only recommended for advanced users. Making mistakes with the seed could cause you to lose access to the funds in case of a problem.","custom-seed-warning-text-recovering":"To avoid possible problems, this option should only be used if you want to recover an unconventional seed.","custom-seed-warning-check":"I understand the risks and want to continue","custom-seed-warning-cancel":"Cancel","custom-seed-warning-continue":"Continue","incorrect-word":"The word you have entered does not match the requested one.","invalid-seed":"The seed you have entered is not valid. Please try again.","enter-word":"Enter the word #{{number}}","new-seed-help":"You must enter the words of the seed that was generated by the system, to confirm it.","recover-seed-help":"Please be sure to enter the correct words in the correct order."}},rename:{title:"Rename Wallet","name-label":"Name","cancel-button":"Cancel","rename-button":"Rename"},"add-addresses":{title:"Select quantity","name-quantity":"How many addresses to create","cancel-button":"Cancel","create-button":"Create",error:"There was an unexpected error. Please try again."},address:{show:"Press to show",copy:"Copy","copy-address":"Copy address",copied:"Copied!",confirm:"Confirm address",outputs:"Unspent outputs",history:"History"}},qr:{title:"QR Code","title-read-only":"QR Code",data:"QR Data:",address:"Address:","request-link":"Request specific amount",amount:"Request amount:",hours:"Request hours:",message:"Message:",invalid:"(invalid value)",copied:"The text has been copied to the clipboard."},send:{"synchronizing-warning":"The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?","from-label":"Send from","to-label":"Send to","amount-label":"Amount","personal-note-label":"Personal note","personal-note-help":"Use this field to add a text for allowing you to identify the transaction in the future. This text is saved locally, so it will only be visible from this computer","wallet-label":"Wallet","addresses-label":"Addresses","invalid-amount":"Please enter a valid amount","convert-confirmation":"Do you also want the already introduced amount to be converted from {{from}} to {{to}}?","convert-confirmation-plural":"Do you also want the already introduced amounts to be converted from {{from}} to {{to}}?","send-all-available-coins":"send all","no-wallet-selected":"You must select a wallet first.","precision-error-warning":"A precision error was detected during conversion. Please check the amount that will be sent.","invaid-amount-warning":"An invalid value was detected during conversion. Please check the amount that will be sent.","precision-errors-warning":"Precision errors were detected during conversion. Please check the amount that will be sent.","invaid-amounts-warning":"Invalid values were detected during conversion. Please check the amount that will be sent.","multiple-problems-warning":"Some values were not converted because they were invalid or could have been converted with precision errors. Please check the amount that will be sent.","no-coins-left":"There are no coins left to send.","addresses-help":"Limit the addresses from where the coins and hours could be sent","all-addresses":"All the addresses of the selected wallet","outputs-label":"Unspent outputs","outputs-help":"Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown","all-outputs":"All the outputs of the selected addresses","available-msg-part1":"With your current selection you can send up to","available-msg-part2":"and","available-msg-part3":"(at least","available-msg-part4":"must be used for the transaction fee).","change-address-label":"Custom change address","change-address-select":"Select","change-address-help":'Address to receive change. If it\'s not provided, it will be chosen automatically. Click on the "Select" link to choose an address from one of your wallets',"destinations-label":"Destinations","destinations-help1":"Destination addresses and their coins","destinations-help2":"Destination addresses, their coins and coin hours","hours-allocation-label":"Automatic coin hours allocation","options-label":"Options","value-label":"Coin hours share factor","value-help":"The higher the value, the more coin hours will be sent to the recipients and less will be retained","preview-button":"Preview","send-button":"Send","back-button":"Back",simple:"Simple",advanced:"Advanced","select-wallet":"Select Wallet","error-saving-note":"The transaction was successfully sent, but it was not possible to save the note.",sent:"Transaction successfully sent.",total:"Total:","bulk-send":{title:"Bulk Send",indications:'To send to multiple destinations in a quick way, type each address, coin amount and hour amount (optional) on a line, separated by a comma. Example: if you want to send 10 coins and 5 hours to the "xyz" address, type "xyz,10,5"; if you want the hours to be calculated automatically, type "xyz,10". Decimal values must be separated with a dot.',process:"Process","error-no-data":"There is no text to process.","error-inconsistent-data":"If you set how many hours you want to send to a destinations, you must do so for all destinations.","error-invalid-data":"The entered text has an invalid format."}},reset:{"wallet-label":"Wallet","seed-label":"Wallet seed","password-label":"New password (leave empty if you want the wallet not to be encrypted)","confirm-label":"Confirm new password","reset-button":"Reset",done:"Password successfully changed."},tx:{transaction:"Transaction","confirm-transaction":"Confirm Transaction",from:"From",to:"To",date:"Date",status:"Status",coins:"Coins",hours:"Hours",id:"Tx ID",note:"Note","without-note":"Without note","show-more":"Show more","hours-moved":"moved","hours-sent":"sent","hours-received":"received","hours-burned":"burned",inputs:"Inputs",outputs:"Outputs",confirmed:"Confirmed",pending:"Pending","current-rate":"Calculated at the current rate"},"edit-note":{title:"Edit note","cancel-button":"Cancel","change-button":"Change"},backup:{"wallet-directory":"Wallet Directory:","seed-warning":"BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.",desc:"Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.","close-button":"Close",wallet:"Wallet Label",filename:"Filename",seed:"Seed","show-seed":"Show seed","no-wallets":"No encrypted wallets"},blockchain:{blocks:"Number of blocks",time:"Timestamp of last block",hash:"Hash of last block","current-supply":"Current SKY supply","total-supply":"Total SKY supply","current-coinhour-supply":"Current Coin Hours supply","total-coinhour-supply":"Total Coin Hours supply"},network:{peer:"Peer",source:"Source","block-height":"Block height","block-height-short":"Block","last-seen":"Last seen","last-received":"Last received","last-sent":"Last sent",in:"Incoming",out:"Outgoing",sources:{default:"Default peer",exchange:"Peer exchange"}},"pending-txs":{timestamp:"Timestamp",txid:"Transaction ID",none:"No pending transactions",my:"Mine",all:"All"},history:{"tx-detail":"Transaction Detail",moving:"Internally moving",moved:"Internally moved",sending:"Sending",sent:"Sent",received:"Received",receiving:"Receiving",pending:"Pending",note:"Note","no-txs":"You have no transaction history","no-txs-filter":"There are no transactions matching the current filter criteria","no-filter":"No filter active (press to select wallets/addresses)",filter:"Active filter: ",filters:"Active filters: ","all-addresses":"All addresses"},teller:{done:"Completed","waiting-confirm":"Waiting for confirmation","waiting-deposit":"Waiting for Bitcoin deposit","waiting-send":"Waiting to send Skycoin",unknown:"Unknown"},confirmation:{"header-text":"Confirmation","confirm-button":"Yes","cancel-button":"No",close:"Close"},service:{api:{"server-error":"Server error"},wallet:{"not-enough-hours":"Not enough available Coin Hours to perform the transaction!"}},"hardware-wallet":{general:{"default-wallet-name":"New Skywallet","error-disconnected":"Unable to perform the operation. The Skywallet is not connected.","simple-error":"Error. Unable to perform the operation.","generic-error":"Unable to perform the operation. Make sure you have connected a valid Skywallet and that it is not waiting for input.","generic-error-internet":"Unable to perform the operation. Make sure you have connected a valid Skywallet that is not waiting for input and that you have a connection to the internet/node.","error-incorrect-wallet":"Unable to perform the operation. The connected Skywallet is different from the expected one.","error-incorrect-pin":"Unable to perform the operation. The PIN you have entered is incorrect.",confirm:"Please confirm the operation on the Skywallet.","confirm-and-more":"Please confirm the operation on the Skywallet and follow the instructions displayed.",follow:"Please follow the instructions displayed on the Skywallet.",close:"Close",cancel:"Cancel",continue:"Continue",completed:"Operation completed successfully.",refused:"The operation failed or was canceled.","name-updated":"The name used to identify this Skywallet in the wallet list has been updated to match the one shown on the device."},errors:{"too-many-inputs-outputs":"The transaction has too many inputs or outputs for the Skywallet. Please try again creating several smaller transactions, each one with a smaller number of recipients (if the current transaction has many) or coins.","daemon-connection":"Problem connecting to the Skywallet service.",timeout:"The operation was canceled due to inactivity. Please try again.","invalid-address-generated":"There was a problem with the address generator and the operation had to be canceled.","invalid-address":"Invalid address.","not-in-bootloader-mode":"To use this option the Skywallet must be in bootloader mode."},"security-warning":{title:"Security warning",text:"The last time this Skywallet was connected, one or more security warnings were found. We recommend that you open the Skywallet options (by pressing the link below) while the device is connected and solve the security problems before continuing.",link:"Open the Skywallet options window.",check:"I understand the risks and want to continue",continue:"Continue",cancel:"Cancel"},options:{connecting:"Connecting...",disconnected:"No Skywallet detected. Please connect a Skywallet to use this option.","unconfigured-detected-title":"Unconfigured Skywallet","unconfigured-detected":'A seedless Skywallet has been detected. Select "Configure automatically" if you want to configure it as a brand new wallet and start using it. Select "Restore backup" if you want to configure the Skywallet with a previously created seed backup.',"configured-detected":"Skywallet detected. The device is identified in the wallets list as:","security-warnings-title":"Security warnings","security-warning-title":"Security warning","unchecked-version-warning":"It was not possible to verify if the firmware of your Skywallet is up to date. This could be due to problems with your internet connection or because the service is under maintenance.","outdated-version-warning":'The firmware of your Skywallet is outdated. We recommend you to update it as soon as possible to ensure safety. To do this, select the "Update firmware" option.',"backup-warning":'You should backup the Skywallet seed or you could lose access to the funds in case of problems. To do this, select the "Create a backup" option.',"pin-warning":'The connected Skywallet does not have a PIN. The PIN code protects the Skywallet from unauthorized parties accessing the device. To create a PIN code, select the "Create PIN code" option.',options:"Options:","update-firmware":"Update firmware","configure-automatically":"Configure automatically","restore-backup":"Restore backup","create-backup":"Create a backup",wipe:"Wipe the device","confirm-seed":"Confirm seed","create-pin":"Create PIN code","change-pin":"Change PIN code","delete-pin":"Delete PIN code","forgotten-pin1":"If you cannot access the wallet because you have forgotten the PIN, you can wipe the Skywallet and then restore it with the seed by clicking","forgotten-pin2":"here.","firmware-version":"Device firmware version:"},"update-firmware-warning":{title:"Outdated Firmware",text:"WARNING: the firmware in your Skywallet is outdated. To stay safe, it is recommended to update it.",cancel:"Cancel",update:"Update"},"update-firmware":{"title-connecting":"Connecting...","title-update":"Update Firmware","title-install":"Install Firmware","text-downloading":"Checking device and downloading files...","text-bootloader":"WARNING: if you have already configured this device, before continuing you must have a backup of your seed or you could permanently lose access to the funds.","text-not-bootloader":"To update the firmware of your Skywallet you must connect it in bootloader mode (connect it to the computer while pressing the two physical buttons of the device). WARNING: if you have already configured this device, before continuing you must have a backup of your seed or you could permanently lose access to the funds.","text-no-firmware":"Welcome. The currently connected Skywallet does not have a firmware installed. A firmware will now be installed so you can start using the device. NOTE: if you have already configured this device and want to recover the funds, you will need your seed.",check:"I understand the risks and want to continue",follow:"The firmware update has been sent to the Skywallet. Please continue the process on the device.","connection-error":"It was not possible to download the firmware. This could be due to problems with your internet connection or because the service is under maintenance.",timeout:"The operation was canceled due to inactivity. Please disconnect the device, reconnect it and try again.",finished:"Your device has been configured correctly. Please unplug it before continuing."},"generate-seed":{text:"Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.",configuring:"Configuring..."},"restore-seed":{text:"Before proceeding, please select the number of words that the seed you want to recover has.","check-text":"You can use this option to enter a seed and check if it is equal to the one in the Skywallet. Before start, select the number of words the seed you want to check has.",warning:"WARNING: to avoid potential problems, use only seeds created with a Skywallet.","error-wrong-word":"Error: The retyped word does not match the one requested by the Skywallet.","error-invalid-seed":"Error: The seed is not valid. Please be sure to enter the correct words in the correct order.","error-wrong-seed":"Error: The seed is valid but does not match the one in the device.","correct-seed":"The seed is valid and matches the one in the device."},added:{title:"New Skywallet",configuring:"New Skywallet detected. Configuring...",done:"Done",added1:"The connected Skywallet has been added to the wallets list with the following name:",added2:"Now you can check the balance and the addresses of the Skywallet even when it is not connected. Additionally, you can change the name of the wallet or remove it from the wallets list, if you wish.","characters-warning":"If you use non-standard English characters, the name may not be displayed correctly on the device.",ok:"Ok"},wipe:{warning:"WARNING: All the data on the Skywallet will be deleted. If you do not have a backup, you will not be able to access your funds again.","confirm-delete":"Also remove from the wallets list"},"create-backup":{warning:'WARNING: You can only create a backup of your Skywallet seed once. If you decide to continue, you will have to write down a group of words (it is recommended to do it on paper and not on a computer) that will appear on the screen of the Skywallet and store the list in a safe place. Anyone with access to the word list (the "seed") will be able access the wallet funds, so extreme caution is advised.',instructions:"Write down the word list that appear on the screen of the Skywallet. Make sure you respect the order and write each word correctly."},"seed-word":{title:"Enter word",info1:"Enter the word shown on the device",info2:"You will be asked to enter the words of your backup seed in random order. Also, additional random words could be requested.",word:"Requested word","error-invalid-word":"The entered word is not valid.","error-loading-words":"Loading the word list. Please wait."},"change-pin":{"pin-mismatch":"Unable to perform the operation. The PINs you have entered do not match."},"remove-pin":{warning:"WARNING: It is not recommended to remove the PIN code from your Skywallet, as it will be vulnerable to being used by unauthorized parties in case of loss or theft.",check:"I understand the risks and want to continue"},"enter-pin":{title:"Enter PIN","title-change-current":"Enter the current PIN","title-change-new":"Enter the new PIN","title-change-confirm":"Confirm the new PIN",instructions:"The PIN layout is displayed on the Skywallet screen.","instructions-tx":"Enter the PIN to confirm and sign the transaction.","instructions-change":"Please enter a secure PIN consisting of 4 to 8 numbers.",help:"Need help?"},"pin-help":{title:"Help",part1:"When it is necessary to enter the PIN to continue, the Skywallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol \u2022.",part2:'To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the Skywallet and press the corresponding buttons in the software wallet. For example, if the PIN is "23" and the number 2 is in the upper left, number 3 in the middle of the Skywallet numbers matrix, press the upper left and middle button in that order in the software wallet.',part3:'If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is "23", you can not simply type "23" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the Skywallet. Taking into account the previous example, you would have to press the "7" and "5" keys, because those are the keys that you are in the same position as the numbers shown by the Skywallet.'},"create-tx":{title:"Create transaction","upper-text":"Please confirm the operation in the Skywallet after verifying if the following data matches EXACTLY with the transaction you wish to send and with those shown by the Skywallet:","lower-text":"If any data does not correspond to what the Skywallet shows or the transaction you wish to send, cancel the operation on your Skywallet.","send-p1":"and","send-p2":"to"},"confirm-address":{title:"Confirm address",instructions:"Please confirm on the Skywallet if the address is:","short-confirmation":"Address confirmed.",confirmation:'Address confirmed. For security, you can re-show the address in the Skywallet using the "Confirm address" option, in the menu that you can display by pressing the button at the right of the address balance.'}},"time-from-now":{"few-seconds":"a few seconds ago",minute:"one minute ago",minutes:"{{time}} minutes ago",hour:"one hour ago",hours:"{{time}} hours ago",day:"one day ago",days:"{{time}} days ago"},exchange:{"you-send":"You send","you-get":"You get (approx.)","to-address":"To {{coin}} address",price:"Exchange rate","time-15":"Exchange time","exchange-button":"Exchange","min-amount":"Minimum amount:","max-amount":"Maximum amount:","agree-1":"I agree with","agree-2":"Terms of Use","agree-3":"and","agree-4":"Privacy Policy","powered-by":"Powered by","need-help":"Need help?","support-portal":"Support portal",history:"Order history","order-not-found":"Order not found",status:"Status",exchanging:"Exchanging {{from}} for {{to}}",select:"Select",offline:"Exchange is temporarily offline","problem-connecting":"Unable to connect with the service. Please check your Internet connection and try again later.","invalid-address":"Invalid address.",statuses:{"user-waiting":"Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below","user-waiting-info":"The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.","market-waiting-confirmations":"Waiting for transaction confirmations","market-waiting-confirmations-info":"The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.","market-confirmed":"Transaction accepted","market-confirmed-info":"The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.","market-exchanged":"Traded {{from}} for {{to}}","market-exchanged-info":"The exchange has been made. The funds will be transferred to your address in a moment.","market-withdraw-waiting":"Sending {{to}} to your address","market-withdraw-waiting-info":"The process for sending the coins to your address has been initiated.",complete:"Exchange completed!","complete-info":"The funds have been successfully sent to your address.",error:"Error occurred","error-info":"There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page.","user-deposit-timeout":"Order canceled due to inactivity","user-deposit-timeout-info":"The system has canceled the order because no deposit was detected, please open a new order. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page."},"history-window":{address:"Address",date:"Date"},details:{"exchange-addr":"Exchange address (valid for this exchange operation only)","exchange-addr-tag":"Payment ID or Destination Tag which must be used for the transaction","tx-id":"Transaction ID","order-id":"Order ID","initial-price":"Initial exchange rate","error-msg":"Error message",details:"Details","start-date":"Start date",back:"Back","back-alert":'The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the "Order history" button'}}}}}); \ No newline at end of file diff --git a/src/gui/static/dist/6.86e4e580e25082578bb8.chunk.js b/src/gui/static/dist/6.86e4e580e25082578bb8.chunk.js new file mode 100644 index 0000000..cae7ef3 --- /dev/null +++ b/src/gui/static/dist/6.86e4e580e25082578bb8.chunk.js @@ -0,0 +1 @@ +webpackJsonp([6],{flj1:function(e,a){e.exports={list:["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","library","license","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"]}}}); \ No newline at end of file diff --git a/src/gui/static/dist/MaterialIcons-Regular.012cf6a10129e2275d79.woff b/src/gui/static/dist/MaterialIcons-Regular.012cf6a10129e2275d79.woff new file mode 100644 index 0000000..b648a3e Binary files /dev/null and b/src/gui/static/dist/MaterialIcons-Regular.012cf6a10129e2275d79.woff differ diff --git a/src/gui/static/dist/MaterialIcons-Regular.570eb83859dc23dd0eec.woff2 b/src/gui/static/dist/MaterialIcons-Regular.570eb83859dc23dd0eec.woff2 new file mode 100644 index 0000000..9fa2112 Binary files /dev/null and b/src/gui/static/dist/MaterialIcons-Regular.570eb83859dc23dd0eec.woff2 differ diff --git a/src/gui/static/dist/MaterialIcons-Regular.a37b0c01c0baf1888ca8.ttf b/src/gui/static/dist/MaterialIcons-Regular.a37b0c01c0baf1888ca8.ttf new file mode 100644 index 0000000..7015564 Binary files /dev/null and b/src/gui/static/dist/MaterialIcons-Regular.a37b0c01c0baf1888ca8.ttf differ diff --git a/src/gui/static/dist/MaterialIcons-Regular.e79bfd88537def476913.eot b/src/gui/static/dist/MaterialIcons-Regular.e79bfd88537def476913.eot new file mode 100644 index 0000000..70508eb Binary files /dev/null and b/src/gui/static/dist/MaterialIcons-Regular.e79bfd88537def476913.eot differ diff --git a/src/gui/static/dist/Skycoin-Bold.42363955889f2f20c527.woff b/src/gui/static/dist/Skycoin-Bold.42363955889f2f20c527.woff new file mode 100644 index 0000000..780de6d Binary files /dev/null and b/src/gui/static/dist/Skycoin-Bold.42363955889f2f20c527.woff differ diff --git a/src/gui/static/dist/Skycoin-Bold.6ccafc6fabc0cc8a971a.woff2 b/src/gui/static/dist/Skycoin-Bold.6ccafc6fabc0cc8a971a.woff2 new file mode 100644 index 0000000..72a32ab Binary files /dev/null and b/src/gui/static/dist/Skycoin-Bold.6ccafc6fabc0cc8a971a.woff2 differ diff --git a/src/gui/static/dist/Skycoin-BoldItalic.923dce74069362d168fe.woff b/src/gui/static/dist/Skycoin-BoldItalic.923dce74069362d168fe.woff new file mode 100644 index 0000000..20ec4ab Binary files /dev/null and b/src/gui/static/dist/Skycoin-BoldItalic.923dce74069362d168fe.woff differ diff --git a/src/gui/static/dist/Skycoin-BoldItalic.c414dad20c4e3020221c.woff2 b/src/gui/static/dist/Skycoin-BoldItalic.c414dad20c4e3020221c.woff2 new file mode 100644 index 0000000..642a2d4 Binary files /dev/null and b/src/gui/static/dist/Skycoin-BoldItalic.c414dad20c4e3020221c.woff2 differ diff --git a/src/gui/static/dist/Skycoin-Light.4be01e4a68be8bf590da.woff b/src/gui/static/dist/Skycoin-Light.4be01e4a68be8bf590da.woff new file mode 100644 index 0000000..a994609 Binary files /dev/null and b/src/gui/static/dist/Skycoin-Light.4be01e4a68be8bf590da.woff differ diff --git a/src/gui/static/dist/Skycoin-Light.770b27ec05c2f97a1a27.woff2 b/src/gui/static/dist/Skycoin-Light.770b27ec05c2f97a1a27.woff2 new file mode 100644 index 0000000..b3238fa Binary files /dev/null and b/src/gui/static/dist/Skycoin-Light.770b27ec05c2f97a1a27.woff2 differ diff --git a/src/gui/static/dist/Skycoin-LightItalic.39e68da05bf8b4a77aa2.woff b/src/gui/static/dist/Skycoin-LightItalic.39e68da05bf8b4a77aa2.woff new file mode 100644 index 0000000..7cc63b7 Binary files /dev/null and b/src/gui/static/dist/Skycoin-LightItalic.39e68da05bf8b4a77aa2.woff differ diff --git a/src/gui/static/dist/Skycoin-LightItalic.d10a437db5d8e2a52b4a.woff2 b/src/gui/static/dist/Skycoin-LightItalic.d10a437db5d8e2a52b4a.woff2 new file mode 100644 index 0000000..3f438f8 Binary files /dev/null and b/src/gui/static/dist/Skycoin-LightItalic.d10a437db5d8e2a52b4a.woff2 differ diff --git a/src/gui/static/dist/Skycoin-Regular.21b4caaaedc00594e7bd.woff2 b/src/gui/static/dist/Skycoin-Regular.21b4caaaedc00594e7bd.woff2 new file mode 100644 index 0000000..46f89cf Binary files /dev/null and b/src/gui/static/dist/Skycoin-Regular.21b4caaaedc00594e7bd.woff2 differ diff --git a/src/gui/static/dist/Skycoin-Regular.98d953e74f174cf013b4.woff b/src/gui/static/dist/Skycoin-Regular.98d953e74f174cf013b4.woff new file mode 100644 index 0000000..40c056e Binary files /dev/null and b/src/gui/static/dist/Skycoin-Regular.98d953e74f174cf013b4.woff differ diff --git a/src/gui/static/dist/Skycoin-RegularItalic.9947360f79b09132fd21.woff b/src/gui/static/dist/Skycoin-RegularItalic.9947360f79b09132fd21.woff new file mode 100644 index 0000000..ddc9c01 Binary files /dev/null and b/src/gui/static/dist/Skycoin-RegularItalic.9947360f79b09132fd21.woff differ diff --git a/src/gui/static/dist/Skycoin-RegularItalic.9eabbc2e01a7e17bb57d.woff2 b/src/gui/static/dist/Skycoin-RegularItalic.9eabbc2e01a7e17bb57d.woff2 new file mode 100644 index 0000000..08d7a51 Binary files /dev/null and b/src/gui/static/dist/Skycoin-RegularItalic.9eabbc2e01a7e17bb57d.woff2 differ diff --git a/src/gui/static/dist/assets/bip39-word-list.json b/src/gui/static/dist/assets/bip39-word-list.json new file mode 100644 index 0000000..c495654 --- /dev/null +++ b/src/gui/static/dist/assets/bip39-word-list.json @@ -0,0 +1,2049 @@ +{ "list": ["abandon", +"ability", +"able", +"about", +"above", +"absent", +"absorb", +"abstract", +"absurd", +"abuse", +"access", +"accident", +"account", +"accuse", +"achieve", +"acid", +"acoustic", +"acquire", +"across", +"act", +"action", +"actor", +"actress", +"actual", +"adapt", +"add", +"addict", +"address", +"adjust", +"admit", +"adult", +"advance", +"advice", +"aerobic", +"affair", +"afford", +"afraid", +"again", +"age", +"agent", +"agree", +"ahead", +"aim", +"air", +"airport", +"aisle", +"alarm", +"album", +"alcohol", +"alert", +"alien", +"all", +"alley", +"allow", +"almost", +"alone", +"alpha", +"already", +"also", +"alter", +"always", +"amateur", +"amazing", +"among", +"amount", +"amused", +"analyst", +"anchor", +"ancient", +"anger", +"angle", +"angry", +"animal", +"ankle", +"announce", +"annual", +"another", +"answer", +"antenna", +"antique", +"anxiety", +"any", +"apart", +"apology", +"appear", +"apple", +"approve", +"april", +"arch", +"arctic", +"area", +"arena", +"argue", +"arm", +"armed", +"armor", +"army", +"around", +"arrange", +"arrest", +"arrive", +"arrow", +"art", +"artefact", +"artist", +"artwork", +"ask", +"aspect", +"assault", +"asset", +"assist", +"assume", +"asthma", +"athlete", +"atom", +"attack", +"attend", +"attitude", +"attract", +"auction", +"audit", +"august", +"aunt", +"author", +"auto", +"autumn", +"average", +"avocado", +"avoid", +"awake", +"aware", +"away", +"awesome", +"awful", +"awkward", +"axis", +"baby", +"bachelor", +"bacon", +"badge", +"bag", +"balance", +"balcony", +"ball", +"bamboo", +"banana", +"banner", +"bar", +"barely", +"bargain", +"barrel", +"base", +"basic", +"basket", +"battle", +"beach", +"bean", +"beauty", +"because", +"become", +"beef", +"before", +"begin", +"behave", +"behind", +"believe", +"below", +"belt", +"bench", +"benefit", +"best", +"betray", +"better", +"between", +"beyond", +"bicycle", +"bid", +"bike", +"bind", +"biology", +"bird", +"birth", +"bitter", +"black", +"blade", +"blame", +"blanket", +"blast", +"bleak", +"bless", +"blind", +"blood", +"blossom", +"blouse", +"blue", +"blur", +"blush", +"board", +"boat", +"body", +"boil", +"bomb", +"bone", +"bonus", +"book", +"boost", +"border", +"boring", +"borrow", +"boss", +"bottom", +"bounce", +"box", +"boy", +"bracket", +"brain", +"brand", +"brass", +"brave", +"bread", +"breeze", +"brick", +"bridge", +"brief", +"bright", +"bring", +"brisk", +"broccoli", +"broken", +"bronze", +"broom", +"brother", +"brown", +"brush", +"bubble", +"buddy", +"budget", +"buffalo", +"build", +"bulb", +"bulk", +"bullet", +"bundle", +"bunker", +"burden", +"burger", +"burst", +"bus", +"business", +"busy", +"butter", +"buyer", +"buzz", +"cabbage", +"cabin", +"cable", +"cactus", +"cage", +"cake", +"call", +"calm", +"camera", +"camp", +"can", +"canal", +"cancel", +"candy", +"cannon", +"canoe", +"canvas", +"canyon", +"capable", +"capital", +"captain", +"car", +"carbon", +"card", +"cargo", +"carpet", +"carry", +"cart", +"case", +"cash", +"casino", +"castle", +"casual", +"cat", +"catalog", +"catch", +"category", +"cattle", +"caught", +"cause", +"caution", +"cave", +"ceiling", +"celery", +"cement", +"census", +"century", +"cereal", +"certain", +"chair", +"chalk", +"champion", +"change", +"chaos", +"chapter", +"charge", +"chase", +"chat", +"cheap", +"check", +"cheese", +"chef", +"cherry", +"chest", +"chicken", +"chief", +"child", +"chimney", +"choice", +"choose", +"chronic", +"chuckle", +"chunk", +"churn", +"cigar", +"cinnamon", +"circle", +"citizen", +"city", +"civil", +"claim", +"clap", +"clarify", +"claw", +"clay", +"clean", +"clerk", +"clever", +"click", +"client", +"cliff", +"climb", +"clinic", +"clip", +"clock", +"clog", +"close", +"cloth", +"cloud", +"clown", +"club", +"clump", +"cluster", +"clutch", +"coach", +"coast", +"coconut", +"code", +"coffee", +"coil", +"coin", +"collect", +"color", +"column", +"combine", +"come", +"comfort", +"comic", +"common", +"company", +"concert", +"conduct", +"confirm", +"congress", +"connect", +"consider", +"control", +"convince", +"cook", +"cool", +"copper", +"copy", +"coral", +"core", +"corn", +"correct", +"cost", +"cotton", +"couch", +"country", +"couple", +"course", +"cousin", +"cover", +"coyote", +"crack", +"cradle", +"craft", +"cram", +"crane", +"crash", +"crater", +"crawl", +"crazy", +"cream", +"credit", +"creek", +"crew", +"cricket", +"crime", +"crisp", +"critic", +"crop", +"cross", +"crouch", +"crowd", +"crucial", +"cruel", +"cruise", +"crumble", +"crunch", +"crush", +"cry", +"crystal", +"cube", +"culture", +"cup", +"cupboard", +"curious", +"current", +"curtain", +"curve", +"cushion", +"custom", +"cute", +"cycle", +"dad", +"damage", +"damp", +"dance", +"danger", +"daring", +"dash", +"daughter", +"dawn", +"day", +"deal", +"debate", +"debris", +"decade", +"december", +"decide", +"decline", +"decorate", +"decrease", +"deer", +"defense", +"define", +"defy", +"degree", +"delay", +"deliver", +"demand", +"demise", +"denial", +"dentist", +"deny", +"depart", +"depend", +"deposit", +"depth", +"deputy", +"derive", +"describe", +"desert", +"design", +"desk", +"despair", +"destroy", +"detail", +"detect", +"develop", +"device", +"devote", +"diagram", +"dial", +"diamond", +"diary", +"dice", +"diesel", +"diet", +"differ", +"digital", +"dignity", +"dilemma", +"dinner", +"dinosaur", +"direct", +"dirt", +"disagree", +"discover", +"disease", +"dish", +"dismiss", +"disorder", +"display", +"distance", +"divert", +"divide", +"divorce", +"dizzy", +"doctor", +"document", +"dog", +"doll", +"dolphin", +"domain", +"donate", +"donkey", +"donor", +"door", +"dose", +"double", +"dove", +"draft", +"dragon", +"drama", +"drastic", +"draw", +"dream", +"dress", +"drift", +"drill", +"drink", +"drip", +"drive", +"drop", +"drum", +"dry", +"duck", +"dumb", +"dune", +"during", +"dust", +"dutch", +"duty", +"dwarf", +"dynamic", +"eager", +"eagle", +"early", +"earn", +"earth", +"easily", +"east", +"easy", +"echo", +"ecology", +"economy", +"edge", +"edit", +"educate", +"effort", +"egg", +"eight", +"either", +"elbow", +"elder", +"electric", +"elegant", +"element", +"elephant", +"elevator", +"elite", +"else", +"embark", +"embody", +"embrace", +"emerge", +"emotion", +"employ", +"empower", +"empty", +"enable", +"enact", +"end", +"endless", +"endorse", +"enemy", +"energy", +"enforce", +"engage", +"engine", +"enhance", +"enjoy", +"enlist", +"enough", +"enrich", +"enroll", +"ensure", +"enter", +"entire", +"entry", +"envelope", +"episode", +"equal", +"equip", +"era", +"erase", +"erode", +"erosion", +"error", +"erupt", +"escape", +"essay", +"essence", +"estate", +"eternal", +"ethics", +"evidence", +"evil", +"evoke", +"evolve", +"exact", +"example", +"excess", +"exchange", +"excite", +"exclude", +"excuse", +"execute", +"exercise", +"exhaust", +"exhibit", +"exile", +"exist", +"exit", +"exotic", +"expand", +"expect", +"expire", +"explain", +"expose", +"express", +"extend", +"extra", +"eye", +"eyebrow", +"fabric", +"face", +"faculty", +"fade", +"faint", +"faith", +"fall", +"false", +"fame", +"family", +"famous", +"fan", +"fancy", +"fantasy", +"farm", +"fashion", +"fat", +"fatal", +"father", +"fatigue", +"fault", +"favorite", +"feature", +"february", +"federal", +"fee", +"feed", +"feel", +"female", +"fence", +"festival", +"fetch", +"fever", +"few", +"fiber", +"fiction", +"field", +"figure", +"file", +"film", +"filter", +"final", +"find", +"fine", +"finger", +"finish", +"fire", +"firm", +"first", +"fiscal", +"fish", +"fit", +"fitness", +"fix", +"flag", +"flame", +"flash", +"flat", +"flavor", +"flee", +"flight", +"flip", +"float", +"flock", +"floor", +"flower", +"fluid", +"flush", +"fly", +"foam", +"focus", +"fog", +"foil", +"fold", +"follow", +"food", +"foot", +"force", +"forest", +"forget", +"fork", +"fortune", +"forum", +"forward", +"fossil", +"foster", +"found", +"fox", +"fragile", +"frame", +"frequent", +"fresh", +"friend", +"fringe", +"frog", +"front", +"frost", +"frown", +"frozen", +"fruit", +"fuel", +"fun", +"funny", +"furnace", +"fury", +"future", +"gadget", +"gain", +"galaxy", +"gallery", +"game", +"gap", +"garage", +"garbage", +"garden", +"garlic", +"garment", +"gas", +"gasp", +"gate", +"gather", +"gauge", +"gaze", +"general", +"genius", +"genre", +"gentle", +"genuine", +"gesture", +"ghost", +"giant", +"gift", +"giggle", +"ginger", +"giraffe", +"girl", +"give", +"glad", +"glance", +"glare", +"glass", +"glide", +"glimpse", +"globe", +"gloom", +"glory", +"glove", +"glow", +"glue", +"goat", +"goddess", +"gold", +"good", +"goose", +"gorilla", +"gospel", +"gossip", +"govern", +"gown", +"grab", +"grace", +"grain", +"grant", +"grape", +"grass", +"gravity", +"great", +"green", +"grid", +"grief", +"grit", +"grocery", +"group", +"grow", +"grunt", +"guard", +"guess", +"guide", +"guilt", +"guitar", +"gun", +"gym", +"habit", +"hair", +"half", +"hammer", +"hamster", +"hand", +"happy", +"harbor", +"hard", +"harsh", +"harvest", +"hat", +"have", +"hawk", +"hazard", +"head", +"health", +"heart", +"heavy", +"hedgehog", +"height", +"hello", +"helmet", +"help", +"hen", +"hero", +"hidden", +"high", +"hill", +"hint", +"hip", +"hire", +"history", +"hobby", +"hockey", +"hold", +"hole", +"holiday", +"hollow", +"home", +"honey", +"hood", +"hope", +"horn", +"horror", +"horse", +"hospital", +"host", +"hotel", +"hour", +"hover", +"hub", +"huge", +"human", +"humble", +"humor", +"hundred", +"hungry", +"hunt", +"hurdle", +"hurry", +"hurt", +"husband", +"hybrid", +"ice", +"icon", +"idea", +"identify", +"idle", +"ignore", +"ill", +"illegal", +"illness", +"image", +"imitate", +"immense", +"immune", +"impact", +"impose", +"improve", +"impulse", +"inch", +"include", +"income", +"increase", +"index", +"indicate", +"indoor", +"industry", +"infant", +"inflict", +"inform", +"inhale", +"inherit", +"initial", +"inject", +"injury", +"inmate", +"inner", +"innocent", +"input", +"inquiry", +"insane", +"insect", +"inside", +"inspire", +"install", +"intact", +"interest", +"into", +"invest", +"invite", +"involve", +"iron", +"island", +"isolate", +"issue", +"item", +"ivory", +"jacket", +"jaguar", +"jar", +"jazz", +"jealous", +"jeans", +"jelly", +"jewel", +"job", +"join", +"joke", +"journey", +"joy", +"judge", +"juice", +"jump", +"jungle", +"junior", +"junk", +"just", +"kangaroo", +"keen", +"keep", +"ketchup", +"key", +"kick", +"kid", +"kidney", +"kind", +"kingdom", +"kiss", +"kit", +"kitchen", +"kite", +"kitten", +"kiwi", +"knee", +"knife", +"knock", +"know", +"lab", +"label", +"labor", +"ladder", +"lady", +"lake", +"lamp", +"language", +"laptop", +"large", +"later", +"latin", +"laugh", +"laundry", +"lava", +"law", +"lawn", +"lawsuit", +"layer", +"lazy", +"leader", +"leaf", +"learn", +"leave", +"lecture", +"left", +"leg", +"legal", +"legend", +"leisure", +"lemon", +"lend", +"length", +"lens", +"leopard", +"lesson", +"letter", +"level", +"liar", +"liberty", +"library", +"license", +"life", +"lift", +"light", +"like", +"limb", +"limit", +"link", +"lion", +"liquid", +"list", +"little", +"live", +"lizard", +"load", +"loan", +"lobster", +"local", +"lock", +"logic", +"lonely", +"long", +"loop", +"lottery", +"loud", +"lounge", +"love", +"loyal", +"lucky", +"luggage", +"lumber", +"lunar", +"lunch", +"luxury", +"lyrics", +"machine", +"mad", +"magic", +"magnet", +"maid", +"mail", +"main", +"major", +"make", +"mammal", +"man", +"manage", +"mandate", +"mango", +"mansion", +"manual", +"maple", +"marble", +"march", +"margin", +"marine", +"market", +"marriage", +"mask", +"mass", +"master", +"match", +"material", +"math", +"matrix", +"matter", +"maximum", +"maze", +"meadow", +"mean", +"measure", +"meat", +"mechanic", +"medal", +"media", +"melody", +"melt", +"member", +"memory", +"mention", +"menu", +"mercy", +"merge", +"merit", +"merry", +"mesh", +"message", +"metal", +"method", +"middle", +"midnight", +"milk", +"million", +"mimic", +"mind", +"minimum", +"minor", +"minute", +"miracle", +"mirror", +"misery", +"miss", +"mistake", +"mix", +"mixed", +"mixture", +"mobile", +"model", +"modify", +"mom", +"moment", +"monitor", +"monkey", +"monster", +"month", +"moon", +"moral", +"more", +"morning", +"mosquito", +"mother", +"motion", +"motor", +"mountain", +"mouse", +"move", +"movie", +"much", +"muffin", +"mule", +"multiply", +"muscle", +"museum", +"mushroom", +"music", +"must", +"mutual", +"myself", +"mystery", +"myth", +"naive", +"name", +"napkin", +"narrow", +"nasty", +"nation", +"nature", +"near", +"neck", +"need", +"negative", +"neglect", +"neither", +"nephew", +"nerve", +"nest", +"net", +"network", +"neutral", +"never", +"news", +"next", +"nice", +"night", +"noble", +"noise", +"nominee", +"noodle", +"normal", +"north", +"nose", +"notable", +"note", +"nothing", +"notice", +"novel", +"now", +"nuclear", +"number", +"nurse", +"nut", +"oak", +"obey", +"object", +"oblige", +"obscure", +"observe", +"obtain", +"obvious", +"occur", +"ocean", +"october", +"odor", +"off", +"offer", +"office", +"often", +"oil", +"okay", +"old", +"olive", +"olympic", +"omit", +"once", +"one", +"onion", +"online", +"only", +"open", +"opera", +"opinion", +"oppose", +"option", +"orange", +"orbit", +"orchard", +"order", +"ordinary", +"organ", +"orient", +"original", +"orphan", +"ostrich", +"other", +"outdoor", +"outer", +"output", +"outside", +"oval", +"oven", +"over", +"own", +"owner", +"oxygen", +"oyster", +"ozone", +"pact", +"paddle", +"page", +"pair", +"palace", +"palm", +"panda", +"panel", +"panic", +"panther", +"paper", +"parade", +"parent", +"park", +"parrot", +"party", +"pass", +"patch", +"path", +"patient", +"patrol", +"pattern", +"pause", +"pave", +"payment", +"peace", +"peanut", +"pear", +"peasant", +"pelican", +"pen", +"penalty", +"pencil", +"people", +"pepper", +"perfect", +"permit", +"person", +"pet", +"phone", +"photo", +"phrase", +"physical", +"piano", +"picnic", +"picture", +"piece", +"pig", +"pigeon", +"pill", +"pilot", +"pink", +"pioneer", +"pipe", +"pistol", +"pitch", +"pizza", +"place", +"planet", +"plastic", +"plate", +"play", +"please", +"pledge", +"pluck", +"plug", +"plunge", +"poem", +"poet", +"point", +"polar", +"pole", +"police", +"pond", +"pony", +"pool", +"popular", +"portion", +"position", +"possible", +"post", +"potato", +"pottery", +"poverty", +"powder", +"power", +"practice", +"praise", +"predict", +"prefer", +"prepare", +"present", +"pretty", +"prevent", +"price", +"pride", +"primary", +"print", +"priority", +"prison", +"private", +"prize", +"problem", +"process", +"produce", +"profit", +"program", +"project", +"promote", +"proof", +"property", +"prosper", +"protect", +"proud", +"provide", +"public", +"pudding", +"pull", +"pulp", +"pulse", +"pumpkin", +"punch", +"pupil", +"puppy", +"purchase", +"purity", +"purpose", +"purse", +"push", +"put", +"puzzle", +"pyramid", +"quality", +"quantum", +"quarter", +"question", +"quick", +"quit", +"quiz", +"quote", +"rabbit", +"raccoon", +"race", +"rack", +"radar", +"radio", +"rail", +"rain", +"raise", +"rally", +"ramp", +"ranch", +"random", +"range", +"rapid", +"rare", +"rate", +"rather", +"raven", +"raw", +"razor", +"ready", +"real", +"reason", +"rebel", +"rebuild", +"recall", +"receive", +"recipe", +"record", +"recycle", +"reduce", +"reflect", +"reform", +"refuse", +"region", +"regret", +"regular", +"reject", +"relax", +"release", +"relief", +"rely", +"remain", +"remember", +"remind", +"remove", +"render", +"renew", +"rent", +"reopen", +"repair", +"repeat", +"replace", +"report", +"require", +"rescue", +"resemble", +"resist", +"resource", +"response", +"result", +"retire", +"retreat", +"return", +"reunion", +"reveal", +"review", +"reward", +"rhythm", +"rib", +"ribbon", +"rice", +"rich", +"ride", +"ridge", +"rifle", +"right", +"rigid", +"ring", +"riot", +"ripple", +"risk", +"ritual", +"rival", +"river", +"road", +"roast", +"robot", +"robust", +"rocket", +"romance", +"roof", +"rookie", +"room", +"rose", +"rotate", +"rough", +"round", +"route", +"royal", +"rubber", +"rude", +"rug", +"rule", +"run", +"runway", +"rural", +"sad", +"saddle", +"sadness", +"safe", +"sail", +"salad", +"salmon", +"salon", +"salt", +"salute", +"same", +"sample", +"sand", +"satisfy", +"satoshi", +"sauce", +"sausage", +"save", +"say", +"scale", +"scan", +"scare", +"scatter", +"scene", +"scheme", +"school", +"science", +"scissors", +"scorpion", +"scout", +"scrap", +"screen", +"script", +"scrub", +"sea", +"search", +"season", +"seat", +"second", +"secret", +"section", +"security", +"seed", +"seek", +"segment", +"select", +"sell", +"seminar", +"senior", +"sense", +"sentence", +"series", +"service", +"session", +"settle", +"setup", +"seven", +"shadow", +"shaft", +"shallow", +"share", +"shed", +"shell", +"sheriff", +"shield", +"shift", +"shine", +"ship", +"shiver", +"shock", +"shoe", +"shoot", +"shop", +"short", +"shoulder", +"shove", +"shrimp", +"shrug", +"shuffle", +"shy", +"sibling", +"sick", +"side", +"siege", +"sight", +"sign", +"silent", +"silk", +"silly", +"silver", +"similar", +"simple", +"since", +"sing", +"siren", +"sister", +"situate", +"six", +"size", +"skate", +"sketch", +"ski", +"skill", +"skin", +"skirt", +"skull", +"slab", +"slam", +"sleep", +"slender", +"slice", +"slide", +"slight", +"slim", +"slogan", +"slot", +"slow", +"slush", +"small", +"smart", +"smile", +"smoke", +"smooth", +"snack", +"snake", +"snap", +"sniff", +"snow", +"soap", +"soccer", +"social", +"sock", +"soda", +"soft", +"solar", +"soldier", +"solid", +"solution", +"solve", +"someone", +"song", +"soon", +"sorry", +"sort", +"soul", +"sound", +"soup", +"source", +"south", +"space", +"spare", +"spatial", +"spawn", +"speak", +"special", +"speed", +"spell", +"spend", +"sphere", +"spice", +"spider", +"spike", +"spin", +"spirit", +"split", +"spoil", +"sponsor", +"spoon", +"sport", +"spot", +"spray", +"spread", +"spring", +"spy", +"square", +"squeeze", +"squirrel", +"stable", +"stadium", +"staff", +"stage", +"stairs", +"stamp", +"stand", +"start", +"state", +"stay", +"steak", +"steel", +"stem", +"step", +"stereo", +"stick", +"still", +"sting", +"stock", +"stomach", +"stone", +"stool", +"story", +"stove", +"strategy", +"street", +"strike", +"strong", +"struggle", +"student", +"stuff", +"stumble", +"style", +"subject", +"submit", +"subway", +"success", +"such", +"sudden", +"suffer", +"sugar", +"suggest", +"suit", +"summer", +"sun", +"sunny", +"sunset", +"super", +"supply", +"supreme", +"sure", +"surface", +"surge", +"surprise", +"surround", +"survey", +"suspect", +"sustain", +"swallow", +"swamp", +"swap", +"swarm", +"swear", +"sweet", +"swift", +"swim", +"swing", +"switch", +"sword", +"symbol", +"symptom", +"syrup", +"system", +"table", +"tackle", +"tag", +"tail", +"talent", +"talk", +"tank", +"tape", +"target", +"task", +"taste", +"tattoo", +"taxi", +"teach", +"team", +"tell", +"ten", +"tenant", +"tennis", +"tent", +"term", +"test", +"text", +"thank", +"that", +"theme", +"then", +"theory", +"there", +"they", +"thing", +"this", +"thought", +"three", +"thrive", +"throw", +"thumb", +"thunder", +"ticket", +"tide", +"tiger", +"tilt", +"timber", +"time", +"tiny", +"tip", +"tired", +"tissue", +"title", +"toast", +"tobacco", +"today", +"toddler", +"toe", +"together", +"toilet", +"token", +"tomato", +"tomorrow", +"tone", +"tongue", +"tonight", +"tool", +"tooth", +"top", +"topic", +"topple", +"torch", +"tornado", +"tortoise", +"toss", +"total", +"tourist", +"toward", +"tower", +"town", +"toy", +"track", +"trade", +"traffic", +"tragic", +"train", +"transfer", +"trap", +"trash", +"travel", +"tray", +"treat", +"tree", +"trend", +"trial", +"tribe", +"trick", +"trigger", +"trim", +"trip", +"trophy", +"trouble", +"truck", +"true", +"truly", +"trumpet", +"trust", +"truth", +"try", +"tube", +"tuition", +"tumble", +"tuna", +"tunnel", +"turkey", +"turn", +"turtle", +"twelve", +"twenty", +"twice", +"twin", +"twist", +"two", +"type", +"typical", +"ugly", +"umbrella", +"unable", +"unaware", +"uncle", +"uncover", +"under", +"undo", +"unfair", +"unfold", +"unhappy", +"uniform", +"unique", +"unit", +"universe", +"unknown", +"unlock", +"until", +"unusual", +"unveil", +"update", +"upgrade", +"uphold", +"upon", +"upper", +"upset", +"urban", +"urge", +"usage", +"use", +"used", +"useful", +"useless", +"usual", +"utility", +"vacant", +"vacuum", +"vague", +"valid", +"valley", +"valve", +"van", +"vanish", +"vapor", +"various", +"vast", +"vault", +"vehicle", +"velvet", +"vendor", +"venture", +"venue", +"verb", +"verify", +"version", +"very", +"vessel", +"veteran", +"viable", +"vibrant", +"vicious", +"victory", +"video", +"view", +"village", +"vintage", +"violin", +"virtual", +"virus", +"visa", +"visit", +"visual", +"vital", +"vivid", +"vocal", +"voice", +"void", +"volcano", +"volume", +"vote", +"voyage", +"wage", +"wagon", +"wait", +"walk", +"wall", +"walnut", +"want", +"warfare", +"warm", +"warrior", +"wash", +"wasp", +"waste", +"water", +"wave", +"way", +"wealth", +"weapon", +"wear", +"weasel", +"weather", +"web", +"wedding", +"weekend", +"weird", +"welcome", +"west", +"wet", +"whale", +"what", +"wheat", +"wheel", +"when", +"where", +"whip", +"whisper", +"wide", +"width", +"wife", +"wild", +"will", +"win", +"window", +"wine", +"wing", +"wink", +"winner", +"winter", +"wire", +"wisdom", +"wise", +"wish", +"witness", +"wolf", +"woman", +"wonder", +"wood", +"wool", +"word", +"work", +"world", +"worry", +"worth", +"wrap", +"wreck", +"wrestle", +"wrist", +"write", +"wrong", +"yard", +"year", +"yellow", +"you", +"young", +"youth", +"zebra", +"zero", +"zone", +"zoo"] +} \ No newline at end of file diff --git a/src/gui/static/dist/assets/error-alert/big-error-icon.png b/src/gui/static/dist/assets/error-alert/big-error-icon.png new file mode 100644 index 0000000..bcbda0c Binary files /dev/null and b/src/gui/static/dist/assets/error-alert/big-error-icon.png differ diff --git a/src/gui/static/dist/assets/error-alert/index.html b/src/gui/static/dist/assets/error-alert/index.html new file mode 100644 index 0000000..3c6f643 --- /dev/null +++ b/src/gui/static/dist/assets/error-alert/index.html @@ -0,0 +1,89 @@ + + + + + + + + +
+
+ +
+
+
+
+ + + + diff --git a/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.eot b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.eot new file mode 100644 index 0000000..70508eb Binary files /dev/null and b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.eot differ diff --git a/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.ijmap b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.ijmap new file mode 100644 index 0000000..d9f1d25 --- /dev/null +++ b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.ijmap @@ -0,0 +1 @@ +{"icons":{"e84d":{"name":"3d Rotation"},"eb3b":{"name":"Ac Unit"},"e190":{"name":"Access Alarm"},"e191":{"name":"Access Alarms"},"e192":{"name":"Access Time"},"e84e":{"name":"Accessibility"},"e914":{"name":"Accessible"},"e84f":{"name":"Account Balance"},"e850":{"name":"Account Balance Wallet"},"e851":{"name":"Account Box"},"e853":{"name":"Account Circle"},"e60e":{"name":"Adb"},"e145":{"name":"Add"},"e439":{"name":"Add A Photo"},"e193":{"name":"Add Alarm"},"e003":{"name":"Add Alert"},"e146":{"name":"Add Box"},"e147":{"name":"Add Circle"},"e148":{"name":"Add Circle Outline"},"e567":{"name":"Add Location"},"e854":{"name":"Add Shopping Cart"},"e39d":{"name":"Add To Photos"},"e05c":{"name":"Add To Queue"},"e39e":{"name":"Adjust"},"e630":{"name":"Airline Seat Flat"},"e631":{"name":"Airline Seat Flat Angled"},"e632":{"name":"Airline Seat Individual Suite"},"e633":{"name":"Airline Seat Legroom Extra"},"e634":{"name":"Airline Seat Legroom Normal"},"e635":{"name":"Airline Seat Legroom Reduced"},"e636":{"name":"Airline Seat Recline Extra"},"e637":{"name":"Airline Seat Recline Normal"},"e195":{"name":"Airplanemode Active"},"e194":{"name":"Airplanemode Inactive"},"e055":{"name":"Airplay"},"eb3c":{"name":"Airport Shuttle"},"e855":{"name":"Alarm"},"e856":{"name":"Alarm Add"},"e857":{"name":"Alarm Off"},"e858":{"name":"Alarm On"},"e019":{"name":"Album"},"eb3d":{"name":"All Inclusive"},"e90b":{"name":"All Out"},"e859":{"name":"Android"},"e85a":{"name":"Announcement"},"e5c3":{"name":"Apps"},"e149":{"name":"Archive"},"e5c4":{"name":"Arrow Back"},"e5db":{"name":"Arrow Downward"},"e5c5":{"name":"Arrow Drop Down"},"e5c6":{"name":"Arrow Drop Down Circle"},"e5c7":{"name":"Arrow Drop Up"},"e5c8":{"name":"Arrow Forward"},"e5d8":{"name":"Arrow Upward"},"e060":{"name":"Art Track"},"e85b":{"name":"Aspect Ratio"},"e85c":{"name":"Assessment"},"e85d":{"name":"Assignment"},"e85e":{"name":"Assignment Ind"},"e85f":{"name":"Assignment Late"},"e860":{"name":"Assignment Return"},"e861":{"name":"Assignment Returned"},"e862":{"name":"Assignment Turned In"},"e39f":{"name":"Assistant"},"e3a0":{"name":"Assistant Photo"},"e226":{"name":"Attach File"},"e227":{"name":"Attach Money"},"e2bc":{"name":"Attachment"},"e3a1":{"name":"Audiotrack"},"e863":{"name":"Autorenew"},"e01b":{"name":"Av Timer"},"e14a":{"name":"Backspace"},"e864":{"name":"Backup"},"e19c":{"name":"Battery Alert"},"e1a3":{"name":"Battery Charging Full"},"e1a4":{"name":"Battery Full"},"e1a5":{"name":"Battery Std"},"e1a6":{"name":"Battery Unknown"},"eb3e":{"name":"Beach Access"},"e52d":{"name":"Beenhere"},"e14b":{"name":"Block"},"e1a7":{"name":"Bluetooth"},"e60f":{"name":"Bluetooth Audio"},"e1a8":{"name":"Bluetooth Connected"},"e1a9":{"name":"Bluetooth Disabled"},"e1aa":{"name":"Bluetooth Searching"},"e3a2":{"name":"Blur Circular"},"e3a3":{"name":"Blur Linear"},"e3a4":{"name":"Blur Off"},"e3a5":{"name":"Blur On"},"e865":{"name":"Book"},"e866":{"name":"Bookmark"},"e867":{"name":"Bookmark Border"},"e228":{"name":"Border All"},"e229":{"name":"Border Bottom"},"e22a":{"name":"Border Clear"},"e22b":{"name":"Border Color"},"e22c":{"name":"Border Horizontal"},"e22d":{"name":"Border Inner"},"e22e":{"name":"Border Left"},"e22f":{"name":"Border Outer"},"e230":{"name":"Border Right"},"e231":{"name":"Border Style"},"e232":{"name":"Border Top"},"e233":{"name":"Border Vertical"},"e06b":{"name":"Branding Watermark"},"e3a6":{"name":"Brightness 1"},"e3a7":{"name":"Brightness 2"},"e3a8":{"name":"Brightness 3"},"e3a9":{"name":"Brightness 4"},"e3aa":{"name":"Brightness 5"},"e3ab":{"name":"Brightness 6"},"e3ac":{"name":"Brightness 7"},"e1ab":{"name":"Brightness Auto"},"e1ac":{"name":"Brightness High"},"e1ad":{"name":"Brightness Low"},"e1ae":{"name":"Brightness Medium"},"e3ad":{"name":"Broken Image"},"e3ae":{"name":"Brush"},"e6dd":{"name":"Bubble Chart"},"e868":{"name":"Bug Report"},"e869":{"name":"Build"},"e43c":{"name":"Burst Mode"},"e0af":{"name":"Business"},"eb3f":{"name":"Business Center"},"e86a":{"name":"Cached"},"e7e9":{"name":"Cake"},"e0b0":{"name":"Call"},"e0b1":{"name":"Call End"},"e0b2":{"name":"Call Made"},"e0b3":{"name":"Call Merge"},"e0b4":{"name":"Call Missed"},"e0e4":{"name":"Call Missed Outgoing"},"e0b5":{"name":"Call Received"},"e0b6":{"name":"Call Split"},"e06c":{"name":"Call To Action"},"e3af":{"name":"Camera"},"e3b0":{"name":"Camera Alt"},"e8fc":{"name":"Camera Enhance"},"e3b1":{"name":"Camera Front"},"e3b2":{"name":"Camera Rear"},"e3b3":{"name":"Camera Roll"},"e5c9":{"name":"Cancel"},"e8f6":{"name":"Card Giftcard"},"e8f7":{"name":"Card Membership"},"e8f8":{"name":"Card Travel"},"eb40":{"name":"Casino"},"e307":{"name":"Cast"},"e308":{"name":"Cast Connected"},"e3b4":{"name":"Center Focus Strong"},"e3b5":{"name":"Center Focus Weak"},"e86b":{"name":"Change History"},"e0b7":{"name":"Chat"},"e0ca":{"name":"Chat Bubble"},"e0cb":{"name":"Chat Bubble Outline"},"e5ca":{"name":"Check"},"e834":{"name":"Check Box"},"e835":{"name":"Check Box Outline Blank"},"e86c":{"name":"Check Circle"},"e5cb":{"name":"Chevron Left"},"e5cc":{"name":"Chevron Right"},"eb41":{"name":"Child Care"},"eb42":{"name":"Child Friendly"},"e86d":{"name":"Chrome Reader Mode"},"e86e":{"name":"Class"},"e14c":{"name":"Clear"},"e0b8":{"name":"Clear All"},"e5cd":{"name":"Close"},"e01c":{"name":"Closed Caption"},"e2bd":{"name":"Cloud"},"e2be":{"name":"Cloud Circle"},"e2bf":{"name":"Cloud Done"},"e2c0":{"name":"Cloud Download"},"e2c1":{"name":"Cloud Off"},"e2c2":{"name":"Cloud Queue"},"e2c3":{"name":"Cloud Upload"},"e86f":{"name":"Code"},"e3b6":{"name":"Collections"},"e431":{"name":"Collections Bookmark"},"e3b7":{"name":"Color Lens"},"e3b8":{"name":"Colorize"},"e0b9":{"name":"Comment"},"e3b9":{"name":"Compare"},"e915":{"name":"Compare Arrows"},"e30a":{"name":"Computer"},"e638":{"name":"Confirmation Number"},"e0d0":{"name":"Contact Mail"},"e0cf":{"name":"Contact Phone"},"e0ba":{"name":"Contacts"},"e14d":{"name":"Content Copy"},"e14e":{"name":"Content Cut"},"e14f":{"name":"Content Paste"},"e3ba":{"name":"Control Point"},"e3bb":{"name":"Control Point Duplicate"},"e90c":{"name":"Copyright"},"e150":{"name":"Create"},"e2cc":{"name":"Create New Folder"},"e870":{"name":"Credit Card"},"e3be":{"name":"Crop"},"e3bc":{"name":"Crop 16 9"},"e3bd":{"name":"Crop 3 2"},"e3bf":{"name":"Crop 5 4"},"e3c0":{"name":"Crop 7 5"},"e3c1":{"name":"Crop Din"},"e3c2":{"name":"Crop Free"},"e3c3":{"name":"Crop Landscape"},"e3c4":{"name":"Crop Original"},"e3c5":{"name":"Crop Portrait"},"e437":{"name":"Crop Rotate"},"e3c6":{"name":"Crop Square"},"e871":{"name":"Dashboard"},"e1af":{"name":"Data Usage"},"e916":{"name":"Date Range"},"e3c7":{"name":"Dehaze"},"e872":{"name":"Delete"},"e92b":{"name":"Delete Forever"},"e16c":{"name":"Delete Sweep"},"e873":{"name":"Description"},"e30b":{"name":"Desktop Mac"},"e30c":{"name":"Desktop Windows"},"e3c8":{"name":"Details"},"e30d":{"name":"Developer Board"},"e1b0":{"name":"Developer Mode"},"e335":{"name":"Device Hub"},"e1b1":{"name":"Devices"},"e337":{"name":"Devices Other"},"e0bb":{"name":"Dialer Sip"},"e0bc":{"name":"Dialpad"},"e52e":{"name":"Directions"},"e52f":{"name":"Directions Bike"},"e532":{"name":"Directions Boat"},"e530":{"name":"Directions Bus"},"e531":{"name":"Directions Car"},"e534":{"name":"Directions Railway"},"e566":{"name":"Directions Run"},"e533":{"name":"Directions Subway"},"e535":{"name":"Directions Transit"},"e536":{"name":"Directions Walk"},"e610":{"name":"Disc Full"},"e875":{"name":"Dns"},"e612":{"name":"Do Not Disturb"},"e611":{"name":"Do Not Disturb Alt"},"e643":{"name":"Do Not Disturb Off"},"e644":{"name":"Do Not Disturb On"},"e30e":{"name":"Dock"},"e7ee":{"name":"Domain"},"e876":{"name":"Done"},"e877":{"name":"Done All"},"e917":{"name":"Donut Large"},"e918":{"name":"Donut Small"},"e151":{"name":"Drafts"},"e25d":{"name":"Drag Handle"},"e613":{"name":"Drive Eta"},"e1b2":{"name":"Dvr"},"e3c9":{"name":"Edit"},"e568":{"name":"Edit Location"},"e8fb":{"name":"Eject"},"e0be":{"name":"Email"},"e63f":{"name":"Enhanced Encryption"},"e01d":{"name":"Equalizer"},"e000":{"name":"Error"},"e001":{"name":"Error Outline"},"e926":{"name":"Euro Symbol"},"e56d":{"name":"Ev Station"},"e878":{"name":"Event"},"e614":{"name":"Event Available"},"e615":{"name":"Event Busy"},"e616":{"name":"Event Note"},"e903":{"name":"Event Seat"},"e879":{"name":"Exit To App"},"e5ce":{"name":"Expand Less"},"e5cf":{"name":"Expand More"},"e01e":{"name":"Explicit"},"e87a":{"name":"Explore"},"e3ca":{"name":"Exposure"},"e3cb":{"name":"Exposure Neg 1"},"e3cc":{"name":"Exposure Neg 2"},"e3cd":{"name":"Exposure Plus 1"},"e3ce":{"name":"Exposure Plus 2"},"e3cf":{"name":"Exposure Zero"},"e87b":{"name":"Extension"},"e87c":{"name":"Face"},"e01f":{"name":"Fast Forward"},"e020":{"name":"Fast Rewind"},"e87d":{"name":"Favorite"},"e87e":{"name":"Favorite Border"},"e06d":{"name":"Featured Play List"},"e06e":{"name":"Featured Video"},"e87f":{"name":"Feedback"},"e05d":{"name":"Fiber Dvr"},"e061":{"name":"Fiber Manual Record"},"e05e":{"name":"Fiber New"},"e06a":{"name":"Fiber Pin"},"e062":{"name":"Fiber Smart Record"},"e2c4":{"name":"File Download"},"e2c6":{"name":"File Upload"},"e3d3":{"name":"Filter"},"e3d0":{"name":"Filter 1"},"e3d1":{"name":"Filter 2"},"e3d2":{"name":"Filter 3"},"e3d4":{"name":"Filter 4"},"e3d5":{"name":"Filter 5"},"e3d6":{"name":"Filter 6"},"e3d7":{"name":"Filter 7"},"e3d8":{"name":"Filter 8"},"e3d9":{"name":"Filter 9"},"e3da":{"name":"Filter 9 Plus"},"e3db":{"name":"Filter B And W"},"e3dc":{"name":"Filter Center Focus"},"e3dd":{"name":"Filter Drama"},"e3de":{"name":"Filter Frames"},"e3df":{"name":"Filter Hdr"},"e152":{"name":"Filter List"},"e3e0":{"name":"Filter None"},"e3e2":{"name":"Filter Tilt Shift"},"e3e3":{"name":"Filter Vintage"},"e880":{"name":"Find In Page"},"e881":{"name":"Find Replace"},"e90d":{"name":"Fingerprint"},"e5dc":{"name":"First Page"},"eb43":{"name":"Fitness Center"},"e153":{"name":"Flag"},"e3e4":{"name":"Flare"},"e3e5":{"name":"Flash Auto"},"e3e6":{"name":"Flash Off"},"e3e7":{"name":"Flash On"},"e539":{"name":"Flight"},"e904":{"name":"Flight Land"},"e905":{"name":"Flight Takeoff"},"e3e8":{"name":"Flip"},"e882":{"name":"Flip To Back"},"e883":{"name":"Flip To Front"},"e2c7":{"name":"Folder"},"e2c8":{"name":"Folder Open"},"e2c9":{"name":"Folder Shared"},"e617":{"name":"Folder Special"},"e167":{"name":"Font Download"},"e234":{"name":"Format Align Center"},"e235":{"name":"Format Align Justify"},"e236":{"name":"Format Align Left"},"e237":{"name":"Format Align Right"},"e238":{"name":"Format Bold"},"e239":{"name":"Format Clear"},"e23a":{"name":"Format Color Fill"},"e23b":{"name":"Format Color Reset"},"e23c":{"name":"Format Color Text"},"e23d":{"name":"Format Indent Decrease"},"e23e":{"name":"Format Indent Increase"},"e23f":{"name":"Format Italic"},"e240":{"name":"Format Line Spacing"},"e241":{"name":"Format List Bulleted"},"e242":{"name":"Format List Numbered"},"e243":{"name":"Format Paint"},"e244":{"name":"Format Quote"},"e25e":{"name":"Format Shapes"},"e245":{"name":"Format Size"},"e246":{"name":"Format Strikethrough"},"e247":{"name":"Format Textdirection L To R"},"e248":{"name":"Format Textdirection R To L"},"e249":{"name":"Format Underlined"},"e0bf":{"name":"Forum"},"e154":{"name":"Forward"},"e056":{"name":"Forward 10"},"e057":{"name":"Forward 30"},"e058":{"name":"Forward 5"},"eb44":{"name":"Free Breakfast"},"e5d0":{"name":"Fullscreen"},"e5d1":{"name":"Fullscreen Exit"},"e24a":{"name":"Functions"},"e927":{"name":"G Translate"},"e30f":{"name":"Gamepad"},"e021":{"name":"Games"},"e90e":{"name":"Gavel"},"e155":{"name":"Gesture"},"e884":{"name":"Get App"},"e908":{"name":"Gif"},"eb45":{"name":"Golf Course"},"e1b3":{"name":"Gps Fixed"},"e1b4":{"name":"Gps Not Fixed"},"e1b5":{"name":"Gps Off"},"e885":{"name":"Grade"},"e3e9":{"name":"Gradient"},"e3ea":{"name":"Grain"},"e1b8":{"name":"Graphic Eq"},"e3eb":{"name":"Grid Off"},"e3ec":{"name":"Grid On"},"e7ef":{"name":"Group"},"e7f0":{"name":"Group Add"},"e886":{"name":"Group Work"},"e052":{"name":"Hd"},"e3ed":{"name":"Hdr Off"},"e3ee":{"name":"Hdr On"},"e3f1":{"name":"Hdr Strong"},"e3f2":{"name":"Hdr Weak"},"e310":{"name":"Headset"},"e311":{"name":"Headset Mic"},"e3f3":{"name":"Healing"},"e023":{"name":"Hearing"},"e887":{"name":"Help"},"e8fd":{"name":"Help Outline"},"e024":{"name":"High Quality"},"e25f":{"name":"Highlight"},"e888":{"name":"Highlight Off"},"e889":{"name":"History"},"e88a":{"name":"Home"},"eb46":{"name":"Hot Tub"},"e53a":{"name":"Hotel"},"e88b":{"name":"Hourglass Empty"},"e88c":{"name":"Hourglass Full"},"e902":{"name":"Http"},"e88d":{"name":"Https"},"e3f4":{"name":"Image"},"e3f5":{"name":"Image Aspect Ratio"},"e0e0":{"name":"Import Contacts"},"e0c3":{"name":"Import Export"},"e912":{"name":"Important Devices"},"e156":{"name":"Inbox"},"e909":{"name":"Indeterminate Check Box"},"e88e":{"name":"Info"},"e88f":{"name":"Info Outline"},"e890":{"name":"Input"},"e24b":{"name":"Insert Chart"},"e24c":{"name":"Insert Comment"},"e24d":{"name":"Insert Drive File"},"e24e":{"name":"Insert Emoticon"},"e24f":{"name":"Insert Invitation"},"e250":{"name":"Insert Link"},"e251":{"name":"Insert Photo"},"e891":{"name":"Invert Colors"},"e0c4":{"name":"Invert Colors Off"},"e3f6":{"name":"Iso"},"e312":{"name":"Keyboard"},"e313":{"name":"Keyboard Arrow Down"},"e314":{"name":"Keyboard Arrow Left"},"e315":{"name":"Keyboard Arrow Right"},"e316":{"name":"Keyboard Arrow Up"},"e317":{"name":"Keyboard Backspace"},"e318":{"name":"Keyboard Capslock"},"e31a":{"name":"Keyboard Hide"},"e31b":{"name":"Keyboard Return"},"e31c":{"name":"Keyboard Tab"},"e31d":{"name":"Keyboard Voice"},"eb47":{"name":"Kitchen"},"e892":{"name":"Label"},"e893":{"name":"Label Outline"},"e3f7":{"name":"Landscape"},"e894":{"name":"Language"},"e31e":{"name":"Laptop"},"e31f":{"name":"Laptop Chromebook"},"e320":{"name":"Laptop Mac"},"e321":{"name":"Laptop Windows"},"e5dd":{"name":"Last Page"},"e895":{"name":"Launch"},"e53b":{"name":"Layers"},"e53c":{"name":"Layers Clear"},"e3f8":{"name":"Leak Add"},"e3f9":{"name":"Leak Remove"},"e3fa":{"name":"Lens"},"e02e":{"name":"Library Add"},"e02f":{"name":"Library Books"},"e030":{"name":"Library Music"},"e90f":{"name":"Lightbulb Outline"},"e919":{"name":"Line Style"},"e91a":{"name":"Line Weight"},"e260":{"name":"Linear Scale"},"e157":{"name":"Link"},"e438":{"name":"Linked Camera"},"e896":{"name":"List"},"e0c6":{"name":"Live Help"},"e639":{"name":"Live Tv"},"e53f":{"name":"Local Activity"},"e53d":{"name":"Local Airport"},"e53e":{"name":"Local Atm"},"e540":{"name":"Local Bar"},"e541":{"name":"Local Cafe"},"e542":{"name":"Local Car Wash"},"e543":{"name":"Local Convenience Store"},"e556":{"name":"Local Dining"},"e544":{"name":"Local Drink"},"e545":{"name":"Local Florist"},"e546":{"name":"Local Gas Station"},"e547":{"name":"Local Grocery Store"},"e548":{"name":"Local Hospital"},"e549":{"name":"Local Hotel"},"e54a":{"name":"Local Laundry Service"},"e54b":{"name":"Local Library"},"e54c":{"name":"Local Mall"},"e54d":{"name":"Local Movies"},"e54e":{"name":"Local Offer"},"e54f":{"name":"Local Parking"},"e550":{"name":"Local Pharmacy"},"e551":{"name":"Local Phone"},"e552":{"name":"Local Pizza"},"e553":{"name":"Local Play"},"e554":{"name":"Local Post Office"},"e555":{"name":"Local Printshop"},"e557":{"name":"Local See"},"e558":{"name":"Local Shipping"},"e559":{"name":"Local Taxi"},"e7f1":{"name":"Location City"},"e1b6":{"name":"Location Disabled"},"e0c7":{"name":"Location Off"},"e0c8":{"name":"Location On"},"e1b7":{"name":"Location Searching"},"e897":{"name":"Lock"},"e898":{"name":"Lock Open"},"e899":{"name":"Lock Outline"},"e3fc":{"name":"Looks"},"e3fb":{"name":"Looks 3"},"e3fd":{"name":"Looks 4"},"e3fe":{"name":"Looks 5"},"e3ff":{"name":"Looks 6"},"e400":{"name":"Looks One"},"e401":{"name":"Looks Two"},"e028":{"name":"Loop"},"e402":{"name":"Loupe"},"e16d":{"name":"Low Priority"},"e89a":{"name":"Loyalty"},"e158":{"name":"Mail"},"e0e1":{"name":"Mail Outline"},"e55b":{"name":"Map"},"e159":{"name":"Markunread"},"e89b":{"name":"Markunread Mailbox"},"e322":{"name":"Memory"},"e5d2":{"name":"Menu"},"e252":{"name":"Merge Type"},"e0c9":{"name":"Message"},"e029":{"name":"Mic"},"e02a":{"name":"Mic None"},"e02b":{"name":"Mic Off"},"e618":{"name":"Mms"},"e253":{"name":"Mode Comment"},"e254":{"name":"Mode Edit"},"e263":{"name":"Monetization On"},"e25c":{"name":"Money Off"},"e403":{"name":"Monochrome Photos"},"e7f2":{"name":"Mood"},"e7f3":{"name":"Mood Bad"},"e619":{"name":"More"},"e5d3":{"name":"More Horiz"},"e5d4":{"name":"More Vert"},"e91b":{"name":"Motorcycle"},"e323":{"name":"Mouse"},"e168":{"name":"Move To Inbox"},"e02c":{"name":"Movie"},"e404":{"name":"Movie Creation"},"e43a":{"name":"Movie Filter"},"e6df":{"name":"Multiline Chart"},"e405":{"name":"Music Note"},"e063":{"name":"Music Video"},"e55c":{"name":"My Location"},"e406":{"name":"Nature"},"e407":{"name":"Nature People"},"e408":{"name":"Navigate Before"},"e409":{"name":"Navigate Next"},"e55d":{"name":"Navigation"},"e569":{"name":"Near Me"},"e1b9":{"name":"Network Cell"},"e640":{"name":"Network Check"},"e61a":{"name":"Network Locked"},"e1ba":{"name":"Network Wifi"},"e031":{"name":"New Releases"},"e16a":{"name":"Next Week"},"e1bb":{"name":"Nfc"},"e641":{"name":"No Encryption"},"e0cc":{"name":"No Sim"},"e033":{"name":"Not Interested"},"e06f":{"name":"Note"},"e89c":{"name":"Note Add"},"e7f4":{"name":"Notifications"},"e7f7":{"name":"Notifications Active"},"e7f5":{"name":"Notifications None"},"e7f6":{"name":"Notifications Off"},"e7f8":{"name":"Notifications Paused"},"e90a":{"name":"Offline Pin"},"e63a":{"name":"Ondemand Video"},"e91c":{"name":"Opacity"},"e89d":{"name":"Open In Browser"},"e89e":{"name":"Open In New"},"e89f":{"name":"Open With"},"e7f9":{"name":"Pages"},"e8a0":{"name":"Pageview"},"e40a":{"name":"Palette"},"e925":{"name":"Pan Tool"},"e40b":{"name":"Panorama"},"e40c":{"name":"Panorama Fish Eye"},"e40d":{"name":"Panorama Horizontal"},"e40e":{"name":"Panorama Vertical"},"e40f":{"name":"Panorama Wide Angle"},"e7fa":{"name":"Party Mode"},"e034":{"name":"Pause"},"e035":{"name":"Pause Circle Filled"},"e036":{"name":"Pause Circle Outline"},"e8a1":{"name":"Payment"},"e7fb":{"name":"People"},"e7fc":{"name":"People Outline"},"e8a2":{"name":"Perm Camera Mic"},"e8a3":{"name":"Perm Contact Calendar"},"e8a4":{"name":"Perm Data Setting"},"e8a5":{"name":"Perm Device Information"},"e8a6":{"name":"Perm Identity"},"e8a7":{"name":"Perm Media"},"e8a8":{"name":"Perm Phone Msg"},"e8a9":{"name":"Perm Scan Wifi"},"e7fd":{"name":"Person"},"e7fe":{"name":"Person Add"},"e7ff":{"name":"Person Outline"},"e55a":{"name":"Person Pin"},"e56a":{"name":"Person Pin Circle"},"e63b":{"name":"Personal Video"},"e91d":{"name":"Pets"},"e0cd":{"name":"Phone"},"e324":{"name":"Phone Android"},"e61b":{"name":"Phone Bluetooth Speaker"},"e61c":{"name":"Phone Forwarded"},"e61d":{"name":"Phone In Talk"},"e325":{"name":"Phone Iphone"},"e61e":{"name":"Phone Locked"},"e61f":{"name":"Phone Missed"},"e620":{"name":"Phone Paused"},"e326":{"name":"Phonelink"},"e0db":{"name":"Phonelink Erase"},"e0dc":{"name":"Phonelink Lock"},"e327":{"name":"Phonelink Off"},"e0dd":{"name":"Phonelink Ring"},"e0de":{"name":"Phonelink Setup"},"e410":{"name":"Photo"},"e411":{"name":"Photo Album"},"e412":{"name":"Photo Camera"},"e43b":{"name":"Photo Filter"},"e413":{"name":"Photo Library"},"e432":{"name":"Photo Size Select Actual"},"e433":{"name":"Photo Size Select Large"},"e434":{"name":"Photo Size Select Small"},"e415":{"name":"Picture As Pdf"},"e8aa":{"name":"Picture In Picture"},"e911":{"name":"Picture In Picture Alt"},"e6c4":{"name":"Pie Chart"},"e6c5":{"name":"Pie Chart Outlined"},"e55e":{"name":"Pin Drop"},"e55f":{"name":"Place"},"e037":{"name":"Play Arrow"},"e038":{"name":"Play Circle Filled"},"e039":{"name":"Play Circle Outline"},"e906":{"name":"Play For Work"},"e03b":{"name":"Playlist Add"},"e065":{"name":"Playlist Add Check"},"e05f":{"name":"Playlist Play"},"e800":{"name":"Plus One"},"e801":{"name":"Poll"},"e8ab":{"name":"Polymer"},"eb48":{"name":"Pool"},"e0ce":{"name":"Portable Wifi Off"},"e416":{"name":"Portrait"},"e63c":{"name":"Power"},"e336":{"name":"Power Input"},"e8ac":{"name":"Power Settings New"},"e91e":{"name":"Pregnant Woman"},"e0df":{"name":"Present To All"},"e8ad":{"name":"Print"},"e645":{"name":"Priority High"},"e80b":{"name":"Public"},"e255":{"name":"Publish"},"e8ae":{"name":"Query Builder"},"e8af":{"name":"Question Answer"},"e03c":{"name":"Queue"},"e03d":{"name":"Queue Music"},"e066":{"name":"Queue Play Next"},"e03e":{"name":"Radio"},"e837":{"name":"Radio Button Checked"},"e836":{"name":"Radio Button Unchecked"},"e560":{"name":"Rate Review"},"e8b0":{"name":"Receipt"},"e03f":{"name":"Recent Actors"},"e91f":{"name":"Record Voice Over"},"e8b1":{"name":"Redeem"},"e15a":{"name":"Redo"},"e5d5":{"name":"Refresh"},"e15b":{"name":"Remove"},"e15c":{"name":"Remove Circle"},"e15d":{"name":"Remove Circle Outline"},"e067":{"name":"Remove From Queue"},"e417":{"name":"Remove Red Eye"},"e928":{"name":"Remove Shopping Cart"},"e8fe":{"name":"Reorder"},"e040":{"name":"Repeat"},"e041":{"name":"Repeat One"},"e042":{"name":"Replay"},"e059":{"name":"Replay 10"},"e05a":{"name":"Replay 30"},"e05b":{"name":"Replay 5"},"e15e":{"name":"Reply"},"e15f":{"name":"Reply All"},"e160":{"name":"Report"},"e8b2":{"name":"Report Problem"},"e56c":{"name":"Restaurant"},"e561":{"name":"Restaurant Menu"},"e8b3":{"name":"Restore"},"e929":{"name":"Restore Page"},"e0d1":{"name":"Ring Volume"},"e8b4":{"name":"Room"},"eb49":{"name":"Room Service"},"e418":{"name":"Rotate 90 Degrees Ccw"},"e419":{"name":"Rotate Left"},"e41a":{"name":"Rotate Right"},"e920":{"name":"Rounded Corner"},"e328":{"name":"Router"},"e921":{"name":"Rowing"},"e0e5":{"name":"Rss Feed"},"e642":{"name":"Rv Hookup"},"e562":{"name":"Satellite"},"e161":{"name":"Save"},"e329":{"name":"Scanner"},"e8b5":{"name":"Schedule"},"e80c":{"name":"School"},"e1be":{"name":"Screen Lock Landscape"},"e1bf":{"name":"Screen Lock Portrait"},"e1c0":{"name":"Screen Lock Rotation"},"e1c1":{"name":"Screen Rotation"},"e0e2":{"name":"Screen Share"},"e623":{"name":"Sd Card"},"e1c2":{"name":"Sd Storage"},"e8b6":{"name":"Search"},"e32a":{"name":"Security"},"e162":{"name":"Select All"},"e163":{"name":"Send"},"e811":{"name":"Sentiment Dissatisfied"},"e812":{"name":"Sentiment Neutral"},"e813":{"name":"Sentiment Satisfied"},"e814":{"name":"Sentiment Very Dissatisfied"},"e815":{"name":"Sentiment Very Satisfied"},"e8b8":{"name":"Settings"},"e8b9":{"name":"Settings Applications"},"e8ba":{"name":"Settings Backup Restore"},"e8bb":{"name":"Settings Bluetooth"},"e8bd":{"name":"Settings Brightness"},"e8bc":{"name":"Settings Cell"},"e8be":{"name":"Settings Ethernet"},"e8bf":{"name":"Settings Input Antenna"},"e8c0":{"name":"Settings Input Component"},"e8c1":{"name":"Settings Input Composite"},"e8c2":{"name":"Settings Input Hdmi"},"e8c3":{"name":"Settings Input Svideo"},"e8c4":{"name":"Settings Overscan"},"e8c5":{"name":"Settings Phone"},"e8c6":{"name":"Settings Power"},"e8c7":{"name":"Settings Remote"},"e1c3":{"name":"Settings System Daydream"},"e8c8":{"name":"Settings Voice"},"e80d":{"name":"Share"},"e8c9":{"name":"Shop"},"e8ca":{"name":"Shop Two"},"e8cb":{"name":"Shopping Basket"},"e8cc":{"name":"Shopping Cart"},"e261":{"name":"Short Text"},"e6e1":{"name":"Show Chart"},"e043":{"name":"Shuffle"},"e1c8":{"name":"Signal Cellular 4 Bar"},"e1cd":{"name":"Signal Cellular Connected No Internet 4 Bar"},"e1ce":{"name":"Signal Cellular No Sim"},"e1cf":{"name":"Signal Cellular Null"},"e1d0":{"name":"Signal Cellular Off"},"e1d8":{"name":"Signal Wifi 4 Bar"},"e1d9":{"name":"Signal Wifi 4 Bar Lock"},"e1da":{"name":"Signal Wifi Off"},"e32b":{"name":"Sim Card"},"e624":{"name":"Sim Card Alert"},"e044":{"name":"Skip Next"},"e045":{"name":"Skip Previous"},"e41b":{"name":"Slideshow"},"e068":{"name":"Slow Motion Video"},"e32c":{"name":"Smartphone"},"eb4a":{"name":"Smoke Free"},"eb4b":{"name":"Smoking Rooms"},"e625":{"name":"Sms"},"e626":{"name":"Sms Failed"},"e046":{"name":"Snooze"},"e164":{"name":"Sort"},"e053":{"name":"Sort By Alpha"},"eb4c":{"name":"Spa"},"e256":{"name":"Space Bar"},"e32d":{"name":"Speaker"},"e32e":{"name":"Speaker Group"},"e8cd":{"name":"Speaker Notes"},"e92a":{"name":"Speaker Notes Off"},"e0d2":{"name":"Speaker Phone"},"e8ce":{"name":"Spellcheck"},"e838":{"name":"Star"},"e83a":{"name":"Star Border"},"e839":{"name":"Star Half"},"e8d0":{"name":"Stars"},"e0d3":{"name":"Stay Current Landscape"},"e0d4":{"name":"Stay Current Portrait"},"e0d5":{"name":"Stay Primary Landscape"},"e0d6":{"name":"Stay Primary Portrait"},"e047":{"name":"Stop"},"e0e3":{"name":"Stop Screen Share"},"e1db":{"name":"Storage"},"e8d1":{"name":"Store"},"e563":{"name":"Store Mall Directory"},"e41c":{"name":"Straighten"},"e56e":{"name":"Streetview"},"e257":{"name":"Strikethrough S"},"e41d":{"name":"Style"},"e5d9":{"name":"Subdirectory Arrow Left"},"e5da":{"name":"Subdirectory Arrow Right"},"e8d2":{"name":"Subject"},"e064":{"name":"Subscriptions"},"e048":{"name":"Subtitles"},"e56f":{"name":"Subway"},"e8d3":{"name":"Supervisor Account"},"e049":{"name":"Surround Sound"},"e0d7":{"name":"Swap Calls"},"e8d4":{"name":"Swap Horiz"},"e8d5":{"name":"Swap Vert"},"e8d6":{"name":"Swap Vertical Circle"},"e41e":{"name":"Switch Camera"},"e41f":{"name":"Switch Video"},"e627":{"name":"Sync"},"e628":{"name":"Sync Disabled"},"e629":{"name":"Sync Problem"},"e62a":{"name":"System Update"},"e8d7":{"name":"System Update Alt"},"e8d8":{"name":"Tab"},"e8d9":{"name":"Tab Unselected"},"e32f":{"name":"Tablet"},"e330":{"name":"Tablet Android"},"e331":{"name":"Tablet Mac"},"e420":{"name":"Tag Faces"},"e62b":{"name":"Tap And Play"},"e564":{"name":"Terrain"},"e262":{"name":"Text Fields"},"e165":{"name":"Text Format"},"e0d8":{"name":"Textsms"},"e421":{"name":"Texture"},"e8da":{"name":"Theaters"},"e8db":{"name":"Thumb Down"},"e8dc":{"name":"Thumb Up"},"e8dd":{"name":"Thumbs Up Down"},"e62c":{"name":"Time To Leave"},"e422":{"name":"Timelapse"},"e922":{"name":"Timeline"},"e425":{"name":"Timer"},"e423":{"name":"Timer 10"},"e424":{"name":"Timer 3"},"e426":{"name":"Timer Off"},"e264":{"name":"Title"},"e8de":{"name":"Toc"},"e8df":{"name":"Today"},"e8e0":{"name":"Toll"},"e427":{"name":"Tonality"},"e913":{"name":"Touch App"},"e332":{"name":"Toys"},"e8e1":{"name":"Track Changes"},"e565":{"name":"Traffic"},"e570":{"name":"Train"},"e571":{"name":"Tram"},"e572":{"name":"Transfer Within A Station"},"e428":{"name":"Transform"},"e8e2":{"name":"Translate"},"e8e3":{"name":"Trending Down"},"e8e4":{"name":"Trending Flat"},"e8e5":{"name":"Trending Up"},"e429":{"name":"Tune"},"e8e6":{"name":"Turned In"},"e8e7":{"name":"Turned In Not"},"e333":{"name":"Tv"},"e169":{"name":"Unarchive"},"e166":{"name":"Undo"},"e5d6":{"name":"Unfold Less"},"e5d7":{"name":"Unfold More"},"e923":{"name":"Update"},"e1e0":{"name":"Usb"},"e8e8":{"name":"Verified User"},"e258":{"name":"Vertical Align Bottom"},"e259":{"name":"Vertical Align Center"},"e25a":{"name":"Vertical Align Top"},"e62d":{"name":"Vibration"},"e070":{"name":"Video Call"},"e071":{"name":"Video Label"},"e04a":{"name":"Video Library"},"e04b":{"name":"Videocam"},"e04c":{"name":"Videocam Off"},"e338":{"name":"Videogame Asset"},"e8e9":{"name":"View Agenda"},"e8ea":{"name":"View Array"},"e8eb":{"name":"View Carousel"},"e8ec":{"name":"View Column"},"e42a":{"name":"View Comfy"},"e42b":{"name":"View Compact"},"e8ed":{"name":"View Day"},"e8ee":{"name":"View Headline"},"e8ef":{"name":"View List"},"e8f0":{"name":"View Module"},"e8f1":{"name":"View Quilt"},"e8f2":{"name":"View Stream"},"e8f3":{"name":"View Week"},"e435":{"name":"Vignette"},"e8f4":{"name":"Visibility"},"e8f5":{"name":"Visibility Off"},"e62e":{"name":"Voice Chat"},"e0d9":{"name":"Voicemail"},"e04d":{"name":"Volume Down"},"e04e":{"name":"Volume Mute"},"e04f":{"name":"Volume Off"},"e050":{"name":"Volume Up"},"e0da":{"name":"Vpn Key"},"e62f":{"name":"Vpn Lock"},"e1bc":{"name":"Wallpaper"},"e002":{"name":"Warning"},"e334":{"name":"Watch"},"e924":{"name":"Watch Later"},"e42c":{"name":"Wb Auto"},"e42d":{"name":"Wb Cloudy"},"e42e":{"name":"Wb Incandescent"},"e436":{"name":"Wb Iridescent"},"e430":{"name":"Wb Sunny"},"e63d":{"name":"Wc"},"e051":{"name":"Web"},"e069":{"name":"Web Asset"},"e16b":{"name":"Weekend"},"e80e":{"name":"Whatshot"},"e1bd":{"name":"Widgets"},"e63e":{"name":"Wifi"},"e1e1":{"name":"Wifi Lock"},"e1e2":{"name":"Wifi Tethering"},"e8f9":{"name":"Work"},"e25b":{"name":"Wrap Text"},"e8fa":{"name":"Youtube Searched For"},"e8ff":{"name":"Zoom In"},"e900":{"name":"Zoom Out"},"e56b":{"name":"Zoom Out Map"}}} \ No newline at end of file diff --git a/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.svg b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.svg new file mode 100644 index 0000000..a449327 --- /dev/null +++ b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.svg @@ -0,0 +1,2373 @@ + + + + + +Created by FontForge 20151118 at Mon Feb 8 11:58:02 2016 + By shyndman +Copyright 2015 Google, Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.ttf b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.ttf new file mode 100644 index 0000000..7015564 Binary files /dev/null and b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.ttf differ diff --git a/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.woff b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.woff new file mode 100644 index 0000000..b648a3e Binary files /dev/null and b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.woff differ diff --git a/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.woff2 b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.woff2 new file mode 100644 index 0000000..9fa2112 Binary files /dev/null and b/src/gui/static/dist/assets/fonts/material-icons/MaterialIcons-Regular.woff2 differ diff --git a/src/gui/static/dist/assets/fonts/material-icons/material-icons.css b/src/gui/static/dist/assets/fonts/material-icons/material-icons.css new file mode 100644 index 0000000..2270c09 --- /dev/null +++ b/src/gui/static/dist/assets/fonts/material-icons/material-icons.css @@ -0,0 +1,36 @@ +@font-face { + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: url(MaterialIcons-Regular.eot); /* For IE6-8 */ + src: local('Material Icons'), + local('MaterialIcons-Regular'), + url(MaterialIcons-Regular.woff2) format('woff2'), + url(MaterialIcons-Regular.woff) format('woff'), + url(MaterialIcons-Regular.ttf) format('truetype'); +} + +.material-icons { + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 24px; /* Preferred icon size */ + display: inline-block; + line-height: 1; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + white-space: nowrap; + direction: ltr; + + /* Support for all WebKit browsers. */ + -webkit-font-smoothing: antialiased; + /* Support for Safari and Chrome. */ + text-rendering: optimizeLegibility; + + /* Support for Firefox. */ + -moz-osx-font-smoothing: grayscale; + + /* Support for IE. */ + font-feature-settings: 'liga'; +} diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Bold.woff b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Bold.woff new file mode 100644 index 0000000..780de6d Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Bold.woff differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Bold.woff2 b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Bold.woff2 new file mode 100644 index 0000000..72a32ab Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Bold.woff2 differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-BoldItalic.woff b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-BoldItalic.woff new file mode 100644 index 0000000..20ec4ab Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-BoldItalic.woff differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-BoldItalic.woff2 b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-BoldItalic.woff2 new file mode 100644 index 0000000..642a2d4 Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-BoldItalic.woff2 differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Light.woff b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Light.woff new file mode 100644 index 0000000..a994609 Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Light.woff differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Light.woff2 b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Light.woff2 new file mode 100644 index 0000000..b3238fa Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Light.woff2 differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-LightItalic.woff b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-LightItalic.woff new file mode 100644 index 0000000..7cc63b7 Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-LightItalic.woff differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-LightItalic.woff2 b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-LightItalic.woff2 new file mode 100644 index 0000000..3f438f8 Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-LightItalic.woff2 differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Regular.woff b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Regular.woff new file mode 100644 index 0000000..40c056e Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Regular.woff differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Regular.woff2 b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Regular.woff2 new file mode 100644 index 0000000..46f89cf Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-Regular.woff2 differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-RegularItalic.woff b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-RegularItalic.woff new file mode 100644 index 0000000..ddc9c01 Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-RegularItalic.woff differ diff --git a/src/gui/static/dist/assets/fonts/skycoin/Skycoin-RegularItalic.woff2 b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-RegularItalic.woff2 new file mode 100644 index 0000000..08d7a51 Binary files /dev/null and b/src/gui/static/dist/assets/fonts/skycoin/Skycoin-RegularItalic.woff2 differ diff --git a/src/gui/static/dist/assets/header.png b/src/gui/static/dist/assets/header.png new file mode 100644 index 0000000..be1002a Binary files /dev/null and b/src/gui/static/dist/assets/header.png differ diff --git a/src/gui/static/dist/assets/i18n/README.md b/src/gui/static/dist/assets/i18n/README.md new file mode 100644 index 0000000..22bccbd --- /dev/null +++ b/src/gui/static/dist/assets/i18n/README.md @@ -0,0 +1,273 @@ +This folder contains the GUI translation files. To maintain order and be able +to easily make any necessary updates to the translation files after updating +the main text file, please follow its instructions if you are working with +its contents. + +# Contents of this folder + +The contents of this folder are: + +- `README.md`: this file. + +- `check.js`: file with the script for detecting if a translation file has errors +or should be updated. + +- `en.json`: main file with all the texts of the application, in English. It should +only be modified when changing the texts of the application (add, modify and +delete). This means that the file must not be modified while creating a new +ranslation or modifying an existing one. + +- Various `xx.json` files: files with the translated versions of the texts of +`en.json`. + +- Various `xx_base.json` files: files with copies of `en.json` made the last time the +corresponding `xx.json` file was modified. + +Normally there is no need to modify the first two files. + +For more information about the `xx.json` and `xx_base.json`, please check the +[Add a new translation](#add-a-new-translation) and +[Update a translation](#update-a-translation) sections. + +# About the meaning of "xx" in this file + +Several parts of this file uses "xx" as part of file names or scripts, like +`xx.json` and `xx_base.json`. In fact, no file in this folder should be called +`xx.json` or `xx_base.json`, the "xx" part must be replaces with the two +characters code of the language. For example, if you are working with the Chinese +translation, the files will be `zh.json` and `zh_base.json`, instead of `xx.json` +and `xx_base.json`. The same if true for the scripts, if you are working with the +Chinese translation, instead of running `node check.js xx` you must run +`node check.js zh`. + +# Add a new translation + +First you must create in this folder two copies of the `en.json` file. The first +copy must be called `xx.json`, where the `xx` part must be the two characters code +of the new language. For example, for Chinese the name of the file should be +`zh.json`; for Spanish, `es.json`; for French, `fr.json`, etc. + +The second copy of `en.json` must be renamed to `xx_base.json`, where the `xx` part +must be the two characters code of the new language. This means that if the first +copy is named `zh.json`, the second one should be named `zh_base.json`. + +It is not necessary to follow a specific standard for the two characters code, but +it must be limited to two letters and be a recognizable code for the language. + +After creating the two files, simply translate the texts in `xx.json`. Please make +sure you do not modify the structure of `xx.json`, just modify the texts. + +The `xx_base.json` file must not be modified in any way, as it is used only as a way +to know what the state of `en.json` was the last time the `xx.json` file was +modified. This copy will be compared in the future with `en.json`, to verify if +there were modifications to `en.json` since the last time the translation file was +modified and if an update is needed. + +If the `xx.json` and `xx_base.json` files do not have the same elements, the +automatic tests could fail when uploading the changes to the repository, preventing +the changes from being accepted, so, again, it is important not to modify the +structure of `xx.json`, but only its contents. + +After doing all this, the translation will be ready, but will not be available in +the GUI until adding it to the code. + +# Verify the translation files + +This folder includes a script that is capable of automatically checking the +translation files, to detect problems and know what should be updated. + +For using it, your computer must have `Node.js` installed. + +## Checking for problems + +For detecting basic problems on the translation files, open a command line window +in this folder and run `node check.js`. This will check the following: + +- The `en.json` must exist, as it is the main language file for the app. + +- For every `xx.json` file (except `en.json`) an `xx_base.json` file must exist +and viceversa. + +- A `xx.json` file and its corresponding `xx_base.json` file must have the exact +same elements (only the content of that elements could be different), as the +`xx.json` is suposed to be the translation of the contents of `xx_base.json`. + +As you can see, this only checks for errors that could be made while creating or +modifying the `xx.json` and `xx_base.json` files, and does not check if any +translation needs to be updated. + +At the end of the script excecution, the console will display the list of all +errors found, if any. This check could be done automatically when making changes +to the repository, to reject updates with problems, so it is good idea to run it +manually before uploading changes. + +Note: at this time the script does not check if the elements of the files are +in the same order, but this could be added in the future, so it is recomended +not to change the order of the elements. + +## Checking if a language file needs to be updated + +To detect if an specific language needs updating, run `node check.js xx`, +where xx is the two characters code of the language you want to check. If you +want to check all languages, run `node check.js all`. + +By doing this, the script will perform all the checks described in the +[Checking for problems](#checking-for-problems) section, plus this: + +- The `en.json` and `xx_base.json` should have the same elements. If `en.json` +has elements that `xx_base.json` does not contain, it means that, since the +last time the translation file was updated, new texts have been added to the +application. If `xx_base.json` has elements that `en.json` does not contain, +it means that, since the last time the translation file was updated, some texts +have been removed from the application. Both cases mean that the translation +file should be updated. + +- The elements of `en.json` and `xx_base.json` should have the same content. +If any element have different content, it means that since the last time the +translation file was updated, some texts of the applications have been changed. +This means that the translation file should be updated. + +At the end of the script excecution, the console will display the list of all +errors found, if any. + +# Update a translation + +Before updating a translation file, you should follow the steps of the +[Checking if a language file needs to be updated](#Checking-if-a-language-file-needs-to-be-updated) +section. By doing so you will quikly know exactly what texts must be added, +deleted or edited. + +After doing that, make all the required modifications in the `xx.json` file, +this means adding, deleting and modifying all the elements indicated by the +script. Please be sure to modify only what is required and to add any new +element in the same position that it is in the `en.json` file. This process +is manual, so be sure check all the changes before finishing. + +After doing the modifications in `xx.json`, delete the `xx_base.json` file, +create a copy of `en.json` and rename it `xx_base.json`. The objetive is to +simply update the `xx_base.json` file to the current state of `en.json`. +this will make possible to check in the future if more updates are nedded, +due to new changes in `en.json`. + +Once all the changes are made, check again the language file as indicated +in the +[Checking if a language file needs to be updated](#Checking-if-a-language-file-needs-to-be-updated) +section. The script should not return errors. If the script returns errors, +please solve them before continuing. + +# How to edit the translation files + +The translation files are in json format (.json files). It is possible to +open these files in a text editor and edit them like normal text files. +However, the json files are used for coding and have a very strict format. +Because of this, **editing the files manually is not recommended** unless +you know exactly what you are doing. + +If you do not know the json format, this section includes useful +information to be able to edit the files easily. + +## Which application should be used for editing the files + +There are several application that allow editing json files, including +some text editors. However, it is recommended to use the Json Editor app +for Google Chrome. Among the advantages of this application are that it +is multiplatform, it allows editing the contents without having to +directly modify the json code and has a relatively simple interface. You +can add it to your Chrome browser from here: +https://chrome.google.com/webstore/detail/json-editor/lhkmoheomjbkfloacpgllgjcamhihfaj + +The app looks like this: + +![app](app1.png) + +As you can see, you can load/save files on the upper-right corner of +the app. The left part shows the source code and the right part shows +a tree view of the elements of the file and its contents. You can +ignore the source code and work with the tree view only. + +![app](app2.png) + +As you will not be editing the soutce code, you can hide it by presing +and draging the 3-dot button (1). While editing the file, you can use +the arrows (2) to expand/contract the different sections in which the +elements are organized. Once you find an item that you want to edit, +click on the content and modify the text (3). Please, do not make any +changes to the name of the element (4). + +You can use the 6-dot buttons (5) to move the elements to a different +location, but please avoid doing it, as that could alter the order of +the file in a way that would make it stop working. Also, as you will +not be working with the source code, avoid using the arrow +buttons (6). + +## Special codes + +Some texts in the language files have special codes that are not +shown in the user interface of the wallet, but serve special purposes. +The codes are: + +- **\\"**: due to how json files work, it is not possible to write +double quotes directly in the texts, the ccorrect way to add double +quotes to a json file is **\\"** (note that the 2 characters must not +be separated by a white space). If you use the Json Editor app for +Google Chrome, you can write double quotes normally and the app will +automatically add the **\\** character behind them, but that is just +a convenience for when you are writing, you could still find the +**\\"** code in files you are editing and have to work with it. + +- **{{ }}**: any text block similar to **{{ something }}** is a +special identifier that the code will replace with a different value +when the app is running. For example, if you find a text like "Your +balance is {{ value }} coins", the application will show something +like "Your balance is 21 coins". In that example the "21" is a value +that the app has to calculate, so it is not possible to add it directly +into the language file. If you find a **{{ }}** text block, please do +not translate it, just move the whole **{{ }}** text block to where the +value should be displayed. If you want to leave a while space before the +value, simply add a white space before the **{{ }}** text block, and do +the same after it if you want a white space after the value. + +- **\
**: this code means "new line". It is just a way to tell +the code that the text after it should be added in a new line. + +# Make a translation available in the application + +Although creating the translation files is the most important step, it is +necessary to make some additional changes before a translation is +available in the application. + +The first thing to do is to add a bitmap in +[src/gui/static/src/assets/img/lang](src/gui/static/src/assets/img/lang), +with the flag that will be used to identify the language. The bitmap +should be a .png file with transparent background and a size of 64x64 +pixels. However, the flag does not have to occupy all the space of the +bitmap, but it should be 64 pixels wide and only 42 pixels high, +centered. Please use as a reference the flags that are already in +the folder. + +After adding the flag, you must modify the +[src/gui/static/src/app/app.config.ts](src/gui/static/src/app/app.config.ts) +file. In particular, you must add a new entry to the `languages` array, +with the data about the language. The object you must add is similar +to this: + +``` +{ + code: 'en', + name: 'English', + iconName: 'en.png' +} +``` + +The properties are: + +- `code`: 2 letter code that was assigned to the language. It must match +the name given to the translation file. + +- `name`: Name of the language. + +- `iconName`: Name of the file with the flag, which was added in the +previous step. + +Please use as a reference the data of the languages that have already +been added to the `languages` array. diff --git a/src/gui/static/dist/assets/i18n/app1.png b/src/gui/static/dist/assets/i18n/app1.png new file mode 100644 index 0000000..67c7501 Binary files /dev/null and b/src/gui/static/dist/assets/i18n/app1.png differ diff --git a/src/gui/static/dist/assets/i18n/app2.png b/src/gui/static/dist/assets/i18n/app2.png new file mode 100644 index 0000000..6cabfe6 Binary files /dev/null and b/src/gui/static/dist/assets/i18n/app2.png differ diff --git a/src/gui/static/dist/assets/i18n/check.js b/src/gui/static/dist/assets/i18n/check.js new file mode 100644 index 0000000..b70f022 --- /dev/null +++ b/src/gui/static/dist/assets/i18n/check.js @@ -0,0 +1,230 @@ +'use strict' + +const fs = require('fs'); + +///////////////////////////////////////////// +// Initial configuration +///////////////////////////////////////////// + +console.log('Starting to check the language files.', '\n'); + +// Load the current English file. +if (!fs.existsSync('en.json')) { + exitWithError('Unable to find the English language file.'); +} +let currentData = JSON.parse(fs.readFileSync('en.json', 'utf8')); + +// 2 charaters code of the languages that will be checked. +const langs = []; +// If false, the code will only verify the differences in the elements (ignoring its contents) of the +// base files and the files with the translations. If not, the code will also verify the differences +// in the elements and contents of the base files and the current English file. +let checkFull = false; + +// If a param was send, it must be "all" or the 2 charaters code of the language that must be checked. +// If a param is provided, checkFull is set to true. +if (process.argv.length > 2) { + if (process.argv.length > 3) { + exitWithError('Invalid number of parameters.'); + } + + if (process.argv[2] != 'all') { + if (process.argv[2].length !== 2) { + exitWithError('You can only send as parameter to this script the 2-letter code of one of the language files in this folder, or "all".'); + } + langs.push(process.argv[2]); + } + + checkFull = true; +} + +// If no language code was send as param, the code will check all languages. +if (langs.length === 0) { + let localFiles = fs.readdirSync('./'); + + const langFiles = []; + const langFilesMap = new Map(); + const baseLangFilesMap = new Map(); + localFiles.forEach(file => { + if (file.length === 12 && file.endsWith('_base.json')) { + langs.push(file.substring(0, 2)); + baseLangFilesMap.set(file.substring(0, 2), true); + } + if (file !== 'en.json' && file.length === 7 && file.endsWith('.json')) { + langFiles.push(file.substring(0, 2)); + langFilesMap.set(file.substring(0, 2), true); + } + }); + + langs.forEach(lang => { + if (!langFilesMap.has(lang)) { + exitWithError('The \"' + lang + '_base.json\" base file does not have its corresponding language file.'); + } + }); + + langFiles.forEach(lang => { + if (!baseLangFilesMap.has(lang)) { + exitWithError('The \"' + lang + '.json\" file does not have its corresponding base file.'); + } + }); + + if (langs.length === 0) { + exitWithError('No language files to check.'); + } +} + +console.log('Checking the following languages:'); +langs.forEach(lang => { + console.log(lang); +}); +console.log(''); + +///////////////////////////////////////////// +// Verifications +///////////////////////////////////////////// + +// The following arrays will contain the list of elements with problems. Each element of the +// arrays contains a "lang" property with the language identifier and a "elements" array with +// the path of the problematic elements. + +// Elements that are present in a base file but not in its corresponding translation file. +const baseFileOnly = []; +// Elements that are present in a translation file but not in its corresponding base file. +const translatedFileOnly = []; +// Elements that are present in the English file but not in the currently checked base translation file. +const enOnly = []; +// Elements that are present in the currently checked base translation file but not in the English file. +const translatedOnly = []; +// Elements that have different values in the currently checked base translation file and the English file. +const different = []; + +function addNewLangToArray(array, lang) { + array.push({ + lang: lang, + elements: [] + }); +} + +langs.forEach(lang => { + addNewLangToArray(baseFileOnly, lang); + addNewLangToArray(translatedFileOnly, lang); + addNewLangToArray(enOnly, lang); + addNewLangToArray(translatedOnly, lang); + addNewLangToArray(different, lang); + + // Try to load the translation file and its corresponding base file. + if (!fs.existsSync(lang + '.json')) { + exitWithError('Unable to find the ' + lang + '.json file.'); + } + let translationData = JSON.parse(fs.readFileSync(lang + '.json', 'utf8')); + + if (!fs.existsSync(lang + '_base.json')) { + exitWithError('Unable to find the ' + lang + '_base.json language file.'); + } + let baseTranslationData = JSON.parse(fs.readFileSync(lang + '_base.json', 'utf8')); + + // Check the differences in the elements of the translation file and its base file. + checkElement('', '', baseTranslationData, translationData, baseFileOnly, true); + checkElement('', '', translationData, baseTranslationData, translatedFileOnly, true); + + // Check the differences in the elements and content of the base translation file the English file. + if (checkFull) { + checkElement('', '', currentData, baseTranslationData, enOnly, false); + checkElement('', '', baseTranslationData, currentData, translatedOnly, true); + } +}); + + +// Check recursively if the elements and content of two language objects are the same. +// +// path: path of the currently checked element. As this function works with nested elements, +// the path is the name of all the parents, separated by a dot. +// key: name of the current element. +// fist: first element for the comparation. +// second: second element for the comparation. +// arrayForMissingElements: array in which the list of "fist" elements that are not in "second" +// will be added. +// ignoreDifferences: if false, each time the content of an element in "fist" is different to the +// same element in "second" that element will be added to the "different" array. +function checkElement(path, key, fist, second, arrayForMissingElements, ignoreDifferences) { + let pathPrefix = ''; + if (path.length > 0) { + pathPrefix = '.'; + } + + // This means that, at some point, the code found an element in the "first" branch that is + // not in the "second" branch. + if (second === undefined || second === null) { + arrayForMissingElements[arrayForMissingElements.length - 1].elements.push(path + pathPrefix + key); + return; + } + + if (typeof fist !== 'object') { + // If the current element is a string, compare the contents, but ony if ignoreDifferences + // is true. + if (!ignoreDifferences && fist != second) { + different[different.length - 1].elements.push(path + pathPrefix + key); + } + } else { + // If the current element is an object, check the childs. + Object.keys(fist).forEach(currentKey => { + checkElement(path + pathPrefix + key, currentKey, fist[currentKey], second[currentKey], arrayForMissingElements, ignoreDifferences); + }); + } +} + +///////////////////////////////////////////// +// Results processing +///////////////////////////////////////////// + +// Becomes true if any of the verifications failed. +let failedValidation = false; + +// If "failedValidation" is false, writes to the console the header of the error list +// and updates the value of "failedValidation" to true. +function updateErrorSumary() { + if (!failedValidation) { + failedValidation = true; + console.log('The following problems were found:', '\n'); + } +} + +// Checks all arrays for errors. This loop is for the languages. +for (let i = 0; i < baseFileOnly.length; i++) { + + // This loop if for checking all the arrays. + [baseFileOnly, translatedFileOnly, enOnly, translatedOnly, different].forEach((array, idx) => { + // If the array has elements, it means that errors were found. + if (array[i].elements.length > 0) { + updateErrorSumary(); + + // Show the appropriate error text according to the current array. + if (idx === 0) { + console.log('The \"' + baseFileOnly[i].lang + '_base.json\" base file has elements that are not present in \"' + baseFileOnly[i].lang + '.json\":'); + } else if (idx === 1) { + console.log("\"" + translatedFileOnly[i].lang + '.json\" has elements that are not present in the \"' + baseFileOnly[i].lang + '_base.json\" base file:'); + } else if (idx === 2) { + console.log('The \"en.json\" file has elements that are not present in the \"' + enOnly[i].lang + '_base.json\" base file:'); + } else if (idx === 3) { + console.log('The \"' + translatedOnly[i].lang + '_base.json\" base file has elements that are not present in \"en.json\":'); + } else if (idx === 4) { + console.log('The \"' + different[i].lang + '_base.json\" base file has values that do not match the ones in \"en.json\":'); + } + // Show all the elements with errors. + array[i].elements.forEach(element => console.log(element)); + console.log(''); + } + }); +} + +// If no error was detected, show a success message on the console. If not, exit with an error code. +if (!failedValidation) { + console.log('The verification passed without problems.'); +} else { + process.exit(1); +} + +function exitWithError(errorMessage) { + console.log('Error: ' + errorMessage) + process.exit(1); +} diff --git a/src/gui/static/dist/assets/i18n/en.json b/src/gui/static/dist/assets/i18n/en.json new file mode 100644 index 0000000..2026efd --- /dev/null +++ b/src/gui/static/dist/assets/i18n/en.json @@ -0,0 +1,626 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "Coin Hours", + "usd": "USD", + "loading": "Loading...", + "new": "New", + "load": "Load", + "success": "Success", + "warning": "Warning", + "changes-made": "The changes have been made." + }, + + "errors": { + "error": "Error", + "fetch-version": "Unable to fetch latest release version from Github", + "incorrect-password": "Incorrect password", + "error-decrypting": "Error decrypting the wallet", + "api-disabled": "API disabled", + "no-wallet": "Wallet does not exist", + "no-outputs": "No unspent outputs", + "window-size": "The window is too narrow for the content" + }, + + "title": { + "language": "Select Language", + "wallets": "Wallets", + "send": "Send", + "history": "History", + "buy-coin": "Buy Skycoin", + "network": "Networking", + "blockchain": "Blockchain", + "outputs": "Outputs", + "transactions": "Transactions", + "pending-txs": "Pending Transactions", + "backup": "Backup Wallet", + "explorer": "Skycoin Explorer", + "seed": "Wallet Seed", + "reset": "Reset Password", + "exchange": "Exchange", + "select-address": "Select Address", + "order-history": "Order history" + }, + + "header": { + "syncing-blocks": "Syncing blocks", + "update1": "Wallet update", + "update2": "available.", + "synchronizing": "The wallet is synchronizing. Data you see may not be updated.", + "pending-txs1": "There are some", + "pending-txs2": "pending transactions.", + "pending-txs3": "Data you see may not be updated.", + + "errors": { + "no-connections": "No connections active, your client is not connected to any other nodes!", + "no-backend1": "Cannot reach backend. Please restart the app and/or seek help on our", + "no-backend2": "Telegram.", + "no-backend3": "", + "csrf": "Security vulnerability: CSRF is not working, please exit immediately." + } + }, + + "password": { + "title": "Enter Password", + "label": "Password", + "confirm-label": "Confirm password", + "button": "Proceed", + "reset-link": "I forgot my password" + }, + + "buy": { + "deposit-address": "Choose an address to generate a BTC deposit link for:", + "select-address": "Select address", + "generate": "Generate", + "deposit-location": "Deposit Location", + "deposit-location-desc": "Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.", + "make-choice": "Make a choice", + "wallets-desc": "Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.", + "send": "Send Bitcoin", + "send-desc": "Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.", + "fraction-warning": "Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!", + "receive": "Receive Sky", + "receive-desc": "After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.", + "status-button": "Status:", + "check-status-button": "Check Status", + "new-order-button": "New Order" + }, + + "wizard": { + "wallet-desc": "If you don't have a Skycoin wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to \"Load Wallet\" and enter your seed.", + "encrypt-desc": "Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.", + "hardware-wallet-link": "Using a Skywallet?", + "finish-button": "Finish", + "back-button": "Back", + + "confirm": { + "title": "Safeguard your seed!", + "desc": "We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your Skycoin wallet!", + "checkbox": "It’s safe, I swear.", + "button": "Continue" + } + }, + + "wallet": { + "new-address": "New Address", + "new-addresses": "New Addresses", + "show-empty": "Show Empty", + "hide-empty": "Hide Empty", + "encrypt": "Encrypt Wallet", + "decrypt": "Decrypt Wallet", + "decrypt-warning": "Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.", + "delete": "Delete Wallet", + "edit": "Edit Wallet", + "add": "Add Wallet", + "load": "Load Wallet", + "encryption-enabled": "Encryption enabled", + "encryption-disabled": "Encryption disabled", + "hw-security-warning": "Possible security risk. Access the Skywallet options (by pressing the \"Skywallet\" button below the wallets list) while the device is connected for more information.", + "wallet": "Wallet", + "hardware-wallet": "Skywallet", + "delete-confirmation": "WARNING: The wallet \"{{ name }}\" will be removed from the list. To add it again, you will have to reconnect the device and open the Skywallet options (by pressing the \"Skywallet\" button below the wallets list). Do you want to continue?", + "delete-confirmation-check": "Yeah, I want to delete the wallet.", + "max-hardware-wallets-error": "You have already reached the max number of addresses that can be added to the Skywallet.", + "add-many-confirmation": "WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?", + + "new": { + "create-title": "Create Wallet", + "load-title": "Load Wallet", + "encrypt-title": "Encrypt Wallet", + "name-label": "Name", + "words-number": "How many word the seed has", + "seed-label": "Seed", + "confirm-seed-label": "Confirm seed", + "seed-warning": "Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!", + "create-button": "Create", + "load-button": "Load", + "cancel-button": "Cancel", + "12-words": "12 words", + "24-words": "24 words", + "generate-12-seed": "Generate 12 word seed", + "generate-24-seed": "Generate 24 word seed", + "encrypt": "Encrypt wallet", + "encrypt-warning": "We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.", + "unconventional-seed-title": "Possible error", + "unconventional-seed-text": "You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.", + "unconventional-seed-check": "Continue with the unconventional seed.", + "synchronizing-warning-title": "Warning", + "synchronizing-warning-text": "The wallet is still synchronizing and some addresses may not be restored. If some addresses are not restored, please wait for the wallet to be fully synchronized and add them again manually.", + "synchronizing-warning-continue": "Continue", + "synchronizing-warning-cancel": "Cancel", + "wallet-created": "The wallet has been added to the list.", + + "seed": { + "enter-seed": "Press here to enter your seed.", + "change-seed": "Press to change", + "confirm-seed": "Press here to confirm your seed.", + "confirmed-seed": "Seed confirmed.", + "use-custom-seed": "Press here if you want to enter the seed manually.", + "use-normal-seed": "Press here if you want to enter the seed using the recommended method.", + "custom-seed-warning-title": "Warning", + "custom-seed-warning-text": "This option is only recommended for advanced users. Making mistakes with the seed could cause you to lose access to the funds in case of a problem.", + "custom-seed-warning-text-recovering": "To avoid possible problems, this option should only be used if you want to recover an unconventional seed.", + "custom-seed-warning-check": "I understand the risks and want to continue", + "custom-seed-warning-cancel": "Cancel", + "custom-seed-warning-continue": "Continue", + "incorrect-word": "The word you have entered does not match the requested one.", + "invalid-seed": "The seed you have entered is not valid. Please try again.", + "enter-word": "Enter the word #{{number}}", + "new-seed-help": "You must enter the words of the seed that was generated by the system, to confirm it.", + "recover-seed-help": "Please be sure to enter the correct words in the correct order." + } + }, + + "rename": { + "title": "Rename Wallet", + "name-label": "Name", + "cancel-button": "Cancel", + "rename-button": "Rename" + }, + + "add-addresses": { + "title": "Select quantity", + "name-quantity": "How many addresses to create", + "cancel-button": "Cancel", + "create-button": "Create", + "error": "There was an unexpected error. Please try again." + }, + + "address": { + "show": "Press to show", + "copy": "Copy", + "copy-address": "Copy address", + "copied": "Copied!", + "confirm": "Confirm address", + "outputs": "Unspent outputs", + "history": "History" + } + }, + + "qr": { + "title": "QR Code", + "title-read-only": "QR Code", + "data": "QR Data:", + "address": "Address:", + "request-link": "Request specific amount", + "amount": "Request amount:", + "hours": "Request hours:", + "message": "Message:", + "invalid": "(invalid value)", + "copied": "The text has been copied to the clipboard." + }, + + "send": { + "synchronizing-warning": "The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?", + "from-label": "Send from", + "to-label": "Send to", + "amount-label": "Amount", + "personal-note-label": "Personal note", + "personal-note-help": "Use this field to add a text for allowing you to identify the transaction in the future. This text is saved locally, so it will only be visible from this computer", + "wallet-label": "Wallet", + "addresses-label": "Addresses", + "invalid-amount": "Please enter a valid amount", + "convert-confirmation": "Do you also want the already introduced amount to be converted from {{from}} to {{to}}?", + "convert-confirmation-plural": "Do you also want the already introduced amounts to be converted from {{from}} to {{to}}?", + "send-all-available-coins": "send all", + "no-wallet-selected": "You must select a wallet first.", + "precision-error-warning": "A precision error was detected during conversion. Please check the amount that will be sent.", + "invaid-amount-warning": "An invalid value was detected during conversion. Please check the amount that will be sent.", + "precision-errors-warning": "Precision errors were detected during conversion. Please check the amount that will be sent.", + "invaid-amounts-warning": "Invalid values were detected during conversion. Please check the amount that will be sent.", + "multiple-problems-warning": "Some values were not converted because they were invalid or could have been converted with precision errors. Please check the amount that will be sent.", + "no-coins-left": "There are no coins left to send.", + "addresses-help": "Limit the addresses from where the coins and hours could be sent", + "all-addresses": "All the addresses of the selected wallet", + "outputs-label": "Unspent outputs", + "outputs-help": "Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown", + "all-outputs": "All the outputs of the selected addresses", + "available-msg-part1": "With your current selection you can send up to", + "available-msg-part2": "and", + "available-msg-part3": "(at least", + "available-msg-part4": "must be used for the transaction fee).", + "change-address-label": "Custom change address", + "change-address-select": "Select", + "change-address-help": "Address to receive change. If it's not provided, it will be chosen automatically. Click on the \"Select\" link to choose an address from one of your wallets", + "destinations-label": "Destinations", + "destinations-help1": "Destination addresses and their coins", + "destinations-help2": "Destination addresses, their coins and coin hours", + "hours-allocation-label": "Automatic coin hours allocation", + "options-label": "Options", + "value-label": "Coin hours share factor", + "value-help": "The higher the value, the more coin hours will be sent to the recipients and less will be retained", + "preview-button": "Preview", + "send-button": "Send", + "back-button": "Back", + "simple": "Simple", + "advanced": "Advanced", + "select-wallet": "Select Wallet", + "error-saving-note": "The transaction was successfully sent, but it was not possible to save the note.", + "sent": "Transaction successfully sent.", + "total": "Total:", + + "bulk-send": { + "title": "Bulk Send", + "indications": "To send to multiple destinations in a quick way, type each address, coin amount and hour amount (optional) on a line, separated by a comma. Example: if you want to send 10 coins and 5 hours to the \"xyz\" address, type \"xyz,10,5\"; if you want the hours to be calculated automatically, type \"xyz,10\". Decimal values must be separated with a dot.", + "process": "Process", + "error-no-data": "There is no text to process.", + "error-inconsistent-data": "If you set how many hours you want to send to a destinations, you must do so for all destinations.", + "error-invalid-data": "The entered text has an invalid format." + } + }, + + "reset": { + "wallet-label": "Wallet", + "seed-label": "Wallet seed", + "password-label": "New password (leave empty if you want the wallet not to be encrypted)", + "confirm-label": "Confirm new password", + "reset-button": "Reset", + "done": "Password successfully changed." + }, + + "tx": { + "transaction": "Transaction", + "confirm-transaction": "Confirm Transaction", + "from": "From", + "to": "To", + "date": "Date", + "status": "Status", + "coins": "Coins", + "hours": "Hours", + "id": "Tx ID", + "note": "Note", + "without-note": "Without note", + "show-more": "Show more", + "hours-moved": "moved", + "hours-sent": "sent", + "hours-received": "received", + "hours-burned": "burned", + "inputs": "Inputs", + "outputs": "Outputs", + "confirmed": "Confirmed", + "pending": "Pending", + "current-rate": "Calculated at the current rate" + }, + + "edit-note": { + "title": "Edit note", + "cancel-button": "Cancel", + "change-button": "Change" + }, + + "backup": { + "wallet-directory": "Wallet Directory:", + "seed-warning": "BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.", + "desc": "Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.", + "close-button": "Close", + "wallet": "Wallet Label", + "filename": "Filename", + "seed": "Seed", + "show-seed": "Show seed", + "no-wallets": "No encrypted wallets" + }, + + "blockchain": { + "blocks": "Number of blocks", + "time": "Timestamp of last block", + "hash": "Hash of last block", + "current-supply": "Current SKY supply", + "total-supply": "Total SKY supply", + "current-coinhour-supply": "Current Coin Hours supply", + "total-coinhour-supply": "Total Coin Hours supply" + }, + + "network": { + "peer": "Peer", + "source": "Source", + "block-height": "Block height", + "block-height-short": "Block", + "last-seen": "Last seen", + "last-received": "Last received", + "last-sent": "Last sent", + "in": "Incoming", + "out": "Outgoing", + + "sources": { + "default": "Default peer", + "exchange": "Peer exchange" + } + }, + + "pending-txs": { + "timestamp": "Timestamp", + "txid": "Transaction ID", + "none": "No pending transactions", + "my": "Mine", + "all": "All" + }, + + "history": { + "tx-detail": "Transaction Detail", + "moving": "Internally moving", + "moved": "Internally moved", + "sending": "Sending", + "sent": "Sent", + "received": "Received", + "receiving": "Receiving", + "pending": "Pending", + "note": "Note", + "no-txs": "You have no transaction history", + "no-txs-filter": "There are no transactions matching the current filter criteria", + "no-filter": "No filter active (press to select wallets/addresses)", + "filter": "Active filter: ", + "filters": "Active filters: ", + "all-addresses": "All addresses" + }, + + "teller": { + "done": "Completed", + "waiting-confirm": "Waiting for confirmation", + "waiting-deposit": "Waiting for Bitcoin deposit", + "waiting-send": "Waiting to send Skycoin", + "unknown": "Unknown" + }, + + "confirmation" : { + "header-text": "Confirmation", + "confirm-button": "Yes", + "cancel-button": "No", + "close": "Close" + }, + + "service": { + "api" : { + "server-error": "Server error" + }, + "wallet": { + "not-enough-hours": "Not enough available Coin Hours to perform the transaction!" + } + }, + + "hardware-wallet": { + "general" : { + "default-wallet-name": "New Skywallet", + "error-disconnected": "Unable to perform the operation. The Skywallet is not connected.", + "simple-error": "Error. Unable to perform the operation.", + "generic-error": "Unable to perform the operation. Make sure you have connected a valid Skywallet and that it is not waiting for input.", + "generic-error-internet": "Unable to perform the operation. Make sure you have connected a valid Skywallet that is not waiting for input and that you have a connection to the internet/node.", + "error-incorrect-wallet": "Unable to perform the operation. The connected Skywallet is different from the expected one.", + "error-incorrect-pin": "Unable to perform the operation. The PIN you have entered is incorrect.", + "confirm": "Please confirm the operation on the Skywallet.", + "confirm-and-more": "Please confirm the operation on the Skywallet and follow the instructions displayed.", + "follow": "Please follow the instructions displayed on the Skywallet.", + "close": "Close", + "cancel": "Cancel", + "continue": "Continue", + "completed": "Operation completed successfully.", + "refused": "The operation failed or was canceled.", + "name-updated": "The name used to identify this Skywallet in the wallet list has been updated to match the one shown on the device." + }, + "errors": { + "too-many-inputs-outputs": "The transaction has too many inputs or outputs for the Skywallet. Please try again creating several smaller transactions, each one with a smaller number of recipients (if the current transaction has many) or coins.", + "daemon-connection": "Problem connecting to the Skywallet service.", + "timeout": "The operation was canceled due to inactivity. Please try again.", + "invalid-address-generated": "There was a problem with the address generator and the operation had to be canceled.", + "invalid-address": "Invalid address.", + "not-in-bootloader-mode": "To use this option the Skywallet must be in bootloader mode." + }, + "security-warning" : { + "title": "Security warning", + "text": "The last time this Skywallet was connected, one or more security warnings were found. We recommend that you open the Skywallet options (by pressing the link below) while the device is connected and solve the security problems before continuing.", + "link": "Open the Skywallet options window.", + "check": "I understand the risks and want to continue", + "continue": "Continue", + "cancel": "Cancel" + }, + "options" : { + "connecting": "Connecting...", + "disconnected": "No Skywallet detected. Please connect a Skywallet to use this option.", + "unconfigured-detected-title": "Unconfigured Skywallet", + "unconfigured-detected": "A seedless Skywallet has been detected. Select \"Configure automatically\" if you want to configure it as a brand new wallet and start using it. Select \"Restore backup\" if you want to configure the Skywallet with a previously created seed backup.", + "configured-detected": "Skywallet detected. The device is identified in the wallets list as:", + "security-warnings-title": "Security warnings", + "security-warning-title": "Security warning", + "unchecked-version-warning": "It was not possible to verify if the firmware of your Skywallet is up to date. This could be due to problems with your internet connection or because the service is under maintenance.", + "outdated-version-warning": "The firmware of your Skywallet is outdated. We recommend you to update it as soon as possible to ensure safety. To do this, select the \"Update firmware\" option.", + "backup-warning": "You should backup the Skywallet seed or you could lose access to the funds in case of problems. To do this, select the \"Create a backup\" option.", + "pin-warning": "The connected Skywallet does not have a PIN. The PIN code protects the Skywallet from unauthorized parties accessing the device. To create a PIN code, select the \"Create PIN code\" option.", + "options": "Options:", + "update-firmware": "Update firmware", + "configure-automatically": "Configure automatically", + "restore-backup": "Restore backup", + "create-backup": "Create a backup", + "wipe": "Wipe the device", + "confirm-seed": "Confirm seed", + "create-pin": "Create PIN code", + "change-pin": "Change PIN code", + "delete-pin": "Delete PIN code", + "forgotten-pin1": "If you cannot access the wallet because you have forgotten the PIN, you can wipe the Skywallet and then restore it with the seed by clicking", + "forgotten-pin2": "here.", + "firmware-version": "Device firmware version:" + }, + "update-firmware-warning" : { + "title": "Outdated Firmware", + "text": "WARNING: the firmware in your Skywallet is outdated. To stay safe, it is recommended to update it.", + "cancel": "Cancel", + "update": "Update" + }, + "update-firmware" : { + "title-connecting": "Connecting...", + "title-update": "Update Firmware", + "title-install": "Install Firmware", + "text-downloading": "Checking device and downloading files...", + "text-bootloader": "WARNING: if you have already configured this device, before continuing you must have a backup of your seed or you could permanently lose access to the funds.", + "text-not-bootloader": "To update the firmware of your Skywallet you must connect it in bootloader mode (connect it to the computer while pressing the two physical buttons of the device). WARNING: if you have already configured this device, before continuing you must have a backup of your seed or you could permanently lose access to the funds.", + "text-no-firmware": "Welcome. The currently connected Skywallet does not have a firmware installed. A firmware will now be installed so you can start using the device. NOTE: if you have already configured this device and want to recover the funds, you will need your seed.", + "check": "I understand the risks and want to continue", + "follow": "The firmware update has been sent to the Skywallet. Please continue the process on the device.", + "connection-error": "It was not possible to download the firmware. This could be due to problems with your internet connection or because the service is under maintenance.", + "timeout": "The operation was canceled due to inactivity. Please disconnect the device, reconnect it and try again.", + "finished": "Your device has been configured correctly. Please unplug it before continuing." + }, + "generate-seed" : { + "text": "Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.", + "configuring": "Configuring..." + }, + "restore-seed" : { + "text": "Before proceeding, please select the number of words that the seed you want to recover has.", + "check-text": "You can use this option to enter a seed and check if it is equal to the one in the Skywallet. Before start, select the number of words the seed you want to check has.", + "warning" : "WARNING: to avoid potential problems, use only seeds created with a Skywallet.", + "error-wrong-word": "Error: The retyped word does not match the one requested by the Skywallet.", + "error-invalid-seed": "Error: The seed is not valid. Please be sure to enter the correct words in the correct order.", + "error-wrong-seed": "Error: The seed is valid but does not match the one in the device.", + "correct-seed": "The seed is valid and matches the one in the device." + }, + "added" : { + "title": "New Skywallet", + "configuring": "New Skywallet detected. Configuring...", + "done": "Done", + "added1": "The connected Skywallet has been added to the wallets list with the following name:", + "added2": "Now you can check the balance and the addresses of the Skywallet even when it is not connected. Additionally, you can change the name of the wallet or remove it from the wallets list, if you wish.", + "characters-warning": "If you use non-standard English characters, the name may not be displayed correctly on the device.", + "ok": "Ok" + }, + "wipe" : { + "warning": "WARNING: All the data on the Skywallet will be deleted. If you do not have a backup, you will not be able to access your funds again.", + "confirm-delete": "Also remove from the wallets list" + }, + "create-backup" : { + "warning": "WARNING: You can only create a backup of your Skywallet seed once. If you decide to continue, you will have to write down a group of words (it is recommended to do it on paper and not on a computer) that will appear on the screen of the Skywallet and store the list in a safe place. Anyone with access to the word list (the \"seed\") will be able access the wallet funds, so extreme caution is advised.", + "instructions": "Write down the word list that appear on the screen of the Skywallet. Make sure you respect the order and write each word correctly." + }, + "seed-word" : { + "title": "Enter word", + "info1": "Enter the word shown on the device", + "info2": "You will be asked to enter the words of your backup seed in random order. Also, additional random words could be requested.", + "word": "Requested word", + "error-invalid-word": "The entered word is not valid.", + "error-loading-words": "Loading the word list. Please wait." + }, + "change-pin" : { + "pin-mismatch": "Unable to perform the operation. The PINs you have entered do not match." + }, + "remove-pin" : { + "warning": "WARNING: It is not recommended to remove the PIN code from your Skywallet, as it will be vulnerable to being used by unauthorized parties in case of loss or theft.", + "check": "I understand the risks and want to continue" + }, + "enter-pin" : { + "title": "Enter PIN", + "title-change-current": "Enter the current PIN", + "title-change-new": "Enter the new PIN", + "title-change-confirm": "Confirm the new PIN", + "instructions": "The PIN layout is displayed on the Skywallet screen.", + "instructions-tx": "Enter the PIN to confirm and sign the transaction.", + "instructions-change": "Please enter a secure PIN consisting of 4 to 8 numbers.", + "help": "Need help?" + }, + "pin-help" : { + "title": "Help", + "part1": "When it is necessary to enter the PIN to continue, the Skywallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol •.", + "part2": "To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the Skywallet and press the corresponding buttons in the software wallet. For example, if the PIN is \"23\" and the number 2 is in the upper left, number 3 in the middle of the Skywallet numbers matrix, press the upper left and middle button in that order in the software wallet.", + "part3": "If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is \"23\", you can not simply type \"23\" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the Skywallet. Taking into account the previous example, you would have to press the \"7\" and \"5\" keys, because those are the keys that you are in the same position as the numbers shown by the Skywallet." + }, + "create-tx" : { + "title": "Create transaction", + "upper-text": "Please confirm the operation in the Skywallet after verifying if the following data matches EXACTLY with the transaction you wish to send and with those shown by the Skywallet:", + "lower-text": "If any data does not correspond to what the Skywallet shows or the transaction you wish to send, cancel the operation on your Skywallet.", + "send-p1": "and", + "send-p2": "to" + }, + "confirm-address" : { + "title": "Confirm address", + "instructions": "Please confirm on the Skywallet if the address is:", + "short-confirmation": "Address confirmed.", + "confirmation": "Address confirmed. For security, you can re-show the address in the Skywallet using the \"Confirm address\" option, in the menu that you can display by pressing the button at the right of the address balance." + } + }, + + "time-from-now": { + "few-seconds": "a few seconds ago", + "minute": "one minute ago", + "minutes": "{{time}} minutes ago", + "hour": "one hour ago", + "hours": "{{time}} hours ago", + "day": "one day ago", + "days": "{{time}} days ago" + }, + + "exchange": { + "you-send": "You send", + "you-get": "You get (approx.)", + "to-address": "To {{coin}} address", + "price": "Exchange rate", + "time-15": "Exchange time", + "exchange-button": "Exchange", + "min-amount": "Minimum amount:", + "max-amount": "Maximum amount:", + "agree-1": "I agree with", + "agree-2": "Terms of Use", + "agree-3": "and", + "agree-4": "Privacy Policy", + "powered-by": "Powered by", + "need-help": "Need help?", + "support-portal": "Support portal", + "history": "Order history", + "order-not-found": "Order not found", + "status": "Status", + "exchanging": "Exchanging {{from}} for {{to}}", + "select": "Select", + "offline": "Exchange is temporarily offline", + "problem-connecting": "Unable to connect with the service. Please check your Internet connection and try again later.", + "invalid-address": "Invalid address.", + "statuses": { + "user-waiting": "Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below", + "user-waiting-info": "The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.", + "market-waiting-confirmations": "Waiting for transaction confirmations", + "market-waiting-confirmations-info": "The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.", + "market-confirmed": "Transaction accepted", + "market-confirmed-info": "The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.", + "market-exchanged": "Traded {{from}} for {{to}}", + "market-exchanged-info": "The exchange has been made. The funds will be transferred to your address in a moment.", + "market-withdraw-waiting": "Sending {{to}} to your address", + "market-withdraw-waiting-info": "The process for sending the coins to your address has been initiated.", + "complete": "Exchange completed!", + "complete-info": "The funds have been successfully sent to your address.", + "error": "Error occurred", + "error-info": "There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page.", + "user-deposit-timeout": "Order canceled due to inactivity", + "user-deposit-timeout-info": "The system has canceled the order because no deposit was detected, please open a new order. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page." + }, + "history-window": { + "address": "Address", + "date": "Date" + }, + "details": { + "exchange-addr": "Exchange address (valid for this exchange operation only)", + "exchange-addr-tag": "Payment ID or Destination Tag which must be used for the transaction", + "tx-id": "Transaction ID", + "order-id": "Order ID", + "initial-price": "Initial exchange rate", + "error-msg": "Error message", + "details": "Details", + "start-date": "Start date", + "back": "Back", + "back-alert": "The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the \"Order history\" button" + } + } +} diff --git a/src/gui/static/dist/assets/i18n/es.json b/src/gui/static/dist/assets/i18n/es.json new file mode 100644 index 0000000..8f9f20f --- /dev/null +++ b/src/gui/static/dist/assets/i18n/es.json @@ -0,0 +1,506 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "Coin Hours", + "usd": "USD", + "loading": "Cargando...", + "new": "Nueva", + "load": "Cargar" + }, + + "errors": { + "error": "Error", + "fetch-version": "No ha sido posible verificar la última versión desde Github", + "incorrect-password": "Contraseña incorrecta", + "error-decrypting": "Error al desencriptar la billetera", + "api-disabled": "API desabilitada", + "no-wallet": "La billetera no existe", + "no-outputs": "No hay salidas no gastadas", + "window-size": "La ventana es demasiado estrecha para el contenido" + }, + + "title": { + "language": "Seleccionar Lenguaje", + "wallets": "Billeteras", + "send": "Enviar", + "history": "Historial", + "buy-coin": "Comprar Skycoins", + "network": "Red", + "blockchain": "Blockchain", + "outputs": "Salidas", + "transactions": "Transacciones", + "pending-txs": "Transacciones Pendientes", + "backup": "Respaldar Billetera", + "explorer": "Explorador de Skycoin", + "seed": "Semilla de la Billetera", + "qrcode": "Código QR", + "reset": "Restablecer contraseña", + "exchange": "Intercambiar", + "select-address": "Seleccionar Dirección", + "order-history": "Historial de órdenes" + }, + + "header": { + "syncing-blocks": "Sincronizando bloques", + "update1": "La actualización", + "update2": "está disponible.", + "synchronizing": "El nodo está sincronizando. Los datos mostrados pueden estar desactualizados.", + "pending-txs1": "Hay una o más", + "pending-txs2": "transacciones pendientes.", + "pending-txs3": "Los datos mostrados pueden estar desactualizados.", + + "errors": { + "no-connections": "Sin conexiones activas, ¡el cliente no está conectado a otros nodos!", + "no-backend1": "Sin acceso al servidor. Por favor, reinicie la aplicación y/o contáctenos vía", + "no-backend2": "Telegram.", + "no-backend3": "", + "csrf": "Vulnerabilidad de seguridad: CSRF no funciona. Por favor, salga de inmediato." + } + }, + + "password": { + "title": "Introduzca Su Contraseña", + "label": "Contraseña", + "confirm-label": "Confirmar contraseña", + "button": "Continuar", + "reset-link": "He olvidado mi contraseña" + }, + + "buy": { + "deposit-address": "Seleccione una dirección para la cual generar un enlace de depósito BTC:", + "select-address": "Seleccione una dirección", + "generate": "Generar", + "deposit-location": "Localización de Depósito", + "deposit-location-desc": "Seleccione la billetera en la que desea que le depositemos sus Skycoins después de recibir los Bitcoins.", + "make-choice": "Realice una selección", + "wallets-desc": "Una nueva dirección BTC es generada cada vez que se selecciona una nueva billetera y dirección. Una única dirección de Skycoin puede tener asignadas hasta 5 direcciones BTC.", + "send": "Enviar Bitcoins", + "send-desc": "Envíe Bitcoins a la dirección abajo indicada. Al recibirlos, le depositaremos los Skycoins en una nueva dirección en la billetera seleccionada más arriba, a la tasa de cambio actual de {{ rate }} SKY/BTC.", + "fraction-warning": "¡Envíe sólo múltiplos de la tasa SKY/BTC! Los Skycoins son enviados en números enteros, ¡no se envían fracciones de SKY!", + "receive": "Recibir SKY", + "receive-desc": "Después de recibir los Bitcoins, le enviaremos sus Skycoins. El tiempo de espera para recibir sus SKY puede ser de entre 20 minutos y una hora.", + "status-button": "Estatus:", + "check-status-button": "Revisar Estatus", + "new-order-button": "Nueva Orden" + }, + + "wizard": { + "wallet-desc": "Si no tiene una billetera, use la semilla generada automáticamente para crear una nueva. Si ya tiene una billetera, seleccione \"Cargar\" e introduzca su semilla.", + "encrypt-desc": "Incremente la seguridad de su billetera encriptándola. Al introducir una contraseña más abajo, su billetera será encriptada. Sólo quien tenga la contraseña podrá acceder a la billetera y retirar fondos.", + "hardware-wallet-link": "¿Utilizando una billetera de hardware?", + "finish-button": "Finalizar", + "back-button": "Volver", + + "confirm": { + "title": "¡Resguarde su semilla!", + "desc": "Queremos asegurarnos de que ha anotado su semilla y la ha almacenado en un lugar seguro. ¡Si olvida su semilla, NO podrá recuperar su billetera!", + "checkbox": "Está segura, lo garantizo.", + "button": "Continuar" + } + }, + + "wallet": { + "new-address": "Nueva Dirección", + "new-addresses": "Nuevas Direcciones", + "show-empty": "Mostrar Vacías", + "hide-empty": "Ocultar Vacías", + "encrypt": "Encriptar Billetera", + "decrypt": "Desencriptar Billetera", + "decrypt-warning": "Advertencia: por razones de seguridad, no se recomienda mantener las carteras desencriptadas. Se aconseja precaución.", + "delete" : "Borrar Billetera", + "edit": "Editar Billetera", + "add": "Agregar Billetera", + "load": "Cargar Billetera", + "encryption-enabled": "Encriptado habilitado", + "encryption-disabled": "Encriptado deshabilitado", + "hw-security-warning": "Posible riesgo de seguridad. Acceda a las opciones de la billetera de hardware (presionando el botón \"Billetera de Hardware\" debajo de la lista de billeteras) mientras el dispositivo está conectado, para más información.", + "wallet": "Billetera", + "hardware-wallet": "Billetera de Hardware", + "delete-confirmation": "ADVERTENCIA: la billetera \"{{ name }}\" será removida de la lista. Para agregarla nuevamente, deberá volver a conectar el dispositivo y abrir las opciones de la billetera del hardware (presionando el botón \"Billetera de hardware\" debajo de la lista de las billeteras). ¿Desea continuar?", + "delete-confirmation-check": "Sí, quiero borrar la billetera.", + "max-hardware-wallets-error": "Ya ha alcanzado el número máximo de direcciones que se puede agregar a la billetera de hardware.", + "add-many-confirmation": "ADVERTENCIA: si agrega demasiadas direcciones sin usar las anteriores o si usa las últimas y no las primeras, es posible que algunas direcciones no se recuperen automáticamente si intenta restaurar la billetera con la semilla (tendrá que agregarlas manualmente). ¿Desea continuar?", + + "new": { + "create-title": "Crear Billetera", + "load-title": "Cargar Billetera", + "encrypt-title": "Encriptar la billetera", + "name-label": "Nombre", + "seed-label": "Semilla", + "confirm-seed-label": "Confirmar semilla", + "seed-warning": "¡Recuerde esta semilla! Manténgala en un lugar seguro. ¡Si olvida su semilla, no podrá recuperar la billetera!", + "create-button": "Crear", + "load-button": "Cargar", + "cancel-button": "Cancelar", + "12-words": "12 palabras", + "24-words": "24 palabras", + "generate-12-seed": "Generar una semilla de 12 palabras", + "generate-24-seed": "Generar una semilla de 24 palabras", + "encrypt": "Encriptar billetera", + "encrypt-warning": "Le sugerimos que encripte con una contraseña cada una de sus billeteras. Si olvida su contraseña, puede restaurarla con la semilla. Asegúrese de guardar su semilla en un lugar seguro antes de encriptar la billetera.", + "unconventional-seed-title": "Posible error", + "unconventional-seed-text": "Usted introdujo una semilla no convencional. Si lo hizo por alguna razón en especial, puede continuar (sólo recomendable para usuarios avanzados). Sin embargo, si su intención es utilizar una semilla normal del sistema, usted debe borrar los textos y/o caracteres especiales adicionales.", + "unconventional-seed-check": "Continuar con la semilla no convencional." + }, + + "rename": { + "title": "Renombrar Billetera", + "name-label": "Nombre", + "cancel-button": "Cancelar", + "rename-button": "Renombrar" + }, + + "add-addresses": { + "title": "Seleccionar cantidad", + "name-quantity": "Cantidad de direcciones a crear", + "cancel-button": "Cancelar", + "create-button": "Crear" + }, + + "address": { + "show": "Presione para mostrar", + "copy": "Copiar", + "copy-address": "Copiar Dirección", + "copied": "¡Copiado!", + "confirm": "Confirmar Dirección", + "outputs": "Salidas No Gastadas", + "history": "Historial" + } + }, + + "send": { + "synchronizing-warning": "La billetera todavía está sincronizando los datos, por lo que el saldo que se muestra puede ser incorrecto. ¿Seguro de que desea continuar?", + "from-label": "Enviar desde", + "to-label": "Enviar a", + "amount-label": "Cantidad", + "notes-label": "Notas", + "wallet-label": "Billetera", + "addresses-label": "Dirección", + "invalid-amount": "Por favor introduzca una cantidad válida", + "addresses-help": "Limite las direcciones desde donde se podrían enviar las monedas y las horas", + "all-addresses": "Todas las direcciones de la billetera seleccionada", + "outputs-label": "Salidas no gastadas", + "outputs-help": "Limite las salidas no gastadas desde donde se podrían enviar las monedas y las horas. Solo se muestran las salidas de las direcciones seleccionadas.", + "all-outputs": "Todas las salidas no gastadas de las direcciones seleccionadas", + "available-msg-part1": "Con su selección actual puede enviar hasta", + "available-msg-part2": "y", + "available-msg-part3": "(al menos", + "available-msg-part4": "deben ser utilizadas para la tarifa de transacción).", + "change-address-label": "Dirección de retorno personalizada", + "change-address-select": "Seleccionar", + "change-address-help": "Dirección para recibir el cambio. Si no se proporciona, será elegida automáticamente. Haga clic en el enlace \"Seleccionar\" para elegir una dirección de una de sus billeteras", + "destinations-label": "Destinos", + "destinations-help1": "Direcciones de destino y sus monedas", + "destinations-help2": "Direcciones de destino, sus monedas y coin hours", + "hours-allocation-label": "Distribución automática de coin hours", + "options-label": "Opciones", + "value-label": "Factor de distribución de las coin hours", + "value-help": "Mientras mayor sea el valor, más coin hours se enviarán a las salidas", + "preview-button": "Preview", + "send-button": "Enviar", + "back-button": "Volver", + "simple": "Simple", + "advanced": "Advanzado", + "select-wallet": "Seleccionar Billetera" + }, + + "reset": { + "wallet-label": "Billetera", + "seed-label": "Semilla de la billetera", + "password-label": "Nueva contraseña (deje en blanco si desea que la billetera no esté encriptada)", + "confirm-label": "Confirme la contraseña", + "reset-button": "Restaurar" + }, + + "tx": { + "transaction": "Transacción", + "confirm-transaction": "Confirmar Transacción", + "from": "Desde", + "to": "A", + "date": "Fecha", + "status": "Estatus", + "coins": "Monedas", + "hours": "Horas", + "id": "Tx ID", + "show-more": "Mostrar más", + "hours-moved": "movida(s)", + "hours-sent": "enviada(s)", + "hours-received": "recibida(s)", + "hours-burned": "quemada(s)", + "inputs": "Entradas", + "outputs": "Salidas", + "confirmed": "Confirmada", + "pending": "Pendiente", + "current-rate": "Calculado a la tasa actual" + }, + + "backup": { + "wallet-directory": "Directorio de la Billetera:", + "seed-warning": "RESPALDE SU SEMILLA. EN PAPEL. EN UN LUGAR SEGURO. Mientras tenga su semilla, podrá recuperar las monedas.", + "desc": "Use la tabla de más abajo para obtener las semillas de sus billeteras encriptadas.
Para obtener las semillas de las billeteras no encriptadas, abra el directorio de más arriba, abra los archivos .wlt en un editor de texto y recupere las semillas.", + "close-button": "Cerrar", + "wallet": "Nombre de la Billetera", + "filename": "Archivo", + "seed": "Semilla", + "show-seed": "Mostrar semilla", + "no-wallets": "No hay billeteras encriptadas" + }, + + "blockchain": { + "blocks": "Cantidad de bloques", + "time": "Fecha del último bloque", + "hash": "Hash del último bloque", + "current-supply": "Suministro de SKY actual", + "total-supply": "Suministro de SKY total", + "current-coinhour-supply": "Suministro de Coin Hours actual", + "total-coinhour-supply": "Suministro de Coin Hours total" + }, + + "network": { + "peer": "Par", + "source": "Fuente", + "block-height": "Altura del bloque", + "block-height-short": "Bloque", + "last-seen": "Última vez visto", + "last-received": "Última recepción", + "last-sent": "Último envío", + "in": "Entrante", + "out": "Saliente", + + "sources": { + "default": "Par por defecto", + "exchange": "Intercambio de pares" + } + }, + + "pending-txs": { + "timestamp": "Fecha", + "txid": "ID de la transacción", + "none": "Actualmente no hay transacciones pendientes", + "my": "Mías", + "all": "Todas" + }, + + "history": { + "tx-detail": "Detalles de la Transacción", + "moving": "Moviendo internamente", + "moved": "Movida internamente", + "sending": "Enviando", + "sent": "Enviada", + "received": "Recibida", + "receiving": "Recibiendo", + "pending": "Pendiente", + "no-txs": "Usted no tiene historial de transacciones", + "no-txs-filter": "No hay transacciones que coincidan con los criterios de filtro actuales", + "no-filter": "Sin filtros activos (Presione para seleccionar billeteras/direcciones)", + "filter": "Filtro activo: ", + "filters": "Filtros activo: ", + "all-addresses": "Todas las direcciones" + }, + + "teller": { + "done": "Completado", + "waiting-confirm": "Esperando confirmación", + "waiting-deposit": "Esperando depósito de Bitcoins", + "waiting-send": "Esperando para envíar Skycoins", + "unknown": "Desconocido" + }, + + "confirmation" : { + "header-text": "Confirmación", + "confirm-button": "Sí", + "cancel-button": "No", + "close": "Cerrar" + }, + + "service": { + "api" : { + "server-error": "Error de servidor" + }, + "wallet": { + "not-enough-hours": "¡No cuenta con suficientes Coin Hours para realizar la operación!" + } + }, + + "hardware-wallet": { + "general" : { + "default-wallet-name": "Nueva billetera de hardware", + "error-disconnected": "No se puede realizar la operación. La billetera de hardware no está conectada.", + "simple-error": "Error, no se puede realizar la operación.", + "generic-error": "No se puede realizar la operación. Asegúrese de haber conectado una billetera de hardware válida y de que no esté esperando por alguna confirmación o respuesta.", + "generic-error-internet": "No se puede realizar la operación. Asegúrese de haber conectado una billetera de hardware válida que no esté esperando por alguna confirmación o respuesta y de que su equipo cuente con conexión a internet y al nodo.", + "error-incorrect-wallet": "No se puede realizar la operación. La billetera de hardware conectada es diferente a la esperada.", + "error-incorrect-pin": "No se puede realizar la operación. El PIN que ha introducido no es correcto.", + "confirm": "Por favor, confirme la operación en la billetera de hardware.", + "confirm-and-more": "Por favor, confirme la operación en la billetera de hardware y siga las instrucciones.", + "close": "Cerrar", + "cancel": "Cancelar", + "continue": "Continuar", + "completed": "La operación se realizó con éxito.", + "refused": "La operación falló o fue cancelada." + }, + "errors": { + "too-many-inputs": "La transacción tiene demasiadas entradas y no se puede procesar. Por favor, póngase en contacto con el soporte técnico.", + "too-many-outputs": "La transacción tiene demasiadas salidas y no se puede procesar. Por favor, póngase en contacto con el soporte técnico." + }, + "security-warning" : { + "title": "Advertencia de seguridad", + "text": "La última vez que se conectó esta billetera de hardware, se encontraron una o más advertencias de seguridad. Le recomendamos que abra las opciones de billetera de hardware (presionando el botón \"Billetera de hardware\" debajo de la lista de billeteras) mientras el dispositivo está conectado y resuelva los problemas de seguridad antes de continuar.", + "check": "Entiendo los riesgos y deseo continuar.", + "continue": "Continuar", + "cancel": "Cancelar" + }, + "options" : { + "connecting": "Conectando...", + "disconnected": "Billetera de hardware no detectada. Por favor, conecte una billetera de hardware para usar esta opción.", + "unconfigured-detected-title": "Billetera de hardware no configurada", + "unconfigured-detected": "Se ha detectado una billetera de hardware sin semilla. Seleccione \"Configurar automáticamente\" si desea configurarla como una billetera nueva y comenzar a usarla inmediatamente, o seleccione \"Restaurar una copia de seguridad\" si desea configurarla con la copia de seguridad de una semilla creada anteriormente y así poder acceder a sus fondos de nuevo.", + "configured-detected": "Billetera de hardware detectada. El dispositivo se identifica en la lista de billeteras como:", + "security-warnings-title": "Advertencias de seguridad", + "security-warning-title": "Advertencia de seguridad", + "backup-warning": "Debe hacer una copia de seguridad de la semilla de la billetera de hardware o podría perder acceso a los fondos en caso de problemas. Para hacer esto, seleccione la opción \"Crear copia de seguridad\".", + "pin-warning": "La billetera de hardware conectada no tiene un PIN. El código PIN protege la billetera de hardware en caso de pérdida, robo y pirateo. Para crear un código PIN, seleccione la opción \"Crear código PIN\".", + "options": "Opciones:", + "configure-automatically": "Configurar automáticamente", + "restore-backup": "Restaurar una copia de seguridad", + "create-backup": "Crear copia de seguridad", + "wipe": "Borrar el dispositivo", + "confirm-seed": "Confirmar la semilla", + "create-pin": "Crear código PIN", + "change-pin": "Cambiar el código PIN", + "forgotten-pin1": "Si no puede acceder a la billetera porque ha olvidado el PIN, puede borrar la billetera del hardware y luego restaurarla con la semilla haciendo clic", + "forgotten-pin2": "aquí." + }, + "generate-seed" : { + "text": "Antes de continuar, puede seleccionar el número de palabras que desea que tenga la semilla. La semilla es una lista de palabras que se pueden usar para recuperar el acceso a las monedas en caso de problemas. Ambos valores son seguros, por lo que si no tiene una razón especial para seleccionar uno u otro, puede dejar el valor predeterminado.", + "configuring": "Configurando..." + }, + "restore-seed" : { + "text": "Antes de continuar, por favor seleccione la cantidad de palabras de la semilla que desea recuperar.", + "check-text": "Puede usar esta opción para ingresar una semilla y verificar si es igual a la de la billetera de hardware. Antes de comenzar, seleccione el número de palabras de la semilla que desea verificar.", + "warning" : "ADVERTENCIA: para evitar posibles problemas, use solo semillas creadas con una billetera de hardware de la misma marca/modelo.", + "error-wrong-word": "Error: la palabra introducida no coincide con la solicitada por la billetera de hardware.", + "error-invalid-seed": "Error: La semilla no es válida. Por favor, asegúrese de ingresar las palabras correctas en el orden correcto.", + "error-wrong-seed": "Error: la semilla es válida pero no coincide con la del dispositivo." + }, + "added" : { + "title": "Nueva Billetera de Hardware", + "configuring": "Nueva billetera de hardware detectada. Configurando...", + "done": "Hecho", + "added1": "La billetera de hardware conectada se ha agregado a la lista de billeteras con el siguiente nombre:", + "added2": "Ahora puede consultar el saldo y las direcciones de la billetera de hardware incluso cuando no está conectada. Además, puede cambiar el nombre de la billetera o eliminarla de la lista de billeteras, si lo desea." + }, + "wipe" : { + "warning": "ADVERTENCIA: Todos los datos en la billetera de hardware serán eliminados. Si no tiene una copia de seguridad, no podrá volver a acceder a sus fondos.", + "confirm-delete": "Quitar también de la lista de billeteras." + }, + "create-backup" : { + "warning": "ADVERTENCIA: Solo puede usar esta opción para hacer una copia de seguridad de la semilla de su billetera de hardware una vez. Si decide continuar, tendrá que escribir un grupo de palabras (se recomienda hacerlo en papel y no en una computadora) que aparecerán en la pantalla de la billetera de hardware y almacenar la lista en un lugar seguro. Cualquier persona con acceso a la lista de palabras (la \"semilla\") podrá acceder a los fondos de la cartera, por lo que se recomienda extremar las precauciones.", + "instructions": "Escriba la lista de palabras que aparecen en la pantalla de la billetera de hardware. Asegúrate de respetar el orden y escribir cada palabra correctamente." + }, + "seed-word" : { + "title": "Ingresar palabra", + "info1": "Introduzca la palabra indicada en el dispositivo", + "info2": "Se le pedirá que ingrese las palabras de su semilla de respaldo en orden aleatorio, más algunas palabras adicionales.", + "word": "Palabra solicitada", + "error-invalid-word": "La palabra introducida no es válida.", + "error-loading-words": "Cargando la lista de palabras. Por favor espere." + }, + "change-pin" : { + "pin-mismatch": "No se puede realizar la operación. Los dos PIN que ha introducido no coinciden." + }, + "enter-pin" : { + "title": "Ingresar PIN", + "title-change-current": "Ingrese el PIN actual", + "title-change-new": "Ingrese el nuevo PIN", + "title-change-confirm": "Confirme el nuevo PIN", + "instructions": "El patrón de números del PIN se muestra en la pantalla de la billetera de hardware.", + "instructions-tx": "Introduzca el PIN para confirmar y firmar la transacción.", + "instructions-change": "Ingrese un PIN difícil de adivinar de entre 4 y 8 números.", + "help": "¿Necesita ayuda?" + }, + "pin-help" : { + "title": "Ayuda", + "part1": "Cuando sea necesario ingresar el PIN para continuar, la pantalla de la billetera del hardware mostrará una matriz de 9 casillas con números en orden aleatorio (el orden cambia cada vez) y se le pedirá que ingrese el PIN en la billetera de software usando una matriz de 9 botones que simplemente muestran el símbolo #.", + "part2": "Para ingresar el PIN, mire la posición de los números del PIN en la matriz de números en la pantalla de la billetera de hardware y presione los botones correspondientes en la billetera de software. Por ejemplo, si el PIN es \"23\", el número 2 está en la esquina superior izquierda y el número 3 en el centro de la matriz de números de billetera de hardware, presione los botones superior izquierdo y central, en ese orden, en la billetera de software.", + "part3": "Si lo desea, también puede usar el teclado numérico para ingresar el PIN. Sin embargo, como en el ejemplo anterior, si el PIN es \"23\", no puede simplemente escribir \"23\" con el teclado numérico, sino que deberá presionar las teclas que están en la posición donde están los números 2 y 3 en la pantalla de la billetera de hardware." + }, + "create-tx" : { + "title": "Crear transacción" + }, + "confirm-address" : { + "title": "Confirmar dirección", + "instructions": "Por favor confirme en la billetera de hardware si la dirección es:", + "short-confirmation": "Dirección confirmada.", + "confirmation": "Dirección confirmada. Por seguridad, puede volver a mostrar la dirección en la billetera de hardware usando la opción \"Confirmar dirección\", en el menú que puede mostrar presionando el botón a la derecha del balance de la direccion." + } + }, + + "time-from-now": { + "few-seconds": "hace pocos segundos", + "minute": "hace un minuto", + "minutes": "hace {{time}} minutos", + "hour": "hace una hora", + "hours": "hace {{time}} horas", + "day": "hace un día", + "days": "hace {{time}} días" + }, + + "exchange": { + "you-send": "Usted envía", + "you-get": "Usted recibe (aprox.)", + "to-address": "A la dirección de {{coin}}", + "price": "Tasa de cambio", + "time-15": "Duración del intercambio", + "exchange-button": "Intercambiar", + "min-amount": "Monto minimo:", + "max-amount": "Monto maximo:", + "agree-1": "Acepto los", + "agree-2": "Términos de Uso", + "agree-3": "y la ", + "agree-4": "Política de Privacidad", + "powered-by": "Manejado por", + "need-help": "¿Necesita ayuda?", + "support-portal": "Portal de soporte", + "history": "Historial de órdenes", + "order-not-found": "Orden no encontrada", + "status": "Estado", + "exchanging": "Intercambiando {{from}} por {{to}}", + "select": "Seleccionar", + "offline": "El servicio está temporalmente offline", + "problem-connecting": "No se puede conectar con el servicio. Por favor, compruebe su conexión a Internet y vuelva a intentarlo más tarde.", + "invalid-address": "Dirección inválida.", + "statuses": { + "user-waiting": "Esperando el deposito. Por favor, envíe {{amount}} {{from}} a la dirección de intercambio indicada más abajo", + "user-waiting-info": "El sistema está a la espera de que realice el depósito en la dirección de intercambio. El proceso de intercambio comenzará después de que se detecte el depósito y sea confirmado en la cadena de bloques. Si ya ha realizado el depósito, debería ser detectado en breve.", + "market-waiting-confirmations": "Esperando las confirmaciones de la transacción", + "market-waiting-confirmations-info": "El depósito ya ha sido detectado y el sistema está esperando que sea confirmado en la cadena de bloques.", + "market-confirmed": "Transacción aceptada", + "market-confirmed-info": "La transacción ya ha sido confirmada en la cadena de bloques. Haciendo los preparativos para realizar el intercambio pronto.", + "market-exchanged": "{{from}} intercambiado por {{to}}", + "market-exchanged-info": "El intercambio se ha realizado. Los fondos serán transferidos a su dirección en un momento.", + "market-withdraw-waiting": "Enviando {{to}} a su dirección", + "market-withdraw-waiting-info": "Se ha iniciado el proceso para enviar las monedas a su dirección.", + "complete": "¡Intercambio completado!", + "complete-info": "Los fondos han sido enviados con éxito a su dirección.", + "error": "Se produjo un error", + "error-info": "Hubo un error en la operación, puede encontrar más información más abajo. Si necesita ayuda, por favor guarde todos los datos de operación que se muestran más abajo y comuníquese con soporte técnico utilizando el enlace que se encuentra en la parte inferior derecha de esta página." + }, + "history-window": { + "address": "Dirección", + "date": "Fecha" + }, + "details": { + "exchange-addr": "Dirección de intercambio", + "exchange-addr-tag": "Payment ID o Destination Tag que debe usarse para la transacción", + "tx-id": "ID de la transacción", + "order-id": "ID de la orden", + "initial-price": "Tasa de cambio inicial", + "error-msg": "Mensaje de error", + "details": "Detalles", + "start-date": "Fecha de inicio", + "back": "Volver", + "back-alert": "La operación aún está en progreso. ¿Realmente desea volver al formulario? Puede ver el progreso de esta operación nuevamente presionando el botón \"Historial de pedidos\"" + } + } +} diff --git a/src/gui/static/dist/assets/i18n/es_base.json b/src/gui/static/dist/assets/i18n/es_base.json new file mode 100644 index 0000000..402d23c --- /dev/null +++ b/src/gui/static/dist/assets/i18n/es_base.json @@ -0,0 +1,506 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "Coin Hours", + "usd": "USD", + "loading": "Loading...", + "new": "New", + "load": "Load" + }, + + "errors": { + "error": "Error", + "fetch-version": "Unable to fetch latest release version from Github", + "incorrect-password": "Incorrect password", + "error-decrypting": "Error decrypting the wallet", + "api-disabled": "API disabled", + "no-wallet": "Wallet does not exist", + "no-outputs": "No unspent outputs", + "window-size": "The window is too narrow for the content" + }, + + "title": { + "language": "Select Language", + "wallets": "Wallets", + "send": "Send", + "history": "History", + "buy-coin": "Buy Skycoin", + "network": "Networking", + "blockchain": "Blockchain", + "outputs": "Outputs", + "transactions": "Transactions", + "pending-txs": "Pending Transactions", + "backup": "Backup Wallet", + "explorer": "Skycoin Explorer", + "seed": "Wallet Seed", + "qrcode": "QR Code", + "reset": "Reset Password", + "exchange": "Exchange", + "select-address": "Select Address", + "order-history": "Order history" + }, + + "header": { + "syncing-blocks": "Syncing blocks", + "update1": "Wallet update", + "update2": "available.", + "synchronizing": "The wallet is synchronizing. Data you see may not be updated.", + "pending-txs1": "There are some", + "pending-txs2": "pending transactions.", + "pending-txs3": "Data you see may not be updated.", + + "errors": { + "no-connections": "No connections active, your client is not connected to any other nodes!", + "no-backend1": "Cannot reach backend. Please restart the app and/or seek help on our", + "no-backend2": "Telegram.", + "no-backend3": "", + "csrf": "Security vulnerability: CSRF is not working, please exit immediately." + } + }, + + "password": { + "title": "Enter Password", + "label": "Password", + "confirm-label": "Confirm password", + "button": "Proceed", + "reset-link": "I forgot my password" + }, + + "buy": { + "deposit-address": "Choose an address to generate a BTC deposit link for:", + "select-address": "Select address", + "generate": "Generate", + "deposit-location": "Deposit Location", + "deposit-location-desc": "Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.", + "make-choice": "Make a choice", + "wallets-desc": "Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.", + "send": "Send Bitcoin", + "send-desc": "Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.", + "fraction-warning": "Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!", + "receive": "Receive Sky", + "receive-desc": "After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.", + "status-button": "Status:", + "check-status-button": "Check Status", + "new-order-button": "New Order" + }, + + "wizard": { + "wallet-desc": "If you don't have a Skycoin wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to \"Load Wallet\" and enter your seed.", + "encrypt-desc": "Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.", + "hardware-wallet-link": "Using a hardware wallet?", + "finish-button": "Finish", + "back-button": "Back", + + "confirm": { + "title": "Safeguard your seed!", + "desc": "We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your Skycoin wallet!", + "checkbox": "It’s safe, I swear.", + "button": "Continue" + } + }, + + "wallet": { + "new-address": "New Address", + "new-addresses": "New Addresses", + "show-empty": "Show Empty", + "hide-empty": "Hide Empty", + "encrypt": "Encrypt Wallet", + "decrypt": "Decrypt Wallet", + "decrypt-warning": "Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.", + "delete": "Delete Wallet", + "edit": "Edit Wallet", + "add": "Add Wallet", + "load": "Load Wallet", + "encryption-enabled": "Encryption enabled", + "encryption-disabled": "Encryption disabled", + "hw-security-warning": "Possible security risk. Access the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list) while the device is connected for more information.", + "wallet": "Wallet", + "hardware-wallet": "Hardware Wallet", + "delete-confirmation": "WARNING: The wallet \"{{ name }}\" will be removed from the list. To add it again, you will have to reconnect the device and open the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list). Do you want to continue?", + "delete-confirmation-check": "Yeah, I want to delete the wallet.", + "max-hardware-wallets-error": "You have already reached the max number of addresses that can be added to the hardware wallet.", + "add-many-confirmation": "WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?", + + "new": { + "create-title": "Create Wallet", + "load-title": "Load Wallet", + "encrypt-title": "Encrypt Wallet", + "name-label": "Name", + "seed-label": "Seed", + "confirm-seed-label": "Confirm seed", + "seed-warning": "Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!", + "create-button": "Create", + "load-button": "Load", + "cancel-button": "Cancel", + "12-words": "12 words", + "24-words": "24 words", + "generate-12-seed": "Generate 12 word seed", + "generate-24-seed": "Generate 24 word seed", + "encrypt": "Encrypt wallet", + "encrypt-warning": "We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.", + "unconventional-seed-title": "Possible error", + "unconventional-seed-text": "You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.", + "unconventional-seed-check": "Continue with the unconventional seed." + }, + + "rename": { + "title": "Rename Wallet", + "name-label": "Name", + "cancel-button": "Cancel", + "rename-button": "Rename" + }, + + "add-addresses": { + "title": "Select quantity", + "name-quantity": "How many addresses to create", + "cancel-button": "Cancel", + "create-button": "Create" + }, + + "address": { + "show": "Press to show", + "copy": "Copy", + "copy-address": "Copy address", + "copied": "Copied!", + "confirm": "Confirm address", + "outputs": "Unspent outputs", + "history": "History" + } + }, + + "send": { + "synchronizing-warning": "The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?", + "from-label": "Send from", + "to-label": "Send to", + "amount-label": "Amount", + "notes-label": "Notes", + "wallet-label": "Wallet", + "addresses-label": "Addresses", + "invalid-amount": "Please enter a valid amount", + "addresses-help": "Limit the addresses from where the coins and hours could be sent", + "all-addresses": "All the addresses of the selected wallet", + "outputs-label": "Unspent outputs", + "outputs-help": "Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown", + "all-outputs": "All the outputs of the selected addresses", + "available-msg-part1": "With your current selection you can send up to", + "available-msg-part2": "and", + "available-msg-part3": "(at least", + "available-msg-part4": "must be used for the transaction fee).", + "change-address-label": "Custom change address", + "change-address-select": "Select", + "change-address-help": "Address to receive change. If it's not provided, it will be chosen automatically. Click on the \"Select\" link to choose an address from one of your wallets", + "destinations-label": "Destinations", + "destinations-help1": "Destination addresses and their coins", + "destinations-help2": "Destination addresses, their coins and coin hours", + "hours-allocation-label": "Automatic coin hours allocation", + "options-label": "Options", + "value-label": "Coin hours share factor", + "value-help": "The higher the value, the more coin hours will be sent to outputs", + "preview-button": "Preview", + "send-button": "Send", + "back-button": "Back", + "simple": "Simple", + "advanced": "Advanced", + "select-wallet": "Select Wallet" + }, + + "reset": { + "wallet-label": "Wallet", + "seed-label": "Wallet seed", + "password-label": "New password (leave empty if you want the wallet not to be encrypted)", + "confirm-label": "Confirm new password", + "reset-button": "Reset" + }, + + "tx": { + "transaction": "Transaction", + "confirm-transaction": "Confirm Transaction", + "from": "From", + "to": "To", + "date": "Date", + "status": "Status", + "coins": "Coins", + "hours": "Hours", + "id": "Tx ID", + "show-more": "Show more", + "hours-moved": "moved", + "hours-sent": "sent", + "hours-received": "received", + "hours-burned": "burned", + "inputs": "Inputs", + "outputs": "Outputs", + "confirmed": "Confirmed", + "pending": "Pending", + "current-rate": "Calculated at the current rate" + }, + + "backup": { + "wallet-directory": "Wallet Directory:", + "seed-warning": "BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.", + "desc": "Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.", + "close-button": "Close", + "wallet": "Wallet Label", + "filename": "Filename", + "seed": "Seed", + "show-seed": "Show seed", + "no-wallets": "No encrypted wallets" + }, + + "blockchain": { + "blocks": "Number of blocks", + "time": "Timestamp of last block", + "hash": "Hash of last block", + "current-supply": "Current SKY supply", + "total-supply": "Total SKY supply", + "current-coinhour-supply": "Current Coin Hours supply", + "total-coinhour-supply": "Total Coin Hours supply" + }, + + "network": { + "peer": "Peer", + "source": "Source", + "block-height": "Block height", + "block-height-short": "Block", + "last-seen": "Last seen", + "last-received": "Last received", + "last-sent": "Last sent", + "in": "Incoming", + "out": "Outgoing", + + "sources": { + "default": "Default peer", + "exchange": "Peer exchange" + } + }, + + "pending-txs": { + "timestamp": "Timestamp", + "txid": "Transaction ID", + "none": "No pending transactions", + "my": "Mine", + "all": "All" + }, + + "history": { + "tx-detail": "Transaction Detail", + "moving": "Internally moving", + "moved": "Internally moved", + "sending": "Sending", + "sent": "Sent", + "received": "Received", + "receiving": "Receiving", + "pending": "Pending", + "no-txs": "You have no transaction history", + "no-txs-filter": "There are no transactions matching the current filter criteria", + "no-filter": "No filter active (press to select wallets/addresses)", + "filter": "Active filter: ", + "filters": "Active filters: ", + "all-addresses": "All addresses" + }, + + "teller": { + "done": "Completed", + "waiting-confirm": "Waiting for confirmation", + "waiting-deposit": "Waiting for Bitcoin deposit", + "waiting-send": "Waiting to send Skycoin", + "unknown": "Unknown" + }, + + "confirmation" : { + "header-text": "Confirmation", + "confirm-button": "Yes", + "cancel-button": "No", + "close": "Close" + }, + + "service": { + "api" : { + "server-error": "Server error" + }, + "wallet": { + "not-enough-hours": "Not enough available Coin Hours to perform the transaction!" + } + }, + + "hardware-wallet": { + "general" : { + "default-wallet-name": "New hardware wallet", + "error-disconnected": "Unable to perform the operation. The hardware wallet is not connected.", + "simple-error": "Error, Unable to perform the operation.", + "generic-error": "Unable to perform the operation. Make sure you have connected a valid hardware wallet and that it is not waiting for input.", + "generic-error-internet": "Unable to perform the operation. Make sure you have connected a valid hardware wallet that is not waiting for input and that you have a connection to the internet/node.", + "error-incorrect-wallet": "Unable to perform the operation. The connected hardware wallet is different from the expected one.", + "error-incorrect-pin": "Unable to perform the operation. The PIN you have entered is not correct.", + "confirm": "Please, confirm the operation in the hardware wallet.", + "confirm-and-more": "Please, confirm the operation in the hardware wallet and follow the instructions.", + "close": "Close", + "cancel": "Cancel", + "continue": "Continue", + "completed": "Operation completed successfully.", + "refused": "The operation failed or was canceled." + }, + "errors": { + "too-many-inputs": "The transaction has too many inputs and can not be processed. Please contact technical support.", + "too-many-outputs": "The transaction has too many outputs and can not be processed. Please contact technical support." + }, + "security-warning" : { + "title": "Security warning", + "text": "The last time this hardware wallet was connected, one or more security warnings were found. We recommend you to open the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list) while the device is connected and solve the security problems before continuing.", + "check": "I understand the risks and want to continue", + "continue": "Continue", + "cancel": "Cancel" + }, + "options" : { + "connecting": "Connecting...", + "disconnected": "No hardware wallet detected. Please connect a hardware wallet to use this option.", + "unconfigured-detected-title": "Unconfigured hardware wallet", + "unconfigured-detected": "A seedless hardware wallet has been detected. Select \"Configure automatically\" if you want to configure it as a brand new wallet and start using it immediately, or select \"Restore backup\" if you want to configure it with a previously created seed backup and thus be able to access your funds again.", + "configured-detected": "Hardware wallet detected. The device is identified in the wallets list as:", + "security-warnings-title": "Security warnings", + "security-warning-title": "Security warning", + "backup-warning": "You should backup the hardware wallet seed or you could lose access to the funds in case of problems. To do this, select the \"Create a backup\" option.", + "pin-warning": "The connected hardware wallet does not have a PIN. The PIN code protects the hardware wallet in case of loss, theft and hacks. To create a PIN code, select the \"Create PIN code\" option.", + "options": "Options:", + "configure-automatically": "Configure automatically", + "restore-backup": "Restore backup", + "create-backup": "Create a backup", + "wipe": "Wipe the device", + "confirm-seed": "Confirm seed", + "create-pin": "Create PIN code", + "change-pin": "Change PIN code", + "forgotten-pin1": "If you can not access the wallet because you have forgotten the PIN, you can wipe the hardware wallet and then restore it with the seed by clicking", + "forgotten-pin2": "here." + }, + "generate-seed" : { + "text": "Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.", + "configuring": "Configuring..." + }, + "restore-seed" : { + "text": "Before proceeding, please select the number of words that the seed you want to recover has.", + "check-text": "You can use this option to enter a seed and check if it is equal to the one in the hardware wallet. Before start, select the number of words the seed you want to check has.", + "warning" : "WARNING: to avoid potential problems, use only seeds created with a hardware wallet from the same brand/model.", + "error-wrong-word": "Error: The retyped word does not match the one requested by the hardware wallet.", + "error-invalid-seed": "Error: The seed is not valid. Please be sure to enter the correct words in the correct order.", + "error-wrong-seed": "Error: The seed is valid but does not match the one in the device." + }, + "added" : { + "title": "New Hardware Wallet", + "configuring": "New hardware wallet detected. Configuring...", + "done": "Done", + "added1": "The connected hardware wallet has been added to the wallets list with the following name:", + "added2": "Now you can check the balance and the addresses of the hardware wallet even when it is not connected. Additionally, you can change the name of the wallet or remove it from the wallets list, if you wish." + }, + "wipe" : { + "warning": "WARNING: All the data in the hardware wallet will be deleted. If you do not have a backup, you will not be able to access your funds again.", + "confirm-delete": "Also remove from the wallets list" + }, + "create-backup" : { + "warning": "WARNING: You can only use this option to backup your hardware wallet seed once. If you decide to continue, you will have to write down a group of words (it is recommended to do it on paper and not on a computer) that will appear on the screen of the hardware wallet and store the list in a safe place. Anyone with access to the word list (the \"seed\") will be able access the wallet balance, so extreme caution is advised.", + "instructions": "Write down the word list that appear on the screen of the hardware wallet. Make sure you respect the order and write each word correctly." + }, + "seed-word" : { + "title": "Enter word", + "info1": "Enter the word indicated in the device", + "info2": "You will be asked to enter the words of your backup seed in random order, plus a few additional words.", + "word": "Requested word", + "error-invalid-word": "The entered word is not valid.", + "error-loading-words": "Loading the word list. Please wait." + }, + "change-pin" : { + "pin-mismatch": "Unable to perform the operation. Two PINs you have entered do not match." + }, + "enter-pin" : { + "title": "Enter PIN", + "title-change-current": "Enter the current PIN", + "title-change-new": "Enter the new PIN", + "title-change-confirm": "Confirm the new PIN", + "instructions": "The PIN layout is displayed on the hardware wallet screen.", + "instructions-tx": "Enter the PIN to confirm and sign the transaction.", + "instructions-change": "Please enter a hard-to-guess PIN of between 4 and 8 numbers.", + "help": "Need help?" + }, + "pin-help" : { + "title": "Help", + "part1": "When it is necessary to enter the PIN to continue, the hardware wallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol #.", + "part2": "To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the hardware wallet and press the corresponding buttons in the software wallet. For example, if the PIN is \"23\" and the number 2 is in the upper left, number 3 in the middle of the hardware wallet numbers matrix, press the upper left and middle button in that order in the software wallet.", + "part3": "If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is \"23\", you can not simply type \"23\" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the hardware wallet." + }, + "create-tx" : { + "title": "Create transaction" + }, + "confirm-address" : { + "title": "Confirm address", + "instructions": "Please confirm on the hardware wallet if the address is:", + "short-confirmation": "Address confirmed.", + "confirmation": "Address confirmed. For security, you can re-show the address in the hardware wallet using the \"Confirm address\" option, in the menu that you can display by pressing the button at the right of the address balance." + } + }, + + "time-from-now": { + "few-seconds": "a few seconds ago", + "minute": "one minute ago", + "minutes": "{{time}} minutes ago", + "hour": "one hour ago", + "hours": "{{time}} hours ago", + "day": "one day ago", + "days": "{{time}} days ago" + }, + + "exchange": { + "you-send": "You send", + "you-get": "You get (approx.)", + "to-address": "To {{coin}} address", + "price": "Exchange rate", + "time-15": "Exchange time", + "exchange-button": "Exchange", + "min-amount": "Minimum amount:", + "max-amount": "Maximum amount:", + "agree-1": "I agree with", + "agree-2": "Terms of Use", + "agree-3": "and", + "agree-4": "Privacy Policy", + "powered-by": "Powered by", + "need-help": "Need help?", + "support-portal": "Support portal", + "history": "Order history", + "order-not-found": "Order not found", + "status": "Status", + "exchanging": "Exchanging {{from}} for {{to}}", + "select": "Select", + "offline": "Exchange is temporarily offline", + "problem-connecting": "Unable to connect with the service. Please check your Internet connection and try again later.", + "invalid-address": "Invalid address.", + "statuses": { + "user-waiting": "Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below", + "user-waiting-info": "The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.", + "market-waiting-confirmations": "Waiting for transaction confirmations", + "market-waiting-confirmations-info": "The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.", + "market-confirmed": "Transaction accepted", + "market-confirmed-info": "The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.", + "market-exchanged": "Traded {{from}} for {{to}}", + "market-exchanged-info": "The exchange has been made. The funds will be transferred to your address in a moment.", + "market-withdraw-waiting": "Sending {{to}} to your address", + "market-withdraw-waiting-info": "The process for sending the coins to your address has been initiated.", + "complete": "Exchange completed!", + "complete-info": "The funds have been successfully sent to your address.", + "error": "Error occurred", + "error-info": "There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page." + }, + "history-window": { + "address": "Address", + "date": "Date" + }, + "details": { + "exchange-addr": "Exchange address", + "exchange-addr-tag": "Payment ID or Destination Tag which must be used for the transaction", + "tx-id": "Transaction ID", + "order-id": "Order ID", + "initial-price": "Initial exchange rate", + "error-msg": "Error message", + "details": "Details", + "start-date": "Start date", + "back": "Back", + "back-alert": "The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the \"Order history\" button" + } + } +} diff --git a/src/gui/static/dist/assets/i18n/ru.json b/src/gui/static/dist/assets/i18n/ru.json new file mode 100644 index 0000000..69cd50e --- /dev/null +++ b/src/gui/static/dist/assets/i18n/ru.json @@ -0,0 +1,250 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "CH", + "loading": "Загрузка...", + "new": "Ðовый", + "load": "Импортировать" + }, + + "errors": { + "fetch-version": "Ðе удалоÑÑŒ получить поÑледнюю верÑию Ñ Github", + "incorrect-password": "Ðеверный пароль", + "api-disabled": "API выключен", + "no-wallet": "Кошелёк не ÑущеÑтвует", + "no-outputs": "Ðе доÑтаточно ÑредÑтв" + }, + + "title": { + "wallets": "Кошельки", + "send": "Отправить", + "history": "ИÑториÑ", + "buy-coin": "Купить Skycoin", + "network": "Сеть", + "blockchain": "Блокчейн", + "outputs": "Выходы (Outputs)", + "transactions": "Транзакции", + "pending-txs": "Ðеподтверждённые транзакции", + "backup": "Резервное копирование", + "explorer": "Skycoin ÑкÑплорер", + "seed": "Фраза воÑтановлениÑ", + "qrcode": "QR-код" + }, + + "header": { + "syncing-blocks": "Идёт ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¾Ð²...", + "update1": "Обновление кошелька", + "update2": "доÑтупно.", + "pending-txs1": "СущеÑтвует", + "pending-txs2": "транзакции, требующие подтверждениÑ.", + "pending-txs3": "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть не актуальной. УбедитеÑÑŒ что у Ð²Ð°Ñ Ð¿Ñ€Ð¸ÑутÑтвует Ñоединение Ñ Ñетью.", + + "errors": { + "no-connections": "Ðет активных Ñоединений, ваш клиент не подключен к другим узлам!", + "no-backend1": "Ðет доÑтупа к ÑервиÑу. ПерезапуÑтите приложение или обратитÑеь за помощью в нашей группе", + "no-backend2": "в телеграмме.", + "no-backend3": "", + "csrf": "Возможные уÑзвимоÑти безопаÑноÑти: CSRF не работает." + } + }, + + "password": { + "title": "Введите пароль", + "label": "Пароль", + "confirm-label": "Подтвердите пароль", + "button": "Продолжить" + }, + + "buy": { + "deposit-address": "Выберите кошелёк Ð´Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ депозитного адреÑа:", + "select-address": "Выберите адреÑ", + "generate": "Сгенерировать", + "deposit-location": "ÐÐ´Ñ€ÐµÑ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ", + "deposit-location-desc": "Выберите кошелёк Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Skycoin, поÑле уÑпешно отправленного депозита.", + "make-choice": "Сделайте выбор", + "wallets-desc": "При выборе адреÑа, каждый раз генерируетÑÑ Ð½Ð¾Ð²Ñ‹Ð¹ Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð´ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð°. Один Ð°Ð´Ñ€ÐµÑ Ð¼Ð¾Ð¶ÐµÑ‚ быть прикреплён к ограниченному количеÑтву адреÑов.", + "send": "Пошлите выбранную криптовалюту", + "send-desc": "Отправьте выбранную вами криптовалюту на Ð°Ð´Ñ€ÐµÑ ÑƒÐºÐ°Ð·Ð°Ð½Ñ‹Ð¹ ниже. По получению и поÑле доÑтаточного Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶ÐµÐ½Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¾Ð², вы получите Skycoin на указаный Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾ курÑу {{ rate }} Skycoin/Selected Coin.", + "fraction-warning": "Рекомендовано поÑылать целые значениÑ.", + "receive": "Получить Skycoin", + "receive-desc": "ПоÑле Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¹ криптавалюты, вы получите Skycoin. Это может занÑÑ‚ÑŒ от неÑкольких Ñекунд до неÑкольких дней, в завиÑимоÑти от выбранного ÑпоÑоба оплаты и загруженноÑти Ñети.", + "status-button": "СтатуÑ:", + "check-status-button": "Проверить ÑтатуÑ", + "new-order-button": "Ðовый заказ", + "refresh": "Обновить", + "available-now": "ДоÑтупно:", + "choose-preference": "Выберите ÑпоÑоб оплаты. Имейте в виду, что некоторые ÑпоÑобы могут быть временно отключены.", + "choose": "Выберите вашу любимую крипту ;)", + "send-coin":"Отправить", + "send-coin-text-1": "на Ð°Ð´Ñ€ÐµÑ Ð½Ð¸Ð¶Ðµ. ПоÑле доÑтаточного количеÑтва подтверждений на блокчейне, вы получите Skycoin на выбранный вами кошелёк по курÑу" + }, + + "wizard": { + "wallet-desc": "ЕÑли у Ð²Ð°Ñ Ð½ÐµÑ‚ кошелька Skycoin, иÑпользуйте Ñгенерированную фразу Ð´Ð»Ñ ÐµÐ³Ð¾ ÑозданиÑ. ЕÑли фраза у Ð²Ð°Ñ ÑƒÐ¶Ðµ еÑÑ‚ÑŒ, нажмите \"Импортирование кошелька\" и введите вашу фразу.", + "encrypt-desc": "Ð”Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐµÐ¹ безопаÑти, рекомендуем добавить пароль Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ. СредÑтва можно будет отправлÑÑ‚ÑŒ только при наличии паролÑ. УбедитеÑÑŒ, что вы его помните.", + "finish-button": "Закончить", + "back-button": "Ðазад", + + "confirm": { + "title": "Держите Ñвою фразу в Ñохраном меÑте!", + "desc": "УбедитеÑÑŒ, что вы запиÑали фразу воÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ держите её в надёжном меÑте. При утере фразы вы потерÑете доÑтуп к вашему кошельку Skycoin!", + "checkbox": "КлÑнуÑÑŒ. Я запиÑал.", + "button": "Продолжить" + } + }, + + "wallet": { + "new-address": "Ðовый адреÑ", + "show-empty": "Показать пуÑтые", + "hide-empty": "Скрыть пуÑтые", + "encrypt": "Зашифровать кошелёк", + "decrypt": "РаÑшифровать кошелёк", + "edit": "Редактирвоать", + "add": "Ðовый кошелёк", + "load": "Импортировать", + "encryption-enabled": "Зашифрован", + "encryption-disabled": "Без шифрованиÑ", + "wallet": "Кошелёк", + + "new": { + "create-title": "Создать кошелёк", + "load-title": "Импортировать кошелёк", + "encrypt-title": "Шифровать кошелёк", + "name-label": "Ð˜Ð¼Ñ ÐºÐ¾ÑˆÐµÐ»ÑŒÐºÐ°", + "seed-label": "Фраза воÑтановлениÑ", + "confirm-seed-label": "Подтвердите фразу", + "seed-warning": "Запомните Ñта фразу или запишите и держите в надежном меÑте, в дали от чужих глаз. При потере фразы вы не Ñможете воÑтановить Skycoin кошелёк!", + "create-button": "Создать", + "load-button": "Импортировать", + "cancel-button": "Отмена", + "12-words": "12 Ñлов", + "24-words": "24 Ñлова", + "generate-12-seed": "Сгенирировать фразу из 12 Ñлов", + "generate-24-seed": "Сгенирировать фразу из 24 Ñлов", + "encrypt": "Включить шифрование", + "encrypt-warning": "Мы рекомендуем шифровать вÑе ваши кашельки при помощи надёжного паролÑ. Так же убедитеÑÑŒ, что фраза воÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñана и хранитÑÑ Ð² надёжном меÑте." + }, + + "rename": { + "title": "Переименование кошелька", + "name-label": "ИмÑ", + "cancel-button": "Отмена", + "rename-button": "Переименовать" + }, + + "address": { + "copy": "Копировать", + "copy-address": "Копировать адреÑ", + "copied": "Скопировано!", + "outputs": "Ðепотраченые выходы (Unspent Outputs)" + } + }, + + "send": { + "from-label": "Отправить Ñ", + "to-label": "Получить на", + "amount-label": "Сумма", + "notes-label": "Заметки", + "wallet-label": "Кошелёк", + "addresses-label": "ÐдреÑ", + "addresses-help": "ÐÐ´Ñ€ÐµÑ ÐºÐ¾ÑˆÐµÐ»ÑŒÐºÐ° Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ", + "change-address-label": "ÐÐ´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¾Ñтатка", + "change-address-help": "ÐÐ´Ñ€ÐµÑ Ð´Ð»Ñ Ñдачи. ЕÑли вы его не укажите, то он будет выбран автоматичеÑки", + "destinations-label": "ÐдреÑа получателей", + "destinations-help1": "ÐдреÑа получателей и Ñумма Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ", + "destinations-help2": "ÐдреÑа получателей, Ñумма Skycoin & CH Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ", + "hours-allocation-label": "ÐвтоматичеÑки подÑчитывать чаÑÑ‹ (CH)", + "options-label": "Дополнительно", + "value-label": "Фактор отправки чаÑов (CH)", + "value-help": "Чем больше фактор, тем больше CH будет отправлено вмеÑте Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸ÐµÐ¹", + "preview-button": "ПредпроÑмотр", + "send-button": "Отправить", + "back-button": "Ðазад", + "simple": "Обычный", + "advanced": "Продвинутый" + }, + + "tx": { + "transaction": "ТранзакциÑ", + "confirm-transaction": "Подтердите транзакцию", + "from": "Отправитель", + "to": "Получатель", + "date": "Дата", + "status": "СтатуÑ", + "coins": "Сумма", + "hours": "ЧаÑÑ‹", + "id": "TX ID", + "show-more": "Инфо", + "hours-sent": "отправлÑем", + "hours-burned": "Ñжигаем", + "inputs": "Входы", + "outputs": "Выходы", + "confirmed": "Подтверждена", + "pending": "Ожидание", + "current-rate": "По текущему курÑу" + }, + + "backup": { + "wallet-directory": "Папка кошелька:", + "seed-warning": "ДЕРЖИТЕ ФРÐЗУ ВОСТÐÐОВЛЕÐИЯ Ð’ ÐÐДÐЖÐОМ МЕСТЕ. ÐРБУМÐГЕ. ОФФЛÐЙÐ. ЕÑли вы держите фразу в надёжном меÑте, и никто не Ñмог её подглÑдеть - вашы токены в безопаÑноÑти.", + "desc": "Из таблицы ниже вы можете получить фразы Ð´Ð»Ñ Ð²Ð°ÑˆÐ¸Ñ… зашифрованных кошельков.
Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ„Ñ€Ð°Ð· воÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð² кошельках без шифрованиÑ, откройте папку указаную выше и найдите в ней файлы Ñ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸ÐµÐ¼ .wlt. Фраза хранитÑÑ Ð² них. Откройте при помощи любого (надёжного) текÑтового редактора", + "close-button": "Закрыть", + "wallet": "Ðазвание кошелька", + "filename": "Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°", + "seed": "Фраза", + "show-seed": "Показать фразу", + "no-wallets": "Кошельков Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸ÐµÐ¼ нет" + }, + + "blockchain": { + "blocks": "КоличеÑтво блоков", + "time": "Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледнего блока", + "hash": "Ð¥Ñш поÑледнего блока", + "current-supply": "Ð’Ñего Skycoin в обращении", + "total-supply": "Ð’Ñего Skycoin ÑущеÑтвует", + "current-coinhour-supply": "Ð’Ñего CH в обращении", + "total-coinhour-supply": "Ð’Ñего CH ÑущеÑтвует" + }, + + "network": { + "peer": "Пир (Peer)", + "source": "ИÑточник", + "block-height": "Ð’Ñ‹Ñота блока", + "last-seen": "ПоÑледний блок", + "last-received": "ПоÑледний полученый", + "last-sent": "ПоÑледний отправленый", + "in": "ВходÑщие", + "out": "ИÑходÑщие", + + "sources": { + "default": "Пир по-умолчанию", + "exchange": "Обмена пирами" + } + }, + + "pending-txs": { + "timestamp": "Метка времени", + "txid": "ID транзакции", + "none": "Ðе найдено траназкций ждущих подтверждений", + "my": "Мой", + "all": "Ð’Ñе" + }, + + "history": { + "tx-detail": "Детали о транзакции", + "sending": "ОтправлÑем", + "sent": "Отправлено", + "received": "Получено", + "receiving": "Получаем", + "pending": "ОжидаетÑÑ", + "no-txs": "У Ð²Ð°Ñ Ð½ÐµÑ‚ иÑтории транзакций" + }, + + "teller": { + "done": "Завершено", + "waiting-confirm": "Ожидаем подтверждений", + "waiting-deposit": "Ожидаем депозит", + "waiting-send": "ПоÑылаем Skycoin", + "unknown": "ÐеизвеÑтно" + } +} diff --git a/src/gui/static/dist/assets/i18n/zh.json b/src/gui/static/dist/assets/i18n/zh.json new file mode 100644 index 0000000..9990b31 --- /dev/null +++ b/src/gui/static/dist/assets/i18n/zh.json @@ -0,0 +1,506 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "å¸æ—¶", + "usd": "美元", + "loading": "加载中...", + "new": "æ–°", + "load": "加载" + }, + + "errors": { + "error": "错误", + "fetch-version": "无法从Github获å–最新版本", + "incorrect-password": "密ç é”™è¯¯", + "error-decrypting": "解密钱包时出错", + "api-disabled": "APIç¦ç”¨", + "no-wallet": "æ— å¯æ”¯ä»˜é’±åŒ…", + "no-outputs": "无未交易输出", + "window-size": "窗å£å¤ªçª„,内容放ä¸ä¸‹" + }, + + "title": { + "language": "选择语言", + "wallets": "钱包", + "send": "å‘é€", + "history": "历å²", + "buy-coin": "ä¹° Skycoin", + "network": "网络", + "blockchain": "区å—链", + "outputs": "未交易输出", + "transactions": "交易", + "pending-txs": "待处ç†äº¤æ˜“", + "backup": "备份钱包", + "explorer": "Skycoin Explorer", + "seed": "钱包ç§å­", + "qrcode": "QR代ç ", + "reset": "é‡ç½®å¯†ç ", + "exchange": "交易", + "select-address": "选择地å€", + "order-history": "订å•åŽ†å²" + }, + + "header": { + "syncing-blocks": "区å—åŒæ­¥ä¸­", + "update1": "钱包更新", + "update2": "å¯èŽ·å–", + "synchronizing": "钱包正在åŒæ­¥ã€‚你看到的数æ®å¯èƒ½ä¸æ˜¯æœ€æ–°çš„。", + "pending-txs1": "这里有一些", + "pending-txs2": "待处ç†äº¤æ˜“.", + "pending-txs3": "你看到的数æ®å¯èƒ½ä¸æ˜¯æœ€æ–°çš„。", + + "errors": { + "no-connections": "没有连接,你的客户端没有连接到任何其他节点", + "no-backend1": "ä¸èƒ½åˆ°è¾¾åŽç«¯ã€‚请é‡æ–°å¯åŠ¨åº”用程åºæˆ–寻求我们的帮助", + "no-backend2": "Telegram", + "no-backend3": "", + "csrf": "安全æ¼æ´ž: CSRF未工作,请立å³é€€å‡ºã€‚" + } + }, + + "password": { + "title": "输入密ç ", + "label": "密ç ", + "confirm-label": "确认密ç ", + "button": "继续", + "reset-link": "我忘记了密ç " + }, + + "buy": { + "deposit-address": "选择一个地å€æ¥ç”ŸæˆBTC充值链接,用于:", + "select-address": "选择地å€", + "generate": "生æˆ", + "deposit-location": "充值ä½ç½®", + "deposit-location-desc": "选择一个钱包,以在我们收到你的比特å¸åŽå……值Skycoin到该钱包", + "make-choice": "åšé€‰æ‹©", + "wallets-desc": "æ¯å½“选择一个新的钱包和地å€ï¼Œä¸€ä¸ªæ–°çš„BTC地å€å°†ä¼šç”Ÿæˆã€‚一个独立的Skycoin地å€æœ€å¤šå¯ç»‘定5个BTC地å€ã€‚", + "send": "å‘é€Bitcoin", + "send-desc": "å‘é€Bitcoin至如下地å€ã€‚一旦收到,我们将会按当å‰æ±‡çŽ‡: {{ rate }} SKY/BTC充值Skycoin到选中钱包的一个新地å€ã€‚", + "fraction-warning": "请按SKY/BTC汇率的å€æ•°å‘é€BTC! Skycoin是以整数å‘é€; SKYçš„å°æ•°ä½å°†ä¸ä¼šå‘é€", + "receive": "接收Sky", + "receive-desc": "收到你的比特å¸åŽï¼Œæˆ‘们将å‘é€Skycoin给你。你å¯èƒ½éœ€è¦20分钟到一个å°æ—¶æ‰èƒ½æ”¶åˆ°è¿™äº›SKY。", + "status-button": "状æ€:", + "check-status-button": "查看状æ€", + "new-order-button": "新订å•" + }, + + "wizard": { + "wallet-desc": "如果你没有Skycoin钱包,请使用生æˆçš„ç§å­æ¥åˆ›å»ºä¸€ä¸ªæ–°é’±åŒ…。如果你已ç»æœ‰ä¸€ä¸ªé’±åŒ…,切æ¢åˆ°\"加载钱包\"并输入你的ç§å­ã€‚", + "encrypt-desc": "通过加密æ¥å¢žåŠ é’±åŒ…的安全性。输入密ç åŽï¼Œä½ çš„钱包会被加密。åªæœ‰è¾“入密ç æ‰å¯ä»¥è®¿é—®çš„钱包或移动资金。", + "hardware-wallet-link": "使用硬件钱包?", + "finish-button": "完æˆ", + "back-button": "åŽé€€", + + "confirm": { + "title": "ä¿æŠ¤ä½ çš„ç§å­!", + "desc": "请确ä¿ä½ å·²ç»å†™ä¸‹ä½ çš„ç§å­å¹¶å°†å®ƒå‚¨å­˜åœ¨äº†ä¸€ä¸ªå®‰å…¨çš„地方。如果你忘记了ç§å­ï¼Œä½ å°†æ— æ³•æ¢å¤ä½ çš„Skycoin钱包", + "checkbox": "它很安全,我å‘誓。", + "button": "继续" + } + }, + + "wallet": { + "new-address": "新地å€", + "new-addresses": "新地å€", + "show-empty": "展示空地å€", + "hide-empty": "éšè—空地å€", + "encrypt": "加密钱包", + "decrypt": "解密钱包", + "decrypt-warning": "警告: 出于安全考虑,建议将钱包加密。建议谨慎一点。", + "delete": "删除钱包", + "edit": "编辑钱包", + "add": "添加钱包", + "load": "加载钱包", + "encryption-enabled": "加密已å¯ç”¨", + "encryption-disabled": "加密已ç¦ç”¨", + "hw-security-warning": "å¯èƒ½çš„安全风险。当硬件设备已连接时(点击钱包列表下的\"硬件钱包\"按钮)访问硬件钱包选项以获å–更多信æ¯", + "wallet": "钱包", + "hardware-wallet": "硬件钱包", + "delete-confirmation": "警告: 钱包\"{{ name }}\"将从列表中删除。若想é‡æ–°æ·»åŠ ï¼Œéœ€é‡æ–°è¿žæŽ¥è®¾å¤‡å¹¶æ‰“开硬件钱包的选项列表(点击钱包列表下的\"硬件钱包\"按钮)。你想继续å—?", + "delete-confirmation-check": "是的,我想è¦åˆ é™¤é’±åŒ…。", + "max-hardware-wallets-error": "你的硬件钱包里的地å€å·²ç»è¾¾åˆ°å…许的最大值。", + "add-many-confirmation": "警告: 如果你在ä¸ä½¿ç”¨å‰ä¸€ä¸ªåœ°å€çš„情况下添加太多地å€ï¼Œæˆ–者如果你使用的是最åŽä¸€ä¸ªåœ°å€è€Œä¸æ˜¯ç¬¬ä¸€ä¸ªåœ°å€ï¼Œé‚£ä¹ˆå¦‚果你å°è¯•ä½¿ç”¨ç§å­æ¢å¤é’±åŒ…,有些地å€å°†å¯èƒ½æ— æ³•è‡ªåŠ¨æ¢å¤ï¼ˆä½ å¿…须手动添加它们)。 你想继续å—?", + + "new": { + "create-title": "创建钱包", + "load-title": "加载钱包", + "encrypt-title": "加密钱包", + "name-label": "å称", + "seed-label": "ç§å­", + "confirm-seed-label": "确认ç§å­", + "seed-warning": "è®°ä½ç§å­! 把它ä¿å­˜åœ¨å®‰å…¨çš„地方。 如果你忘记了你的ç§å­ï¼Œä½ å°†æ— æ³•æ‰¾å›žä½ çš„钱包!", + "create-button": "创建", + "load-button": "加载", + "cancel-button": "删除", + "12-words": "12å­—", + "24-words": "24å­—", + "generate-12-seed": "生æˆ12å­—ç§å­", + "generate-24-seed": "生æˆ24å­—ç§å­", + "encrypt": "加密钱包", + "encrypt-warning": "我们建议你为æ¯ä¸ªé’±åŒ…设置一个独立的密ç ã€‚如果你忘记密ç ï¼Œä½ å¯ä»¥é€šè¿‡ç§å­é‡ç½®é’±åŒ…。在加密你的钱包之å‰ï¼Œç¡®ä¿ä½ çš„ç§å­ä¿å­˜åœ¨å®‰å…¨çš„地方。", + "unconventional-seed-title": "å¯èƒ½é”™è¯¯", + "unconventional-seed-text": "你引进了一ç§éžä¼ ç»Ÿçš„ç§å­ã€‚如果你出于任何特殊原因这样åšï¼Œä½ å¯ä»¥ç»§ç»­(åªæŽ¨è高级用户)。但是,如果你打算使用普通的系统ç§å­ï¼Œåˆ™å¿…须删除所有附加文本和特殊字符。", + "unconventional-seed-check": "继续使用éžä¼ ç»Ÿç§å­ã€‚" + }, + + "rename": { + "title": "é‡å‘½å钱包", + "name-label": "命å", + "cancel-button": "å–消", + "rename-button": "é‡å‘½å" + }, + + "add-addresses": { + "title": "选择数é‡", + "name-quantity": "创建多少地å€", + "cancel-button": "å–消", + "create-button": "创建" + }, + + "address": { + "show": "点击显示", + "copy": "å¤åˆ¶", + "copy-address": "å¤åˆ¶åœ°å€", + "copied": "å·²å¤åˆ¶!", + "confirm": "确认地å€", + "outputs": "未交易输出", + "history": "历å²" + } + }, + + "send": { + "synchronizing-warning":"钱包ä»åœ¨åŒæ­¥æ•°æ®ï¼Œæ‰€ä»¥æ˜¾ç¤ºçš„ä½™é¢å¯èƒ½ä¸æ­£ç¡®ã€‚你确定è¦ç»§ç»­å—?", + "from-label": "å‘é€è‡ª", + "to-label": "å‘é€è‡³", + "amount-label": "总é¢", + "notes-label": "标注", + "wallet-label": "钱包", + "addresses-label": "地å€", + "invalid-amount": "请输入一个有效数值", + "addresses-help": "é™å®šæºå‘é€åœ°å€", + "all-addresses": "所有地å€(所选钱包的)", + "outputs-label": "未交易输出", + "outputs-help": "é™å®šæœªäº¤æ˜“输出", + "all-outputs": "所有未交易输出(所选地å€çš„)", + "available-msg-part1": "æ ¹æ®ä½ å½“å‰çš„选择,你最多å¯ä»¥å‘é€", + "available-msg-part2": "å’Œ", + "available-msg-part3": "(至少", + "available-msg-part4": "将作为必须的交易手续费)。", + "change-address-label": "自定义找零地å€", + "change-address-select": "选择", + "change-address-help": "自定义找零地å€ã€‚如果ä¸æ供,钱包将会自动选择。点击\"选择\" æ¥é€‰æ‹©ä¸€ä¸ªåœ°å€", + "destinations-label": "目标地å€", + "destinations-help1": "目标地å€å’Œå³å°†å‘é€çš„å¸", + "destinations-help2": "目标地å€å’Œå³å°†å‘é€çš„å¸ä»¥åŠå¸æ—¶", + "hours-allocation-label": "自动分é…å¸æ—¶", + "options-label": "选项", + "value-label": "å¸æ—¶åˆ†å‘å› å­", + "value-help": "分å‘å› å­å€¼è¶Šé«˜ï¼Œè¶Šå¤šå¸æ—¶å°†è¢«å‘é€", + "preview-button": "预览", + "send-button": "å‘é€", + "back-button": "åŽé€€", + "simple": "简易", + "advanced": "高级的", + "select-wallet": "选择钱包" + }, + + "reset": { + "wallet-label": "钱包", + "seed-label": "钱包ç§å­", + "password-label": "æ–°å¯†ç  (如果你ä¸å¸Œæœ›é’±åŒ…加密,请将密ç ç•™ç©º)", + "confirm-label": "确认新密ç ", + "reset-button": "é‡ç½®" + }, + + "tx": { + "transaction": "交易", + "confirm-transaction": "确认交易", + "from": "æ¥è‡ª", + "to": "到", + "date": "日期", + "status": "状æ€", + "coins": "å¸", + "hours": "å¸æ—¶", + "id": "交易ID", + "show-more": "展示更多", + "hours-moved": "已转移", + "hours-sent": "å·²å‘é€", + "hours-received": "已接收", + "hours-burned": "已燃烧", + "inputs": "输入", + "outputs": "输出", + "confirmed": "已确认", + "pending": "待处ç†", + "current-rate": "按当å‰æ±‡çŽ‡è®¡ç®—" + }, + + "backup": { + "wallet-directory": "钱包目录:", + "seed-warning": "在纸上备份你的ç§å­ï¼Œå¹¶ä¿å­˜åœ¨ä¸€ä¸ªå®‰å…¨çš„地方。åªè¦æœ‰ç§å­ï¼Œä½ å°±å¯ä»¥æ‰¾å›žä½ çš„å¸ã€‚", + "desc": "使用下表从加密的钱包中得到ç§å­ã€‚
为了从未加密的钱包中获得ç§å­ï¼Œæ‰“开上é¢çš„文件夹,在文本编辑器中打开.wlt文件并æ¢å¤ç§å­ã€‚", + "close-button": "Close", + "wallet": "钱包", + "filename": "文件å", + "seed": "ç§å­", + "show-seed": "显示ç§å­", + "no-wallets": "未加密钱包" + }, + + "blockchain": { + "blocks": "区å—æ•°é‡", + "time": "上一个区å—的时间戳", + "hash": "上一个区å—的哈希值", + "current-supply": "ç›®å‰SKY供应é‡", + "total-supply": "SKY的总供应é‡", + "current-coinhour-supply": "ç›®å‰å¸æ—¶ä¾›åº”é‡", + "total-coinhour-supply": "å¸æ—¶æ€»ä¾›åº”é‡" + }, + + "network": { + "peer": "节点", + "source": "节点æ¥æº", + "block-height": "区å—高度", + "block-height-short": "区å—", + "last-seen": "上一次出现", + "last-received": "上一次接收", + "last-sent": "上一次å‘é€", + "in": "è¿›æ¥çš„", + "out": "出去的", + + "sources": { + "default": "默认节点", + "exchange": "交æ¢èŠ‚点" + } + }, + + "pending-txs": { + "timestamp": "时间戳", + "txid": "交易ID", + "none": "无待处ç†äº¤æ˜“", + "my": "我的", + "all": "全部" + }, + + "history": { + "tx-detail": "交易明细", + "moving": "内部转账中", + "moved": "已内部转账", + "sending": "å‘é€ä¸­", + "sent": "å·²å‘é€", + "received": "已接收", + "receiving": "接收中", + "pending": "待处ç†", + "no-txs": "你没有历å²äº¤æ˜“", + "no-txs-filter": "没有与当å‰ç­›é€‰æ¡ä»¶åŒ¹é…的交易", + "no-filter": "未ç»ç­›é€‰ (点击选择钱包/地å€)", + "filter": "已筛选: ", + "filters": "已筛选: ", + "all-addresses": "所有地å€" + }, + + "teller": { + "done": "完æˆ", + "waiting-confirm": "等待确认", + "waiting-deposit": "等待比特å¸å……值", + "waiting-send": "等待å‘é€Skycoin", + "unknown": "未知" + }, + + "confirmation" : { + "header-text": "确认", + "confirm-button": "是", + "cancel-button": "å¦", + "close": "关闭" + }, + + "service": { + "api" : { + "server-error": "æœåŠ¡å™¨é”™è¯¯" + }, + "wallet": { + "not-enough-hours": "没有足够的å¸æ—¶æ¥æ‰§è¡Œäº¤æ˜“" + } + }, + + "hardware-wallet": { + "general": { + "default-wallet-name": "新硬件钱包", + "error-disconnected": "无法执行该æ“作。硬件钱包未连接。", + "simple-error": "错误,无法执行æ“作。", + "generic-error": "无法执行该æ“作。确ä¿ä½ å·²ç»è¿žæŽ¥äº†ä¸€ä¸ªæœ‰æ•ˆçš„硬件钱包,并且它没有在等待输入。", + "generic-error-internet": "无法执行该æ“作。确ä¿ä½ å·²ç»è¿žæŽ¥äº†ä¸€ä¸ªæœ‰æ•ˆçš„硬件钱包,它ä¸åœ¨ç­‰å¾…输入,并且你已ç»è¿žæŽ¥åˆ°ç½‘络/节点", + "error-incorrect-wallet": "无法执行该æ“作。所连接的硬件钱包与预期ä¸åŒã€‚", + "error-incorrect-pin": "无法执行该æ“作。你输入的密ç ä¸æ­£ç¡®ã€‚", + "confirm": "请在硬件钱包中确认æ“作。", + "confirm-and-more": "请在硬件钱包中确认æ“作并按éµå¾ªæŒ‡ç¤ºã€‚", + "close": "关闭", + "cancel": "å–消", + "continue": "继续", + "completed": "æ“作完æˆã€‚", + "refused": "æ“作失败或被å–消。" + }, + "errors": { + "too-many-inputs": "此笔交易有太多的输入,无法处ç†ã€‚请è”系技术支æŒã€‚", + "too-many-outputs": "此笔交易有太多的输出,无法处ç†ï¼Œè¯·è”系技术支æŒã€‚" + }, + "security-warning": { + "title": "安全警告", + "text": "上次连接此硬件钱包时,å‘现一个或多个安全警告。我们建议你打开硬件钱包选项(点击钱包列表下的\"硬件钱包\"按钮)并ä¿æŒè®¾å¤‡å·²è¿žæŽ¥ï¼Œåœ¨ç»§ç»­ä¹‹å‰ï¼Œè§£å†³å®‰å…¨é—®é¢˜", + "check": "我明白其中的风险,并希望继续下去", + "continue": "继续", + "cancel": "å–消" + }, + "options": { + "connecting": "连接...", + "disconnected": "没有检测到硬件钱包。请连接硬件钱包åŽä½¿ç”¨æ­¤é€‰é¡¹ã€‚", + "unconfigured-detected-title": "未é…置的硬件钱包", + "unconfigured-detected": "检测到无ç§å­çš„硬件钱包。选择\"自动é…ç½®\"如果你想将其é…置为全新的钱包并立å³å¼€å§‹ä½¿ç”¨å®ƒï¼Œæˆ–选择\"æ¢å¤å¤‡ä»½\"如果你想使用先å‰åˆ›å»ºçš„备份ç§å­å¯¹å…¶è¿›è¡Œé…置,从而能够å†æ¬¡è®¿é—®ä½ çš„资产。", + "configured-detected": "检测到硬件钱包。该设备在钱包列表中被识别为:", + "security-warnings-title": "安全警告", + "security-warning-title": "安全警告", + "backup-warning": "你应该备份硬件钱包ç§å­ï¼Œå¦åˆ™ä¸‡ä¸€å‡ºçŽ°é—®é¢˜ï¼Œä½ å¯èƒ½å°†æ— æ³•è®¿é—®ä½ çš„资金,è¦åšåˆ°è¿™ä¸€ç‚¹ã€‚选择\"创建一个备份\"选项。", + "pin-warning": "当å‰è¿žæŽ¥çš„硬件钱包未设置密ç ã€‚密ç å¯ä¿æŠ¤ç¡¬ä»¶é’±åŒ…,以防丢失ã€ç›—窃和黑客入侵。è¦åˆ›å»ºä¸€ä¸ªå¯†ç ï¼Œé€‰æ‹©\"创建PINç \"选项。", + "options": "选项:", + "configure-automatically": "自动é…ç½®", + "restore-backup": "æ¢å¤å¤‡ä»½", + "create-backup": "创建备份", + "wipe": "删除设备", + "confirm-seed": "确认ç§å­", + "create-pin": "创建密ç ", + "change-pin": "更改密ç ", + "forgotten-pin1": "如果你因为忘记密ç è€Œæ— æ³•è¿›å…¥é’±åŒ…,你å¯ä»¥åˆ é™¤ç¡¬ä»¶é’±åŒ…,然åŽé€šè¿‡ç§å­", + "forgotten-pin2": "æ¢å¤" + }, + "generate-seed" : { + "text": "在继续之å‰ï¼Œä½ å¯ä»¥é€‰æ‹©ç”Ÿæˆç§å­çš„å•è¯æ•°ã€‚ç§å­æ˜¯ä¸€ä¸ªå•è¯åˆ—表,出现问题åŽå¯ä»¥ç”¨æ¥æ¢å¤è®¿é—®ä½ çš„å¸ã€‚所有选项都是安全的,如果你没有特殊原因必须选择æŸä¸€é¡¹ï¼Œä½ å¯ä»¥ä½¿ç”¨é»˜è®¤å€¼ã€‚", + "configuring": "é…ç½®..." + }, + "restore-seed" : { + "text": "在继续å‰ï¼Œè¯·é€‰æ‹©ä½ æƒ³è¦æ¢å¤ç§å­çš„å•è¯æ•°é‡ã€‚", + "check-text": "ä½ å¯ä»¥ä½¿ç”¨æ­¤é€‰é¡¹è¾“å…¥ç§å­ï¼Œå¹¶æ£€æŸ¥å®ƒæ˜¯å¦ä¸Žç¡¬ä»¶é’±åŒ…中的一致。在开始之å‰ï¼Œé€‰æ‹©ä½ æƒ³è¦æ£€æŸ¥çš„ç§å­çš„å•è¯æ•°ã€‚", + "warning" : "警告: 为了é¿å…å¯èƒ½å‡ºçŽ°çš„问题,请仅使用åŒä¸€å“牌/åž‹å·çš„硬件钱包创建ç§å­ã€‚", + "error-wrong-word": "错误: é‡æ–°é”®å…¥çš„å•è¯ä¸Žç¡¬ä»¶é’±åŒ…所请求的ä¸åŒ¹é…。", + "error-invalid-seed": "错误: ç§å­æ— æ•ˆã€‚请务必按正确的顺åºè¾“入正确的å•è¯ã€‚", + "error-wrong-seed": "错误: ç§å­æ˜¯æœ‰æ•ˆçš„,但与设备中的ç§å­ä¸åŒ¹é…。" + }, + "added": { + "title": "新硬件钱包", + "configuring": "检测到新的硬件钱包。é…ç½®...", + "done": "已完æˆ", + "added1": "已连接的硬件的钱包已ç»ç”¨å¦‚下å字被添加到钱包列表:", + "added2": "现在你å¯ä»¥æŸ¥çœ‹ç¡¬ä»¶é’±åŒ…中的余é¢å’Œåœ°å€äº†ï¼Œå³ä½¿ç¡¬ä»¶é’±åŒ…并未连接。此外如果你愿æ„,你还å¯ä»¥æ›´æ”¹é’±åŒ…å称或从将其从钱包列表删除。" + }, + "wipe": { + "warning": "警告: 硬件钱包中的所有数æ®å°†è¢«åˆ é™¤ã€‚如果没有备份,你将无法å†æ¬¡è®¿é—®ä½ çš„资金。", + "confirm-delete": "还是将其从钱包列表中删除" + }, + "create-backup": { + "warning": "警告: ä½ åªèƒ½ä½¿ç”¨æ­¤é€‰é¡¹å¤‡ä»½ä½ çš„硬件钱包ç§å­ä¸€æ¬¡ã€‚如果你决定继续,你将ä¸å¾—ä¸å†™ä¸‹ä¸€ç»„å•è¯(建议写在纸上,而ä¸æ˜¯ç”µè„‘上),这些å•è¯å°†å‡ºçŽ°åœ¨ç¡¬ä»¶é’±åŒ…çš„å±å¹•ä¸Šï¼Œå¹¶å°†å…¶å­˜å‚¨åœ¨ä¸€ä¸ªå®‰å…¨çš„地方。任何å¯ä»¥è®¿é—®å•è¯åˆ—表(\"ç§å­\")的人都å¯ä»¥è®¿é—®é’±åŒ…ä½™é¢ï¼Œå› æ­¤å»ºè®®è¯·æ ¼å¤–谨慎。", + "instructions": "写下出现在硬件钱包å±å¹•ä¸Šçš„å•è¯åˆ—表。一定è¦æŒ‰é¡ºåºå¹¶æŠŠæ¯ä¸ªå•è¯éƒ½å†™å¯¹ã€‚" + }, + "seed-word": { + "title": "输入字", + "info1": "输入设备中显示的字", + "info2": "你将被è¦æ±‚以éšæœºçš„顺åºè¾“入你备份的ç§å­ï¼ŒåŠ ä¸Šä¸€äº›é¢å¤–的字。", + "word": "è¦æ±‚çš„å­—", + "error-invalid-word": "输入字无效。", + "error-loading-words": "正在加载字列表。请ç¨ç­‰ã€‚" + }, + "change-pin" : { + "pin-mismatch":"无法执行æ“作。你输入的两个密ç ä¸åŒ¹é…" + }, + "enter-pin" : { + "title": "输入密ç ", + "title-change-current": "输入当å‰å¯†ç ", + "title-change-new": "输入新的密ç ", + "title-change-confirm": "确认新的密ç ", + "instructions": " 密ç å·²æ˜¾ç¤ºåœ¨ç¡¬ä»¶é’±åŒ…çš„å±å¹•ä¸Šã€‚", + "instructions-tx": "进入密ç ä»¥ç¡®è®¤å¹¶ç­¾ç½²äº¤æ˜“。", + "instructions-change": "请输入一个4到8个数字之间的难以被猜中的密ç ã€‚", + "help": "需è¦å¸®åŠ©ï¼Ÿ" + }, + "pin-help" : { + "title": "帮助", + "part1": "当需è¦è¾“入密ç æ‰èƒ½ç»§ç»­æ—¶ï¼Œç¡¬ä»¶é’±åŒ…å±å¹•ä¼šæ˜¾ç¤ºä¸€ä¸ªçŸ©é˜µï¼ŒçŸ©é˜µç”±9个éšæœºæŽ’列的å—组æˆ(æ¯æ¬¡é¡ºåºéƒ½ä¼šæ”¹å˜),你将被è¦æ±‚在软件钱包中输入密ç ï¼Œä½¿ç”¨ä¸€ä¸ªçŸ©é˜µï¼Œæ­¤çŸ©é˜µåŒ…å«9个按钮,åªæ˜¾ç¤ºç¬¦å·#。", + "part2": "è¦è¾“入密ç ï¼Œè¯·åœ¨ç¡¬ä»¶é’±åŒ…å±å¹•ä¸Šä»¥æ•°å­—矩阵查看密ç çš„ä½ç½®ï¼Œç„¶åŽç‚¹å‡»è½¯ä»¶é’±åŒ…中的相应按钮。例如,如果密ç ä¸º\"23\"且数字2ä½äºŽç¡¬ä»¶é’±åŒ…数字矩阵的左上角,数字3ä½äºŽç¡¬ä»¶é’±åŒ…数字矩阵的正中间,则按顺åºç‚¹å‡»è½¯ä»¶é’±åŒ…中的左上角和中间按钮。", + "part3": "如果你愿æ„,还å¯ä»¥ä½¿ç”¨é”®ç›˜ä¸Šçš„å°é”®ç›˜è¾“入密ç ã€‚但是,如之å‰ç¤ºä¾‹æ‰€ç¤ºï¼Œå¦‚果密ç æ˜¯\"23\",你ä¸èƒ½ç®€å•åœ°ç”¨å°é”®ç›˜é”®å…¥\"23\",而是必须选择点击硬件钱包å±å¹•ä¸Š2å’Œ3对应ä½ç½®çš„值。" + }, + "create-tx" : { + "title": "创建交易" + }, + "confirm-address" : { + "title": "确认地å€", + "instructions": "请在硬件钱包上确认,如果地å€ä¸º:", + "short-confirmation": "地å€å·²ç¡®è®¤", + "confirmation": "地å€å·²ç¡®è®¤ã€‚为了安全, 选择 \"确认地å€\" 选项å¯ä»¥åœ¨ç¡¬ä»¶é’±åŒ…上å†æ¬¡æ˜¾ç¤ºåœ°å€ï¼Œåœ¨èœå•ä¸­å¯ç‚¹å‡»åœ°å€ä½™é¢å³ä¾§çš„按钮显示。" + } + }, + + "time-from-now": { + "few-seconds": "几秒钟之å‰", + "minute": "一分钟之å‰", + "minutes": "{{time}} 分钟之å‰", + "hour": "一å°æ—¶ä¹‹å‰", + "hours": "{{time}} å°æ—¶ä¹‹å‰", + "day": "一天之å‰", + "days": "{{time}} 天之å‰" + }, + + "exchange": { + "you-send": "ä½ å‘é€", + "you-get": "你收到 (大约)", + "to-address": "到 {{coin}} 地å€", + "price": "交易汇率", + "time-15": "交易时间", + "exchange-button": "交易", + "min-amount": "最å°æ•°é¢:", + "max-amount": "最大数é¢:", + "agree-1": "我åŒæ„", + "agree-2": "使用æ¡æ¬¾", + "agree-3": "å’Œ", + "agree-4": "éšç§æ”¿ç­–", + "powered-by": "技术支æŒ", + "need-help": "需è¦å¸®åŠ©?", + "support-portal": "帮助入å£", + "history": "订å•åŽ†å²", + "order-not-found": "订å•æœªæ‰¾åˆ°", + "status": "状æ€", + "exchanging": "{{from}}交易{{to}}", + "select": "选择", + "offline": "交易暂时下线", + "problem-connecting": "未能连接到æœåŠ¡å™¨ã€‚请检查你的网络连接并ç¨åŽå†è¯•ã€‚", + "invalid-address": "无效地å€ã€‚", + "statuses": { + "user-waiting": "等待充值。请将{{amount}} {{from}}å‘é€åˆ°ä¸‹é¢æ˜¾ç¤ºçš„交易地å€", + "user-waiting-info": "系统正在等待你充值到交易地å€ã€‚交易将在系统检测到你的充值并在区å—链中确认åŽå¼€å§‹ã€‚如果你已ç»å……值,应该很快就会检测到。", + "market-waiting-confirmations": "等待链上交易确认", + "market-waiting-confirmations-info": "å·²ç»æ£€æµ‹åˆ°å……值,等待区å—链中被确认。", + "market-confirmed": "链上交易已接å—", + "market-confirmed-info": "链上交易已ç»åœ¨åŒºå—链上确认。准备马上执行兑æ¢ã€‚", + "market-exchanged": "完æˆ{{from}}到{{to}}çš„å…‘æ¢", + "market-exchanged-info": "å…‘æ¢å·²ç»å®Œæˆã€‚资金将很快å‘é€åˆ°ä½ çš„地å€ã€‚", + "market-withdraw-waiting": "正在å‘é€{{to}}到你的地å€", + "market-withdraw-waiting-info": "å‘é€{{to}}到你地å€çš„进程已å¯åŠ¨", + "complete": "交易已完æˆ!", + "complete-info": "资金已ç»æˆåŠŸå‘é€åˆ°ä½ çš„地å€ã€‚", + "error": "å‘生错误", + "error-info": "è¿è½¬è¿‡ç¨‹ä¸­å‡ºçŽ°é”™è¯¯ï¼Œä½ å¯ä»¥åœ¨ä¸‹é¢æ‰¾åˆ°æ›´å¤šä¿¡æ¯ã€‚如果你需è¦å¸®åŠ©ï¼Œè¯·ä¿å­˜ä¸‹é¢æ˜¾ç¤ºçš„所有数æ®å¹¶ä½¿ç”¨é¡µé¢å³ä¸‹è§’的帮助链接æ¥è”系技术支æŒã€‚" + }, + "history-window": { + "address": "地å€", + "date": "日期" + }, + "details": { + "exchange-addr": "交易地å€", + "exchange-addr-tag": "支付ID或交易必须用到的目标标签", + "tx-id": "交易ID", + "order-id": "订å•ID", + "initial-price": "åˆå§‹æ±‡çŽ‡", + "error-msg": "é”™è¯¯ä¿¡æ¯ ", + "details": "详情", + "start-date": "开始日期", + "back": "返回", + "back-alert": "æ“作正在执行。你真的想è¦è¿”回到表格å—?你å¯ä»¥é€šè¿‡ç‚¹å‡»\"订å•åŽ†å²\"å†æ¬¡çœ‹åˆ°æ‰§è¡Œè¿‡ç¨‹" + } + } +} diff --git a/src/gui/static/dist/assets/i18n/zh_base.json b/src/gui/static/dist/assets/i18n/zh_base.json new file mode 100644 index 0000000..402d23c --- /dev/null +++ b/src/gui/static/dist/assets/i18n/zh_base.json @@ -0,0 +1,506 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "Coin Hours", + "usd": "USD", + "loading": "Loading...", + "new": "New", + "load": "Load" + }, + + "errors": { + "error": "Error", + "fetch-version": "Unable to fetch latest release version from Github", + "incorrect-password": "Incorrect password", + "error-decrypting": "Error decrypting the wallet", + "api-disabled": "API disabled", + "no-wallet": "Wallet does not exist", + "no-outputs": "No unspent outputs", + "window-size": "The window is too narrow for the content" + }, + + "title": { + "language": "Select Language", + "wallets": "Wallets", + "send": "Send", + "history": "History", + "buy-coin": "Buy Skycoin", + "network": "Networking", + "blockchain": "Blockchain", + "outputs": "Outputs", + "transactions": "Transactions", + "pending-txs": "Pending Transactions", + "backup": "Backup Wallet", + "explorer": "Skycoin Explorer", + "seed": "Wallet Seed", + "qrcode": "QR Code", + "reset": "Reset Password", + "exchange": "Exchange", + "select-address": "Select Address", + "order-history": "Order history" + }, + + "header": { + "syncing-blocks": "Syncing blocks", + "update1": "Wallet update", + "update2": "available.", + "synchronizing": "The wallet is synchronizing. Data you see may not be updated.", + "pending-txs1": "There are some", + "pending-txs2": "pending transactions.", + "pending-txs3": "Data you see may not be updated.", + + "errors": { + "no-connections": "No connections active, your client is not connected to any other nodes!", + "no-backend1": "Cannot reach backend. Please restart the app and/or seek help on our", + "no-backend2": "Telegram.", + "no-backend3": "", + "csrf": "Security vulnerability: CSRF is not working, please exit immediately." + } + }, + + "password": { + "title": "Enter Password", + "label": "Password", + "confirm-label": "Confirm password", + "button": "Proceed", + "reset-link": "I forgot my password" + }, + + "buy": { + "deposit-address": "Choose an address to generate a BTC deposit link for:", + "select-address": "Select address", + "generate": "Generate", + "deposit-location": "Deposit Location", + "deposit-location-desc": "Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.", + "make-choice": "Make a choice", + "wallets-desc": "Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.", + "send": "Send Bitcoin", + "send-desc": "Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.", + "fraction-warning": "Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!", + "receive": "Receive Sky", + "receive-desc": "After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.", + "status-button": "Status:", + "check-status-button": "Check Status", + "new-order-button": "New Order" + }, + + "wizard": { + "wallet-desc": "If you don't have a Skycoin wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to \"Load Wallet\" and enter your seed.", + "encrypt-desc": "Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.", + "hardware-wallet-link": "Using a hardware wallet?", + "finish-button": "Finish", + "back-button": "Back", + + "confirm": { + "title": "Safeguard your seed!", + "desc": "We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your Skycoin wallet!", + "checkbox": "It’s safe, I swear.", + "button": "Continue" + } + }, + + "wallet": { + "new-address": "New Address", + "new-addresses": "New Addresses", + "show-empty": "Show Empty", + "hide-empty": "Hide Empty", + "encrypt": "Encrypt Wallet", + "decrypt": "Decrypt Wallet", + "decrypt-warning": "Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.", + "delete": "Delete Wallet", + "edit": "Edit Wallet", + "add": "Add Wallet", + "load": "Load Wallet", + "encryption-enabled": "Encryption enabled", + "encryption-disabled": "Encryption disabled", + "hw-security-warning": "Possible security risk. Access the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list) while the device is connected for more information.", + "wallet": "Wallet", + "hardware-wallet": "Hardware Wallet", + "delete-confirmation": "WARNING: The wallet \"{{ name }}\" will be removed from the list. To add it again, you will have to reconnect the device and open the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list). Do you want to continue?", + "delete-confirmation-check": "Yeah, I want to delete the wallet.", + "max-hardware-wallets-error": "You have already reached the max number of addresses that can be added to the hardware wallet.", + "add-many-confirmation": "WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?", + + "new": { + "create-title": "Create Wallet", + "load-title": "Load Wallet", + "encrypt-title": "Encrypt Wallet", + "name-label": "Name", + "seed-label": "Seed", + "confirm-seed-label": "Confirm seed", + "seed-warning": "Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!", + "create-button": "Create", + "load-button": "Load", + "cancel-button": "Cancel", + "12-words": "12 words", + "24-words": "24 words", + "generate-12-seed": "Generate 12 word seed", + "generate-24-seed": "Generate 24 word seed", + "encrypt": "Encrypt wallet", + "encrypt-warning": "We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.", + "unconventional-seed-title": "Possible error", + "unconventional-seed-text": "You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.", + "unconventional-seed-check": "Continue with the unconventional seed." + }, + + "rename": { + "title": "Rename Wallet", + "name-label": "Name", + "cancel-button": "Cancel", + "rename-button": "Rename" + }, + + "add-addresses": { + "title": "Select quantity", + "name-quantity": "How many addresses to create", + "cancel-button": "Cancel", + "create-button": "Create" + }, + + "address": { + "show": "Press to show", + "copy": "Copy", + "copy-address": "Copy address", + "copied": "Copied!", + "confirm": "Confirm address", + "outputs": "Unspent outputs", + "history": "History" + } + }, + + "send": { + "synchronizing-warning": "The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?", + "from-label": "Send from", + "to-label": "Send to", + "amount-label": "Amount", + "notes-label": "Notes", + "wallet-label": "Wallet", + "addresses-label": "Addresses", + "invalid-amount": "Please enter a valid amount", + "addresses-help": "Limit the addresses from where the coins and hours could be sent", + "all-addresses": "All the addresses of the selected wallet", + "outputs-label": "Unspent outputs", + "outputs-help": "Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown", + "all-outputs": "All the outputs of the selected addresses", + "available-msg-part1": "With your current selection you can send up to", + "available-msg-part2": "and", + "available-msg-part3": "(at least", + "available-msg-part4": "must be used for the transaction fee).", + "change-address-label": "Custom change address", + "change-address-select": "Select", + "change-address-help": "Address to receive change. If it's not provided, it will be chosen automatically. Click on the \"Select\" link to choose an address from one of your wallets", + "destinations-label": "Destinations", + "destinations-help1": "Destination addresses and their coins", + "destinations-help2": "Destination addresses, their coins and coin hours", + "hours-allocation-label": "Automatic coin hours allocation", + "options-label": "Options", + "value-label": "Coin hours share factor", + "value-help": "The higher the value, the more coin hours will be sent to outputs", + "preview-button": "Preview", + "send-button": "Send", + "back-button": "Back", + "simple": "Simple", + "advanced": "Advanced", + "select-wallet": "Select Wallet" + }, + + "reset": { + "wallet-label": "Wallet", + "seed-label": "Wallet seed", + "password-label": "New password (leave empty if you want the wallet not to be encrypted)", + "confirm-label": "Confirm new password", + "reset-button": "Reset" + }, + + "tx": { + "transaction": "Transaction", + "confirm-transaction": "Confirm Transaction", + "from": "From", + "to": "To", + "date": "Date", + "status": "Status", + "coins": "Coins", + "hours": "Hours", + "id": "Tx ID", + "show-more": "Show more", + "hours-moved": "moved", + "hours-sent": "sent", + "hours-received": "received", + "hours-burned": "burned", + "inputs": "Inputs", + "outputs": "Outputs", + "confirmed": "Confirmed", + "pending": "Pending", + "current-rate": "Calculated at the current rate" + }, + + "backup": { + "wallet-directory": "Wallet Directory:", + "seed-warning": "BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.", + "desc": "Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.", + "close-button": "Close", + "wallet": "Wallet Label", + "filename": "Filename", + "seed": "Seed", + "show-seed": "Show seed", + "no-wallets": "No encrypted wallets" + }, + + "blockchain": { + "blocks": "Number of blocks", + "time": "Timestamp of last block", + "hash": "Hash of last block", + "current-supply": "Current SKY supply", + "total-supply": "Total SKY supply", + "current-coinhour-supply": "Current Coin Hours supply", + "total-coinhour-supply": "Total Coin Hours supply" + }, + + "network": { + "peer": "Peer", + "source": "Source", + "block-height": "Block height", + "block-height-short": "Block", + "last-seen": "Last seen", + "last-received": "Last received", + "last-sent": "Last sent", + "in": "Incoming", + "out": "Outgoing", + + "sources": { + "default": "Default peer", + "exchange": "Peer exchange" + } + }, + + "pending-txs": { + "timestamp": "Timestamp", + "txid": "Transaction ID", + "none": "No pending transactions", + "my": "Mine", + "all": "All" + }, + + "history": { + "tx-detail": "Transaction Detail", + "moving": "Internally moving", + "moved": "Internally moved", + "sending": "Sending", + "sent": "Sent", + "received": "Received", + "receiving": "Receiving", + "pending": "Pending", + "no-txs": "You have no transaction history", + "no-txs-filter": "There are no transactions matching the current filter criteria", + "no-filter": "No filter active (press to select wallets/addresses)", + "filter": "Active filter: ", + "filters": "Active filters: ", + "all-addresses": "All addresses" + }, + + "teller": { + "done": "Completed", + "waiting-confirm": "Waiting for confirmation", + "waiting-deposit": "Waiting for Bitcoin deposit", + "waiting-send": "Waiting to send Skycoin", + "unknown": "Unknown" + }, + + "confirmation" : { + "header-text": "Confirmation", + "confirm-button": "Yes", + "cancel-button": "No", + "close": "Close" + }, + + "service": { + "api" : { + "server-error": "Server error" + }, + "wallet": { + "not-enough-hours": "Not enough available Coin Hours to perform the transaction!" + } + }, + + "hardware-wallet": { + "general" : { + "default-wallet-name": "New hardware wallet", + "error-disconnected": "Unable to perform the operation. The hardware wallet is not connected.", + "simple-error": "Error, Unable to perform the operation.", + "generic-error": "Unable to perform the operation. Make sure you have connected a valid hardware wallet and that it is not waiting for input.", + "generic-error-internet": "Unable to perform the operation. Make sure you have connected a valid hardware wallet that is not waiting for input and that you have a connection to the internet/node.", + "error-incorrect-wallet": "Unable to perform the operation. The connected hardware wallet is different from the expected one.", + "error-incorrect-pin": "Unable to perform the operation. The PIN you have entered is not correct.", + "confirm": "Please, confirm the operation in the hardware wallet.", + "confirm-and-more": "Please, confirm the operation in the hardware wallet and follow the instructions.", + "close": "Close", + "cancel": "Cancel", + "continue": "Continue", + "completed": "Operation completed successfully.", + "refused": "The operation failed or was canceled." + }, + "errors": { + "too-many-inputs": "The transaction has too many inputs and can not be processed. Please contact technical support.", + "too-many-outputs": "The transaction has too many outputs and can not be processed. Please contact technical support." + }, + "security-warning" : { + "title": "Security warning", + "text": "The last time this hardware wallet was connected, one or more security warnings were found. We recommend you to open the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list) while the device is connected and solve the security problems before continuing.", + "check": "I understand the risks and want to continue", + "continue": "Continue", + "cancel": "Cancel" + }, + "options" : { + "connecting": "Connecting...", + "disconnected": "No hardware wallet detected. Please connect a hardware wallet to use this option.", + "unconfigured-detected-title": "Unconfigured hardware wallet", + "unconfigured-detected": "A seedless hardware wallet has been detected. Select \"Configure automatically\" if you want to configure it as a brand new wallet and start using it immediately, or select \"Restore backup\" if you want to configure it with a previously created seed backup and thus be able to access your funds again.", + "configured-detected": "Hardware wallet detected. The device is identified in the wallets list as:", + "security-warnings-title": "Security warnings", + "security-warning-title": "Security warning", + "backup-warning": "You should backup the hardware wallet seed or you could lose access to the funds in case of problems. To do this, select the \"Create a backup\" option.", + "pin-warning": "The connected hardware wallet does not have a PIN. The PIN code protects the hardware wallet in case of loss, theft and hacks. To create a PIN code, select the \"Create PIN code\" option.", + "options": "Options:", + "configure-automatically": "Configure automatically", + "restore-backup": "Restore backup", + "create-backup": "Create a backup", + "wipe": "Wipe the device", + "confirm-seed": "Confirm seed", + "create-pin": "Create PIN code", + "change-pin": "Change PIN code", + "forgotten-pin1": "If you can not access the wallet because you have forgotten the PIN, you can wipe the hardware wallet and then restore it with the seed by clicking", + "forgotten-pin2": "here." + }, + "generate-seed" : { + "text": "Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.", + "configuring": "Configuring..." + }, + "restore-seed" : { + "text": "Before proceeding, please select the number of words that the seed you want to recover has.", + "check-text": "You can use this option to enter a seed and check if it is equal to the one in the hardware wallet. Before start, select the number of words the seed you want to check has.", + "warning" : "WARNING: to avoid potential problems, use only seeds created with a hardware wallet from the same brand/model.", + "error-wrong-word": "Error: The retyped word does not match the one requested by the hardware wallet.", + "error-invalid-seed": "Error: The seed is not valid. Please be sure to enter the correct words in the correct order.", + "error-wrong-seed": "Error: The seed is valid but does not match the one in the device." + }, + "added" : { + "title": "New Hardware Wallet", + "configuring": "New hardware wallet detected. Configuring...", + "done": "Done", + "added1": "The connected hardware wallet has been added to the wallets list with the following name:", + "added2": "Now you can check the balance and the addresses of the hardware wallet even when it is not connected. Additionally, you can change the name of the wallet or remove it from the wallets list, if you wish." + }, + "wipe" : { + "warning": "WARNING: All the data in the hardware wallet will be deleted. If you do not have a backup, you will not be able to access your funds again.", + "confirm-delete": "Also remove from the wallets list" + }, + "create-backup" : { + "warning": "WARNING: You can only use this option to backup your hardware wallet seed once. If you decide to continue, you will have to write down a group of words (it is recommended to do it on paper and not on a computer) that will appear on the screen of the hardware wallet and store the list in a safe place. Anyone with access to the word list (the \"seed\") will be able access the wallet balance, so extreme caution is advised.", + "instructions": "Write down the word list that appear on the screen of the hardware wallet. Make sure you respect the order and write each word correctly." + }, + "seed-word" : { + "title": "Enter word", + "info1": "Enter the word indicated in the device", + "info2": "You will be asked to enter the words of your backup seed in random order, plus a few additional words.", + "word": "Requested word", + "error-invalid-word": "The entered word is not valid.", + "error-loading-words": "Loading the word list. Please wait." + }, + "change-pin" : { + "pin-mismatch": "Unable to perform the operation. Two PINs you have entered do not match." + }, + "enter-pin" : { + "title": "Enter PIN", + "title-change-current": "Enter the current PIN", + "title-change-new": "Enter the new PIN", + "title-change-confirm": "Confirm the new PIN", + "instructions": "The PIN layout is displayed on the hardware wallet screen.", + "instructions-tx": "Enter the PIN to confirm and sign the transaction.", + "instructions-change": "Please enter a hard-to-guess PIN of between 4 and 8 numbers.", + "help": "Need help?" + }, + "pin-help" : { + "title": "Help", + "part1": "When it is necessary to enter the PIN to continue, the hardware wallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol #.", + "part2": "To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the hardware wallet and press the corresponding buttons in the software wallet. For example, if the PIN is \"23\" and the number 2 is in the upper left, number 3 in the middle of the hardware wallet numbers matrix, press the upper left and middle button in that order in the software wallet.", + "part3": "If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is \"23\", you can not simply type \"23\" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the hardware wallet." + }, + "create-tx" : { + "title": "Create transaction" + }, + "confirm-address" : { + "title": "Confirm address", + "instructions": "Please confirm on the hardware wallet if the address is:", + "short-confirmation": "Address confirmed.", + "confirmation": "Address confirmed. For security, you can re-show the address in the hardware wallet using the \"Confirm address\" option, in the menu that you can display by pressing the button at the right of the address balance." + } + }, + + "time-from-now": { + "few-seconds": "a few seconds ago", + "minute": "one minute ago", + "minutes": "{{time}} minutes ago", + "hour": "one hour ago", + "hours": "{{time}} hours ago", + "day": "one day ago", + "days": "{{time}} days ago" + }, + + "exchange": { + "you-send": "You send", + "you-get": "You get (approx.)", + "to-address": "To {{coin}} address", + "price": "Exchange rate", + "time-15": "Exchange time", + "exchange-button": "Exchange", + "min-amount": "Minimum amount:", + "max-amount": "Maximum amount:", + "agree-1": "I agree with", + "agree-2": "Terms of Use", + "agree-3": "and", + "agree-4": "Privacy Policy", + "powered-by": "Powered by", + "need-help": "Need help?", + "support-portal": "Support portal", + "history": "Order history", + "order-not-found": "Order not found", + "status": "Status", + "exchanging": "Exchanging {{from}} for {{to}}", + "select": "Select", + "offline": "Exchange is temporarily offline", + "problem-connecting": "Unable to connect with the service. Please check your Internet connection and try again later.", + "invalid-address": "Invalid address.", + "statuses": { + "user-waiting": "Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below", + "user-waiting-info": "The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.", + "market-waiting-confirmations": "Waiting for transaction confirmations", + "market-waiting-confirmations-info": "The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.", + "market-confirmed": "Transaction accepted", + "market-confirmed-info": "The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.", + "market-exchanged": "Traded {{from}} for {{to}}", + "market-exchanged-info": "The exchange has been made. The funds will be transferred to your address in a moment.", + "market-withdraw-waiting": "Sending {{to}} to your address", + "market-withdraw-waiting-info": "The process for sending the coins to your address has been initiated.", + "complete": "Exchange completed!", + "complete-info": "The funds have been successfully sent to your address.", + "error": "Error occurred", + "error-info": "There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page." + }, + "history-window": { + "address": "Address", + "date": "Date" + }, + "details": { + "exchange-addr": "Exchange address", + "exchange-addr-tag": "Payment ID or Destination Tag which must be used for the transaction", + "tx-id": "Transaction ID", + "order-id": "Order ID", + "initial-price": "Initial exchange rate", + "error-msg": "Error message", + "details": "Details", + "start-date": "Start date", + "back": "Back", + "back-alert": "The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the \"Order history\" button" + } + } +} diff --git a/src/gui/static/dist/assets/img/alert-red.png b/src/gui/static/dist/assets/img/alert-red.png new file mode 100644 index 0000000..17118ad Binary files /dev/null and b/src/gui/static/dist/assets/img/alert-red.png differ diff --git a/src/gui/static/dist/assets/img/big-error-icon.png b/src/gui/static/dist/assets/img/big-error-icon.png new file mode 100644 index 0000000..bcbda0c Binary files /dev/null and b/src/gui/static/dist/assets/img/big-error-icon.png differ diff --git a/src/gui/static/dist/assets/img/chevron-right-grey.png b/src/gui/static/dist/assets/img/chevron-right-grey.png new file mode 100644 index 0000000..d040458 Binary files /dev/null and b/src/gui/static/dist/assets/img/chevron-right-grey.png differ diff --git a/src/gui/static/dist/assets/img/close-grey.png b/src/gui/static/dist/assets/img/close-grey.png new file mode 100644 index 0000000..2f0ec3b Binary files /dev/null and b/src/gui/static/dist/assets/img/close-grey.png differ diff --git a/src/gui/static/dist/assets/img/delete-grey.png b/src/gui/static/dist/assets/img/delete-grey.png new file mode 100644 index 0000000..42ea934 Binary files /dev/null and b/src/gui/static/dist/assets/img/delete-grey.png differ diff --git a/src/gui/static/dist/assets/img/delete-red.png b/src/gui/static/dist/assets/img/delete-red.png new file mode 100644 index 0000000..62175e3 Binary files /dev/null and b/src/gui/static/dist/assets/img/delete-red.png differ diff --git a/src/gui/static/dist/assets/img/edit-blue.png b/src/gui/static/dist/assets/img/edit-blue.png new file mode 100644 index 0000000..de88a9a Binary files /dev/null and b/src/gui/static/dist/assets/img/edit-blue.png differ diff --git a/src/gui/static/dist/assets/img/edit-grey.png b/src/gui/static/dist/assets/img/edit-grey.png new file mode 100644 index 0000000..a5cf11e Binary files /dev/null and b/src/gui/static/dist/assets/img/edit-grey.png differ diff --git a/src/gui/static/dist/assets/img/header.png b/src/gui/static/dist/assets/img/header.png new file mode 100644 index 0000000..d73c273 Binary files /dev/null and b/src/gui/static/dist/assets/img/header.png differ diff --git a/src/gui/static/dist/assets/img/hw-gold.png b/src/gui/static/dist/assets/img/hw-gold.png new file mode 100644 index 0000000..af36aa9 Binary files /dev/null and b/src/gui/static/dist/assets/img/hw-gold.png differ diff --git a/src/gui/static/dist/assets/img/lang/en.png b/src/gui/static/dist/assets/img/lang/en.png new file mode 100644 index 0000000..bb03eaa Binary files /dev/null and b/src/gui/static/dist/assets/img/lang/en.png differ diff --git a/src/gui/static/dist/assets/img/lang/es.png b/src/gui/static/dist/assets/img/lang/es.png new file mode 100644 index 0000000..4590656 Binary files /dev/null and b/src/gui/static/dist/assets/img/lang/es.png differ diff --git a/src/gui/static/dist/assets/img/lang/ru.png b/src/gui/static/dist/assets/img/lang/ru.png new file mode 100644 index 0000000..61c27f9 Binary files /dev/null and b/src/gui/static/dist/assets/img/lang/ru.png differ diff --git a/src/gui/static/dist/assets/img/lang/zh.png b/src/gui/static/dist/assets/img/lang/zh.png new file mode 100644 index 0000000..ba5615b Binary files /dev/null and b/src/gui/static/dist/assets/img/lang/zh.png differ diff --git a/src/gui/static/dist/assets/img/load-gold.png b/src/gui/static/dist/assets/img/load-gold.png new file mode 100644 index 0000000..4d1cbf7 Binary files /dev/null and b/src/gui/static/dist/assets/img/load-gold.png differ diff --git a/src/gui/static/dist/assets/img/lock-gold.png b/src/gui/static/dist/assets/img/lock-gold.png new file mode 100644 index 0000000..fc53863 Binary files /dev/null and b/src/gui/static/dist/assets/img/lock-gold.png differ diff --git a/src/gui/static/dist/assets/img/lock-grey.png b/src/gui/static/dist/assets/img/lock-grey.png new file mode 100644 index 0000000..3f835e7 Binary files /dev/null and b/src/gui/static/dist/assets/img/lock-grey.png differ diff --git a/src/gui/static/dist/assets/img/logo-white.png b/src/gui/static/dist/assets/img/logo-white.png new file mode 100644 index 0000000..8b714cf Binary files /dev/null and b/src/gui/static/dist/assets/img/logo-white.png differ diff --git a/src/gui/static/dist/assets/img/minus-grey.png b/src/gui/static/dist/assets/img/minus-grey.png new file mode 100644 index 0000000..b81e568 Binary files /dev/null and b/src/gui/static/dist/assets/img/minus-grey.png differ diff --git a/src/gui/static/dist/assets/img/minus-red.png b/src/gui/static/dist/assets/img/minus-red.png new file mode 100644 index 0000000..6686a98 Binary files /dev/null and b/src/gui/static/dist/assets/img/minus-red.png differ diff --git a/src/gui/static/dist/assets/img/money-gold.png b/src/gui/static/dist/assets/img/money-gold.png new file mode 100644 index 0000000..649fc3b Binary files /dev/null and b/src/gui/static/dist/assets/img/money-gold.png differ diff --git a/src/gui/static/dist/assets/img/otc-background.jpg b/src/gui/static/dist/assets/img/otc-background.jpg new file mode 100644 index 0000000..03a8401 Binary files /dev/null and b/src/gui/static/dist/assets/img/otc-background.jpg differ diff --git a/src/gui/static/dist/assets/img/plus-gold.png b/src/gui/static/dist/assets/img/plus-gold.png new file mode 100644 index 0000000..854692e Binary files /dev/null and b/src/gui/static/dist/assets/img/plus-gold.png differ diff --git a/src/gui/static/dist/assets/img/plus-green.png b/src/gui/static/dist/assets/img/plus-green.png new file mode 100644 index 0000000..ab02079 Binary files /dev/null and b/src/gui/static/dist/assets/img/plus-green.png differ diff --git a/src/gui/static/dist/assets/img/plus-grey.png b/src/gui/static/dist/assets/img/plus-grey.png new file mode 100644 index 0000000..35dbfff Binary files /dev/null and b/src/gui/static/dist/assets/img/plus-grey.png differ diff --git a/src/gui/static/dist/assets/img/qr-code-black.png b/src/gui/static/dist/assets/img/qr-code-black.png new file mode 100644 index 0000000..f9a2fab Binary files /dev/null and b/src/gui/static/dist/assets/img/qr-code-black.png differ diff --git a/src/gui/static/dist/assets/img/send-black.png b/src/gui/static/dist/assets/img/send-black.png new file mode 100644 index 0000000..9f27742 Binary files /dev/null and b/src/gui/static/dist/assets/img/send-black.png differ diff --git a/src/gui/static/dist/assets/img/send-blue.png b/src/gui/static/dist/assets/img/send-blue.png new file mode 100644 index 0000000..4226468 Binary files /dev/null and b/src/gui/static/dist/assets/img/send-blue.png differ diff --git a/src/gui/static/dist/assets/img/send-gold.png b/src/gui/static/dist/assets/img/send-gold.png new file mode 100644 index 0000000..59645e7 Binary files /dev/null and b/src/gui/static/dist/assets/img/send-gold.png differ diff --git a/src/gui/static/dist/assets/img/send-white.png b/src/gui/static/dist/assets/img/send-white.png new file mode 100644 index 0000000..16261a2 Binary files /dev/null and b/src/gui/static/dist/assets/img/send-white.png differ diff --git a/src/gui/static/dist/assets/img/size-alert.png b/src/gui/static/dist/assets/img/size-alert.png new file mode 100644 index 0000000..49b639c Binary files /dev/null and b/src/gui/static/dist/assets/img/size-alert.png differ diff --git a/src/gui/static/dist/assets/img/transactions-black.png b/src/gui/static/dist/assets/img/transactions-black.png new file mode 100644 index 0000000..413f223 Binary files /dev/null and b/src/gui/static/dist/assets/img/transactions-black.png differ diff --git a/src/gui/static/dist/assets/img/unlock-gold.png b/src/gui/static/dist/assets/img/unlock-gold.png new file mode 100644 index 0000000..3ecf4ae Binary files /dev/null and b/src/gui/static/dist/assets/img/unlock-gold.png differ diff --git a/src/gui/static/dist/assets/img/unlock-grey.png b/src/gui/static/dist/assets/img/unlock-grey.png new file mode 100644 index 0000000..61a3177 Binary files /dev/null and b/src/gui/static/dist/assets/img/unlock-grey.png differ diff --git a/src/gui/static/dist/assets/img/wallet-black.png b/src/gui/static/dist/assets/img/wallet-black.png new file mode 100644 index 0000000..cdb2ec8 Binary files /dev/null and b/src/gui/static/dist/assets/img/wallet-black.png differ diff --git a/src/gui/static/dist/assets/logo-white.png b/src/gui/static/dist/assets/logo-white.png new file mode 100644 index 0000000..cd615cf Binary files /dev/null and b/src/gui/static/dist/assets/logo-white.png differ diff --git a/src/gui/static/dist/assets/scripts/qrcode.min.js b/src/gui/static/dist/assets/scripts/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/src/gui/static/dist/assets/scripts/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/src/gui/static/dist/favicon.ico b/src/gui/static/dist/favicon.ico new file mode 100644 index 0000000..cc325fd Binary files /dev/null and b/src/gui/static/dist/favicon.ico differ diff --git a/src/gui/static/dist/fontawesome-webfont.674f50d287a8c48dc19b.eot b/src/gui/static/dist/fontawesome-webfont.674f50d287a8c48dc19b.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/src/gui/static/dist/fontawesome-webfont.674f50d287a8c48dc19b.eot differ diff --git a/src/gui/static/dist/fontawesome-webfont.912ec66d7572ff821749.svg b/src/gui/static/dist/fontawesome-webfont.912ec66d7572ff821749.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/src/gui/static/dist/fontawesome-webfont.912ec66d7572ff821749.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gui/static/dist/fontawesome-webfont.af7ae505a9eed503f8b8.woff2 b/src/gui/static/dist/fontawesome-webfont.af7ae505a9eed503f8b8.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/src/gui/static/dist/fontawesome-webfont.af7ae505a9eed503f8b8.woff2 differ diff --git a/src/gui/static/dist/fontawesome-webfont.b06871f281fee6b241d6.ttf b/src/gui/static/dist/fontawesome-webfont.b06871f281fee6b241d6.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/src/gui/static/dist/fontawesome-webfont.b06871f281fee6b241d6.ttf differ diff --git a/src/gui/static/dist/fontawesome-webfont.fee66e712a8a08eef580.woff b/src/gui/static/dist/fontawesome-webfont.fee66e712a8a08eef580.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/src/gui/static/dist/fontawesome-webfont.fee66e712a8a08eef580.woff differ diff --git a/src/gui/static/dist/header.03fb33b04c982a1a804d.png b/src/gui/static/dist/header.03fb33b04c982a1a804d.png new file mode 100644 index 0000000..d73c273 Binary files /dev/null and b/src/gui/static/dist/header.03fb33b04c982a1a804d.png differ diff --git a/src/gui/static/dist/header.e11f7c6852766b9319d6.png b/src/gui/static/dist/header.e11f7c6852766b9319d6.png new file mode 100644 index 0000000..be1002a Binary files /dev/null and b/src/gui/static/dist/header.e11f7c6852766b9319d6.png differ diff --git a/src/gui/static/dist/index.html b/src/gui/static/dist/index.html new file mode 100644 index 0000000..6f468ee --- /dev/null +++ b/src/gui/static/dist/index.html @@ -0,0 +1,25 @@ +Skycoin
\ No newline at end of file diff --git a/src/gui/static/dist/inline.2fc97466d3eec1b646d4.bundle.js b/src/gui/static/dist/inline.2fc97466d3eec1b646d4.bundle.js new file mode 100644 index 0000000..e28bc7c --- /dev/null +++ b/src/gui/static/dist/inline.2fc97466d3eec1b646d4.bundle.js @@ -0,0 +1 @@ +!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var f,u,i,d=0,l=[];d12?n:n+12:"sanje"===t?n+12:void 0},meridiem:function(n,t,e){return n<4?"rati":n<12?"sokalli":n<16?"donparam":n<20?"sanje":"rati"}})}(e("PJh5"))},"+3/4":function(n,t,e){"use strict";e.d(t,"a",function(){return r});var l=e("TToO"),r=function(n){function t(t){n.call(this),this.scheduler=t}return Object(l.__extends)(t,n),t.create=function(n){return new t(n)},t.dispatch=function(n){n.subscriber.complete()},t.prototype._subscribe=function(n){var e=this.scheduler;if(e)return e.schedule(t.dispatch,0,{subscriber:n});n.complete()},t}(e("YaPU").a)},"+7/x":function(n,t,e){!function(n){"use strict";var t={1:"\u0be7",2:"\u0be8",3:"\u0be9",4:"\u0bea",5:"\u0beb",6:"\u0bec",7:"\u0bed",8:"\u0bee",9:"\u0bef",0:"\u0be6"},e={"\u0be7":"1","\u0be8":"2","\u0be9":"3","\u0bea":"4","\u0beb":"5","\u0bec":"6","\u0bed":"7","\u0bee":"8","\u0bef":"9","\u0be6":"0"};n.defineLocale("ta",{months:"\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf_\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf_\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd_\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd_\u0bae\u0bc7_\u0b9c\u0bc2\u0ba9\u0bcd_\u0b9c\u0bc2\u0bb2\u0bc8_\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd_\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bc6\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b85\u0b95\u0bcd\u0b9f\u0bc7\u0bbe\u0baa\u0bb0\u0bcd_\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd".split("_"),monthsShort:"\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf_\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf_\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd_\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd_\u0bae\u0bc7_\u0b9c\u0bc2\u0ba9\u0bcd_\u0b9c\u0bc2\u0bb2\u0bc8_\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd_\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bc6\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b85\u0b95\u0bcd\u0b9f\u0bc7\u0bbe\u0baa\u0bb0\u0bcd_\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd".split("_"),weekdays:"\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bcd\u0bb1\u0bc1\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0b9f\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0baa\u0bc1\u0ba4\u0ba9\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0b9a\u0ba9\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8".split("_"),weekdaysShort:"\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1_\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd_\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd_\u0baa\u0bc1\u0ba4\u0ba9\u0bcd_\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd_\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf_\u0b9a\u0ba9\u0bbf".split("_"),weekdaysMin:"\u0b9e\u0bbe_\u0ba4\u0bbf_\u0b9a\u0bc6_\u0baa\u0bc1_\u0bb5\u0bbf_\u0bb5\u0bc6_\u0b9a".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, HH:mm",LLLL:"dddd, D MMMM YYYY, HH:mm"},calendar:{sameDay:"[\u0b87\u0ba9\u0bcd\u0bb1\u0bc1] LT",nextDay:"[\u0ba8\u0bbe\u0bb3\u0bc8] LT",nextWeek:"dddd, LT",lastDay:"[\u0ba8\u0bc7\u0bb1\u0bcd\u0bb1\u0bc1] LT",lastWeek:"[\u0b95\u0b9f\u0ba8\u0bcd\u0ba4 \u0bb5\u0bbe\u0bb0\u0bae\u0bcd] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0b87\u0bb2\u0bcd",past:"%s \u0bae\u0bc1\u0ba9\u0bcd",s:"\u0b92\u0bb0\u0bc1 \u0b9a\u0bbf\u0bb2 \u0bb5\u0bbf\u0ba8\u0bbe\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",ss:"%d \u0bb5\u0bbf\u0ba8\u0bbe\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",m:"\u0b92\u0bb0\u0bc1 \u0ba8\u0bbf\u0bae\u0bbf\u0b9f\u0bae\u0bcd",mm:"%d \u0ba8\u0bbf\u0bae\u0bbf\u0b9f\u0b99\u0bcd\u0b95\u0bb3\u0bcd",h:"\u0b92\u0bb0\u0bc1 \u0bae\u0ba3\u0bbf \u0ba8\u0bc7\u0bb0\u0bae\u0bcd",hh:"%d \u0bae\u0ba3\u0bbf \u0ba8\u0bc7\u0bb0\u0bae\u0bcd",d:"\u0b92\u0bb0\u0bc1 \u0ba8\u0bbe\u0bb3\u0bcd",dd:"%d \u0ba8\u0bbe\u0b9f\u0bcd\u0b95\u0bb3\u0bcd",M:"\u0b92\u0bb0\u0bc1 \u0bae\u0bbe\u0ba4\u0bae\u0bcd",MM:"%d \u0bae\u0bbe\u0ba4\u0b99\u0bcd\u0b95\u0bb3\u0bcd",y:"\u0b92\u0bb0\u0bc1 \u0bb5\u0bb0\u0bc1\u0b9f\u0bae\u0bcd",yy:"%d \u0b86\u0ba3\u0bcd\u0b9f\u0bc1\u0b95\u0bb3\u0bcd"},dayOfMonthOrdinalParse:/\d{1,2}\u0bb5\u0ba4\u0bc1/,ordinal:function(n){return n+"\u0bb5\u0ba4\u0bc1"},preparse:function(n){return n.replace(/[\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0be6]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u0baf\u0bbe\u0bae\u0bae\u0bcd|\u0bb5\u0bc8\u0b95\u0bb1\u0bc8|\u0b95\u0bbe\u0bb2\u0bc8|\u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd|\u0b8e\u0bb1\u0bcd\u0baa\u0bbe\u0b9f\u0bc1|\u0bae\u0bbe\u0bb2\u0bc8/,meridiem:function(n,t,e){return n<2?" \u0baf\u0bbe\u0bae\u0bae\u0bcd":n<6?" \u0bb5\u0bc8\u0b95\u0bb1\u0bc8":n<10?" \u0b95\u0bbe\u0bb2\u0bc8":n<14?" \u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd":n<18?" \u0b8e\u0bb1\u0bcd\u0baa\u0bbe\u0b9f\u0bc1":n<22?" \u0bae\u0bbe\u0bb2\u0bc8":" \u0baf\u0bbe\u0bae\u0bae\u0bcd"},meridiemHour:function(n,t){return 12===n&&(n=0),"\u0baf\u0bbe\u0bae\u0bae\u0bcd"===t?n<2?n:n+12:"\u0bb5\u0bc8\u0b95\u0bb1\u0bc8"===t||"\u0b95\u0bbe\u0bb2\u0bc8"===t?n:"\u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd"===t&&n>=10?n:n+12},week:{dow:0,doy:6}})}(e("PJh5"))},"+CnV":function(n,t,e){"use strict";e.d(t,"a",function(){return l});var l=function(n){var t,l=e("AMGY").a.Symbol;return"function"==typeof l?l.observable?t=l.observable:(t=l("observable"),l.observable=t):t="@@observable",t}()},"/4Bh":function(n,t,e){"use strict";t.a=function(n,t){return arguments.length>=2?function(e){return Object(o.a)(Object(l.a)(n,t),Object(r.a)(1),Object(i.a)(t))(e)}:function(t){return Object(o.a)(Object(l.a)(function(t,e,l){return n(t,e,l+1)}),Object(r.a)(1))(t)}};var l=e("E5SG"),r=e("T1Dh"),i=e("2ESx"),o=e("f9aG")},"/6P1":function(n,t,e){!function(n){"use strict";var t={ss:"sekund\u0117_sekund\u017ei\u0173_sekundes",m:"minut\u0117_minut\u0117s_minut\u0119",mm:"minut\u0117s_minu\u010di\u0173_minutes",h:"valanda_valandos_valand\u0105",hh:"valandos_valand\u0173_valandas",d:"diena_dienos_dien\u0105",dd:"dienos_dien\u0173_dienas",M:"m\u0117nuo_m\u0117nesio_m\u0117nes\u012f",MM:"m\u0117nesiai_m\u0117nesi\u0173_m\u0117nesius",y:"metai_met\u0173_metus",yy:"metai_met\u0173_metus"};function e(n,t,e,l){return t?r(e)[0]:l?r(e)[1]:r(e)[2]}function l(n){return n%10==0||n>10&&n<20}function r(n){return t[n].split("_")}function i(n,t,i,o){var s=n+" ";return 1===n?s+e(0,t,i[0],o):t?s+(l(n)?r(i)[1]:r(i)[0]):o?s+r(i)[1]:s+(l(n)?r(i)[1]:r(i)[2])}n.defineLocale("lt",{months:{format:"sausio_vasario_kovo_baland\u017eio_gegu\u017e\u0117s_bir\u017eelio_liepos_rugpj\u016b\u010dio_rugs\u0117jo_spalio_lapkri\u010dio_gruod\u017eio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegu\u017e\u0117_bir\u017eelis_liepa_rugpj\u016btis_rugs\u0117jis_spalis_lapkritis_gruodis".split("_"),isFormat:/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadien\u012f_pirmadien\u012f_antradien\u012f_tre\u010diadien\u012f_ketvirtadien\u012f_penktadien\u012f_\u0161e\u0161tadien\u012f".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_tre\u010diadienis_ketvirtadienis_penktadienis_\u0161e\u0161tadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_\u0160e\u0161".split("_"),weekdaysMin:"S_P_A_T_K_Pn_\u0160".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[\u0160iandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Pra\u0117jus\u012f] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prie\u0161 %s",s:function(n,t,e,l){return t?"kelios sekund\u0117s":l?"keli\u0173 sekund\u017ei\u0173":"kelias sekundes"},ss:i,m:e,mm:i,h:e,hh:i,d:e,dd:i,M:e,MM:i,y:e,yy:i},dayOfMonthOrdinalParse:/\d{1,2}-oji/,ordinal:function(n){return n+"-oji"},week:{dow:1,doy:4}})}(e("PJh5"))},"/bsm":function(n,t,e){!function(n){"use strict";n.defineLocale("uz-latn",{months:"Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr".split("_"),monthsShort:"Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek".split("_"),weekdays:"Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba".split("_"),weekdaysShort:"Yak_Dush_Sesh_Chor_Pay_Jum_Shan".split("_"),weekdaysMin:"Ya_Du_Se_Cho_Pa_Ju_Sha".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Bugun soat] LT [da]",nextDay:"[Ertaga] LT [da]",nextWeek:"dddd [kuni soat] LT [da]",lastDay:"[Kecha soat] LT [da]",lastWeek:"[O'tgan] dddd [kuni soat] LT [da]",sameElse:"L"},relativeTime:{future:"Yaqin %s ichida",past:"Bir necha %s oldin",s:"soniya",ss:"%d soniya",m:"bir daqiqa",mm:"%d daqiqa",h:"bir soat",hh:"%d soat",d:"bir kun",dd:"%d kun",M:"bir oy",MM:"%d oy",y:"bir yil",yy:"%d yil"},week:{dow:1,doy:7}})}(e("PJh5"))},"/iUD":function(n,t,e){"use strict";t.a=function(n){return"function"==typeof n}},"/mhn":function(n,t,e){!function(n){"use strict";var t={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},e={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};n.defineLocale("ne",{months:"\u091c\u0928\u0935\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u093f\u0932_\u092e\u0908_\u091c\u0941\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0937\u094d\u091f_\u0938\u0947\u092a\u094d\u091f\u0947\u092e\u094d\u092c\u0930_\u0905\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u092d\u0947\u092e\u094d\u092c\u0930_\u0921\u093f\u0938\u0947\u092e\u094d\u092c\u0930".split("_"),monthsShort:"\u091c\u0928._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u093f._\u092e\u0908_\u091c\u0941\u0928_\u091c\u0941\u0932\u093e\u0908._\u0905\u0917._\u0938\u0947\u092a\u094d\u091f._\u0905\u0915\u094d\u091f\u094b._\u0928\u094b\u092d\u0947._\u0921\u093f\u0938\u0947.".split("_"),monthsParseExact:!0,weekdays:"\u0906\u0907\u0924\u092c\u093e\u0930_\u0938\u094b\u092e\u092c\u093e\u0930_\u092e\u0919\u094d\u0917\u0932\u092c\u093e\u0930_\u092c\u0941\u0927\u092c\u093e\u0930_\u092c\u093f\u0939\u093f\u092c\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u092c\u093e\u0930_\u0936\u0928\u093f\u092c\u093e\u0930".split("_"),weekdaysShort:"\u0906\u0907\u0924._\u0938\u094b\u092e._\u092e\u0919\u094d\u0917\u0932._\u092c\u0941\u0927._\u092c\u093f\u0939\u093f._\u0936\u0941\u0915\u094d\u0930._\u0936\u0928\u093f.".split("_"),weekdaysMin:"\u0906._\u0938\u094b._\u092e\u0902._\u092c\u0941._\u092c\u093f._\u0936\u0941._\u0936.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A\u0915\u094b h:mm \u092c\u091c\u0947",LTS:"A\u0915\u094b h:mm:ss \u092c\u091c\u0947",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A\u0915\u094b h:mm \u092c\u091c\u0947",LLLL:"dddd, D MMMM YYYY, A\u0915\u094b h:mm \u092c\u091c\u0947"},preparse:function(n){return n.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u0930\u093e\u0924\u093f|\u092c\u093f\u0939\u093e\u0928|\u0926\u093f\u0909\u0901\u0938\u094b|\u0938\u093e\u0901\u091d/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0930\u093e\u0924\u093f"===t?n<4?n:n+12:"\u092c\u093f\u0939\u093e\u0928"===t?n:"\u0926\u093f\u0909\u0901\u0938\u094b"===t?n>=10?n:n+12:"\u0938\u093e\u0901\u091d"===t?n+12:void 0},meridiem:function(n,t,e){return n<3?"\u0930\u093e\u0924\u093f":n<12?"\u092c\u093f\u0939\u093e\u0928":n<16?"\u0926\u093f\u0909\u0901\u0938\u094b":n<20?"\u0938\u093e\u0901\u091d":"\u0930\u093e\u0924\u093f"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u092d\u094b\u0932\u093f] LT",nextWeek:"[\u0906\u0909\u0901\u0926\u094b] dddd[,] LT",lastDay:"[\u0939\u093f\u091c\u094b] LT",lastWeek:"[\u0917\u090f\u0915\u094b] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s\u092e\u093e",past:"%s \u0905\u0917\u093e\u0921\u093f",s:"\u0915\u0947\u0939\u0940 \u0915\u094d\u0937\u0923",ss:"%d \u0938\u0947\u0915\u0947\u0923\u094d\u0921",m:"\u090f\u0915 \u092e\u093f\u0928\u0947\u091f",mm:"%d \u092e\u093f\u0928\u0947\u091f",h:"\u090f\u0915 \u0918\u0923\u094d\u091f\u093e",hh:"%d \u0918\u0923\u094d\u091f\u093e",d:"\u090f\u0915 \u0926\u093f\u0928",dd:"%d \u0926\u093f\u0928",M:"\u090f\u0915 \u092e\u0939\u093f\u0928\u093e",MM:"%d \u092e\u0939\u093f\u0928\u093e",y:"\u090f\u0915 \u092c\u0930\u094d\u0937",yy:"%d \u092c\u0930\u094d\u0937"},week:{dow:0,doy:6}})}(e("PJh5"))},"/nXB":function(n,t,e){"use strict";t.a=function(){for(var n=[],t=0;t1&&"number"==typeof n[n.length-1]&&(e=n.pop())):"number"==typeof a&&(e=n.pop()),null===s&&1===n.length&&n[0]instanceof l.a?n[0]:Object(o.a)(e)(new r.a(n,s))};var l=e("YaPU"),r=e("Veqx"),i=e("1Q68"),o=e("8D5t")},0:function(n,t,e){n.exports=e("x35b")},"0P3J":function(n,t,e){"use strict";t.a=function(){return function(n){return n.lift(new i(n))}};var l=e("TToO"),r=e("OVmG"),i=function(){function n(n){this.connectable=n}return n.prototype.call=function(n,t){var e=this.connectable;e._refCount++;var l=new o(n,e),r=t.subscribe(l);return l.closed||(l.connection=e.connect()),r},n}(),o=function(n){function t(t,e){n.call(this,t),this.connectable=e}return Object(l.__extends)(t,n),t.prototype._unsubscribe=function(){var n=this.connectable;if(n){this.connectable=null;var t=n._refCount;if(t<=0)this.connection=null;else if(n._refCount=t-1,t>1)this.connection=null;else{var e=this.connection,l=n._connection;this.connection=null,!l||e&&l!==e||l.unsubscribe()}}else this.connection=null},t}(r.a)},"0X8Q":function(n,t,e){!function(n){"use strict";n.defineLocale("vi",{months:"th\xe1ng 1_th\xe1ng 2_th\xe1ng 3_th\xe1ng 4_th\xe1ng 5_th\xe1ng 6_th\xe1ng 7_th\xe1ng 8_th\xe1ng 9_th\xe1ng 10_th\xe1ng 11_th\xe1ng 12".split("_"),monthsShort:"Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),monthsParseExact:!0,weekdays:"ch\u1ee7 nh\u1eadt_th\u1ee9 hai_th\u1ee9 ba_th\u1ee9 t\u01b0_th\u1ee9 n\u0103m_th\u1ee9 s\xe1u_th\u1ee9 b\u1ea3y".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysParseExact:!0,meridiemParse:/sa|ch/i,isPM:function(n){return/^ch$/i.test(n)},meridiem:function(n,t,e){return n<12?e?"sa":"SA":e?"ch":"CH"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [n\u0103m] YYYY",LLL:"D MMMM [n\u0103m] YYYY HH:mm",LLLL:"dddd, D MMMM [n\u0103m] YYYY HH:mm",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[H\xf4m nay l\xfac] LT",nextDay:"[Ng\xe0y mai l\xfac] LT",nextWeek:"dddd [tu\u1ea7n t\u1edbi l\xfac] LT",lastDay:"[H\xf4m qua l\xfac] LT",lastWeek:"dddd [tu\u1ea7n r\u1ed3i l\xfac] LT",sameElse:"L"},relativeTime:{future:"%s t\u1edbi",past:"%s tr\u01b0\u1edbc",s:"v\xe0i gi\xe2y",ss:"%d gi\xe2y",m:"m\u1ed9t ph\xfat",mm:"%d ph\xfat",h:"m\u1ed9t gi\u1edd",hh:"%d gi\u1edd",d:"m\u1ed9t ng\xe0y",dd:"%d ng\xe0y",M:"m\u1ed9t th\xe1ng",MM:"%d th\xe1ng",y:"m\u1ed9t n\u0103m",yy:"%d n\u0103m"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(n){return n},week:{dow:1,doy:4}})}(e("PJh5"))},"1Bqh":function(n,t,e){"use strict";e.d(t,"a",function(){return r});var l=e("TToO"),r=function(n){function t(t,e){n.call(this),this.subject=t,this.subscriber=e,this.closed=!1}return Object(l.__extends)(t,n),t.prototype.unsubscribe=function(){if(!this.closed){this.closed=!0;var n=this.subject,t=n.observers;if(this.subject=null,t&&0!==t.length&&!n.isStopped&&!n.closed){var e=t.indexOf(this.subscriber);-1!==e&&t.splice(e,1)}}},t}(e("VwZZ").a)},"1Q68":function(n,t,e){"use strict";t.a=function(n){return n&&"function"==typeof n.schedule}},"2ESx":function(n,t,e){"use strict";t.a=function(n){return void 0===n&&(n=null),function(t){return t.lift(new i(n))}};var l=e("TToO"),r=e("OVmG"),i=function(){function n(n){this.defaultValue=n}return n.prototype.call=function(n,t){return t.subscribe(new o(n,this.defaultValue))},n}(),o=function(n){function t(t,e){n.call(this,t),this.defaultValue=e,this.isEmpty=!0}return Object(l.__extends)(t,n),t.prototype._next=function(n){this.isEmpty=!1,this.destination.next(n)},t.prototype._complete=function(){this.isEmpty&&this.destination.next(this.defaultValue),this.destination.complete()},t}(r.a)},"2pmY":function(n,t,e){!function(n){"use strict";var t={1:"\u06f1",2:"\u06f2",3:"\u06f3",4:"\u06f4",5:"\u06f5",6:"\u06f6",7:"\u06f7",8:"\u06f8",9:"\u06f9",0:"\u06f0"},e={"\u06f1":"1","\u06f2":"2","\u06f3":"3","\u06f4":"4","\u06f5":"5","\u06f6":"6","\u06f7":"7","\u06f8":"8","\u06f9":"9","\u06f0":"0"};n.defineLocale("fa",{months:"\u0698\u0627\u0646\u0648\u06cc\u0647_\u0641\u0648\u0631\u06cc\u0647_\u0645\u0627\u0631\u0633_\u0622\u0648\u0631\u06cc\u0644_\u0645\u0647_\u0698\u0648\u0626\u0646_\u0698\u0648\u0626\u06cc\u0647_\u0627\u0648\u062a_\u0633\u067e\u062a\u0627\u0645\u0628\u0631_\u0627\u06a9\u062a\u0628\u0631_\u0646\u0648\u0627\u0645\u0628\u0631_\u062f\u0633\u0627\u0645\u0628\u0631".split("_"),monthsShort:"\u0698\u0627\u0646\u0648\u06cc\u0647_\u0641\u0648\u0631\u06cc\u0647_\u0645\u0627\u0631\u0633_\u0622\u0648\u0631\u06cc\u0644_\u0645\u0647_\u0698\u0648\u0626\u0646_\u0698\u0648\u0626\u06cc\u0647_\u0627\u0648\u062a_\u0633\u067e\u062a\u0627\u0645\u0628\u0631_\u0627\u06a9\u062a\u0628\u0631_\u0646\u0648\u0627\u0645\u0628\u0631_\u062f\u0633\u0627\u0645\u0628\u0631".split("_"),weekdays:"\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647_\u062f\u0648\u0634\u0646\u0628\u0647_\u0633\u0647\u200c\u0634\u0646\u0628\u0647_\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647_\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647_\u062c\u0645\u0639\u0647_\u0634\u0646\u0628\u0647".split("_"),weekdaysShort:"\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647_\u062f\u0648\u0634\u0646\u0628\u0647_\u0633\u0647\u200c\u0634\u0646\u0628\u0647_\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647_\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647_\u062c\u0645\u0639\u0647_\u0634\u0646\u0628\u0647".split("_"),weekdaysMin:"\u06cc_\u062f_\u0633_\u0686_\u067e_\u062c_\u0634".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/\u0642\u0628\u0644 \u0627\u0632 \u0638\u0647\u0631|\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631/,isPM:function(n){return/\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631/.test(n)},meridiem:function(n,t,e){return n<12?"\u0642\u0628\u0644 \u0627\u0632 \u0638\u0647\u0631":"\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631"},calendar:{sameDay:"[\u0627\u0645\u0631\u0648\u0632 \u0633\u0627\u0639\u062a] LT",nextDay:"[\u0641\u0631\u062f\u0627 \u0633\u0627\u0639\u062a] LT",nextWeek:"dddd [\u0633\u0627\u0639\u062a] LT",lastDay:"[\u062f\u06cc\u0631\u0648\u0632 \u0633\u0627\u0639\u062a] LT",lastWeek:"dddd [\u067e\u06cc\u0634] [\u0633\u0627\u0639\u062a] LT",sameElse:"L"},relativeTime:{future:"\u062f\u0631 %s",past:"%s \u067e\u06cc\u0634",s:"\u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647",ss:"\u062b\u0627\u0646\u06cc\u0647 d%",m:"\u06cc\u06a9 \u062f\u0642\u06cc\u0642\u0647",mm:"%d \u062f\u0642\u06cc\u0642\u0647",h:"\u06cc\u06a9 \u0633\u0627\u0639\u062a",hh:"%d \u0633\u0627\u0639\u062a",d:"\u06cc\u06a9 \u0631\u0648\u0632",dd:"%d \u0631\u0648\u0632",M:"\u06cc\u06a9 \u0645\u0627\u0647",MM:"%d \u0645\u0627\u0647",y:"\u06cc\u06a9 \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(n){return n.replace(/[\u06f0-\u06f9]/g,function(n){return e[n]}).replace(/\u060c/g,",")},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]}).replace(/,/g,"\u060c")},dayOfMonthOrdinalParse:/\d{1,2}\u0645/,ordinal:"%d\u0645",week:{dow:6,doy:12}})}(e("PJh5"))},"2s1U":function(n,t,e){!function(n){"use strict";function t(n,t,e,l){var r=n+" ";switch(e){case"s":return t||l?"nekaj sekund":"nekaj sekundami";case"ss":return r+(1===n?t?"sekundo":"sekundi":2===n?t||l?"sekundi":"sekundah":n<5?t||l?"sekunde":"sekundah":"sekund");case"m":return t?"ena minuta":"eno minuto";case"mm":return r+(1===n?t?"minuta":"minuto":2===n?t||l?"minuti":"minutama":n<5?t||l?"minute":"minutami":t||l?"minut":"minutami");case"h":return t?"ena ura":"eno uro";case"hh":return r+(1===n?t?"ura":"uro":2===n?t||l?"uri":"urama":n<5?t||l?"ure":"urami":t||l?"ur":"urami");case"d":return t||l?"en dan":"enim dnem";case"dd":return r+(1===n?t||l?"dan":"dnem":2===n?t||l?"dni":"dnevoma":t||l?"dni":"dnevi");case"M":return t||l?"en mesec":"enim mesecem";case"MM":return r+(1===n?t||l?"mesec":"mesecem":2===n?t||l?"meseca":"mesecema":n<5?t||l?"mesece":"meseci":t||l?"mesecev":"meseci");case"y":return t||l?"eno leto":"enim letom";case"yy":return r+(1===n?t||l?"leto":"letom":2===n?t||l?"leti":"letoma":n<5?t||l?"leta":"leti":t||l?"let":"leti")}}n.defineLocale("sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljek_torek_sreda_\u010detrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._\u010det._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_\u010de_pe_so".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[v\u010deraj ob] LT",lastWeek:function(){switch(this.day()){case 0:return"[prej\u0161njo] [nedeljo] [ob] LT";case 3:return"[prej\u0161njo] [sredo] [ob] LT";case 6:return"[prej\u0161njo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prej\u0161nji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"\u010dez %s",past:"pred %s",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e("PJh5"))},"3CJN":function(n,t,e){!function(n){"use strict";n.defineLocale("af",{months:"Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"),weekdays:"Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"),weekdaysShort:"Son_Maa_Din_Woe_Don_Vry_Sat".split("_"),weekdaysMin:"So_Ma_Di_Wo_Do_Vr_Sa".split("_"),meridiemParse:/vm|nm/i,isPM:function(n){return/^nm$/i.test(n)},meridiem:function(n,t,e){return n<12?e?"vm":"VM":e?"nm":"NM"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Vandag om] LT",nextDay:"[M\xf4re om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gister om] LT",lastWeek:"[Laas] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oor %s",past:"%s gelede",s:"'n paar sekondes",ss:"%d sekondes",m:"'n minuut",mm:"%d minute",h:"'n uur",hh:"%d ure",d:"'n dag",dd:"%d dae",M:"'n maand",MM:"%d maande",y:"'n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(n){return n+(1===n||8===n||n>=20?"ste":"de")},week:{dow:1,doy:4}})}(e("PJh5"))},"3IRH":function(n,t){n.exports=function(n){return n.webpackPolyfill||(n.deprecate=function(){},n.paths=[],n.children||(n.children=[]),Object.defineProperty(n,"loaded",{enumerable:!0,get:function(){return n.l}}),Object.defineProperty(n,"id",{enumerable:!0,get:function(){return n.i}}),n.webpackPolyfill=1),n}},"3K28":function(n,t,e){!function(n){"use strict";var t="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),e="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),l=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],r=/^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;n.defineLocale("nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(n,l){return n?/-MMM-/.test(l)?e[n.month()]:t[n.month()]:t},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:l,longMonthsParse:l,shortMonthsParse:l,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"\xe9\xe9n minuut",mm:"%d minuten",h:"\xe9\xe9n uur",hh:"%d uur",d:"\xe9\xe9n dag",dd:"%d dagen",M:"\xe9\xe9n maand",MM:"%d maanden",y:"\xe9\xe9n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(n){return n+(1===n||8===n||n>=20?"ste":"de")},week:{dow:1,doy:4}})}(e("PJh5"))},"3LKG":function(n,t,e){!function(n){"use strict";n.defineLocale("tl-ph",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(n){return n},week:{dow:1,doy:4}})}(e("PJh5"))},"3MVc":function(n,t,e){!function(n){"use strict";var t={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},e={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"},l=function(n){return 0===n?0:1===n?1:2===n?2:n%100>=3&&n%100<=10?3:n%100>=11?4:5},r={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},i=function(n){return function(t,e,i,o){var s=l(t),a=r[n][l(t)];return 2===s&&(a=a[e?0:1]),a.replace(/%d/i,t)}},o=["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0648","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];n.defineLocale("ar",{months:o,monthsShort:o,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(n){return"\u0645"===n},meridiem:function(n,t,e){return n<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:i("s"),ss:i("s"),m:i("m"),mm:i("m"),h:i("h"),hh:i("h"),d:i("d"),dd:i("d"),M:i("M"),MM:i("M"),y:i("y"),yy:i("y")},preparse:function(n){return n.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(n){return e[n]}).replace(/\u060c/g,",")},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}})}(e("PJh5"))},"3a3m":function(n,t,e){"use strict";t.a=function(){return function(n){return Object(r.a)()(Object(l.a)(o)(n))}};var l=e("Jwyl"),r=e("0P3J"),i=e("g5jc");function o(){return new i.a}},"3hfc":function(n,t,e){!function(n){"use strict";function t(n,t,e){var l,r;return"m"===e?t?"\u0445\u0432\u0456\u043b\u0456\u043d\u0430":"\u0445\u0432\u0456\u043b\u0456\u043d\u0443":"h"===e?t?"\u0433\u0430\u0434\u0437\u0456\u043d\u0430":"\u0433\u0430\u0434\u0437\u0456\u043d\u0443":n+" "+(l=+n,r={ss:t?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434",mm:t?"\u0445\u0432\u0456\u043b\u0456\u043d\u0430_\u0445\u0432\u0456\u043b\u0456\u043d\u044b_\u0445\u0432\u0456\u043b\u0456\u043d":"\u0445\u0432\u0456\u043b\u0456\u043d\u0443_\u0445\u0432\u0456\u043b\u0456\u043d\u044b_\u0445\u0432\u0456\u043b\u0456\u043d",hh:t?"\u0433\u0430\u0434\u0437\u0456\u043d\u0430_\u0433\u0430\u0434\u0437\u0456\u043d\u044b_\u0433\u0430\u0434\u0437\u0456\u043d":"\u0433\u0430\u0434\u0437\u0456\u043d\u0443_\u0433\u0430\u0434\u0437\u0456\u043d\u044b_\u0433\u0430\u0434\u0437\u0456\u043d",dd:"\u0434\u0437\u0435\u043d\u044c_\u0434\u043d\u0456_\u0434\u0437\u0451\u043d",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u044b_\u043c\u0435\u0441\u044f\u0446\u0430\u045e",yy:"\u0433\u043e\u0434_\u0433\u0430\u0434\u044b_\u0433\u0430\u0434\u043e\u045e"}[e].split("_"),l%10==1&&l%100!=11?r[0]:l%10>=2&&l%10<=4&&(l%100<10||l%100>=20)?r[1]:r[2])}n.defineLocale("be",{months:{format:"\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044f_\u043b\u044e\u0442\u0430\u0433\u0430_\u0441\u0430\u043a\u0430\u0432\u0456\u043a\u0430_\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a\u0430_\u0442\u0440\u0430\u045e\u043d\u044f_\u0447\u044d\u0440\u0432\u0435\u043d\u044f_\u043b\u0456\u043f\u0435\u043d\u044f_\u0436\u043d\u0456\u045e\u043d\u044f_\u0432\u0435\u0440\u0430\u0441\u043d\u044f_\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a\u0430_\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434\u0430_\u0441\u043d\u0435\u0436\u043d\u044f".split("_"),standalone:"\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044c_\u043b\u044e\u0442\u044b_\u0441\u0430\u043a\u0430\u0432\u0456\u043a_\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a_\u0442\u0440\u0430\u0432\u0435\u043d\u044c_\u0447\u044d\u0440\u0432\u0435\u043d\u044c_\u043b\u0456\u043f\u0435\u043d\u044c_\u0436\u043d\u0456\u0432\u0435\u043d\u044c_\u0432\u0435\u0440\u0430\u0441\u0435\u043d\u044c_\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a_\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434_\u0441\u043d\u0435\u0436\u0430\u043d\u044c".split("_")},monthsShort:"\u0441\u0442\u0443\u0434_\u043b\u044e\u0442_\u0441\u0430\u043a_\u043a\u0440\u0430\u0441_\u0442\u0440\u0430\u0432_\u0447\u044d\u0440\u0432_\u043b\u0456\u043f_\u0436\u043d\u0456\u0432_\u0432\u0435\u0440_\u043a\u0430\u0441\u0442_\u043b\u0456\u0441\u0442_\u0441\u043d\u0435\u0436".split("_"),weekdays:{format:"\u043d\u044f\u0434\u0437\u0435\u043b\u044e_\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a_\u0430\u045e\u0442\u043e\u0440\u0430\u043a_\u0441\u0435\u0440\u0430\u0434\u0443_\u0447\u0430\u0446\u0432\u0435\u0440_\u043f\u044f\u0442\u043d\u0456\u0446\u0443_\u0441\u0443\u0431\u043e\u0442\u0443".split("_"),standalone:"\u043d\u044f\u0434\u0437\u0435\u043b\u044f_\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a_\u0430\u045e\u0442\u043e\u0440\u0430\u043a_\u0441\u0435\u0440\u0430\u0434\u0430_\u0447\u0430\u0446\u0432\u0435\u0440_\u043f\u044f\u0442\u043d\u0456\u0446\u0430_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),isFormat:/\[ ?[\u0412\u0432] ?(?:\u043c\u0456\u043d\u0443\u043b\u0443\u044e|\u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0443\u044e)? ?\] ?dddd/},weekdaysShort:"\u043d\u0434_\u043f\u043d_\u0430\u0442_\u0441\u0440_\u0447\u0446_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0430\u0442_\u0441\u0440_\u0447\u0446_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0433.",LLL:"D MMMM YYYY \u0433., HH:mm",LLLL:"dddd, D MMMM YYYY \u0433., HH:mm"},calendar:{sameDay:"[\u0421\u0451\u043d\u043d\u044f \u045e] LT",nextDay:"[\u0417\u0430\u045e\u0442\u0440\u0430 \u045e] LT",lastDay:"[\u0423\u0447\u043e\u0440\u0430 \u045e] LT",nextWeek:function(){return"[\u0423] dddd [\u045e] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[\u0423 \u043c\u0456\u043d\u0443\u043b\u0443\u044e] dddd [\u045e] LT";case 1:case 2:case 4:return"[\u0423 \u043c\u0456\u043d\u0443\u043b\u044b] dddd [\u045e] LT"}},sameElse:"L"},relativeTime:{future:"\u043f\u0440\u0430\u0437 %s",past:"%s \u0442\u0430\u043c\u0443",s:"\u043d\u0435\u043a\u0430\u043b\u044c\u043a\u0456 \u0441\u0435\u043a\u0443\u043d\u0434",m:t,mm:t,h:t,hh:t,d:"\u0434\u0437\u0435\u043d\u044c",dd:t,M:"\u043c\u0435\u0441\u044f\u0446",MM:t,y:"\u0433\u043e\u0434",yy:t},meridiemParse:/\u043d\u043e\u0447\u044b|\u0440\u0430\u043d\u0456\u0446\u044b|\u0434\u043d\u044f|\u0432\u0435\u0447\u0430\u0440\u0430/,isPM:function(n){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u0430\u0440\u0430)$/.test(n)},meridiem:function(n,t,e){return n<4?"\u043d\u043e\u0447\u044b":n<12?"\u0440\u0430\u043d\u0456\u0446\u044b":n<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u0430\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0456|\u044b|\u0433\u0430)/,ordinal:function(n,t){switch(t){case"M":case"d":case"DDD":case"w":case"W":return n%10!=2&&n%10!=3||n%100==12||n%100==13?n+"-\u044b":n+"-\u0456";case"D":return n+"-\u0433\u0430";default:return n}},week:{dow:1,doy:7}})}(e("PJh5"))},"5Omq":function(n,t,e){!function(n){"use strict";n.defineLocale("se",{months:"o\u0111\u0111ajagem\xe1nnu_guovvam\xe1nnu_njuk\u010dam\xe1nnu_cuo\u014bom\xe1nnu_miessem\xe1nnu_geassem\xe1nnu_suoidnem\xe1nnu_borgem\xe1nnu_\u010dak\u010dam\xe1nnu_golggotm\xe1nnu_sk\xe1bmam\xe1nnu_juovlam\xe1nnu".split("_"),monthsShort:"o\u0111\u0111j_guov_njuk_cuo_mies_geas_suoi_borg_\u010dak\u010d_golg_sk\xe1b_juov".split("_"),weekdays:"sotnabeaivi_vuoss\xe1rga_ma\u014b\u014beb\xe1rga_gaskavahkku_duorastat_bearjadat_l\xe1vvardat".split("_"),weekdaysShort:"sotn_vuos_ma\u014b_gask_duor_bear_l\xe1v".split("_"),weekdaysMin:"s_v_m_g_d_b_L".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"MMMM D. [b.] YYYY",LLL:"MMMM D. [b.] YYYY [ti.] HH:mm",LLLL:"dddd, MMMM D. [b.] YYYY [ti.] HH:mm"},calendar:{sameDay:"[otne ti] LT",nextDay:"[ihttin ti] LT",nextWeek:"dddd [ti] LT",lastDay:"[ikte ti] LT",lastWeek:"[ovddit] dddd [ti] LT",sameElse:"L"},relativeTime:{future:"%s gea\u017ees",past:"ma\u014bit %s",s:"moadde sekunddat",ss:"%d sekunddat",m:"okta minuhta",mm:"%d minuhtat",h:"okta diimmu",hh:"%d diimmut",d:"okta beaivi",dd:"%d beaivvit",M:"okta m\xe1nnu",MM:"%d m\xe1nut",y:"okta jahki",yy:"%d jagit"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},"5SNd":function(n,t,e){!function(n){"use strict";var t={0:"-\u0443\u043c",1:"-\u0443\u043c",2:"-\u044e\u043c",3:"-\u044e\u043c",4:"-\u0443\u043c",5:"-\u0443\u043c",6:"-\u0443\u043c",7:"-\u0443\u043c",8:"-\u0443\u043c",9:"-\u0443\u043c",10:"-\u0443\u043c",12:"-\u0443\u043c",13:"-\u0443\u043c",20:"-\u0443\u043c",30:"-\u044e\u043c",40:"-\u0443\u043c",50:"-\u0443\u043c",60:"-\u0443\u043c",70:"-\u0443\u043c",80:"-\u0443\u043c",90:"-\u0443\u043c",100:"-\u0443\u043c"};n.defineLocale("tg",{months:"\u044f\u043d\u0432\u0430\u0440_\u0444\u0435\u0432\u0440\u0430\u043b_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440_\u043e\u043a\u0442\u044f\u0431\u0440_\u043d\u043e\u044f\u0431\u0440_\u0434\u0435\u043a\u0430\u0431\u0440".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u044f\u043a\u0448\u0430\u043d\u0431\u0435_\u0434\u0443\u0448\u0430\u043d\u0431\u0435_\u0441\u0435\u0448\u0430\u043d\u0431\u0435_\u0447\u043e\u0440\u0448\u0430\u043d\u0431\u0435_\u043f\u0430\u043d\u04b7\u0448\u0430\u043d\u0431\u0435_\u04b7\u0443\u043c\u044a\u0430_\u0448\u0430\u043d\u0431\u0435".split("_"),weekdaysShort:"\u044f\u0448\u0431_\u0434\u0448\u0431_\u0441\u0448\u0431_\u0447\u0448\u0431_\u043f\u0448\u0431_\u04b7\u0443\u043c_\u0448\u043d\u0431".split("_"),weekdaysMin:"\u044f\u0448_\u0434\u0448_\u0441\u0448_\u0447\u0448_\u043f\u0448_\u04b7\u043c_\u0448\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0418\u043c\u0440\u04ef\u0437 \u0441\u043e\u0430\u0442\u0438] LT",nextDay:"[\u041f\u0430\u0433\u043e\u04b3 \u0441\u043e\u0430\u0442\u0438] LT",lastDay:"[\u0414\u0438\u0440\u04ef\u0437 \u0441\u043e\u0430\u0442\u0438] LT",nextWeek:"dddd[\u0438] [\u04b3\u0430\u0444\u0442\u0430\u0438 \u043e\u044f\u043d\u0434\u0430 \u0441\u043e\u0430\u0442\u0438] LT",lastWeek:"dddd[\u0438] [\u04b3\u0430\u0444\u0442\u0430\u0438 \u0433\u0443\u0437\u0430\u0448\u0442\u0430 \u0441\u043e\u0430\u0442\u0438] LT",sameElse:"L"},relativeTime:{future:"\u0431\u0430\u044a\u0434\u0438 %s",past:"%s \u043f\u0435\u0448",s:"\u044f\u043a\u0447\u0430\u043d\u0434 \u0441\u043e\u043d\u0438\u044f",m:"\u044f\u043a \u0434\u0430\u049b\u0438\u049b\u0430",mm:"%d \u0434\u0430\u049b\u0438\u049b\u0430",h:"\u044f\u043a \u0441\u043e\u0430\u0442",hh:"%d \u0441\u043e\u0430\u0442",d:"\u044f\u043a \u0440\u04ef\u0437",dd:"%d \u0440\u04ef\u0437",M:"\u044f\u043a \u043c\u043e\u04b3",MM:"%d \u043c\u043e\u04b3",y:"\u044f\u043a \u0441\u043e\u043b",yy:"%d \u0441\u043e\u043b"},meridiemParse:/\u0448\u0430\u0431|\u0441\u0443\u0431\u04b3|\u0440\u04ef\u0437|\u0431\u0435\u0433\u043e\u04b3/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0448\u0430\u0431"===t?n<4?n:n+12:"\u0441\u0443\u0431\u04b3"===t?n:"\u0440\u04ef\u0437"===t?n>=11?n:n+12:"\u0431\u0435\u0433\u043e\u04b3"===t?n+12:void 0},meridiem:function(n,t,e){return n<4?"\u0448\u0430\u0431":n<11?"\u0441\u0443\u0431\u04b3":n<16?"\u0440\u04ef\u0437":n<19?"\u0431\u0435\u0433\u043e\u04b3":"\u0448\u0430\u0431"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0443\u043c|\u044e\u043c)/,ordinal:function(n){return n+(t[n]||t[n%10]||t[n>=100?100:null])},week:{dow:1,doy:7}})}(e("PJh5"))},"5X6E":function(n,t,e){"use strict";t.a=function(n,t){return function(e){return e.lift(new o(n,t))}};var l=e("TToO"),r=e("tZ2B"),i=e("PIsA"),o=function(){function n(n,t){this.project=n,this.resultSelector=t}return n.prototype.call=function(n,t){return t.subscribe(new s(n,this.project,this.resultSelector))},n}(),s=function(n){function t(t,e,l){n.call(this,t),this.project=e,this.resultSelector=l,this.index=0}return Object(l.__extends)(t,n),t.prototype._next=function(n){var t,e=this.index++;try{t=this.project(n,e)}catch(n){return void this.destination.error(n)}this._innerSub(t,n,e)},t.prototype._innerSub=function(n,t,e){var l=this.innerSubscription;l&&l.unsubscribe(),this.add(this.innerSubscription=Object(i.a)(this,n,t,e))},t.prototype._complete=function(){var t=this.innerSubscription;t&&!t.closed||n.prototype._complete.call(this)},t.prototype._unsubscribe=function(){this.innerSubscription=null},t.prototype.notifyComplete=function(t){this.remove(t),this.innerSubscription=null,this.isStopped&&n.prototype._complete.call(this)},t.prototype.notifyNext=function(n,t,e,l,r){this.resultSelector?this._tryNotifyNext(n,t,e,l):this.destination.next(t)},t.prototype._tryNotifyNext=function(n,t,e,l){var r;try{r=this.resultSelector(n,t,e,l)}catch(n){return void this.destination.error(n)}this.destination.next(r)},t}(r.a)},"5j66":function(n,t,e){!function(n){"use strict";n.defineLocale("km",{months:"\u1798\u1780\u179a\u17b6_\u1780\u17bb\u1798\u17d2\u1797\u17c8_\u1798\u17b8\u1793\u17b6_\u1798\u17c1\u179f\u17b6_\u17a7\u179f\u1797\u17b6_\u1798\u17b7\u1790\u17bb\u1793\u17b6_\u1780\u1780\u17d2\u1780\u178a\u17b6_\u179f\u17b8\u17a0\u17b6_\u1780\u1789\u17d2\u1789\u17b6_\u178f\u17bb\u179b\u17b6_\u179c\u17b7\u1785\u17d2\u1786\u17b7\u1780\u17b6_\u1792\u17d2\u1793\u17bc".split("_"),monthsShort:"\u1798\u1780\u179a\u17b6_\u1780\u17bb\u1798\u17d2\u1797\u17c8_\u1798\u17b8\u1793\u17b6_\u1798\u17c1\u179f\u17b6_\u17a7\u179f\u1797\u17b6_\u1798\u17b7\u1790\u17bb\u1793\u17b6_\u1780\u1780\u17d2\u1780\u178a\u17b6_\u179f\u17b8\u17a0\u17b6_\u1780\u1789\u17d2\u1789\u17b6_\u178f\u17bb\u179b\u17b6_\u179c\u17b7\u1785\u17d2\u1786\u17b7\u1780\u17b6_\u1792\u17d2\u1793\u17bc".split("_"),weekdays:"\u17a2\u17b6\u1791\u17b7\u178f\u17d2\u1799_\u1785\u17d0\u1793\u17d2\u1791_\u17a2\u1784\u17d2\u1782\u17b6\u179a_\u1796\u17bb\u1792_\u1796\u17d2\u179a\u17a0\u179f\u17d2\u1794\u178f\u17b7\u17cd_\u179f\u17bb\u1780\u17d2\u179a_\u179f\u17c5\u179a\u17cd".split("_"),weekdaysShort:"\u17a2\u17b6\u1791\u17b7\u178f\u17d2\u1799_\u1785\u17d0\u1793\u17d2\u1791_\u17a2\u1784\u17d2\u1782\u17b6\u179a_\u1796\u17bb\u1792_\u1796\u17d2\u179a\u17a0\u179f\u17d2\u1794\u178f\u17b7\u17cd_\u179f\u17bb\u1780\u17d2\u179a_\u179f\u17c5\u179a\u17cd".split("_"),weekdaysMin:"\u17a2\u17b6\u1791\u17b7\u178f\u17d2\u1799_\u1785\u17d0\u1793\u17d2\u1791_\u17a2\u1784\u17d2\u1782\u17b6\u179a_\u1796\u17bb\u1792_\u1796\u17d2\u179a\u17a0\u179f\u17d2\u1794\u178f\u17b7\u17cd_\u179f\u17bb\u1780\u17d2\u179a_\u179f\u17c5\u179a\u17cd".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u1790\u17d2\u1784\u17c3\u1793\u17c1\u17c7 \u1798\u17c9\u17c4\u1784] LT",nextDay:"[\u179f\u17d2\u17a2\u17c2\u1780 \u1798\u17c9\u17c4\u1784] LT",nextWeek:"dddd [\u1798\u17c9\u17c4\u1784] LT",lastDay:"[\u1798\u17d2\u179f\u17b7\u179b\u1798\u17b7\u1789 \u1798\u17c9\u17c4\u1784] LT",lastWeek:"dddd [\u179f\u1794\u17d2\u178f\u17b6\u17a0\u17cd\u1798\u17bb\u1793] [\u1798\u17c9\u17c4\u1784] LT",sameElse:"L"},relativeTime:{future:"%s\u1791\u17c0\u178f",past:"%s\u1798\u17bb\u1793",s:"\u1794\u17c9\u17bb\u1793\u17d2\u1798\u17b6\u1793\u179c\u17b7\u1793\u17b6\u1791\u17b8",ss:"%d \u179c\u17b7\u1793\u17b6\u1791\u17b8",m:"\u1798\u17bd\u1799\u1793\u17b6\u1791\u17b8",mm:"%d \u1793\u17b6\u1791\u17b8",h:"\u1798\u17bd\u1799\u1798\u17c9\u17c4\u1784",hh:"%d \u1798\u17c9\u17c4\u1784",d:"\u1798\u17bd\u1799\u1790\u17d2\u1784\u17c3",dd:"%d \u1790\u17d2\u1784\u17c3",M:"\u1798\u17bd\u1799\u1781\u17c2",MM:"%d \u1781\u17c2",y:"\u1798\u17bd\u1799\u1786\u17d2\u1793\u17b6\u17c6",yy:"%d \u1786\u17d2\u1793\u17b6\u17c6"},week:{dow:1,doy:4}})}(e("PJh5"))},"5vPg":function(n,t,e){!function(n){"use strict";var t={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},e={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};function l(n,t,e,l){var r="";if(t)switch(e){case"s":r="\u0915\u093e\u0939\u0940 \u0938\u0947\u0915\u0902\u0926";break;case"ss":r="%d \u0938\u0947\u0915\u0902\u0926";break;case"m":r="\u090f\u0915 \u092e\u093f\u0928\u093f\u091f";break;case"mm":r="%d \u092e\u093f\u0928\u093f\u091f\u0947";break;case"h":r="\u090f\u0915 \u0924\u093e\u0938";break;case"hh":r="%d \u0924\u093e\u0938";break;case"d":r="\u090f\u0915 \u0926\u093f\u0935\u0938";break;case"dd":r="%d \u0926\u093f\u0935\u0938";break;case"M":r="\u090f\u0915 \u092e\u0939\u093f\u0928\u093e";break;case"MM":r="%d \u092e\u0939\u093f\u0928\u0947";break;case"y":r="\u090f\u0915 \u0935\u0930\u094d\u0937";break;case"yy":r="%d \u0935\u0930\u094d\u0937\u0947"}else switch(e){case"s":r="\u0915\u093e\u0939\u0940 \u0938\u0947\u0915\u0902\u0926\u093e\u0902";break;case"ss":r="%d \u0938\u0947\u0915\u0902\u0926\u093e\u0902";break;case"m":r="\u090f\u0915\u093e \u092e\u093f\u0928\u093f\u091f\u093e";break;case"mm":r="%d \u092e\u093f\u0928\u093f\u091f\u093e\u0902";break;case"h":r="\u090f\u0915\u093e \u0924\u093e\u0938\u093e";break;case"hh":r="%d \u0924\u093e\u0938\u093e\u0902";break;case"d":r="\u090f\u0915\u093e \u0926\u093f\u0935\u0938\u093e";break;case"dd":r="%d \u0926\u093f\u0935\u0938\u093e\u0902";break;case"M":r="\u090f\u0915\u093e \u092e\u0939\u093f\u0928\u094d\u092f\u093e";break;case"MM":r="%d \u092e\u0939\u093f\u0928\u094d\u092f\u093e\u0902";break;case"y":r="\u090f\u0915\u093e \u0935\u0930\u094d\u0937\u093e";break;case"yy":r="%d \u0935\u0930\u094d\u0937\u093e\u0902"}return r.replace(/%d/i,n)}n.defineLocale("mr",{months:"\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u090f\u092a\u094d\u0930\u093f\u0932_\u092e\u0947_\u091c\u0942\u0928_\u091c\u0941\u0932\u0948_\u0911\u0917\u0938\u094d\u091f_\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930_\u0911\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930_\u0921\u093f\u0938\u0947\u0902\u092c\u0930".split("_"),monthsShort:"\u091c\u093e\u0928\u0947._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a._\u090f\u092a\u094d\u0930\u093f._\u092e\u0947._\u091c\u0942\u0928._\u091c\u0941\u0932\u0948._\u0911\u0917._\u0938\u092a\u094d\u091f\u0947\u0902._\u0911\u0915\u094d\u091f\u094b._\u0928\u094b\u0935\u094d\u0939\u0947\u0902._\u0921\u093f\u0938\u0947\u0902.".split("_"),monthsParseExact:!0,weekdays:"\u0930\u0935\u093f\u0935\u093e\u0930_\u0938\u094b\u092e\u0935\u093e\u0930_\u092e\u0902\u0917\u0933\u0935\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u0917\u0941\u0930\u0942\u0935\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930_\u0936\u0928\u093f\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0930\u0935\u093f_\u0938\u094b\u092e_\u092e\u0902\u0917\u0933_\u092c\u0941\u0927_\u0917\u0941\u0930\u0942_\u0936\u0941\u0915\u094d\u0930_\u0936\u0928\u093f".split("_"),weekdaysMin:"\u0930_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u0917\u0941_\u0936\u0941_\u0936".split("_"),longDateFormat:{LT:"A h:mm \u0935\u093e\u091c\u0924\u093e",LTS:"A h:mm:ss \u0935\u093e\u091c\u0924\u093e",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0935\u093e\u091c\u0924\u093e",LLLL:"dddd, D MMMM YYYY, A h:mm \u0935\u093e\u091c\u0924\u093e"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u0909\u0926\u094d\u092f\u093e] LT",nextWeek:"dddd, LT",lastDay:"[\u0915\u093e\u0932] LT",lastWeek:"[\u092e\u093e\u0917\u0940\u0932] dddd, LT",sameElse:"L"},relativeTime:{future:"%s\u092e\u0927\u094d\u092f\u0947",past:"%s\u092a\u0942\u0930\u094d\u0935\u0940",s:l,ss:l,m:l,mm:l,h:l,hh:l,d:l,dd:l,M:l,MM:l,y:l,yy:l},preparse:function(n){return n.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u0930\u093e\u0924\u094d\u0930\u0940|\u0938\u0915\u093e\u0933\u0940|\u0926\u0941\u092a\u093e\u0930\u0940|\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0930\u093e\u0924\u094d\u0930\u0940"===t?n<4?n:n+12:"\u0938\u0915\u093e\u0933\u0940"===t?n:"\u0926\u0941\u092a\u093e\u0930\u0940"===t?n>=10?n:n+12:"\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940"===t?n+12:void 0},meridiem:function(n,t,e){return n<4?"\u0930\u093e\u0924\u094d\u0930\u0940":n<10?"\u0938\u0915\u093e\u0933\u0940":n<17?"\u0926\u0941\u092a\u093e\u0930\u0940":n<20?"\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940":"\u0930\u093e\u0924\u094d\u0930\u0940"},week:{dow:0,doy:6}})}(e("PJh5"))},"6cf8":function(n,t,e){!function(n){"use strict";var t={0:"-\u0447\u04af",1:"-\u0447\u0438",2:"-\u0447\u0438",3:"-\u0447\u04af",4:"-\u0447\u04af",5:"-\u0447\u0438",6:"-\u0447\u044b",7:"-\u0447\u0438",8:"-\u0447\u0438",9:"-\u0447\u0443",10:"-\u0447\u0443",20:"-\u0447\u044b",30:"-\u0447\u0443",40:"-\u0447\u044b",50:"-\u0447\u04af",60:"-\u0447\u044b",70:"-\u0447\u0438",80:"-\u0447\u0438",90:"-\u0447\u0443",100:"-\u0447\u04af"};n.defineLocale("ky",{months:"\u044f\u043d\u0432\u0430\u0440\u044c_\u0444\u0435\u0432\u0440\u0430\u043b\u044c_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b\u044c_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c_\u043e\u043a\u0442\u044f\u0431\u0440\u044c_\u043d\u043e\u044f\u0431\u0440\u044c_\u0434\u0435\u043a\u0430\u0431\u0440\u044c".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u0416\u0435\u043a\u0448\u0435\u043c\u0431\u0438_\u0414\u04af\u0439\u0448\u04e9\u043c\u0431\u04af_\u0428\u0435\u0439\u0448\u0435\u043c\u0431\u0438_\u0428\u0430\u0440\u0448\u0435\u043c\u0431\u0438_\u0411\u0435\u0439\u0448\u0435\u043c\u0431\u0438_\u0416\u0443\u043c\u0430_\u0418\u0448\u0435\u043c\u0431\u0438".split("_"),weekdaysShort:"\u0416\u0435\u043a_\u0414\u04af\u0439_\u0428\u0435\u0439_\u0428\u0430\u0440_\u0411\u0435\u0439_\u0416\u0443\u043c_\u0418\u0448\u0435".split("_"),weekdaysMin:"\u0416\u043a_\u0414\u0439_\u0428\u0439_\u0428\u0440_\u0411\u0439_\u0416\u043c_\u0418\u0448".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0411\u04af\u0433\u04af\u043d \u0441\u0430\u0430\u0442] LT",nextDay:"[\u042d\u0440\u0442\u0435\u04a3 \u0441\u0430\u0430\u0442] LT",nextWeek:"dddd [\u0441\u0430\u0430\u0442] LT",lastDay:"[\u041a\u0435\u0447\u0435 \u0441\u0430\u0430\u0442] LT",lastWeek:"[\u04e8\u0442\u043a\u0435\u043d \u0430\u043f\u0442\u0430\u043d\u044b\u043d] dddd [\u043a\u04af\u043d\u04af] [\u0441\u0430\u0430\u0442] LT",sameElse:"L"},relativeTime:{future:"%s \u0438\u0447\u0438\u043d\u0434\u0435",past:"%s \u043c\u0443\u0440\u0443\u043d",s:"\u0431\u0438\u0440\u043d\u0435\u0447\u0435 \u0441\u0435\u043a\u0443\u043d\u0434",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434",m:"\u0431\u0438\u0440 \u043c\u04af\u043d\u04e9\u0442",mm:"%d \u043c\u04af\u043d\u04e9\u0442",h:"\u0431\u0438\u0440 \u0441\u0430\u0430\u0442",hh:"%d \u0441\u0430\u0430\u0442",d:"\u0431\u0438\u0440 \u043a\u04af\u043d",dd:"%d \u043a\u04af\u043d",M:"\u0431\u0438\u0440 \u0430\u0439",MM:"%d \u0430\u0439",y:"\u0431\u0438\u0440 \u0436\u044b\u043b",yy:"%d \u0436\u044b\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0447\u0438|\u0447\u044b|\u0447\u04af|\u0447\u0443)/,ordinal:function(n){return n+(t[n]||t[n%10]||t[n>=100?100:null])},week:{dow:1,doy:7}})}(e("PJh5"))},"7LV+":function(n,t,e){!function(n){"use strict";var t="stycze\u0144_luty_marzec_kwiecie\u0144_maj_czerwiec_lipiec_sierpie\u0144_wrzesie\u0144_pa\u017adziernik_listopad_grudzie\u0144".split("_"),e="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_wrze\u015bnia_pa\u017adziernika_listopada_grudnia".split("_");function l(n){return n%10<5&&n%10>1&&~~(n/10)%10!=1}function r(n,t,e){var r=n+" ";switch(e){case"ss":return r+(l(n)?"sekundy":"sekund");case"m":return t?"minuta":"minut\u0119";case"mm":return r+(l(n)?"minuty":"minut");case"h":return t?"godzina":"godzin\u0119";case"hh":return r+(l(n)?"godziny":"godzin");case"MM":return r+(l(n)?"miesi\u0105ce":"miesi\u0119cy");case"yy":return r+(l(n)?"lata":"lat")}}n.defineLocale("pl",{months:function(n,l){return n?""===l?"("+e[n.month()]+"|"+t[n.month()]+")":/D MMMM/.test(l)?e[n.month()]:t[n.month()]:t},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_pa\u017a_lis_gru".split("_"),weekdays:"niedziela_poniedzia\u0142ek_wtorek_\u015broda_czwartek_pi\u0105tek_sobota".split("_"),weekdaysShort:"ndz_pon_wt_\u015br_czw_pt_sob".split("_"),weekdaysMin:"Nd_Pn_Wt_\u015ar_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dzi\u015b o] LT",nextDay:"[Jutro o] LT",nextWeek:function(){switch(this.day()){case 0:return"[W niedziel\u0119 o] LT";case 2:return"[We wtorek o] LT";case 3:return"[W \u015brod\u0119 o] LT";case 6:return"[W sobot\u0119 o] LT";default:return"[W] dddd [o] LT"}},lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zesz\u0142\u0105 niedziel\u0119 o] LT";case 3:return"[W zesz\u0142\u0105 \u015brod\u0119 o] LT";case 6:return"[W zesz\u0142\u0105 sobot\u0119 o] LT";default:return"[W zesz\u0142y] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",ss:r,m:r,mm:r,h:r,hh:r,d:"1 dzie\u0144",dd:"%d dni",M:"miesi\u0105c",MM:r,y:"rok",yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},"7MHZ":function(n,t,e){!function(n){"use strict";var t="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),e="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),l=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],r=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;n.defineLocale("es-do",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(n,l){return n?/-MMM-/.test(l)?e[n.month()]:t[n.month()]:t},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:l,longMonthsParse:l,shortMonthsParse:l,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(e("PJh5"))},"7OnE":function(n,t,e){!function(n){"use strict";var t={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},e={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"};n.defineLocale("ar-sa",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a\u0648_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648_\u0623\u063a\u0633\u0637\u0633_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a\u0648_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648_\u0623\u063a\u0633\u0637\u0633_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(n){return"\u0645"===n},meridiem:function(n,t,e){return n<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},preparse:function(n){return n.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(n){return e[n]}).replace(/\u060c/g,",")},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]}).replace(/,/g,"\u060c")},week:{dow:0,doy:6}})}(e("PJh5"))},"7Q8x":function(n,t,e){!function(n){"use strict";n.defineLocale("ss",{months:"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split("_"),monthsShort:"Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo".split("_"),weekdays:"Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo".split("_"),weekdaysShort:"Lis_Umb_Lsb_Les_Lsi_Lsh_Umg".split("_"),weekdaysMin:"Li_Us_Lb_Lt_Ls_Lh_Ug".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Namuhla nga] LT",nextDay:"[Kusasa nga] LT",nextWeek:"dddd [nga] LT",lastDay:"[Itolo nga] LT",lastWeek:"dddd [leliphelile] [nga] LT",sameElse:"L"},relativeTime:{future:"nga %s",past:"wenteka nga %s",s:"emizuzwana lomcane",ss:"%d mzuzwana",m:"umzuzu",mm:"%d emizuzu",h:"lihora",hh:"%d emahora",d:"lilanga",dd:"%d emalanga",M:"inyanga",MM:"%d tinyanga",y:"umnyaka",yy:"%d iminyaka"},meridiemParse:/ekuseni|emini|entsambama|ebusuku/,meridiem:function(n,t,e){return n<11?"ekuseni":n<15?"emini":n<19?"entsambama":"ebusuku"},meridiemHour:function(n,t){return 12===n&&(n=0),"ekuseni"===t?n:"emini"===t?n>=11?n:n+12:"entsambama"===t||"ebusuku"===t?0===n?0:n+12:void 0},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:"%d",week:{dow:1,doy:4}})}(e("PJh5"))},"8D5t":function(n,t,e){"use strict";t.a=function(n){return void 0===n&&(n=Number.POSITIVE_INFINITY),Object(l.a)(r.a,null,n)};var l=e("Qnch"),r=e("lAP5")},"8v14":function(n,t,e){!function(n){"use strict";function t(n,t,e,l){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[n+" Tage",n+" Tagen"],M:["ein Monat","einem Monat"],MM:[n+" Monate",n+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[n+" Jahre",n+" Jahren"]};return t?r[e][0]:r[e][1]}n.defineLocale("de-at",{months:"J\xe4nner_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"J\xe4n._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:t,mm:"%d Minuten",h:t,hh:"%d Stunden",d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},"9Ocp":function(n,t,e){"use strict";t.a=function(n){return function(t){return 0===n?new o.a:t.lift(new s(n))}};var l=e("TToO"),r=e("OVmG"),i=e("pU/0"),o=e("+3/4"),s=function(){function n(n){if(this.total=n,this.total<0)throw new i.a}return n.prototype.call=function(n,t){return t.subscribe(new a(n,this.total))},n}(),a=function(n){function t(t,e){n.call(this,t),this.total=e,this.count=0}return Object(l.__extends)(t,n),t.prototype._next=function(n){var t=this.total,e=++this.count;e<=t&&(this.destination.next(n),e===t&&(this.destination.complete(),this.unsubscribe()))},t}(r.a)},ALEw:function(n,t,e){!function(n){"use strict";n.defineLocale("en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(n){var t=n%10;return n+(1==~~(n%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")},week:{dow:1,doy:4}})}(e("PJh5"))},AMGY:function(n,t,e){"use strict";(function(n){e.d(t,"a",function(){return i});var l="undefined"!=typeof window&&window,r="undefined"!=typeof self&&"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&self,i=l||"undefined"!=typeof n&&n||r}).call(t,e("DuR2"))},Ab7C:function(n,t,e){!function(n){"use strict";n.defineLocale("mk",{months:"\u0458\u0430\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0458_\u0458\u0443\u043d\u0438_\u0458\u0443\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u0458\u0430\u043d_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u0430_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0440\u0442\u043e\u043a_\u043f\u0435\u0442\u043e\u043a_\u0441\u0430\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u0435_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u0430\u0431".split("_"),weekdaysMin:"\u043de_\u043fo_\u0432\u0442_\u0441\u0440_\u0447\u0435_\u043f\u0435_\u0441a".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[\u0414\u0435\u043d\u0435\u0441 \u0432\u043e] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432\u043e] LT",nextWeek:"[\u0412\u043e] dddd [\u0432\u043e] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432\u043e] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0418\u0437\u043c\u0438\u043d\u0430\u0442\u0430\u0442\u0430] dddd [\u0432\u043e] LT";case 1:case 2:case 4:case 5:return"[\u0418\u0437\u043c\u0438\u043d\u0430\u0442\u0438\u043e\u0442] dddd [\u0432\u043e] LT"}},sameElse:"L"},relativeTime:{future:"\u043f\u043e\u0441\u043b\u0435 %s",past:"\u043f\u0440\u0435\u0434 %s",s:"\u043d\u0435\u043a\u043e\u043b\u043a\u0443 \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u0435\u043d\u0430",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0438",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0435\u0432|\u0435\u043d|\u0442\u0438|\u0432\u0438|\u0440\u0438|\u043c\u0438)/,ordinal:function(n){var t=n%10,e=n%100;return 0===n?n+"-\u0435\u0432":0===e?n+"-\u0435\u043d":e>10&&e<20?n+"-\u0442\u0438":1===t?n+"-\u0432\u0438":2===t?n+"-\u0440\u0438":7===t||8===t?n+"-\u043c\u0438":n+"-\u0442\u0438"},week:{dow:1,doy:7}})}(e("PJh5"))},AoDM:function(n,t,e){!function(n){"use strict";n.defineLocale("pt-br",{months:"janeiro_fevereiro_mar\xe7o_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\xe7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\xe1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\xe1b".split("_"),weekdaysMin:"Do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [\xe0s] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [\xe0s] HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"h\xe1 %s",s:"poucos segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba"})}(e("PJh5"))},BEem:function(n,t,e){!function(n){"use strict";n.defineLocale("ar-tn",{months:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:1,doy:4}})}(e("PJh5"))},BX3T:function(n,t,e){"use strict";e.d(t,"a",function(){return l});var l=Array.isArray||function(n){return n&&"number"==typeof n.length}},BbgG:function(n,t,e){!function(n){"use strict";n.defineLocale("zh-tw",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u51cc\u6668"===t||"\u65e9\u4e0a"===t||"\u4e0a\u5348"===t?n:"\u4e2d\u5348"===t?n>=11?n:n+12:"\u4e0b\u5348"===t||"\u665a\u4e0a"===t?n+12:void 0},meridiem:function(n,t,e){var l=100*n+t;return l<600?"\u51cc\u6668":l<900?"\u65e9\u4e0a":l<1130?"\u4e0a\u5348":l<1230?"\u4e2d\u5348":l<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(n,t){switch(t){case"d":case"D":case"DDD":return n+"\u65e5";case"M":return n+"\u6708";case"w":case"W":return n+"\u9031";default:return n}},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}})}(e("PJh5"))},Bp2f:function(n,t,e){!function(n){"use strict";var t="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),e="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),l=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],r=/^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;n.defineLocale("nl-be",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(n,l){return n?/-MMM-/.test(l)?e[n.month()]:t[n.month()]:t},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:l,longMonthsParse:l,shortMonthsParse:l,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"\xe9\xe9n minuut",mm:"%d minuten",h:"\xe9\xe9n uur",hh:"%d uur",d:"\xe9\xe9n dag",dd:"%d dagen",M:"\xe9\xe9n maand",MM:"%d maanden",y:"\xe9\xe9n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(n){return n+(1===n||8===n||n>=20?"ste":"de")},week:{dow:1,doy:4}})}(e("PJh5"))},C7av:function(n,t,e){!function(n){"use strict";n.defineLocale("nn",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sundag_m\xe5ndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),weekdaysShort:"sun_m\xe5n_tys_ons_tor_fre_lau".split("_"),weekdaysMin:"su_m\xe5_ty_on_to_fr_l\xf8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[I dag klokka] LT",nextDay:"[I morgon klokka] LT",nextWeek:"dddd [klokka] LT",lastDay:"[I g\xe5r klokka] LT",lastWeek:"[F\xf8reg\xe5ande] dddd [klokka] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s sidan",s:"nokre sekund",ss:"%d sekund",m:"eit minutt",mm:"%d minutt",h:"ein time",hh:"%d timar",d:"ein dag",dd:"%d dagar",M:"ein m\xe5nad",MM:"%d m\xe5nader",y:"eit \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},CFqe:function(n,t,e){!function(n){"use strict";n.defineLocale("el",{monthsNominativeEl:"\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2_\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2_\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2_\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2_\u039c\u03ac\u03b9\u03bf\u03c2_\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2_\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2_\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2_\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2_\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2_\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2_\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2".split("_"),monthsGenitiveEl:"\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5_\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5_\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5_\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5_\u039c\u03b1\u0390\u03bf\u03c5_\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5_\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5_\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5_\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5_\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5_\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5_\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5".split("_"),months:function(n,t){return n?"string"==typeof t&&/D/.test(t.substring(0,t.indexOf("MMMM")))?this._monthsGenitiveEl[n.month()]:this._monthsNominativeEl[n.month()]:this._monthsNominativeEl},monthsShort:"\u0399\u03b1\u03bd_\u03a6\u03b5\u03b2_\u039c\u03b1\u03c1_\u0391\u03c0\u03c1_\u039c\u03b1\u03ca_\u0399\u03bf\u03c5\u03bd_\u0399\u03bf\u03c5\u03bb_\u0391\u03c5\u03b3_\u03a3\u03b5\u03c0_\u039f\u03ba\u03c4_\u039d\u03bf\u03b5_\u0394\u03b5\u03ba".split("_"),weekdays:"\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae_\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1_\u03a4\u03c1\u03af\u03c4\u03b7_\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7_\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7_\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae_\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf".split("_"),weekdaysShort:"\u039a\u03c5\u03c1_\u0394\u03b5\u03c5_\u03a4\u03c1\u03b9_\u03a4\u03b5\u03c4_\u03a0\u03b5\u03bc_\u03a0\u03b1\u03c1_\u03a3\u03b1\u03b2".split("_"),weekdaysMin:"\u039a\u03c5_\u0394\u03b5_\u03a4\u03c1_\u03a4\u03b5_\u03a0\u03b5_\u03a0\u03b1_\u03a3\u03b1".split("_"),meridiem:function(n,t,e){return n>11?e?"\u03bc\u03bc":"\u039c\u039c":e?"\u03c0\u03bc":"\u03a0\u039c"},isPM:function(n){return"\u03bc"===(n+"").toLowerCase()[0]},meridiemParse:/[\u03a0\u039c]\.?\u039c?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 {}] LT",nextDay:"[\u0391\u03cd\u03c1\u03b9\u03bf {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[\u03a7\u03b8\u03b5\u03c2 {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[\u03c4\u03bf \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf] dddd [{}] LT";default:return"[\u03c4\u03b7\u03bd \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03b7] dddd [{}] LT"}},sameElse:"L"},calendar:function(n,t){var e,l=this._calendarEl[n],r=t&&t.hours();return((e=l)instanceof Function||"[object Function]"===Object.prototype.toString.call(e))&&(l=l.apply(t)),l.replace("{}",r%12==1?"\u03c3\u03c4\u03b7":"\u03c3\u03c4\u03b9\u03c2")},relativeTime:{future:"\u03c3\u03b5 %s",past:"%s \u03c0\u03c1\u03b9\u03bd",s:"\u03bb\u03af\u03b3\u03b1 \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1",ss:"%d \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1",m:"\u03ad\u03bd\u03b1 \u03bb\u03b5\u03c0\u03c4\u03cc",mm:"%d \u03bb\u03b5\u03c0\u03c4\u03ac",h:"\u03bc\u03af\u03b1 \u03ce\u03c1\u03b1",hh:"%d \u03ce\u03c1\u03b5\u03c2",d:"\u03bc\u03af\u03b1 \u03bc\u03ad\u03c1\u03b1",dd:"%d \u03bc\u03ad\u03c1\u03b5\u03c2",M:"\u03ad\u03bd\u03b1\u03c2 \u03bc\u03ae\u03bd\u03b1\u03c2",MM:"%d \u03bc\u03ae\u03bd\u03b5\u03c2",y:"\u03ad\u03bd\u03b1\u03c2 \u03c7\u03c1\u03cc\u03bd\u03bf\u03c2",yy:"%d \u03c7\u03c1\u03cc\u03bd\u03b9\u03b1"},dayOfMonthOrdinalParse:/\d{1,2}\u03b7/,ordinal:"%d\u03b7",week:{dow:1,doy:4}})}(e("PJh5"))},DDro:function(n,t,e){"use strict";t.a=function(){return Object(l.a)(r,[])};var l=e("/4Bh");function r(n,t,e){return n.push(t),n}},DOkx:function(n,t,e){!function(n){"use strict";function t(n,t,e,l){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[n+" Tage",n+" Tagen"],M:["ein Monat","einem Monat"],MM:[n+" Monate",n+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[n+" Jahre",n+" Jahren"]};return t?r[e][0]:r[e][1]}n.defineLocale("de",{months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:t,mm:"%d Minuten",h:t,hh:"%d Stunden",d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},DSXN:function(n,t,e){!function(n){"use strict";n.defineLocale("sw",{months:"Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des".split("_"),weekdays:"Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi".split("_"),weekdaysShort:"Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos".split("_"),weekdaysMin:"J2_J3_J4_J5_Al_Ij_J1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[leo saa] LT",nextDay:"[kesho saa] LT",nextWeek:"[wiki ijayo] dddd [saat] LT",lastDay:"[jana] LT",lastWeek:"[wiki iliyopita] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s baadaye",past:"tokea %s",s:"hivi punde",ss:"sekunde %d",m:"dakika moja",mm:"dakika %d",h:"saa limoja",hh:"masaa %d",d:"siku moja",dd:"masiku %d",M:"mwezi mmoja",MM:"miezi %d",y:"mwaka mmoja",yy:"miaka %d"},week:{dow:1,doy:7}})}(e("PJh5"))},DuR2:function(n,t){var e;e=function(){return this}();try{e=e||Function("return this")()||(0,eval)("this")}catch(n){"object"==typeof window&&(e=window)}n.exports=e},E5SG:function(n,t,e){"use strict";t.a=function(n,t){var e=!1;return arguments.length>=2&&(e=!0),function(l){return l.lift(new i(n,t,e))}};var l=e("TToO"),r=e("OVmG"),i=function(){function n(n,t,e){void 0===e&&(e=!1),this.accumulator=n,this.seed=t,this.hasSeed=e}return n.prototype.call=function(n,t){return t.subscribe(new o(n,this.accumulator,this.seed,this.hasSeed))},n}(),o=function(n){function t(t,e,l,r){n.call(this,t),this.accumulator=e,this._seed=l,this.hasSeed=r,this.index=0}return Object(l.__extends)(t,n),Object.defineProperty(t.prototype,"seed",{get:function(){return this._seed},set:function(n){this.hasSeed=!0,this._seed=n},enumerable:!0,configurable:!0}),t.prototype._next=function(n){if(this.hasSeed)return this._tryNext(n);this.seed=n,this.destination.next(n)},t.prototype._tryNext=function(n){var t,e=this.index++;try{t=this.accumulator(this.seed,n,e)}catch(n){this.destination.error(n)}this.seed=t,this.destination.next(t)},t}(r.a)},EKta:function(n,t,e){"use strict";t.byteLength=function(n){return 3*n.length/4-u(n)},t.toByteArray=function(n){var t,e,l,o,s,a=n.length;o=u(n),s=new i(3*a/4-o),e=o>0?a-4:a;var c=0;for(t=0;t>16&255,s[c++]=l>>8&255,s[c++]=255&l;return 2===o?(l=r[n.charCodeAt(t)]<<2|r[n.charCodeAt(t+1)]>>4,s[c++]=255&l):1===o&&(l=r[n.charCodeAt(t)]<<10|r[n.charCodeAt(t+1)]<<4|r[n.charCodeAt(t+2)]>>2,s[c++]=l>>8&255,s[c++]=255&l),s},t.fromByteArray=function(n){for(var t,e=n.length,r=e%3,i="",o=[],s=0,a=e-r;sa?a:s+16383));return 1===r?(i+=l[(t=n[e-1])>>2],i+=l[t<<4&63],i+="=="):2===r&&(i+=l[(t=(n[e-2]<<8)+n[e-1])>>10],i+=l[t>>4&63],i+=l[t<<2&63],i+="="),o.push(i),o.join("")};for(var l=[],r=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,a=o.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");return"="===n[t-2]?2:"="===n[t-1]?1:0}function c(n,t,e){for(var r,i=[],o=t;o>18&63]+l[r>>12&63]+l[r>>6&63]+l[63&r]);return i.join("")}r["-".charCodeAt(0)]=62,r["_".charCodeAt(0)]=63},ETHv:function(n,t,e){!function(n){"use strict";var t={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},e={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};n.defineLocale("hi",{months:"\u091c\u0928\u0935\u0930\u0940_\u092b\u093c\u0930\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948\u0932_\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0938\u094d\u0924_\u0938\u093f\u0924\u092e\u094d\u092c\u0930_\u0905\u0915\u094d\u091f\u0942\u092c\u0930_\u0928\u0935\u092e\u094d\u092c\u0930_\u0926\u093f\u0938\u092e\u094d\u092c\u0930".split("_"),monthsShort:"\u091c\u0928._\u092b\u093c\u0930._\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948._\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932._\u0905\u0917._\u0938\u093f\u0924._\u0905\u0915\u094d\u091f\u0942._\u0928\u0935._\u0926\u093f\u0938.".split("_"),monthsParseExact:!0,weekdays:"\u0930\u0935\u093f\u0935\u093e\u0930_\u0938\u094b\u092e\u0935\u093e\u0930_\u092e\u0902\u0917\u0932\u0935\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u0917\u0941\u0930\u0942\u0935\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930_\u0936\u0928\u093f\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0930\u0935\u093f_\u0938\u094b\u092e_\u092e\u0902\u0917\u0932_\u092c\u0941\u0927_\u0917\u0941\u0930\u0942_\u0936\u0941\u0915\u094d\u0930_\u0936\u0928\u093f".split("_"),weekdaysMin:"\u0930_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u0917\u0941_\u0936\u0941_\u0936".split("_"),longDateFormat:{LT:"A h:mm \u092c\u091c\u0947",LTS:"A h:mm:ss \u092c\u091c\u0947",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u092c\u091c\u0947",LLLL:"dddd, D MMMM YYYY, A h:mm \u092c\u091c\u0947"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u0915\u0932] LT",nextWeek:"dddd, LT",lastDay:"[\u0915\u0932] LT",lastWeek:"[\u092a\u093f\u091b\u0932\u0947] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u092e\u0947\u0902",past:"%s \u092a\u0939\u0932\u0947",s:"\u0915\u0941\u091b \u0939\u0940 \u0915\u094d\u0937\u0923",ss:"%d \u0938\u0947\u0915\u0902\u0921",m:"\u090f\u0915 \u092e\u093f\u0928\u091f",mm:"%d \u092e\u093f\u0928\u091f",h:"\u090f\u0915 \u0918\u0902\u091f\u093e",hh:"%d \u0918\u0902\u091f\u0947",d:"\u090f\u0915 \u0926\u093f\u0928",dd:"%d \u0926\u093f\u0928",M:"\u090f\u0915 \u092e\u0939\u0940\u0928\u0947",MM:"%d \u092e\u0939\u0940\u0928\u0947",y:"\u090f\u0915 \u0935\u0930\u094d\u0937",yy:"%d \u0935\u0930\u094d\u0937"},preparse:function(n){return n.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u0930\u093e\u0924|\u0938\u0941\u092c\u0939|\u0926\u094b\u092a\u0939\u0930|\u0936\u093e\u092e/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0930\u093e\u0924"===t?n<4?n:n+12:"\u0938\u0941\u092c\u0939"===t?n:"\u0926\u094b\u092a\u0939\u0930"===t?n>=10?n:n+12:"\u0936\u093e\u092e"===t?n+12:void 0},meridiem:function(n,t,e){return n<4?"\u0930\u093e\u0924":n<10?"\u0938\u0941\u092c\u0939":n<17?"\u0926\u094b\u092a\u0939\u0930":n<20?"\u0936\u093e\u092e":"\u0930\u093e\u0924"},week:{dow:0,doy:6}})}(e("PJh5"))},EuP9:function(n,t,e){"use strict";(function(n){var l=e("EKta"),r=e("ujcs"),i=e("sOR5");function o(){return a.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(n,t){if(o()=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|n}function f(n,t){if(a.isBuffer(n))return n.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(n)||n instanceof ArrayBuffer))return n.byteLength;"string"!=typeof n&&(n=""+n);var e=n.length;if(0===e)return 0;for(var l=!1;;)switch(t){case"ascii":case"latin1":case"binary":return e;case"utf8":case"utf-8":case void 0:return N(n).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*e;case"hex":return e>>>1;case"base64":return F(n).length;default:if(l)return N(n).length;t=(""+t).toLowerCase(),l=!0}}function _(n,t,e){var l=n[t];n[t]=n[e],n[e]=l}function m(n,t,e,l,r){if(0===n.length)return-1;if("string"==typeof e?(l=e,e=0):e>2147483647?e=2147483647:e<-2147483648&&(e=-2147483648),e=+e,isNaN(e)&&(e=r?0:n.length-1),e<0&&(e=n.length+e),e>=n.length){if(r)return-1;e=n.length-1}else if(e<0){if(!r)return-1;e=0}if("string"==typeof t&&(t=a.from(t,l)),a.isBuffer(t))return 0===t.length?-1:g(n,t,e,l,r);if("number"==typeof t)return t&=255,a.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?r?Uint8Array.prototype.indexOf.call(n,t,e):Uint8Array.prototype.lastIndexOf.call(n,t,e):g(n,[t],e,l,r);throw new TypeError("val must be string, number or Buffer")}function g(n,t,e,l,r){var i,o=1,s=n.length,a=t.length;if(void 0!==l&&("ucs2"===(l=String(l).toLowerCase())||"ucs-2"===l||"utf16le"===l||"utf-16le"===l)){if(n.length<2||t.length<2)return-1;o=2,s/=2,a/=2,e/=2}function u(n,t){return 1===o?n[t]:n.readUInt16BE(t*o)}if(r){var c=-1;for(i=e;is&&(e=s-a),i=e;i>=0;i--){for(var d=!0,h=0;hr&&(l=r):l=r;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");l>i/2&&(l=i/2);for(var o=0;o>8,r.push(e%256),r.push(l);return r}(t,n.length-e),n,e,l)}function k(n,t,e){return l.fromByteArray(0===t&&e===n.length?n:n.slice(t,e))}function C(n,t,e){e=Math.min(n.length,e);for(var l=[],r=t;r239?4:u>223?3:u>191?2:1;if(r+d<=e)switch(d){case 1:u<128&&(c=u);break;case 2:128==(192&(i=n[r+1]))&&(a=(31&u)<<6|63&i)>127&&(c=a);break;case 3:o=n[r+2],128==(192&(i=n[r+1]))&&128==(192&o)&&(a=(15&u)<<12|(63&i)<<6|63&o)>2047&&(a<55296||a>57343)&&(c=a);break;case 4:o=n[r+2],s=n[r+3],128==(192&(i=n[r+1]))&&128==(192&o)&&128==(192&s)&&(a=(15&u)<<18|(63&i)<<12|(63&o)<<6|63&s)>65535&&a<1114112&&(c=a)}null===c?(c=65533,d=1):c>65535&&(l.push((c-=65536)>>>10&1023|55296),c=56320|1023&c),l.push(c),r+=d}return function(n){var t=n.length;if(t<=S)return String.fromCharCode.apply(String,n);for(var e="",l=0;lthis.length)return"";if((void 0===e||e>this.length)&&(e=this.length),e<=0)return"";if((e>>>=0)<=(t>>>=0))return"";for(n||(n="utf8");;)switch(n){case"hex":return L(this,t,e);case"utf8":case"utf-8":return C(this,t,e);case"ascii":return O(this,t,e);case"latin1":case"binary":return T(this,t,e);case"base64":return k(this,t,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return P(this,t,e);default:if(l)throw new TypeError("Unknown encoding: "+n);n=(n+"").toLowerCase(),l=!0}}).apply(this,arguments)},a.prototype.equals=function(n){if(!a.isBuffer(n))throw new TypeError("Argument must be a Buffer");return this===n||0===a.compare(this,n)},a.prototype.inspect=function(){var n="",e=t.INSPECT_MAX_BYTES;return this.length>0&&(n=this.toString("hex",0,e).match(/.{2}/g).join(" "),this.length>e&&(n+=" ... ")),""},a.prototype.compare=function(n,t,e,l,r){if(!a.isBuffer(n))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===e&&(e=n?n.length:0),void 0===l&&(l=0),void 0===r&&(r=this.length),t<0||e>n.length||l<0||r>this.length)throw new RangeError("out of range index");if(l>=r&&t>=e)return 0;if(l>=r)return-1;if(t>=e)return 1;if(t>>>=0,e>>>=0,l>>>=0,r>>>=0,this===n)return 0;for(var i=r-l,o=e-t,s=Math.min(i,o),u=this.slice(l,r),c=n.slice(t,e),d=0;dr)&&(e=r),n.length>0&&(e<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");l||(l="utf8");for(var i=!1;;)switch(l){case"hex":return y(this,n,t,e);case"utf8":case"utf-8":return b(this,n,t,e);case"ascii":return v(this,n,t,e);case"latin1":case"binary":return w(this,n,t,e);case"base64":return x(this,n,t,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return M(this,n,t,e);default:if(i)throw new TypeError("Unknown encoding: "+l);l=(""+l).toLowerCase(),i=!0}},a.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var S=4096;function O(n,t,e){var l="";e=Math.min(n.length,e);for(var r=t;rr)&&(e=r);for(var i="",o=t;oe)throw new RangeError("Trying to access beyond buffer length")}function A(n,t,e,l,r,i){if(!a.isBuffer(n))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>r||tn.length)throw new RangeError("Index out of range")}function E(n,t,e,l){t<0&&(t=65535+t+1);for(var r=0,i=Math.min(n.length-e,2);r>>8*(l?r:1-r)}function Y(n,t,e,l){t<0&&(t=4294967295+t+1);for(var r=0,i=Math.min(n.length-e,4);r>>8*(l?r:3-r)&255}function j(n,t,e,l,r,i){if(e+l>n.length)throw new RangeError("Index out of range");if(e<0)throw new RangeError("Index out of range")}function I(n,t,e,l,i){return i||j(n,0,e,4),r.write(n,t,e,l,23,4),e+4}function R(n,t,e,l,i){return i||j(n,0,e,8),r.write(n,t,e,l,52,8),e+8}a.prototype.slice=function(n,t){var e,l=this.length;if(n=~~n,t=void 0===t?l:~~t,n<0?(n+=l)<0&&(n=0):n>l&&(n=l),t<0?(t+=l)<0&&(t=0):t>l&&(t=l),t0&&(r*=256);)l+=this[n+--t]*r;return l},a.prototype.readUInt8=function(n,t){return t||D(n,1,this.length),this[n]},a.prototype.readUInt16LE=function(n,t){return t||D(n,2,this.length),this[n]|this[n+1]<<8},a.prototype.readUInt16BE=function(n,t){return t||D(n,2,this.length),this[n]<<8|this[n+1]},a.prototype.readUInt32LE=function(n,t){return t||D(n,4,this.length),(this[n]|this[n+1]<<8|this[n+2]<<16)+16777216*this[n+3]},a.prototype.readUInt32BE=function(n,t){return t||D(n,4,this.length),16777216*this[n]+(this[n+1]<<16|this[n+2]<<8|this[n+3])},a.prototype.readIntLE=function(n,t,e){n|=0,t|=0,e||D(n,t,this.length);for(var l=this[n],r=1,i=0;++i=(r*=128)&&(l-=Math.pow(2,8*t)),l},a.prototype.readIntBE=function(n,t,e){n|=0,t|=0,e||D(n,t,this.length);for(var l=t,r=1,i=this[n+--l];l>0&&(r*=256);)i+=this[n+--l]*r;return i>=(r*=128)&&(i-=Math.pow(2,8*t)),i},a.prototype.readInt8=function(n,t){return t||D(n,1,this.length),128&this[n]?-1*(255-this[n]+1):this[n]},a.prototype.readInt16LE=function(n,t){t||D(n,2,this.length);var e=this[n]|this[n+1]<<8;return 32768&e?4294901760|e:e},a.prototype.readInt16BE=function(n,t){t||D(n,2,this.length);var e=this[n+1]|this[n]<<8;return 32768&e?4294901760|e:e},a.prototype.readInt32LE=function(n,t){return t||D(n,4,this.length),this[n]|this[n+1]<<8|this[n+2]<<16|this[n+3]<<24},a.prototype.readInt32BE=function(n,t){return t||D(n,4,this.length),this[n]<<24|this[n+1]<<16|this[n+2]<<8|this[n+3]},a.prototype.readFloatLE=function(n,t){return t||D(n,4,this.length),r.read(this,n,!0,23,4)},a.prototype.readFloatBE=function(n,t){return t||D(n,4,this.length),r.read(this,n,!1,23,4)},a.prototype.readDoubleLE=function(n,t){return t||D(n,8,this.length),r.read(this,n,!0,52,8)},a.prototype.readDoubleBE=function(n,t){return t||D(n,8,this.length),r.read(this,n,!1,52,8)},a.prototype.writeUIntLE=function(n,t,e,l){n=+n,t|=0,e|=0,l||A(this,n,t,e,Math.pow(2,8*e)-1,0);var r=1,i=0;for(this[t]=255&n;++i=0&&(i*=256);)this[t+r]=n/i&255;return t+e},a.prototype.writeUInt8=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,1,255,0),a.TYPED_ARRAY_SUPPORT||(n=Math.floor(n)),this[t]=255&n,t+1},a.prototype.writeUInt16LE=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,2,65535,0),a.TYPED_ARRAY_SUPPORT?(this[t]=255&n,this[t+1]=n>>>8):E(this,n,t,!0),t+2},a.prototype.writeUInt16BE=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,2,65535,0),a.TYPED_ARRAY_SUPPORT?(this[t]=n>>>8,this[t+1]=255&n):E(this,n,t,!1),t+2},a.prototype.writeUInt32LE=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,4,4294967295,0),a.TYPED_ARRAY_SUPPORT?(this[t+3]=n>>>24,this[t+2]=n>>>16,this[t+1]=n>>>8,this[t]=255&n):Y(this,n,t,!0),t+4},a.prototype.writeUInt32BE=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,4,4294967295,0),a.TYPED_ARRAY_SUPPORT?(this[t]=n>>>24,this[t+1]=n>>>16,this[t+2]=n>>>8,this[t+3]=255&n):Y(this,n,t,!1),t+4},a.prototype.writeIntLE=function(n,t,e,l){if(n=+n,t|=0,!l){var r=Math.pow(2,8*e-1);A(this,n,t,e,r-1,-r)}var i=0,o=1,s=0;for(this[t]=255&n;++i>0)-s&255;return t+e},a.prototype.writeIntBE=function(n,t,e,l){if(n=+n,t|=0,!l){var r=Math.pow(2,8*e-1);A(this,n,t,e,r-1,-r)}var i=e-1,o=1,s=0;for(this[t+i]=255&n;--i>=0&&(o*=256);)n<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(n/o>>0)-s&255;return t+e},a.prototype.writeInt8=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,1,127,-128),a.TYPED_ARRAY_SUPPORT||(n=Math.floor(n)),n<0&&(n=255+n+1),this[t]=255&n,t+1},a.prototype.writeInt16LE=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,2,32767,-32768),a.TYPED_ARRAY_SUPPORT?(this[t]=255&n,this[t+1]=n>>>8):E(this,n,t,!0),t+2},a.prototype.writeInt16BE=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,2,32767,-32768),a.TYPED_ARRAY_SUPPORT?(this[t]=n>>>8,this[t+1]=255&n):E(this,n,t,!1),t+2},a.prototype.writeInt32LE=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,4,2147483647,-2147483648),a.TYPED_ARRAY_SUPPORT?(this[t]=255&n,this[t+1]=n>>>8,this[t+2]=n>>>16,this[t+3]=n>>>24):Y(this,n,t,!0),t+4},a.prototype.writeInt32BE=function(n,t,e){return n=+n,t|=0,e||A(this,n,t,4,2147483647,-2147483648),n<0&&(n=4294967295+n+1),a.TYPED_ARRAY_SUPPORT?(this[t]=n>>>24,this[t+1]=n>>>16,this[t+2]=n>>>8,this[t+3]=255&n):Y(this,n,t,!1),t+4},a.prototype.writeFloatLE=function(n,t,e){return I(this,n,t,!0,e)},a.prototype.writeFloatBE=function(n,t,e){return I(this,n,t,!1,e)},a.prototype.writeDoubleLE=function(n,t,e){return R(this,n,t,!0,e)},a.prototype.writeDoubleBE=function(n,t,e){return R(this,n,t,!1,e)},a.prototype.copy=function(n,t,e,l){if(e||(e=0),l||0===l||(l=this.length),t>=n.length&&(t=n.length),t||(t=0),l>0&&l=this.length)throw new RangeError("sourceStart out of bounds");if(l<0)throw new RangeError("sourceEnd out of bounds");l>this.length&&(l=this.length),n.length-t=0;--r)n[r+t]=this[r+e];else if(i<1e3||!a.TYPED_ARRAY_SUPPORT)for(r=0;r>>=0,e=void 0===e?this.length:e>>>0,n||(n=0),"number"==typeof n)for(i=t;i55295&&e<57344){if(!r){if(e>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(o+1===l){(t-=3)>-1&&i.push(239,191,189);continue}r=e;continue}if(e<56320){(t-=3)>-1&&i.push(239,191,189),r=e;continue}e=65536+(r-55296<<10|e-56320)}else r&&(t-=3)>-1&&i.push(239,191,189);if(r=null,e<128){if((t-=1)<0)break;i.push(e)}else if(e<2048){if((t-=2)<0)break;i.push(e>>6|192,63&e|128)}else if(e<65536){if((t-=3)<0)break;i.push(e>>12|224,e>>6&63|128,63&e|128)}else{if(!(e<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}}return i}function F(n){return l.toByteArray(function(n){if((n=function(n){return n.trim?n.trim():n.replace(/^\s+|\s+$/g,"")}(n).replace(H,"")).length<2)return"";for(;n.length%4!=0;)n+="=";return n}(n))}function B(n,t,e,l){for(var r=0;r=t.length||r>=n.length);++r)t[r+e]=n[r];return r}}).call(t,e("DuR2"))},"F+2e":function(n,t,e){!function(n){"use strict";var t={1:"\u1041",2:"\u1042",3:"\u1043",4:"\u1044",5:"\u1045",6:"\u1046",7:"\u1047",8:"\u1048",9:"\u1049",0:"\u1040"},e={"\u1041":"1","\u1042":"2","\u1043":"3","\u1044":"4","\u1045":"5","\u1046":"6","\u1047":"7","\u1048":"8","\u1049":"9","\u1040":"0"};n.defineLocale("my",{months:"\u1007\u1014\u103a\u1014\u101d\u102b\u101b\u102e_\u1016\u1031\u1016\u1031\u102c\u103a\u101d\u102b\u101b\u102e_\u1019\u1010\u103a_\u1027\u1015\u103c\u102e_\u1019\u1031_\u1007\u103d\u1014\u103a_\u1007\u1030\u101c\u102d\u102f\u1004\u103a_\u101e\u103c\u1002\u102f\u1010\u103a_\u1005\u1000\u103a\u1010\u1004\u103a\u1018\u102c_\u1021\u1031\u102c\u1000\u103a\u1010\u102d\u102f\u1018\u102c_\u1014\u102d\u102f\u101d\u1004\u103a\u1018\u102c_\u1012\u102e\u1007\u1004\u103a\u1018\u102c".split("_"),monthsShort:"\u1007\u1014\u103a_\u1016\u1031_\u1019\u1010\u103a_\u1015\u103c\u102e_\u1019\u1031_\u1007\u103d\u1014\u103a_\u101c\u102d\u102f\u1004\u103a_\u101e\u103c_\u1005\u1000\u103a_\u1021\u1031\u102c\u1000\u103a_\u1014\u102d\u102f_\u1012\u102e".split("_"),weekdays:"\u1010\u1014\u1004\u103a\u1039\u1002\u1014\u103d\u1031_\u1010\u1014\u1004\u103a\u1039\u101c\u102c_\u1021\u1004\u103a\u1039\u1002\u102b_\u1017\u102f\u1012\u1039\u1013\u101f\u1030\u1038_\u1000\u103c\u102c\u101e\u1015\u1010\u1031\u1038_\u101e\u1031\u102c\u1000\u103c\u102c_\u1005\u1014\u1031".split("_"),weekdaysShort:"\u1014\u103d\u1031_\u101c\u102c_\u1002\u102b_\u101f\u1030\u1038_\u1000\u103c\u102c_\u101e\u1031\u102c_\u1014\u1031".split("_"),weekdaysMin:"\u1014\u103d\u1031_\u101c\u102c_\u1002\u102b_\u101f\u1030\u1038_\u1000\u103c\u102c_\u101e\u1031\u102c_\u1014\u1031".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u101a\u1014\u1031.] LT [\u1019\u103e\u102c]",nextDay:"[\u1019\u1014\u1000\u103a\u1016\u103c\u1014\u103a] LT [\u1019\u103e\u102c]",nextWeek:"dddd LT [\u1019\u103e\u102c]",lastDay:"[\u1019\u1014\u1031.\u1000] LT [\u1019\u103e\u102c]",lastWeek:"[\u1015\u103c\u102e\u1038\u1001\u1032\u1037\u101e\u1031\u102c] dddd LT [\u1019\u103e\u102c]",sameElse:"L"},relativeTime:{future:"\u101c\u102c\u1019\u100a\u103a\u1037 %s \u1019\u103e\u102c",past:"\u101c\u103d\u1014\u103a\u1001\u1032\u1037\u101e\u1031\u102c %s \u1000",s:"\u1005\u1000\u1039\u1000\u1014\u103a.\u1021\u1014\u100a\u103a\u1038\u1004\u101a\u103a",ss:"%d \u1005\u1000\u1039\u1000\u1014\u1037\u103a",m:"\u1010\u1005\u103a\u1019\u102d\u1014\u1005\u103a",mm:"%d \u1019\u102d\u1014\u1005\u103a",h:"\u1010\u1005\u103a\u1014\u102c\u101b\u102e",hh:"%d \u1014\u102c\u101b\u102e",d:"\u1010\u1005\u103a\u101b\u1000\u103a",dd:"%d \u101b\u1000\u103a",M:"\u1010\u1005\u103a\u101c",MM:"%d \u101c",y:"\u1010\u1005\u103a\u1014\u103e\u1005\u103a",yy:"%d \u1014\u103e\u1005\u103a"},preparse:function(n){return n.replace(/[\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1040]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},week:{dow:1,doy:4}})}(e("PJh5"))},FKXc:function(n,t,e){!function(n){"use strict";n.defineLocale("it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_luned\xec_marted\xec_mercoled\xec_gioved\xec_venerd\xec_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(n){return(/^[0-9].+$/.test(n)?"tra":"in")+" "+n},past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(e("PJh5"))},FRPF:function(n,t,e){!function(n){"use strict";n.defineLocale("tzm",{months:"\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54_\u2d31\u2d55\u2d30\u2d62\u2d55_\u2d4e\u2d30\u2d55\u2d5a_\u2d49\u2d31\u2d54\u2d49\u2d54_\u2d4e\u2d30\u2d62\u2d62\u2d53_\u2d62\u2d53\u2d4f\u2d62\u2d53_\u2d62\u2d53\u2d4d\u2d62\u2d53\u2d63_\u2d56\u2d53\u2d5b\u2d5c_\u2d5b\u2d53\u2d5c\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d3d\u2d5f\u2d53\u2d31\u2d55_\u2d4f\u2d53\u2d61\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d37\u2d53\u2d4a\u2d4f\u2d31\u2d49\u2d54".split("_"),monthsShort:"\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54_\u2d31\u2d55\u2d30\u2d62\u2d55_\u2d4e\u2d30\u2d55\u2d5a_\u2d49\u2d31\u2d54\u2d49\u2d54_\u2d4e\u2d30\u2d62\u2d62\u2d53_\u2d62\u2d53\u2d4f\u2d62\u2d53_\u2d62\u2d53\u2d4d\u2d62\u2d53\u2d63_\u2d56\u2d53\u2d5b\u2d5c_\u2d5b\u2d53\u2d5c\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d3d\u2d5f\u2d53\u2d31\u2d55_\u2d4f\u2d53\u2d61\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d37\u2d53\u2d4a\u2d4f\u2d31\u2d49\u2d54".split("_"),weekdays:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),weekdaysShort:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),weekdaysMin:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u2d30\u2d59\u2d37\u2d45 \u2d34] LT",nextDay:"[\u2d30\u2d59\u2d3d\u2d30 \u2d34] LT",nextWeek:"dddd [\u2d34] LT",lastDay:"[\u2d30\u2d5a\u2d30\u2d4f\u2d5c \u2d34] LT",lastWeek:"dddd [\u2d34] LT",sameElse:"L"},relativeTime:{future:"\u2d37\u2d30\u2d37\u2d45 \u2d59 \u2d62\u2d30\u2d4f %s",past:"\u2d62\u2d30\u2d4f %s",s:"\u2d49\u2d4e\u2d49\u2d3d",ss:"%d \u2d49\u2d4e\u2d49\u2d3d",m:"\u2d4e\u2d49\u2d4f\u2d53\u2d3a",mm:"%d \u2d4e\u2d49\u2d4f\u2d53\u2d3a",h:"\u2d59\u2d30\u2d44\u2d30",hh:"%d \u2d5c\u2d30\u2d59\u2d59\u2d30\u2d44\u2d49\u2d4f",d:"\u2d30\u2d59\u2d59",dd:"%d o\u2d59\u2d59\u2d30\u2d4f",M:"\u2d30\u2d62o\u2d53\u2d54",MM:"%d \u2d49\u2d62\u2d62\u2d49\u2d54\u2d4f",y:"\u2d30\u2d59\u2d33\u2d30\u2d59",yy:"%d \u2d49\u2d59\u2d33\u2d30\u2d59\u2d4f"},week:{dow:6,doy:12}})}(e("PJh5"))},FlzV:function(n,t,e){!function(n){"use strict";n.defineLocale("nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"s\xf8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\xf8rdag".split("_"),weekdaysShort:"s\xf8._ma._ti._on._to._fr._l\xf8.".split("_"),weekdaysMin:"s\xf8_ma_ti_on_to_fr_l\xf8".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i g\xe5r kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",ss:"%d sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en m\xe5ned",MM:"%d m\xe5neder",y:"ett \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},Fpqq:function(n,t,e){!function(n){"use strict";n.defineLocale("sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"s\xf6ndag_m\xe5ndag_tisdag_onsdag_torsdag_fredag_l\xf6rdag".split("_"),weekdaysShort:"s\xf6n_m\xe5n_tis_ons_tor_fre_l\xf6r".split("_"),weekdaysMin:"s\xf6_m\xe5_ti_on_to_fr_l\xf6".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Ig\xe5r] LT",nextWeek:"[P\xe5] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"f\xf6r %s sedan",s:"n\xe5gra sekunder",ss:"%d sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en m\xe5nad",MM:"%d m\xe5nader",y:"ett \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}(e|a)/,ordinal:function(n){var t=n%10;return n+(1==~~(n%100/10)?"e":1===t?"a":2===t?"a":"e")},week:{dow:1,doy:4}})}(e("PJh5"))},Frex:function(n,t,e){!function(n){"use strict";function t(n,t,e,l){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[n+" Tage",n+" Tagen"],M:["ein Monat","einem Monat"],MM:[n+" Monate",n+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[n+" Jahre",n+" Jahren"]};return t?r[e][0]:r[e][1]}n.defineLocale("de-ch",{months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:t,mm:"%d Minuten",h:t,hh:"%d Stunden",d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},FuaP:function(n,t,e){!function(n){"use strict";n.defineLocale("gl",{months:"xaneiro_febreiro_marzo_abril_maio_xu\xf1o_xullo_agosto_setembro_outubro_novembro_decembro".split("_"),monthsShort:"xan._feb._mar._abr._mai._xu\xf1._xul._ago._set._out._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"domingo_luns_martes_m\xe9rcores_xoves_venres_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._m\xe9r._xov._ven._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_m\xe9_xo_ve_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"\xe1s":"\xe1")+"] LT"},nextDay:function(){return"[ma\xf1\xe1 "+(1!==this.hours()?"\xe1s":"\xe1")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"\xe1s":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"\xe1":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"\xe1s":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(n){return 0===n.indexOf("un")?"n"+n:"en "+n},past:"hai %s",s:"uns segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(e("PJh5"))},"G++c":function(n,t,e){!function(n){"use strict";n.defineLocale("ms-my",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(n,t){return 12===n&&(n=0),"pagi"===t?n:"tengahari"===t?n>=11?n:n+12:"petang"===t||"malam"===t?n+12:void 0},meridiem:function(n,t,e){return n<11?"pagi":n<15?"tengahari":n<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}(e("PJh5"))},GK6M:function(n,t,e){"use strict";t.a=function(n){return l=n,i};var l,r=e("fKB6");function i(){try{return l.apply(this,arguments)}catch(n){return r.a.e=n,r.a}}},GrS7:function(n,t,e){!function(n){"use strict";n.defineLocale("hy-am",{months:{format:"\u0570\u0578\u0582\u0576\u057e\u0561\u0580\u056b_\u0583\u0565\u057f\u0580\u057e\u0561\u0580\u056b_\u0574\u0561\u0580\u057f\u056b_\u0561\u057a\u0580\u056b\u056c\u056b_\u0574\u0561\u0575\u056b\u057d\u056b_\u0570\u0578\u0582\u0576\u056b\u057d\u056b_\u0570\u0578\u0582\u056c\u056b\u057d\u056b_\u0585\u0563\u0578\u057d\u057f\u0578\u057d\u056b_\u057d\u0565\u057a\u057f\u0565\u0574\u0562\u0565\u0580\u056b_\u0570\u0578\u056f\u057f\u0565\u0574\u0562\u0565\u0580\u056b_\u0576\u0578\u0575\u0565\u0574\u0562\u0565\u0580\u056b_\u0564\u0565\u056f\u057f\u0565\u0574\u0562\u0565\u0580\u056b".split("_"),standalone:"\u0570\u0578\u0582\u0576\u057e\u0561\u0580_\u0583\u0565\u057f\u0580\u057e\u0561\u0580_\u0574\u0561\u0580\u057f_\u0561\u057a\u0580\u056b\u056c_\u0574\u0561\u0575\u056b\u057d_\u0570\u0578\u0582\u0576\u056b\u057d_\u0570\u0578\u0582\u056c\u056b\u057d_\u0585\u0563\u0578\u057d\u057f\u0578\u057d_\u057d\u0565\u057a\u057f\u0565\u0574\u0562\u0565\u0580_\u0570\u0578\u056f\u057f\u0565\u0574\u0562\u0565\u0580_\u0576\u0578\u0575\u0565\u0574\u0562\u0565\u0580_\u0564\u0565\u056f\u057f\u0565\u0574\u0562\u0565\u0580".split("_")},monthsShort:"\u0570\u0576\u057e_\u0583\u057f\u0580_\u0574\u0580\u057f_\u0561\u057a\u0580_\u0574\u0575\u057d_\u0570\u0576\u057d_\u0570\u056c\u057d_\u0585\u0563\u057d_\u057d\u057a\u057f_\u0570\u056f\u057f_\u0576\u0574\u0562_\u0564\u056f\u057f".split("_"),weekdays:"\u056f\u056b\u0580\u0561\u056f\u056b_\u0565\u0580\u056f\u0578\u0582\u0577\u0561\u0562\u0569\u056b_\u0565\u0580\u0565\u0584\u0577\u0561\u0562\u0569\u056b_\u0579\u0578\u0580\u0565\u0584\u0577\u0561\u0562\u0569\u056b_\u0570\u056b\u0576\u0563\u0577\u0561\u0562\u0569\u056b_\u0578\u0582\u0580\u0562\u0561\u0569_\u0577\u0561\u0562\u0561\u0569".split("_"),weekdaysShort:"\u056f\u0580\u056f_\u0565\u0580\u056f_\u0565\u0580\u0584_\u0579\u0580\u0584_\u0570\u0576\u0563_\u0578\u0582\u0580\u0562_\u0577\u0562\u0569".split("_"),weekdaysMin:"\u056f\u0580\u056f_\u0565\u0580\u056f_\u0565\u0580\u0584_\u0579\u0580\u0584_\u0570\u0576\u0563_\u0578\u0582\u0580\u0562_\u0577\u0562\u0569".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0569.",LLL:"D MMMM YYYY \u0569., HH:mm",LLLL:"dddd, D MMMM YYYY \u0569., HH:mm"},calendar:{sameDay:"[\u0561\u0575\u057d\u0585\u0580] LT",nextDay:"[\u057e\u0561\u0572\u0568] LT",lastDay:"[\u0565\u0580\u0565\u056f] LT",nextWeek:function(){return"dddd [\u0585\u0580\u0568 \u056a\u0561\u0574\u0568] LT"},lastWeek:function(){return"[\u0561\u0576\u0581\u0561\u056e] dddd [\u0585\u0580\u0568 \u056a\u0561\u0574\u0568] LT"},sameElse:"L"},relativeTime:{future:"%s \u0570\u0565\u057f\u0578",past:"%s \u0561\u057c\u0561\u057b",s:"\u0574\u056b \u0584\u0561\u0576\u056b \u057e\u0561\u0575\u0580\u056f\u0575\u0561\u0576",ss:"%d \u057e\u0561\u0575\u0580\u056f\u0575\u0561\u0576",m:"\u0580\u0578\u057a\u0565",mm:"%d \u0580\u0578\u057a\u0565",h:"\u056a\u0561\u0574",hh:"%d \u056a\u0561\u0574",d:"\u0585\u0580",dd:"%d \u0585\u0580",M:"\u0561\u0574\u056b\u057d",MM:"%d \u0561\u0574\u056b\u057d",y:"\u057f\u0561\u0580\u056b",yy:"%d \u057f\u0561\u0580\u056b"},meridiemParse:/\u0563\u056b\u0577\u0565\u0580\u057e\u0561|\u0561\u057c\u0561\u057e\u0578\u057f\u057e\u0561|\u0581\u0565\u0580\u0565\u056f\u057e\u0561|\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576/,isPM:function(n){return/^(\u0581\u0565\u0580\u0565\u056f\u057e\u0561|\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576)$/.test(n)},meridiem:function(n){return n<4?"\u0563\u056b\u0577\u0565\u0580\u057e\u0561":n<12?"\u0561\u057c\u0561\u057e\u0578\u057f\u057e\u0561":n<17?"\u0581\u0565\u0580\u0565\u056f\u057e\u0561":"\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576"},dayOfMonthOrdinalParse:/\d{1,2}|\d{1,2}-(\u056b\u0576|\u0580\u0564)/,ordinal:function(n,t){switch(t){case"DDD":case"w":case"W":case"DDDo":return 1===n?n+"-\u056b\u0576":n+"-\u0580\u0564";default:return n}},week:{dow:1,doy:7}})}(e("PJh5"))},HdCx:function(n,t,e){"use strict";t.a=function(n,t){return function(e){if("function"!=typeof n)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return e.lift(new i(n,t))}};var l=e("TToO"),r=e("OVmG"),i=function(){function n(n,t){this.project=n,this.thisArg=t}return n.prototype.call=function(n,t){return t.subscribe(new o(n,this.project,this.thisArg))},n}(),o=function(n){function t(t,e,l){n.call(this,t),this.project=e,this.count=0,this.thisArg=l||this}return Object(l.__extends)(t,n),t.prototype._next=function(n){var t;try{t=this.project.call(this.thisArg,n,this.count++)}catch(n){return void this.destination.error(n)}this.destination.next(t)},t}(r.a)},INcR:function(n,t,e){!function(n){"use strict";var t="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),e="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_");n.defineLocale("es-us",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(n,l){return n?/-MMM-/.test(l)?e[n.month()]:t[n.month()]:t},monthsParseExact:!0,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"MM/DD/YYYY",LL:"MMMM [de] D [de] YYYY",LLL:"MMMM [de] D [de] YYYY h:mm A",LLLL:"dddd, MMMM [de] D [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:0,doy:6}})}(e("PJh5"))},Jnfr:function(n,t){function e(n){return Promise.resolve().then(function(){throw new Error("Cannot find module '"+n+"'.")})}e.keys=function(){return[]},e.resolve=e,n.exports=e,e.id="Jnfr"},JwiF:function(n,t,e){!function(n){"use strict";n.defineLocale("jv",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des".split("_"),weekdays:"Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu".split("_"),weekdaysShort:"Min_Sen_Sel_Reb_Kem_Jem_Sep".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sp".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/enjing|siyang|sonten|ndalu/,meridiemHour:function(n,t){return 12===n&&(n=0),"enjing"===t?n:"siyang"===t?n>=11?n:n+12:"sonten"===t||"ndalu"===t?n+12:void 0},meridiem:function(n,t,e){return n<11?"enjing":n<15?"siyang":n<19?"sonten":"ndalu"},calendar:{sameDay:"[Dinten puniko pukul] LT",nextDay:"[Mbenjang pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kala wingi pukul] LT",lastWeek:"dddd [kepengker pukul] LT",sameElse:"L"},relativeTime:{future:"wonten ing %s",past:"%s ingkang kepengker",s:"sawetawis detik",ss:"%d detik",m:"setunggal menit",mm:"%d menit",h:"setunggal jam",hh:"%d jam",d:"sedinten",dd:"%d dinten",M:"sewulan",MM:"%d wulan",y:"setaun",yy:"%d taun"},week:{dow:1,doy:7}})}(e("PJh5"))},Jwyl:function(n,t,e){"use strict";var l=e("TToO"),r=e("g5jc"),i=e("YaPU"),o=(e("OVmG"),e("VwZZ")),s=e("0P3J"),a=function(n){function t(t,e){n.call(this),this.source=t,this.subjectFactory=e,this._refCount=0,this._isComplete=!1}return Object(l.__extends)(t,n),t.prototype._subscribe=function(n){return this.getSubject().subscribe(n)},t.prototype.getSubject=function(){var n=this._subject;return n&&!n.isStopped||(this._subject=this.subjectFactory()),this._subject},t.prototype.connect=function(){var n=this._connection;return n||(this._isComplete=!1,(n=this._connection=new o.a).add(this.source.subscribe(new c(this.getSubject(),this))),n.closed?(this._connection=null,n=o.a.EMPTY):this._connection=n),n},t.prototype.refCount=function(){return Object(s.a)()(this)},t}(i.a).prototype,u={operator:{value:null},_refCount:{value:0,writable:!0},_subject:{value:null,writable:!0},_connection:{value:null,writable:!0},_subscribe:{value:a._subscribe},_isComplete:{value:a._isComplete,writable:!0},getSubject:{value:a.getSubject},connect:{value:a.connect},refCount:{value:a.refCount}},c=function(n){function t(t,e){n.call(this,t),this.connectable=e}return Object(l.__extends)(t,n),t.prototype._error=function(t){this._unsubscribe(),n.prototype._error.call(this,t)},t.prototype._complete=function(){this.connectable._isComplete=!0,this._unsubscribe(),n.prototype._complete.call(this)},t.prototype._unsubscribe=function(){var n=this.connectable;if(n){this.connectable=null;var t=n._connection;n._refCount=0,n._subject=null,n._connection=null,t&&t.unsubscribe()}},t}(r.b);t.a=function(n,t){return function(e){var l;if(l="function"==typeof n?n:function(){return n},"function"==typeof t)return e.lift(new d(l,t));var r=Object.create(e,u);return r.source=e,r.subjectFactory=l,r}};var d=function(){function n(n,t){this.subjectFactory=n,this.selector=t}return n.prototype.call=function(n,t){var e=this.selector,l=this.subjectFactory(),r=e(l).subscribe(n);return r.add(t.subscribe(l)),r},n}()},LT9G:function(n,t,e){!function(n){"use strict";var t="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),e="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),l=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],r=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;n.defineLocale("es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(n,l){return n?/-MMM-/.test(l)?e[n.month()]:t[n.month()]:t},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:l,longMonthsParse:l,shortMonthsParse:l,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(e("PJh5"))},Lgqo:function(n,t,e){!function(n){"use strict";n.defineLocale("si",{months:"\u0da2\u0db1\u0dc0\u0dcf\u0dbb\u0dd2_\u0db4\u0dd9\u0db6\u0dbb\u0dc0\u0dcf\u0dbb\u0dd2_\u0db8\u0dcf\u0dbb\u0dca\u0dad\u0dd4_\u0d85\u0db4\u0dca\u200d\u0dbb\u0dda\u0dbd\u0dca_\u0db8\u0dd0\u0dba\u0dd2_\u0da2\u0dd6\u0db1\u0dd2_\u0da2\u0dd6\u0dbd\u0dd2_\u0d85\u0d9c\u0ddd\u0dc3\u0dca\u0dad\u0dd4_\u0dc3\u0dd0\u0db4\u0dca\u0dad\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca_\u0d94\u0d9a\u0dca\u0dad\u0ddd\u0db6\u0dbb\u0dca_\u0db1\u0ddc\u0dc0\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca_\u0daf\u0dd9\u0dc3\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca".split("_"),monthsShort:"\u0da2\u0db1_\u0db4\u0dd9\u0db6_\u0db8\u0dcf\u0dbb\u0dca_\u0d85\u0db4\u0dca_\u0db8\u0dd0\u0dba\u0dd2_\u0da2\u0dd6\u0db1\u0dd2_\u0da2\u0dd6\u0dbd\u0dd2_\u0d85\u0d9c\u0ddd_\u0dc3\u0dd0\u0db4\u0dca_\u0d94\u0d9a\u0dca_\u0db1\u0ddc\u0dc0\u0dd0_\u0daf\u0dd9\u0dc3\u0dd0".split("_"),weekdays:"\u0d89\u0dbb\u0dd2\u0daf\u0dcf_\u0dc3\u0db3\u0dd4\u0daf\u0dcf_\u0d85\u0d9f\u0dc4\u0dbb\u0dd4\u0dc0\u0dcf\u0daf\u0dcf_\u0db6\u0daf\u0dcf\u0daf\u0dcf_\u0db6\u0dca\u200d\u0dbb\u0dc4\u0dc3\u0dca\u0db4\u0dad\u0dd2\u0db1\u0dca\u0daf\u0dcf_\u0dc3\u0dd2\u0d9a\u0dd4\u0dbb\u0dcf\u0daf\u0dcf_\u0dc3\u0dd9\u0db1\u0dc3\u0dd4\u0dbb\u0dcf\u0daf\u0dcf".split("_"),weekdaysShort:"\u0d89\u0dbb\u0dd2_\u0dc3\u0db3\u0dd4_\u0d85\u0d9f_\u0db6\u0daf\u0dcf_\u0db6\u0dca\u200d\u0dbb\u0dc4_\u0dc3\u0dd2\u0d9a\u0dd4_\u0dc3\u0dd9\u0db1".split("_"),weekdaysMin:"\u0d89_\u0dc3_\u0d85_\u0db6_\u0db6\u0dca\u200d\u0dbb_\u0dc3\u0dd2_\u0dc3\u0dd9".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"a h:mm",LTS:"a h:mm:ss",L:"YYYY/MM/DD",LL:"YYYY MMMM D",LLL:"YYYY MMMM D, a h:mm",LLLL:"YYYY MMMM D [\u0dc0\u0dd0\u0db1\u0dd2] dddd, a h:mm:ss"},calendar:{sameDay:"[\u0d85\u0daf] LT[\u0da7]",nextDay:"[\u0dc4\u0dd9\u0da7] LT[\u0da7]",nextWeek:"dddd LT[\u0da7]",lastDay:"[\u0d8a\u0dba\u0dda] LT[\u0da7]",lastWeek:"[\u0db4\u0dc3\u0dd4\u0d9c\u0dd2\u0dba] dddd LT[\u0da7]",sameElse:"L"},relativeTime:{future:"%s\u0d9a\u0dd2\u0db1\u0dca",past:"%s\u0d9a\u0da7 \u0db4\u0dd9\u0dbb",s:"\u0dad\u0dad\u0dca\u0db4\u0dbb \u0d9a\u0dd2\u0dc4\u0dd2\u0db4\u0dba",ss:"\u0dad\u0dad\u0dca\u0db4\u0dbb %d",m:"\u0db8\u0dd2\u0db1\u0dd2\u0dad\u0dca\u0dad\u0dd4\u0dc0",mm:"\u0db8\u0dd2\u0db1\u0dd2\u0dad\u0dca\u0dad\u0dd4 %d",h:"\u0db4\u0dd0\u0dba",hh:"\u0db4\u0dd0\u0dba %d",d:"\u0daf\u0dd2\u0db1\u0dba",dd:"\u0daf\u0dd2\u0db1 %d",M:"\u0db8\u0dcf\u0dc3\u0dba",MM:"\u0db8\u0dcf\u0dc3 %d",y:"\u0dc0\u0dc3\u0dbb",yy:"\u0dc0\u0dc3\u0dbb %d"},dayOfMonthOrdinalParse:/\d{1,2} \u0dc0\u0dd0\u0db1\u0dd2/,ordinal:function(n){return n+" \u0dc0\u0dd0\u0db1\u0dd2"},meridiemParse:/\u0db4\u0dd9\u0dbb \u0dc0\u0dbb\u0dd4|\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4|\u0db4\u0dd9.\u0dc0|\u0db4.\u0dc0./,isPM:function(n){return"\u0db4.\u0dc0."===n||"\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4"===n},meridiem:function(n,t,e){return n>11?e?"\u0db4.\u0dc0.":"\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4":e?"\u0db4\u0dd9.\u0dc0.":"\u0db4\u0dd9\u0dbb \u0dc0\u0dbb\u0dd4"}})}(e("PJh5"))},N3vo:function(n,t,e){!function(n){"use strict";n.defineLocale("cv",{months:"\u043a\u04d1\u0440\u043b\u0430\u0447_\u043d\u0430\u0440\u04d1\u0441_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u04ab\u04d7\u0440\u0442\u043c\u0435_\u0443\u0442\u04d1_\u04ab\u0443\u0440\u043b\u0430_\u0430\u0432\u04d1\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448\u0442\u0430\u0432".split("_"),monthsShort:"\u043a\u04d1\u0440_\u043d\u0430\u0440_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u04ab\u04d7\u0440_\u0443\u0442\u04d1_\u04ab\u0443\u0440_\u0430\u0432\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448".split("_"),weekdays:"\u0432\u044b\u0440\u0441\u0430\u0440\u043d\u0438\u043a\u0443\u043d_\u0442\u0443\u043d\u0442\u0438\u043a\u0443\u043d_\u044b\u0442\u043b\u0430\u0440\u0438\u043a\u0443\u043d_\u044e\u043d\u043a\u0443\u043d_\u043a\u04d7\u04ab\u043d\u0435\u0440\u043d\u0438\u043a\u0443\u043d_\u044d\u0440\u043d\u0435\u043a\u0443\u043d_\u0448\u04d1\u043c\u0430\u0442\u043a\u0443\u043d".split("_"),weekdaysShort:"\u0432\u044b\u0440_\u0442\u0443\u043d_\u044b\u0442\u043b_\u044e\u043d_\u043a\u04d7\u04ab_\u044d\u0440\u043d_\u0448\u04d1\u043c".split("_"),weekdaysMin:"\u0432\u0440_\u0442\u043d_\u044b\u0442_\u044e\u043d_\u043a\u04ab_\u044d\u0440_\u0448\u043c".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7]",LLL:"YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7], HH:mm",LLLL:"dddd, YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7], HH:mm"},calendar:{sameDay:"[\u041f\u0430\u044f\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextDay:"[\u042b\u0440\u0430\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastDay:"[\u04d6\u043d\u0435\u0440] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextWeek:"[\u04aa\u0438\u0442\u0435\u0441] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastWeek:"[\u0418\u0440\u0442\u043d\u04d7] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",sameElse:"L"},relativeTime:{future:function(n){return n+(/\u0441\u0435\u0445\u0435\u0442$/i.exec(n)?"\u0440\u0435\u043d":/\u04ab\u0443\u043b$/i.exec(n)?"\u0442\u0430\u043d":"\u0440\u0430\u043d")},past:"%s \u043a\u0430\u044f\u043b\u043b\u0430",s:"\u043f\u04d7\u0440-\u0438\u043a \u04ab\u0435\u043a\u043a\u0443\u043d\u0442",ss:"%d \u04ab\u0435\u043a\u043a\u0443\u043d\u0442",m:"\u043f\u04d7\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u043f\u04d7\u0440 \u0441\u0435\u0445\u0435\u0442",hh:"%d \u0441\u0435\u0445\u0435\u0442",d:"\u043f\u04d7\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u043f\u04d7\u0440 \u0443\u0439\u04d1\u0445",MM:"%d \u0443\u0439\u04d1\u0445",y:"\u043f\u04d7\u0440 \u04ab\u0443\u043b",yy:"%d \u04ab\u0443\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-\u043c\u04d7\u0448/,ordinal:"%d-\u043c\u04d7\u0448",week:{dow:1,doy:7}})}(e("PJh5"))},N4j0:function(n,t,e){"use strict";e.d(t,"a",function(){return l});var l=function(n){return n&&"number"==typeof n.length}},Nd3h:function(n,t,e){!function(n){"use strict";n.defineLocale("eo",{months:"januaro_februaro_marto_aprilo_majo_junio_julio_a\u016dgusto_septembro_oktobro_novembro_decembro".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_a\u016dg_sep_okt_nov_dec".split("_"),weekdays:"diman\u0109o_lundo_mardo_merkredo_\u0135a\u016ddo_vendredo_sabato".split("_"),weekdaysShort:"dim_lun_mard_merk_\u0135a\u016d_ven_sab".split("_"),weekdaysMin:"di_lu_ma_me_\u0135a_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D[-a de] MMMM, YYYY",LLL:"D[-a de] MMMM, YYYY HH:mm",LLLL:"dddd, [la] D[-a de] MMMM, YYYY HH:mm"},meridiemParse:/[ap]\.t\.m/i,isPM:function(n){return"p"===n.charAt(0).toLowerCase()},meridiem:function(n,t,e){return n>11?e?"p.t.m.":"P.T.M.":e?"a.t.m.":"A.T.M."},calendar:{sameDay:"[Hodia\u016d je] LT",nextDay:"[Morga\u016d je] LT",nextWeek:"dddd [je] LT",lastDay:"[Hiera\u016d je] LT",lastWeek:"[pasinta] dddd [je] LT",sameElse:"L"},relativeTime:{future:"post %s",past:"anta\u016d %s",s:"sekundoj",ss:"%d sekundoj",m:"minuto",mm:"%d minutoj",h:"horo",hh:"%d horoj",d:"tago",dd:"%d tagoj",M:"monato",MM:"%d monatoj",y:"jaro",yy:"%d jaroj"},dayOfMonthOrdinalParse:/\d{1,2}a/,ordinal:"%da",week:{dow:1,doy:7}})}(e("PJh5"))},Nlnz:function(n,t,e){!function(n){"use strict";n.defineLocale("te",{months:"\u0c1c\u0c28\u0c35\u0c30\u0c3f_\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f_\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f_\u0c0f\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d_\u0c2e\u0c47_\u0c1c\u0c42\u0c28\u0c4d_\u0c1c\u0c42\u0c32\u0c46\u0c56_\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41_\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d_\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d_\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d_\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d".split("_"),monthsShort:"\u0c1c\u0c28._\u0c2b\u0c3f\u0c2c\u0c4d\u0c30._\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f_\u0c0f\u0c2a\u0c4d\u0c30\u0c3f._\u0c2e\u0c47_\u0c1c\u0c42\u0c28\u0c4d_\u0c1c\u0c42\u0c32\u0c46\u0c56_\u0c06\u0c17._\u0c38\u0c46\u0c2a\u0c4d._\u0c05\u0c15\u0c4d\u0c1f\u0c4b._\u0c28\u0c35._\u0c21\u0c3f\u0c38\u0c46.".split("_"),monthsParseExact:!0,weekdays:"\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02_\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02_\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02_\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02_\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02_\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02_\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02".split("_"),weekdaysShort:"\u0c06\u0c26\u0c3f_\u0c38\u0c4b\u0c2e_\u0c2e\u0c02\u0c17\u0c33_\u0c2c\u0c41\u0c27_\u0c17\u0c41\u0c30\u0c41_\u0c36\u0c41\u0c15\u0c4d\u0c30_\u0c36\u0c28\u0c3f".split("_"),weekdaysMin:"\u0c06_\u0c38\u0c4b_\u0c2e\u0c02_\u0c2c\u0c41_\u0c17\u0c41_\u0c36\u0c41_\u0c36".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0c28\u0c47\u0c21\u0c41] LT",nextDay:"[\u0c30\u0c47\u0c2a\u0c41] LT",nextWeek:"dddd, LT",lastDay:"[\u0c28\u0c3f\u0c28\u0c4d\u0c28] LT",lastWeek:"[\u0c17\u0c24] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0c32\u0c4b",past:"%s \u0c15\u0c4d\u0c30\u0c3f\u0c24\u0c02",s:"\u0c15\u0c4a\u0c28\u0c4d\u0c28\u0c3f \u0c15\u0c4d\u0c37\u0c23\u0c3e\u0c32\u0c41",ss:"%d \u0c38\u0c46\u0c15\u0c28\u0c4d\u0c32\u0c41",m:"\u0c12\u0c15 \u0c28\u0c3f\u0c2e\u0c3f\u0c37\u0c02",mm:"%d \u0c28\u0c3f\u0c2e\u0c3f\u0c37\u0c3e\u0c32\u0c41",h:"\u0c12\u0c15 \u0c17\u0c02\u0c1f",hh:"%d \u0c17\u0c02\u0c1f\u0c32\u0c41",d:"\u0c12\u0c15 \u0c30\u0c4b\u0c1c\u0c41",dd:"%d \u0c30\u0c4b\u0c1c\u0c41\u0c32\u0c41",M:"\u0c12\u0c15 \u0c28\u0c46\u0c32",MM:"%d \u0c28\u0c46\u0c32\u0c32\u0c41",y:"\u0c12\u0c15 \u0c38\u0c02\u0c35\u0c24\u0c4d\u0c38\u0c30\u0c02",yy:"%d \u0c38\u0c02\u0c35\u0c24\u0c4d\u0c38\u0c30\u0c3e\u0c32\u0c41"},dayOfMonthOrdinalParse:/\d{1,2}\u0c35/,ordinal:"%d\u0c35",meridiemParse:/\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f|\u0c09\u0c26\u0c2f\u0c02|\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02|\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f"===t?n<4?n:n+12:"\u0c09\u0c26\u0c2f\u0c02"===t?n:"\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02"===t?n>=10?n:n+12:"\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02"===t?n+12:void 0},meridiem:function(n,t,e){return n<4?"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f":n<10?"\u0c09\u0c26\u0c2f\u0c02":n<17?"\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02":n<20?"\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02":"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f"},week:{dow:0,doy:6}})}(e("PJh5"))},Nzt2:function(n,t,e){!function(n){"use strict";n.defineLocale("he",{months:"\u05d9\u05e0\u05d5\u05d0\u05e8_\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8_\u05de\u05e8\u05e5_\u05d0\u05e4\u05e8\u05d9\u05dc_\u05de\u05d0\u05d9_\u05d9\u05d5\u05e0\u05d9_\u05d9\u05d5\u05dc\u05d9_\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8_\u05e1\u05e4\u05d8\u05de\u05d1\u05e8_\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8_\u05e0\u05d5\u05d1\u05de\u05d1\u05e8_\u05d3\u05e6\u05de\u05d1\u05e8".split("_"),monthsShort:"\u05d9\u05e0\u05d5\u05f3_\u05e4\u05d1\u05e8\u05f3_\u05de\u05e8\u05e5_\u05d0\u05e4\u05e8\u05f3_\u05de\u05d0\u05d9_\u05d9\u05d5\u05e0\u05d9_\u05d9\u05d5\u05dc\u05d9_\u05d0\u05d5\u05d2\u05f3_\u05e1\u05e4\u05d8\u05f3_\u05d0\u05d5\u05e7\u05f3_\u05e0\u05d5\u05d1\u05f3_\u05d3\u05e6\u05de\u05f3".split("_"),weekdays:"\u05e8\u05d0\u05e9\u05d5\u05df_\u05e9\u05e0\u05d9_\u05e9\u05dc\u05d9\u05e9\u05d9_\u05e8\u05d1\u05d9\u05e2\u05d9_\u05d7\u05de\u05d9\u05e9\u05d9_\u05e9\u05d9\u05e9\u05d9_\u05e9\u05d1\u05ea".split("_"),weekdaysShort:"\u05d0\u05f3_\u05d1\u05f3_\u05d2\u05f3_\u05d3\u05f3_\u05d4\u05f3_\u05d5\u05f3_\u05e9\u05f3".split("_"),weekdaysMin:"\u05d0_\u05d1_\u05d2_\u05d3_\u05d4_\u05d5_\u05e9".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [\u05d1]MMMM YYYY",LLL:"D [\u05d1]MMMM YYYY HH:mm",LLLL:"dddd, D [\u05d1]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[\u05d4\u05d9\u05d5\u05dd \u05d1\u05be]LT",nextDay:"[\u05de\u05d7\u05e8 \u05d1\u05be]LT",nextWeek:"dddd [\u05d1\u05e9\u05e2\u05d4] LT",lastDay:"[\u05d0\u05ea\u05de\u05d5\u05dc \u05d1\u05be]LT",lastWeek:"[\u05d1\u05d9\u05d5\u05dd] dddd [\u05d4\u05d0\u05d7\u05e8\u05d5\u05df \u05d1\u05e9\u05e2\u05d4] LT",sameElse:"L"},relativeTime:{future:"\u05d1\u05e2\u05d5\u05d3 %s",past:"\u05dc\u05e4\u05e0\u05d9 %s",s:"\u05de\u05e1\u05e4\u05e8 \u05e9\u05e0\u05d9\u05d5\u05ea",ss:"%d \u05e9\u05e0\u05d9\u05d5\u05ea",m:"\u05d3\u05e7\u05d4",mm:"%d \u05d3\u05e7\u05d5\u05ea",h:"\u05e9\u05e2\u05d4",hh:function(n){return 2===n?"\u05e9\u05e2\u05ea\u05d9\u05d9\u05dd":n+" \u05e9\u05e2\u05d5\u05ea"},d:"\u05d9\u05d5\u05dd",dd:function(n){return 2===n?"\u05d9\u05d5\u05de\u05d9\u05d9\u05dd":n+" \u05d9\u05de\u05d9\u05dd"},M:"\u05d7\u05d5\u05d3\u05e9",MM:function(n){return 2===n?"\u05d7\u05d5\u05d3\u05e9\u05d9\u05d9\u05dd":n+" \u05d7\u05d5\u05d3\u05e9\u05d9\u05dd"},y:"\u05e9\u05e0\u05d4",yy:function(n){return 2===n?"\u05e9\u05e0\u05ea\u05d9\u05d9\u05dd":n%10==0&&10!==n?n+" \u05e9\u05e0\u05d4":n+" \u05e9\u05e0\u05d9\u05dd"}},meridiemParse:/\u05d0\u05d7\u05d4"\u05e6|\u05dc\u05e4\u05e0\u05d4"\u05e6|\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05dc\u05e4\u05e0\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05dc\u05e4\u05e0\u05d5\u05ea \u05d1\u05d5\u05e7\u05e8|\u05d1\u05d1\u05d5\u05e7\u05e8|\u05d1\u05e2\u05e8\u05d1/i,isPM:function(n){return/^(\u05d0\u05d7\u05d4"\u05e6|\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05d1\u05e2\u05e8\u05d1)$/.test(n)},meridiem:function(n,t,e){return n<5?"\u05dc\u05e4\u05e0\u05d5\u05ea \u05d1\u05d5\u05e7\u05e8":n<10?"\u05d1\u05d1\u05d5\u05e7\u05e8":n<12?e?'\u05dc\u05e4\u05e0\u05d4"\u05e6':"\u05dc\u05e4\u05e0\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd":n<18?e?'\u05d0\u05d7\u05d4"\u05e6':"\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd":"\u05d1\u05e2\u05e8\u05d1"}})}(e("PJh5"))},ORgI:function(n,t,e){!function(n){"use strict";n.defineLocale("ja",{months:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u65e5\u66dc\u65e5_\u6708\u66dc\u65e5_\u706b\u66dc\u65e5_\u6c34\u66dc\u65e5_\u6728\u66dc\u65e5_\u91d1\u66dc\u65e5_\u571f\u66dc\u65e5".split("_"),weekdaysShort:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),weekdaysMin:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm dddd",l:"YYYY/MM/DD",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5 HH:mm dddd"},meridiemParse:/\u5348\u524d|\u5348\u5f8c/i,isPM:function(n){return"\u5348\u5f8c"===n},meridiem:function(n,t,e){return n<12?"\u5348\u524d":"\u5348\u5f8c"},calendar:{sameDay:"[\u4eca\u65e5] LT",nextDay:"[\u660e\u65e5] LT",nextWeek:"[\u6765\u9031]dddd LT",lastDay:"[\u6628\u65e5] LT",lastWeek:"[\u524d\u9031]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}\u65e5/,ordinal:function(n,t){switch(t){case"d":case"D":case"DDD":return n+"\u65e5";default:return n}},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u6570\u79d2",ss:"%d\u79d2",m:"1\u5206",mm:"%d\u5206",h:"1\u6642\u9593",hh:"%d\u6642\u9593",d:"1\u65e5",dd:"%d\u65e5",M:"1\u30f6\u6708",MM:"%d\u30f6\u6708",y:"1\u5e74",yy:"%d\u5e74"}})}(e("PJh5"))},OSsP:function(n,t,e){!function(n){"use strict";function t(n,t,e){return n+" "+function(n,t){return 2===t?function(n){var t={m:"v",b:"v",d:"z"};return void 0===t[n.charAt(0)]?n:t[n.charAt(0)]+n.substring(1)}(n):n}({mm:"munutenn",MM:"miz",dd:"devezh"}[e],n)}n.defineLocale("br",{months:"Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h[e]mm A",LTS:"h[e]mm:ss A",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY h[e]mm A",LLLL:"dddd, D [a viz] MMMM YYYY h[e]mm A"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warc'hoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Dec'h da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s 'zo",s:"un nebeud segondenno\xf9",ss:"%d eilenn",m:"ur vunutenn",mm:t,h:"un eur",hh:"%d eur",d:"un devezh",dd:t,M:"ur miz",MM:t,y:"ur bloaz",yy:function(n){switch(function n(t){return t>9?n(t%10):t}(n)){case 1:case 3:case 4:case 5:case 9:return n+" bloaz";default:return n+" vloaz"}}},dayOfMonthOrdinalParse:/\d{1,2}(a\xf1|vet)/,ordinal:function(n){return n+(1===n?"a\xf1":"vet")},week:{dow:1,doy:4}})}(e("PJh5"))},OUMt:function(n,t,e){!function(n){"use strict";var t="janu\xe1r_febru\xe1r_marec_apr\xedl_m\xe1j_j\xfan_j\xfal_august_september_okt\xf3ber_november_december".split("_"),e="jan_feb_mar_apr_m\xe1j_j\xfan_j\xfal_aug_sep_okt_nov_dec".split("_");function l(n){return n>1&&n<5}function r(n,t,e,r){var i=n+" ";switch(e){case"s":return t||r?"p\xe1r sek\xfand":"p\xe1r sekundami";case"ss":return t||r?i+(l(n)?"sekundy":"sek\xfand"):i+"sekundami";case"m":return t?"min\xfata":r?"min\xfatu":"min\xfatou";case"mm":return t||r?i+(l(n)?"min\xfaty":"min\xfat"):i+"min\xfatami";case"h":return t?"hodina":r?"hodinu":"hodinou";case"hh":return t||r?i+(l(n)?"hodiny":"hod\xedn"):i+"hodinami";case"d":return t||r?"de\u0148":"d\u0148om";case"dd":return t||r?i+(l(n)?"dni":"dn\xed"):i+"d\u0148ami";case"M":return t||r?"mesiac":"mesiacom";case"MM":return t||r?i+(l(n)?"mesiace":"mesiacov"):i+"mesiacmi";case"y":return t||r?"rok":"rokom";case"yy":return t||r?i+(l(n)?"roky":"rokov"):i+"rokmi"}}n.defineLocale("sk",{months:t,monthsShort:e,weekdays:"nede\u013ea_pondelok_utorok_streda_\u0161tvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_\u0161t_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_\u0161t_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nede\u013eu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo \u0161tvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[v\u010dera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minul\xfa nede\u013eu o] LT";case 1:case 2:return"[minul\xfd] dddd [o] LT";case 3:return"[minul\xfa stredu o] LT";case 4:case 5:return"[minul\xfd] dddd [o] LT";case 6:return"[minul\xfa sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:r,ss:r,m:r,mm:r,h:r,hh:r,d:r,dd:r,M:r,MM:r,y:r,yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},OVPi:function(n,t,e){!function(n){"use strict";n.defineLocale("fo",{months:"januar_februar_mars_apr\xedl_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sunnudagur_m\xe1nadagur_t\xfdsdagur_mikudagur_h\xf3sdagur_fr\xedggjadagur_leygardagur".split("_"),weekdaysShort:"sun_m\xe1n_t\xfds_mik_h\xf3s_fr\xed_ley".split("_"),weekdaysMin:"su_m\xe1_t\xfd_mi_h\xf3_fr_le".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D. MMMM, YYYY HH:mm"},calendar:{sameDay:"[\xcd dag kl.] LT",nextDay:"[\xcd morgin kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\xcd gj\xe1r kl.] LT",lastWeek:"[s\xed\xf0stu] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"um %s",past:"%s s\xed\xf0ani",s:"f\xe1 sekund",ss:"%d sekundir",m:"ein minutt",mm:"%d minuttir",h:"ein t\xedmi",hh:"%d t\xedmar",d:"ein dagur",dd:"%d dagar",M:"ein m\xe1na\xf0i",MM:"%d m\xe1na\xf0ir",y:"eitt \xe1r",yy:"%d \xe1r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},OVmG:function(n,t,e){"use strict";e.d(t,"a",function(){return a});var l=e("TToO"),r=e("/iUD"),i=e("VwZZ"),o=e("t7NR"),s=e("tLDX"),a=function(n){function t(e,l,r){switch(n.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=o.a;break;case 1:if(!e){this.destination=o.a;break}if("object"==typeof e){e instanceof t?(this.syncErrorThrowable=e.syncErrorThrowable,this.destination=e,this.destination.add(this)):(this.syncErrorThrowable=!0,this.destination=new u(this,e));break}default:this.syncErrorThrowable=!0,this.destination=new u(this,e,l,r)}}return Object(l.__extends)(t,n),t.prototype[s.a]=function(){return this},t.create=function(n,e,l){var r=new t(n,e,l);return r.syncErrorThrowable=!1,r},t.prototype.next=function(n){this.isStopped||this._next(n)},t.prototype.error=function(n){this.isStopped||(this.isStopped=!0,this._error(n))},t.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},t.prototype.unsubscribe=function(){this.closed||(this.isStopped=!0,n.prototype.unsubscribe.call(this))},t.prototype._next=function(n){this.destination.next(n)},t.prototype._error=function(n){this.destination.error(n),this.unsubscribe()},t.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},t.prototype._unsubscribeAndRecycle=function(){var n=this._parent,t=this._parents;return this._parent=null,this._parents=null,this.unsubscribe(),this.closed=!1,this.isStopped=!1,this._parent=n,this._parents=t,this},t}(i.a),u=function(n){function t(t,e,l,i){var s;n.call(this),this._parentSubscriber=t;var a=this;Object(r.a)(e)?s=e:e&&(s=e.next,l=e.error,i=e.complete,e!==o.a&&(a=Object.create(e),Object(r.a)(a.unsubscribe)&&this.add(a.unsubscribe.bind(a)),a.unsubscribe=this.unsubscribe.bind(this))),this._context=a,this._next=s,this._error=l,this._complete=i}return Object(l.__extends)(t,n),t.prototype.next=function(n){if(!this.isStopped&&this._next){var t=this._parentSubscriber;t.syncErrorThrowable?this.__tryOrSetError(t,this._next,n)&&this.unsubscribe():this.__tryOrUnsub(this._next,n)}},t.prototype.error=function(n){if(!this.isStopped){var t=this._parentSubscriber;if(this._error)t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,n),this.unsubscribe()):(this.__tryOrUnsub(this._error,n),this.unsubscribe());else{if(!t.syncErrorThrowable)throw this.unsubscribe(),n;t.syncErrorValue=n,t.syncErrorThrown=!0,this.unsubscribe()}}},t.prototype.complete=function(){var n=this;if(!this.isStopped){var t=this._parentSubscriber;if(this._complete){var e=function(){return n._complete.call(n._context)};t.syncErrorThrowable?(this.__tryOrSetError(t,e),this.unsubscribe()):(this.__tryOrUnsub(e),this.unsubscribe())}else this.unsubscribe()}},t.prototype.__tryOrUnsub=function(n,t){try{n.call(this._context,t)}catch(n){throw this.unsubscribe(),n}},t.prototype.__tryOrSetError=function(n,t,e){try{t.call(this._context,e)}catch(t){return n.syncErrorValue=t,n.syncErrorThrown=!0,!0}return!1},t.prototype._unsubscribe=function(){var n=this._parentSubscriber;this._context=null,this._parentSubscriber=null,n.unsubscribe()},t}(a)},PIsA:function(n,t,e){"use strict";var l=e("AMGY"),r=e("N4j0"),i=e("cQXm"),o=e("dgOU"),s=e("YaPU"),a=e("etqZ"),u=e("TToO"),c=function(n){function t(t,e,l){n.call(this),this.parent=t,this.outerValue=e,this.outerIndex=l,this.index=0}return Object(u.__extends)(t,n),t.prototype._next=function(n){this.parent.notifyNext(this.outerValue,n,this.outerIndex,this.index++,this)},t.prototype._error=function(n){this.parent.notifyError(n,this),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(this),this.unsubscribe()},t}(e("OVmG").a),d=e("+CnV");t.a=function(n,t,e,u){var h=new c(n,e,u);if(h.closed)return null;if(t instanceof s.a)return t._isScalar?(h.next(t.value),h.complete(),null):(h.syncErrorThrowable=!0,t.subscribe(h));if(Object(r.a)(t)){for(var p=0,f=t.length;p>>0,l=0;l0)for(e=0;e=0?e?"+":"":"-")+Math.pow(10,Math.max(0,t-l.length)).toString().substr(1)+l}var F=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,B=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,V={},W={};function z(n,t,e,l){var r=l;"string"==typeof l&&(r=function(){return this[l]()}),n&&(W[n]=r),t&&(W[t[0]]=function(){return N(r.apply(this,arguments),t[1],t[2])}),e&&(W[e]=function(){return this.localeData().ordinal(r.apply(this,arguments),n)})}function U(n,t){return n.isValid()?(t=G(t,n.localeData()),V[t]=V[t]||function(n){var t,e,l,r=n.match(F);for(t=0,e=r.length;t=0&&B.test(n);)n=n.replace(B,l),B.lastIndex=0,e-=1;return n}var q=/\d/,J=/\d\d/,Q=/\d{3}/,K=/\d{4}/,X=/[+-]?\d{6}/,Z=/\d\d?/,$=/\d\d\d\d?/,nn=/\d\d\d\d\d\d?/,tn=/\d{1,3}/,en=/\d{1,4}/,ln=/[+-]?\d{1,6}/,rn=/\d+/,on=/[+-]?\d+/,sn=/Z|[+-]\d\d:?\d\d/gi,an=/Z|[+-]\d\d(?::?\d\d)?/gi,un=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,cn={};function dn(n,t,e){cn[n]=P(t)?t:function(n,l){return n&&e?e:t}}function hn(n,t){return d(cn,n)?cn[n](t._strict,t._locale):new RegExp(pn(n.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(n,t,e,l,r){return t||e||l||r})))}function pn(n){return n.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var fn={};function _n(n,t){var e,l=t;for("string"==typeof n&&(n=[n]),a(t)&&(l=function(n,e){e[t]=M(n)}),e=0;e68?1900:2e3)};var Ln,Pn=Dn("FullYear",!0);function Dn(n,t){return function(e){return null!=e?(En(this,n,e),r.updateOffset(this,t),this):An(this,n)}}function An(n,t){return n.isValid()?n._d["get"+(n._isUTC?"UTC":"")+t]():NaN}function En(n,t,e){n.isValid()&&!isNaN(e)&&("FullYear"===t&&Tn(n.year())&&1===n.month()&&29===n.date()?n._d["set"+(n._isUTC?"UTC":"")+t](e,n.month(),Yn(e,n.month())):n._d["set"+(n._isUTC?"UTC":"")+t](e))}function Yn(n,t){if(isNaN(n)||isNaN(t))return NaN;var e=(t%12+12)%12;return n+=(t-e)/12,1===e?Tn(n)?29:28:31-e%7%2}Ln=Array.prototype.indexOf?Array.prototype.indexOf:function(n){var t;for(t=0;t=0&&isFinite(t.getUTCFullYear())&&t.setUTCFullYear(n),t}function zn(n,t,e){var l=7+t-e;return-(7+Wn(n,0,l).getUTCDay()-t)%7+l-1}function Un(n,t,e,l,r){var i,o,s=1+7*(t-1)+(7+e-l)%7+zn(n,l,r);return s<=0?o=On(i=n-1)+s:s>On(n)?(i=n+1,o=s-On(n)):(i=n,o=s),{year:i,dayOfYear:o}}function Gn(n,t,e){var l,r,i=zn(n.year(),t,e),o=Math.floor((n.dayOfYear()-i-1)/7)+1;return o<1?l=o+qn(r=n.year()-1,t,e):o>qn(n.year(),t,e)?(l=o-qn(n.year(),t,e),r=n.year()+1):(r=n.year(),l=o),{week:l,year:r}}function qn(n,t,e){var l=zn(n,t,e),r=zn(n+1,t,e);return(On(n)-l+r)/7}z("w",["ww",2],"wo","week"),z("W",["WW",2],"Wo","isoWeek"),Y("week","w"),Y("isoWeek","W"),H("week",5),H("isoWeek",5),dn("w",Z),dn("ww",Z,J),dn("W",Z),dn("WW",Z,J),mn(["w","ww","W","WW"],function(n,t,e,l){t[l.substr(0,1)]=M(n)}),z("d",0,"do","day"),z("dd",0,0,function(n){return this.localeData().weekdaysMin(this,n)}),z("ddd",0,0,function(n){return this.localeData().weekdaysShort(this,n)}),z("dddd",0,0,function(n){return this.localeData().weekdays(this,n)}),z("e",0,0,"weekday"),z("E",0,0,"isoWeekday"),Y("day","d"),Y("weekday","e"),Y("isoWeekday","E"),H("day",11),H("weekday",11),H("isoWeekday",11),dn("d",Z),dn("e",Z),dn("E",Z),dn("dd",function(n,t){return t.weekdaysMinRegex(n)}),dn("ddd",function(n,t){return t.weekdaysShortRegex(n)}),dn("dddd",function(n,t){return t.weekdaysRegex(n)}),mn(["dd","ddd","dddd"],function(n,t,e,l){var r=e._locale.weekdaysParse(n,l,e._strict);null!=r?t.d=r:f(e).invalidWeekday=n}),mn(["d","e","E"],function(n,t,e,l){t[l]=M(n)});var Jn="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Qn="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Kn="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Xn=un,Zn=un,$n=un;function nt(){function n(n,t){return t.length-n.length}var t,e,l,r,i,o=[],s=[],a=[],u=[];for(t=0;t<7;t++)e=p([2e3,1]).day(t),l=this.weekdaysMin(e,""),r=this.weekdaysShort(e,""),i=this.weekdays(e,""),o.push(l),s.push(r),a.push(i),u.push(l),u.push(r),u.push(i);for(o.sort(n),s.sort(n),a.sort(n),u.sort(n),t=0;t<7;t++)s[t]=pn(s[t]),a[t]=pn(a[t]),u[t]=pn(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function tt(){return this.hours()%12||12}function et(n,t){z(n,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function lt(n,t){return t._meridiemParse}z("H",["HH",2],0,"hour"),z("h",["hh",2],0,tt),z("k",["kk",2],0,function(){return this.hours()||24}),z("hmm",0,0,function(){return""+tt.apply(this)+N(this.minutes(),2)}),z("hmmss",0,0,function(){return""+tt.apply(this)+N(this.minutes(),2)+N(this.seconds(),2)}),z("Hmm",0,0,function(){return""+this.hours()+N(this.minutes(),2)}),z("Hmmss",0,0,function(){return""+this.hours()+N(this.minutes(),2)+N(this.seconds(),2)}),et("a",!0),et("A",!1),Y("hour","h"),H("hour",13),dn("a",lt),dn("A",lt),dn("H",Z),dn("h",Z),dn("k",Z),dn("HH",Z,J),dn("hh",Z,J),dn("kk",Z,J),dn("hmm",$),dn("hmmss",nn),dn("Hmm",$),dn("Hmmss",nn),_n(["H","HH"],wn),_n(["k","kk"],function(n,t,e){var l=M(n);t[wn]=24===l?0:l}),_n(["a","A"],function(n,t,e){e._isPm=e._locale.isPM(n),e._meridiem=n}),_n(["h","hh"],function(n,t,e){t[wn]=M(n),f(e).bigHour=!0}),_n("hmm",function(n,t,e){var l=n.length-2;t[wn]=M(n.substr(0,l)),t[xn]=M(n.substr(l)),f(e).bigHour=!0}),_n("hmmss",function(n,t,e){var l=n.length-4,r=n.length-2;t[wn]=M(n.substr(0,l)),t[xn]=M(n.substr(l,2)),t[Mn]=M(n.substr(r)),f(e).bigHour=!0}),_n("Hmm",function(n,t,e){var l=n.length-2;t[wn]=M(n.substr(0,l)),t[xn]=M(n.substr(l))}),_n("Hmmss",function(n,t,e){var l=n.length-4,r=n.length-2;t[wn]=M(n.substr(0,l)),t[xn]=M(n.substr(l,2)),t[Mn]=M(n.substr(r))});var rt,it=Dn("Hours",!0),ot={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:In,monthsShort:Rn,week:{dow:0,doy:6},weekdays:Jn,weekdaysMin:Kn,weekdaysShort:Qn,meridiemParse:/[ap]\.?m?\.?/i},st={},at={};function ut(n){return n?n.toLowerCase().replace("_","-"):n}function ct(t){var l=null;if(!st[t]&&"undefined"!=typeof n&&n&&n.exports)try{l=rt._abbr,e("uslO")("./"+t),dt(l)}catch(n){}return st[t]}function dt(n,t){var e;return n&&((e=s(t)?pt(n):ht(n,t))?rt=e:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+n+" not found. Did you forget to load it?")),rt._abbr}function ht(n,t){if(null!==t){var e,l=ot;if(t.abbr=n,null!=st[n])L("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),l=st[n]._config;else if(null!=t.parentLocale)if(null!=st[t.parentLocale])l=st[t.parentLocale]._config;else{if(null==(e=ct(t.parentLocale)))return at[t.parentLocale]||(at[t.parentLocale]=[]),at[t.parentLocale].push({name:n,config:t}),null;l=e._config}return st[n]=new A(D(l,t)),at[n]&&at[n].forEach(function(n){ht(n.name,n.config)}),dt(n),st[n]}return delete st[n],null}function pt(n){var t;if(n&&n._locale&&n._locale._abbr&&(n=n._locale._abbr),!n)return rt;if(!i(n)){if(t=ct(n))return t;n=[n]}return function(n){for(var t,e,l,r,i=0;i0;){if(l=ct(r.slice(0,t).join("-")))return l;if(e&&e.length>=t&&k(r,e,!0)>=t-1)break;t--}i++}return rt}(n)}function ft(n){var t,e=n._a;return e&&-2===f(n).overflow&&(t=e[bn]<0||e[bn]>11?bn:e[vn]<1||e[vn]>Yn(e[yn],e[bn])?vn:e[wn]<0||e[wn]>24||24===e[wn]&&(0!==e[xn]||0!==e[Mn]||0!==e[kn])?wn:e[xn]<0||e[xn]>59?xn:e[Mn]<0||e[Mn]>59?Mn:e[kn]<0||e[kn]>999?kn:-1,f(n)._overflowDayOfYear&&(tvn)&&(t=vn),f(n)._overflowWeeks&&-1===t&&(t=Cn),f(n)._overflowWeekday&&-1===t&&(t=Sn),f(n).overflow=t),n}function _t(n,t,e){return null!=n?n:null!=t?t:e}function mt(n){var t,e,l,i,o,s=[];if(!n._d){for(l=function(n){var t=new Date(r.now());return n._useUTC?[t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()]:[t.getFullYear(),t.getMonth(),t.getDate()]}(n),n._w&&null==n._a[vn]&&null==n._a[bn]&&function(n){var t,e,l,r,i,o,s,a;if(null!=(t=n._w).GG||null!=t.W||null!=t.E)i=1,o=4,e=_t(t.GG,n._a[yn],Gn(Pt(),1,4).year),l=_t(t.W,1),((r=_t(t.E,1))<1||r>7)&&(a=!0);else{i=n._locale._week.dow,o=n._locale._week.doy;var u=Gn(Pt(),i,o);e=_t(t.gg,n._a[yn],u.year),l=_t(t.w,u.week),null!=t.d?((r=t.d)<0||r>6)&&(a=!0):null!=t.e?(r=t.e+i,(t.e<0||t.e>6)&&(a=!0)):r=i}l<1||l>qn(e,i,o)?f(n)._overflowWeeks=!0:null!=a?f(n)._overflowWeekday=!0:(s=Un(e,l,r,i,o),n._a[yn]=s.year,n._dayOfYear=s.dayOfYear)}(n),null!=n._dayOfYear&&(o=_t(n._a[yn],l[yn]),(n._dayOfYear>On(o)||0===n._dayOfYear)&&(f(n)._overflowDayOfYear=!0),e=Wn(o,0,n._dayOfYear),n._a[bn]=e.getUTCMonth(),n._a[vn]=e.getUTCDate()),t=0;t<3&&null==n._a[t];++t)n._a[t]=s[t]=l[t];for(;t<7;t++)n._a[t]=s[t]=null==n._a[t]?2===t?1:0:n._a[t];24===n._a[wn]&&0===n._a[xn]&&0===n._a[Mn]&&0===n._a[kn]&&(n._nextDay=!0,n._a[wn]=0),n._d=(n._useUTC?Wn:function(n,t,e,l,r,i,o){var s=new Date(n,t,e,l,r,i,o);return n<100&&n>=0&&isFinite(s.getFullYear())&&s.setFullYear(n),s}).apply(null,s),i=n._useUTC?n._d.getUTCDay():n._d.getDay(),null!=n._tzm&&n._d.setUTCMinutes(n._d.getUTCMinutes()-n._tzm),n._nextDay&&(n._a[wn]=24),n._w&&"undefined"!=typeof n._w.d&&n._w.d!==i&&(f(n).weekdayMismatch=!0)}}var gt=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,yt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,bt=/Z|[+-]\d\d(?::?\d\d)?/,vt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],wt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],xt=/^\/?Date\((\-?\d+)/i;function Mt(n){var t,e,l,r,i,o,s=n._i,a=gt.exec(s)||yt.exec(s);if(a){for(f(n).iso=!0,t=0,e=vt.length;t0&&f(n).unusedInput.push(o),s=s.slice(s.indexOf(e)+e.length),u+=e.length),W[i]?(e?f(n).empty=!1:f(n).unusedTokens.push(i),gn(i,e,n)):n._strict&&!e&&f(n).unusedTokens.push(i);f(n).charsLeftOver=a-u,s.length>0&&f(n).unusedInput.push(s),n._a[wn]<=12&&!0===f(n).bigHour&&n._a[wn]>0&&(f(n).bigHour=void 0),f(n).parsedDateParts=n._a.slice(0),f(n).meridiem=n._meridiem,n._a[wn]=(c=n._locale,d=n._a[wn],null==(h=n._meridiem)?d:null!=c.meridiemHour?c.meridiemHour(d,h):null!=c.isPM?((p=c.isPM(h))&&d<12&&(d+=12),p||12!==d||(d=0),d):d),mt(n),ft(n)}else St(n);else Mt(n);var c,d,h,p}function Tt(n){var t=n._i,e=n._f;return n._locale=n._locale||pt(n._l),null===t||void 0===e&&""===t?m({nullInput:!0}):("string"==typeof t&&(n._i=t=n._locale.preparse(t)),w(t)?new v(ft(t)):(u(t)?n._d=t:i(e)?function(n){var t,e,l,r,i;if(0===n._f.length)return f(n).invalidFormat=!0,void(n._d=new Date(NaN));for(r=0;rthis?this:n:m()});function Et(n,t){var e,l;if(1===t.length&&i(t[0])&&(t=t[0]),!t.length)return Pt();for(e=t[0],l=1;l(i=qn(n,l,r))&&(t=i),(function(n,t,e,l,r){var i=Un(n,t,e,l,r),o=Wn(i.year,0,i.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}).call(this,n,t,e,l,r))}z(0,["gg",2],0,function(){return this.weekYear()%100}),z(0,["GG",2],0,function(){return this.isoWeekYear()%100}),le("gggg","weekYear"),le("ggggg","weekYear"),le("GGGG","isoWeekYear"),le("GGGGG","isoWeekYear"),Y("weekYear","gg"),Y("isoWeekYear","GG"),H("weekYear",1),H("isoWeekYear",1),dn("G",on),dn("g",on),dn("GG",Z,J),dn("gg",Z,J),dn("GGGG",en,K),dn("gggg",en,K),dn("GGGGG",ln,X),dn("ggggg",ln,X),mn(["gggg","ggggg","GGGG","GGGGG"],function(n,t,e,l){t[l.substr(0,2)]=M(n)}),mn(["gg","GG"],function(n,t,e,l){t[l]=r.parseTwoDigitYear(n)}),z("Q",0,"Qo","quarter"),Y("quarter","Q"),H("quarter",7),dn("Q",q),_n("Q",function(n,t){t[bn]=3*(M(n)-1)}),z("D",["DD",2],"Do","date"),Y("date","D"),H("date",9),dn("D",Z),dn("DD",Z,J),dn("Do",function(n,t){return n?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),_n(["D","DD"],vn),_n("Do",function(n,t){t[vn]=M(n.match(Z)[0])});var ie=Dn("Date",!0);z("DDD",["DDDD",3],"DDDo","dayOfYear"),Y("dayOfYear","DDD"),H("dayOfYear",4),dn("DDD",tn),dn("DDDD",Q),_n(["DDD","DDDD"],function(n,t,e){e._dayOfYear=M(n)}),z("m",["mm",2],0,"minute"),Y("minute","m"),H("minute",14),dn("m",Z),dn("mm",Z,J),_n(["m","mm"],xn);var oe=Dn("Minutes",!1);z("s",["ss",2],0,"second"),Y("second","s"),H("second",15),dn("s",Z),dn("ss",Z,J),_n(["s","ss"],Mn);var se,ae=Dn("Seconds",!1);for(z("S",0,0,function(){return~~(this.millisecond()/100)}),z(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),z(0,["SSS",3],0,"millisecond"),z(0,["SSSS",4],0,function(){return 10*this.millisecond()}),z(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),z(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),z(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),z(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),z(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),Y("millisecond","ms"),H("millisecond",16),dn("S",tn,q),dn("SS",tn,J),dn("SSS",tn,Q),se="SSSS";se.length<=9;se+="S")dn(se,rn);function ue(n,t){t[kn]=M(1e3*("0."+n))}for(se="S";se.length<=9;se+="S")_n(se,ue);var ce=Dn("Milliseconds",!1);z("z",0,0,"zoneAbbr"),z("zz",0,0,"zoneName");var de=v.prototype;function he(n){return n}de.add=Xt,de.calendar=function(n,t){var e=n||Pt(),l=Bt(e,this).startOf("day"),i=r.calendarFormat(this,l)||"sameElse",o=t&&(P(t[i])?t[i].call(this,e):t[i]);return this.format(o||this.localeData().calendar(i,this,Pt(e)))},de.clone=function(){return new v(this)},de.diff=function(n,t,e){var l,r,i;if(!this.isValid())return NaN;if(!(l=Bt(n,this)).isValid())return NaN;switch(r=6e4*(l.utcOffset()-this.utcOffset()),t=j(t)){case"year":i=$t(this,l)/12;break;case"month":i=$t(this,l);break;case"quarter":i=$t(this,l)/3;break;case"second":i=(this-l)/1e3;break;case"minute":i=(this-l)/6e4;break;case"hour":i=(this-l)/36e5;break;case"day":i=(this-l-r)/864e5;break;case"week":i=(this-l-r)/6048e5;break;default:i=this-l}return e?i:x(i)},de.endOf=function(n){return void 0===(n=j(n))||"millisecond"===n?this:("date"===n&&(n="day"),this.startOf(n).add(1,"isoWeek"===n?"week":n).subtract(1,"ms"))},de.format=function(n){n||(n=this.isUtc()?r.defaultFormatUtc:r.defaultFormat);var t=U(this,n);return this.localeData().postformat(t)},de.from=function(n,t){return this.isValid()&&(w(n)&&n.isValid()||Pt(n).isValid())?Gt({to:this,from:n}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},de.fromNow=function(n){return this.from(Pt(),n)},de.to=function(n,t){return this.isValid()&&(w(n)&&n.isValid()||Pt(n).isValid())?Gt({from:this,to:n}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},de.toNow=function(n){return this.to(Pt(),n)},de.get=function(n){return P(this[n=j(n)])?this[n]():this},de.invalidAt=function(){return f(this).overflow},de.isAfter=function(n,t){var e=w(n)?n:Pt(n);return!(!this.isValid()||!e.isValid())&&("millisecond"===(t=j(s(t)?"millisecond":t))?this.valueOf()>e.valueOf():e.valueOf()9999?U(e,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):P(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",U(e,"Z")):U(e,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},de.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var n="moment",t="";this.isLocal()||(n=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var e="["+n+'("]',l=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY";return this.format(e+l+"-MM-DD[T]HH:mm:ss.SSS"+t+'[")]')},de.toJSON=function(){return this.isValid()?this.toISOString():null},de.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},de.unix=function(){return Math.floor(this.valueOf()/1e3)},de.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},de.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},de.year=Pn,de.isLeapYear=function(){return Tn(this.year())},de.weekYear=function(n){return re.call(this,n,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},de.isoWeekYear=function(n){return re.call(this,n,this.isoWeek(),this.isoWeekday(),1,4)},de.quarter=de.quarters=function(n){return null==n?Math.ceil((this.month()+1)/3):this.month(3*(n-1)+this.month()%3)},de.month=Nn,de.daysInMonth=function(){return Yn(this.year(),this.month())},de.week=de.weeks=function(n){var t=this.localeData().week(this);return null==n?t:this.add(7*(n-t),"d")},de.isoWeek=de.isoWeeks=function(n){var t=Gn(this,1,4).week;return null==n?t:this.add(7*(n-t),"d")},de.weeksInYear=function(){var n=this.localeData()._week;return qn(this.year(),n.dow,n.doy)},de.isoWeeksInYear=function(){return qn(this.year(),1,4)},de.date=ie,de.day=de.days=function(n){if(!this.isValid())return null!=n?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=n?(n=function(n,t){return"string"!=typeof n?n:isNaN(n)?"number"==typeof(n=t.weekdaysParse(n))?n:null:parseInt(n,10)}(n,this.localeData()),this.add(n-t,"d")):t},de.weekday=function(n){if(!this.isValid())return null!=n?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==n?t:this.add(n-t,"d")},de.isoWeekday=function(n){if(!this.isValid())return null!=n?this:NaN;if(null!=n){var t=function(n,t){return"string"==typeof n?t.weekdaysParse(n)%7||7:isNaN(n)?null:n}(n,this.localeData());return this.day(this.day()%7?t:t-7)}return this.day()||7},de.dayOfYear=function(n){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==n?t:this.add(n-t,"d")},de.hour=de.hours=it,de.minute=de.minutes=oe,de.second=de.seconds=ae,de.millisecond=de.milliseconds=ce,de.utcOffset=function(n,t,e){var l,i=this._offset||0;if(!this.isValid())return null!=n?this:NaN;if(null!=n){if("string"==typeof n){if(null===(n=Ft(an,n)))return this}else Math.abs(n)<16&&!e&&(n*=60);return!this._isUTC&&t&&(l=Vt(this)),this._offset=n,this._isUTC=!0,null!=l&&this.add(l,"m"),i!==n&&(!t||this._changeInProgress?Kt(this,Gt(n-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,r.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?i:Vt(this)},de.utc=function(n){return this.utcOffset(0,n)},de.local=function(n){return this._isUTC&&(this.utcOffset(0,n),this._isUTC=!1,n&&this.subtract(Vt(this),"m")),this},de.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var n=Ft(sn,this._i);null!=n?this.utcOffset(n):this.utcOffset(0,!0)}return this},de.hasAlignedHourOffset=function(n){return!!this.isValid()&&(n=n?Pt(n).utcOffset():0,(this.utcOffset()-n)%60==0)},de.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},de.isLocal=function(){return!!this.isValid()&&!this._isUTC},de.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},de.isUtc=Wt,de.isUTC=Wt,de.zoneAbbr=function(){return this._isUTC?"UTC":""},de.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},de.dates=S("dates accessor is deprecated. Use date instead.",ie),de.months=S("months accessor is deprecated. Use month instead",Nn),de.years=S("years accessor is deprecated. Use year instead",Pn),de.zone=S("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(n,t){return null!=n?("string"!=typeof n&&(n=-n),this.utcOffset(n,t),this):-this.utcOffset()}),de.isDSTShifted=S("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var n={};if(y(n,this),(n=Tt(n))._a){var t=n._isUTC?p(n._a):Pt(n._a);this._isDSTShifted=this.isValid()&&k(n._a,t.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted});var pe=A.prototype;function fe(n,t,e,l){var r=pt(),i=p().set(l,t);return r[e](i,n)}function _e(n,t,e){if(a(n)&&(t=n,n=void 0),n=n||"",null!=t)return fe(n,t,e,"month");var l,r=[];for(l=0;l<12;l++)r[l]=fe(n,l,e,"month");return r}function me(n,t,e,l){"boolean"==typeof n?(a(t)&&(e=t,t=void 0),t=t||""):(e=t=n,n=!1,a(t)&&(e=t,t=void 0),t=t||"");var r,i=pt(),o=n?i._week.dow:0;if(null!=e)return fe(t,(e+o)%7,l,"day");var s=[];for(r=0;r<7;r++)s[r]=fe(t,(r+o)%7,l,"day");return s}pe.calendar=function(n,t,e){var l=this._calendar[n]||this._calendar.sameElse;return P(l)?l.call(t,e):l},pe.longDateFormat=function(n){var t=this._longDateFormat[n],e=this._longDateFormat[n.toUpperCase()];return t||!e?t:(this._longDateFormat[n]=e.replace(/MMMM|MM|DD|dddd/g,function(n){return n.slice(1)}),this._longDateFormat[n])},pe.invalidDate=function(){return this._invalidDate},pe.ordinal=function(n){return this._ordinal.replace("%d",n)},pe.preparse=he,pe.postformat=he,pe.relativeTime=function(n,t,e,l){var r=this._relativeTime[e];return P(r)?r(n,t,e,l):r.replace(/%d/i,n)},pe.pastFuture=function(n,t){var e=this._relativeTime[n>0?"future":"past"];return P(e)?e(t):e.replace(/%s/i,t)},pe.set=function(n){var t,e;for(e in n)P(t=n[e])?this[e]=t:this["_"+e]=t;this._config=n,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},pe.months=function(n,t){return n?i(this._months)?this._months[n.month()]:this._months[(this._months.isFormat||jn).test(t)?"format":"standalone"][n.month()]:i(this._months)?this._months:this._months.standalone},pe.monthsShort=function(n,t){return n?i(this._monthsShort)?this._monthsShort[n.month()]:this._monthsShort[jn.test(t)?"format":"standalone"][n.month()]:i(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},pe.monthsParse=function(n,t,e){var l,r,i;if(this._monthsParseExact)return(function(n,t,e){var l,r,i,o=n.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],l=0;l<12;++l)i=p([2e3,l]),this._shortMonthsParse[l]=this.monthsShort(i,"").toLocaleLowerCase(),this._longMonthsParse[l]=this.months(i,"").toLocaleLowerCase();return e?"MMM"===t?-1!==(r=Ln.call(this._shortMonthsParse,o))?r:null:-1!==(r=Ln.call(this._longMonthsParse,o))?r:null:"MMM"===t?-1!==(r=Ln.call(this._shortMonthsParse,o))?r:-1!==(r=Ln.call(this._longMonthsParse,o))?r:null:-1!==(r=Ln.call(this._longMonthsParse,o))?r:-1!==(r=Ln.call(this._shortMonthsParse,o))?r:null}).call(this,n,t,e);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),l=0;l<12;l++){if(r=p([2e3,l]),e&&!this._longMonthsParse[l]&&(this._longMonthsParse[l]=new RegExp("^"+this.months(r,"").replace(".","")+"$","i"),this._shortMonthsParse[l]=new RegExp("^"+this.monthsShort(r,"").replace(".","")+"$","i")),e||this._monthsParse[l]||(i="^"+this.months(r,"")+"|^"+this.monthsShort(r,""),this._monthsParse[l]=new RegExp(i.replace(".",""),"i")),e&&"MMMM"===t&&this._longMonthsParse[l].test(n))return l;if(e&&"MMM"===t&&this._shortMonthsParse[l].test(n))return l;if(!e&&this._monthsParse[l].test(n))return l}},pe.monthsRegex=function(n){return this._monthsParseExact?(d(this,"_monthsRegex")||Vn.call(this),n?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=Bn),this._monthsStrictRegex&&n?this._monthsStrictRegex:this._monthsRegex)},pe.monthsShortRegex=function(n){return this._monthsParseExact?(d(this,"_monthsRegex")||Vn.call(this),n?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=Fn),this._monthsShortStrictRegex&&n?this._monthsShortStrictRegex:this._monthsShortRegex)},pe.week=function(n){return Gn(n,this._week.dow,this._week.doy).week},pe.firstDayOfYear=function(){return this._week.doy},pe.firstDayOfWeek=function(){return this._week.dow},pe.weekdays=function(n,t){return n?i(this._weekdays)?this._weekdays[n.day()]:this._weekdays[this._weekdays.isFormat.test(t)?"format":"standalone"][n.day()]:i(this._weekdays)?this._weekdays:this._weekdays.standalone},pe.weekdaysMin=function(n){return n?this._weekdaysMin[n.day()]:this._weekdaysMin},pe.weekdaysShort=function(n){return n?this._weekdaysShort[n.day()]:this._weekdaysShort},pe.weekdaysParse=function(n,t,e){var l,r,i;if(this._weekdaysParseExact)return(function(n,t,e){var l,r,i,o=n.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],l=0;l<7;++l)i=p([2e3,1]).day(l),this._minWeekdaysParse[l]=this.weekdaysMin(i,"").toLocaleLowerCase(),this._shortWeekdaysParse[l]=this.weekdaysShort(i,"").toLocaleLowerCase(),this._weekdaysParse[l]=this.weekdays(i,"").toLocaleLowerCase();return e?"dddd"===t?-1!==(r=Ln.call(this._weekdaysParse,o))?r:null:"ddd"===t?-1!==(r=Ln.call(this._shortWeekdaysParse,o))?r:null:-1!==(r=Ln.call(this._minWeekdaysParse,o))?r:null:"dddd"===t?-1!==(r=Ln.call(this._weekdaysParse,o))?r:-1!==(r=Ln.call(this._shortWeekdaysParse,o))?r:-1!==(r=Ln.call(this._minWeekdaysParse,o))?r:null:"ddd"===t?-1!==(r=Ln.call(this._shortWeekdaysParse,o))?r:-1!==(r=Ln.call(this._weekdaysParse,o))?r:-1!==(r=Ln.call(this._minWeekdaysParse,o))?r:null:-1!==(r=Ln.call(this._minWeekdaysParse,o))?r:-1!==(r=Ln.call(this._weekdaysParse,o))?r:-1!==(r=Ln.call(this._shortWeekdaysParse,o))?r:null}).call(this,n,t,e);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),l=0;l<7;l++){if(r=p([2e3,1]).day(l),e&&!this._fullWeekdaysParse[l]&&(this._fullWeekdaysParse[l]=new RegExp("^"+this.weekdays(r,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[l]=new RegExp("^"+this.weekdaysShort(r,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[l]=new RegExp("^"+this.weekdaysMin(r,"").replace(".",".?")+"$","i")),this._weekdaysParse[l]||(i="^"+this.weekdays(r,"")+"|^"+this.weekdaysShort(r,"")+"|^"+this.weekdaysMin(r,""),this._weekdaysParse[l]=new RegExp(i.replace(".",""),"i")),e&&"dddd"===t&&this._fullWeekdaysParse[l].test(n))return l;if(e&&"ddd"===t&&this._shortWeekdaysParse[l].test(n))return l;if(e&&"dd"===t&&this._minWeekdaysParse[l].test(n))return l;if(!e&&this._weekdaysParse[l].test(n))return l}},pe.weekdaysRegex=function(n){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||nt.call(this),n?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=Xn),this._weekdaysStrictRegex&&n?this._weekdaysStrictRegex:this._weekdaysRegex)},pe.weekdaysShortRegex=function(n){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||nt.call(this),n?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Zn),this._weekdaysShortStrictRegex&&n?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},pe.weekdaysMinRegex=function(n){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||nt.call(this),n?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=$n),this._weekdaysMinStrictRegex&&n?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},pe.isPM=function(n){return"p"===(n+"").toLowerCase().charAt(0)},pe.meridiem=function(n,t,e){return n>11?e?"pm":"PM":e?"am":"AM"},dt("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(n){var t=n%10;return n+(1===M(n%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),r.lang=S("moment.lang is deprecated. Use moment.locale instead.",dt),r.langData=S("moment.langData is deprecated. Use moment.localeData instead.",pt);var ge=Math.abs;function ye(n,t,e,l){var r=Gt(t,e);return n._milliseconds+=l*r._milliseconds,n._days+=l*r._days,n._months+=l*r._months,n._bubble()}function be(n){return n<0?Math.floor(n):Math.ceil(n)}function ve(n){return 4800*n/146097}function we(n){return 146097*n/4800}function xe(n){return function(){return this.as(n)}}var Me=xe("ms"),ke=xe("s"),Ce=xe("m"),Se=xe("h"),Oe=xe("d"),Te=xe("w"),Le=xe("M"),Pe=xe("y");function De(n){return function(){return this.isValid()?this._data[n]:NaN}}var Ae=De("milliseconds"),Ee=De("seconds"),Ye=De("minutes"),je=De("hours"),Ie=De("days"),Re=De("months"),He=De("years"),Ne=Math.round,Fe={ss:44,s:45,m:45,h:22,d:26,M:11},Be=Math.abs;function Ve(n){return(n>0)-(n<0)||+n}function We(){if(!this.isValid())return this.localeData().invalidDate();var n,t,e=Be(this._milliseconds)/1e3,l=Be(this._days),r=Be(this._months);t=x((n=x(e/60))/60),e%=60,n%=60;var i=x(r/12),o=r%=12,s=l,a=t,u=n,c=e?e.toFixed(3).replace(/\.?0+$/,""):"",d=this.asSeconds();if(!d)return"P0D";var h=d<0?"-":"",p=Ve(this._months)!==Ve(d)?"-":"",f=Ve(this._days)!==Ve(d)?"-":"",_=Ve(this._milliseconds)!==Ve(d)?"-":"";return h+"P"+(i?p+i+"Y":"")+(o?p+o+"M":"")+(s?f+s+"D":"")+(a||u||c?"T":"")+(a?_+a+"H":"")+(u?_+u+"M":"")+(c?_+c+"S":"")}var ze=jt.prototype;return ze.isValid=function(){return this._isValid},ze.abs=function(){var n=this._data;return this._milliseconds=ge(this._milliseconds),this._days=ge(this._days),this._months=ge(this._months),n.milliseconds=ge(n.milliseconds),n.seconds=ge(n.seconds),n.minutes=ge(n.minutes),n.hours=ge(n.hours),n.months=ge(n.months),n.years=ge(n.years),this},ze.add=function(n,t){return ye(this,n,t,1)},ze.subtract=function(n,t){return ye(this,n,t,-1)},ze.as=function(n){if(!this.isValid())return NaN;var t,e,l=this._milliseconds;if("month"===(n=j(n))||"year"===n)return e=this._months+ve(t=this._days+l/864e5),"month"===n?e:e/12;switch(t=this._days+Math.round(we(this._months)),n){case"week":return t/7+l/6048e5;case"day":return t+l/864e5;case"hour":return 24*t+l/36e5;case"minute":return 1440*t+l/6e4;case"second":return 86400*t+l/1e3;case"millisecond":return Math.floor(864e5*t)+l;default:throw new Error("Unknown unit "+n)}},ze.asMilliseconds=Me,ze.asSeconds=ke,ze.asMinutes=Ce,ze.asHours=Se,ze.asDays=Oe,ze.asWeeks=Te,ze.asMonths=Le,ze.asYears=Pe,ze.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*M(this._months/12):NaN},ze._bubble=function(){var n,t,e,l,r,i=this._milliseconds,o=this._days,s=this._months,a=this._data;return i>=0&&o>=0&&s>=0||i<=0&&o<=0&&s<=0||(i+=864e5*be(we(s)+o),o=0,s=0),a.milliseconds=i%1e3,n=x(i/1e3),a.seconds=n%60,t=x(n/60),a.minutes=t%60,e=x(t/60),a.hours=e%24,s+=r=x(ve(o+=x(e/24))),o-=be(we(r)),l=x(s/12),s%=12,a.days=o,a.months=s,a.years=l,this},ze.clone=function(){return Gt(this)},ze.get=function(n){return n=j(n),this.isValid()?this[n+"s"]():NaN},ze.milliseconds=Ae,ze.seconds=Ee,ze.minutes=Ye,ze.hours=je,ze.days=Ie,ze.weeks=function(){return x(this.days()/7)},ze.months=Re,ze.years=He,ze.humanize=function(n){if(!this.isValid())return this.localeData().invalidDate();var t=this.localeData(),e=function(n,t,e){var l=Gt(n).abs(),r=Ne(l.as("s")),i=Ne(l.as("m")),o=Ne(l.as("h")),s=Ne(l.as("d")),a=Ne(l.as("M")),u=Ne(l.as("y")),c=r<=Fe.ss&&["s",r]||r0,c[4]=e,(function(n,t,e,l,r){return r.relativeTime(t||1,!!e,n,l)}).apply(null,c)}(this,!n,t);return n&&(e=t.pastFuture(+this,e)),t.postformat(e)},ze.toISOString=We,ze.toString=We,ze.toJSON=We,ze.locale=ne,ze.localeData=ee,ze.toIsoString=S("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",We),ze.lang=te,z("X",0,0,"unix"),z("x",0,0,"valueOf"),dn("x",on),dn("X",/[+-]?\d+(\.\d{1,3})?/),_n("X",function(n,t,e){e._d=new Date(1e3*parseFloat(n,10))}),_n("x",function(n,t,e){e._d=new Date(M(n))}),r.version="2.21.0",t=Pt,r.fn=de,r.min=function(){return Et("isBefore",[].slice.call(arguments,0))},r.max=function(){return Et("isAfter",[].slice.call(arguments,0))},r.now=function(){return Date.now?Date.now():+new Date},r.utc=p,r.unix=function(n){return Pt(1e3*n)},r.months=function(n,t){return _e(n,t,"months")},r.isDate=u,r.locale=dt,r.invalid=m,r.duration=Gt,r.isMoment=w,r.weekdays=function(n,t,e){return me(n,t,e,"weekdays")},r.parseZone=function(){return Pt.apply(null,arguments).parseZone()},r.localeData=pt,r.isDuration=It,r.monthsShort=function(n,t){return _e(n,t,"monthsShort")},r.weekdaysMin=function(n,t,e){return me(n,t,e,"weekdaysMin")},r.defineLocale=ht,r.updateLocale=function(n,t){if(null!=t){var e,l,r=ot;null!=(l=ct(n))&&(r=l._config),(e=new A(t=D(r,t))).parentLocale=st[n],st[n]=e,dt(n)}else null!=st[n]&&(null!=st[n].parentLocale?st[n]=st[n].parentLocale:null!=st[n]&&delete st[n]);return st[n]},r.locales=function(){return O(st)},r.weekdaysShort=function(n,t,e){return me(n,t,e,"weekdaysShort")},r.normalizeUnits=j,r.relativeTimeRounding=function(n){return void 0===n?Ne:"function"==typeof n&&(Ne=n,!0)},r.relativeTimeThreshold=function(n,t){return void 0!==Fe[n]&&(void 0===t?Fe[n]:(Fe[n]=t,"s"===n&&(Fe.ss=t-1),!0))},r.calendarFormat=function(n,t){var e=n.diff(t,"days",!0);return e<-6?"sameElse":e<-1?"lastWeek":e<0?"lastDay":e<1?"sameDay":e<2?"nextDay":e<7?"nextWeek":"sameElse"},r.prototype=de,r.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},r}()}).call(t,e("3IRH")(n))},QZk1:function(n,t,e){!function(n){"use strict";n.defineLocale("en-il",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(n){var t=n%10;return n+(1==~~(n%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}})}(e("PJh5"))},Qnch:function(n,t,e){"use strict";t.a=function(n,t,e){return void 0===e&&(e=Number.POSITIVE_INFINITY),function(l){return"number"==typeof t&&(e=t,t=null),l.lift(new o(n,t,e))}};var l=e("TToO"),r=e("PIsA"),i=e("tZ2B"),o=function(){function n(n,t,e){void 0===e&&(e=Number.POSITIVE_INFINITY),this.project=n,this.resultSelector=t,this.concurrent=e}return n.prototype.call=function(n,t){return t.subscribe(new s(n,this.project,this.resultSelector,this.concurrent))},n}(),s=function(n){function t(t,e,l,r){void 0===r&&(r=Number.POSITIVE_INFINITY),n.call(this,t),this.project=e,this.resultSelector=l,this.concurrent=r,this.hasCompleted=!1,this.buffer=[],this.active=0,this.index=0}return Object(l.__extends)(t,n),t.prototype._next=function(n){this.active0?this._next(t.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()},t}(i.a)},RMhj:function(n,t,e){var l={"./en.json":["TKku",5],"./es.json":["/YBz",4],"./es_base.json":["0v8u",3],"./ru.json":["P+VX",2],"./zh.json":["ODm5",1],"./zh_base.json":["dXVM",0]};function r(n){var t=l[n];return t?e.e(t[1]).then(function(){return e(t[0])}):Promise.reject(new Error("Cannot find module '"+n+"'."))}r.keys=function(){return Object.keys(l)},r.id="RMhj",n.exports=r},Rf9G:function(n,t,e){"use strict";t.a=function(){return Object(l.a)()(this)};var l=e("3a3m")},RnJI:function(n,t,e){!function(n){"use strict";n.defineLocale("ka",{months:{standalone:"\u10d8\u10d0\u10dc\u10d5\u10d0\u10e0\u10d8_\u10d7\u10d4\u10d1\u10d4\u10e0\u10d5\u10d0\u10da\u10d8_\u10db\u10d0\u10e0\u10e2\u10d8_\u10d0\u10de\u10e0\u10d8\u10da\u10d8_\u10db\u10d0\u10d8\u10e1\u10d8_\u10d8\u10d5\u10dc\u10d8\u10e1\u10d8_\u10d8\u10d5\u10da\u10d8\u10e1\u10d8_\u10d0\u10d2\u10d5\u10d8\u10e1\u10e2\u10dd_\u10e1\u10d4\u10e5\u10e2\u10d4\u10db\u10d1\u10d4\u10e0\u10d8_\u10dd\u10e5\u10e2\u10dd\u10db\u10d1\u10d4\u10e0\u10d8_\u10dc\u10dd\u10d4\u10db\u10d1\u10d4\u10e0\u10d8_\u10d3\u10d4\u10d9\u10d4\u10db\u10d1\u10d4\u10e0\u10d8".split("_"),format:"\u10d8\u10d0\u10dc\u10d5\u10d0\u10e0\u10e1_\u10d7\u10d4\u10d1\u10d4\u10e0\u10d5\u10d0\u10da\u10e1_\u10db\u10d0\u10e0\u10e2\u10e1_\u10d0\u10de\u10e0\u10d8\u10da\u10d8\u10e1_\u10db\u10d0\u10d8\u10e1\u10e1_\u10d8\u10d5\u10dc\u10d8\u10e1\u10e1_\u10d8\u10d5\u10da\u10d8\u10e1\u10e1_\u10d0\u10d2\u10d5\u10d8\u10e1\u10e2\u10e1_\u10e1\u10d4\u10e5\u10e2\u10d4\u10db\u10d1\u10d4\u10e0\u10e1_\u10dd\u10e5\u10e2\u10dd\u10db\u10d1\u10d4\u10e0\u10e1_\u10dc\u10dd\u10d4\u10db\u10d1\u10d4\u10e0\u10e1_\u10d3\u10d4\u10d9\u10d4\u10db\u10d1\u10d4\u10e0\u10e1".split("_")},monthsShort:"\u10d8\u10d0\u10dc_\u10d7\u10d4\u10d1_\u10db\u10d0\u10e0_\u10d0\u10de\u10e0_\u10db\u10d0\u10d8_\u10d8\u10d5\u10dc_\u10d8\u10d5\u10da_\u10d0\u10d2\u10d5_\u10e1\u10d4\u10e5_\u10dd\u10e5\u10e2_\u10dc\u10dd\u10d4_\u10d3\u10d4\u10d9".split("_"),weekdays:{standalone:"\u10d9\u10d5\u10d8\u10e0\u10d0_\u10dd\u10e0\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10e1\u10d0\u10db\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10dd\u10d7\u10ee\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10ee\u10e3\u10d7\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10de\u10d0\u10e0\u10d0\u10e1\u10d9\u10d4\u10d5\u10d8_\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8".split("_"),format:"\u10d9\u10d5\u10d8\u10e0\u10d0\u10e1_\u10dd\u10e0\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10e1\u10d0\u10db\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10dd\u10d7\u10ee\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10ee\u10e3\u10d7\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10de\u10d0\u10e0\u10d0\u10e1\u10d9\u10d4\u10d5\u10e1_\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1".split("_"),isFormat:/(\u10ec\u10d8\u10dc\u10d0|\u10e8\u10d4\u10db\u10d3\u10d4\u10d2)/},weekdaysShort:"\u10d9\u10d5\u10d8_\u10dd\u10e0\u10e8_\u10e1\u10d0\u10db_\u10dd\u10d7\u10ee_\u10ee\u10e3\u10d7_\u10de\u10d0\u10e0_\u10e8\u10d0\u10d1".split("_"),weekdaysMin:"\u10d9\u10d5_\u10dd\u10e0_\u10e1\u10d0_\u10dd\u10d7_\u10ee\u10e3_\u10de\u10d0_\u10e8\u10d0".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[\u10d3\u10e6\u10d4\u10e1] LT[-\u10d6\u10d4]",nextDay:"[\u10ee\u10d5\u10d0\u10da] LT[-\u10d6\u10d4]",lastDay:"[\u10d2\u10e3\u10e8\u10d8\u10dc] LT[-\u10d6\u10d4]",nextWeek:"[\u10e8\u10d4\u10db\u10d3\u10d4\u10d2] dddd LT[-\u10d6\u10d4]",lastWeek:"[\u10ec\u10d8\u10dc\u10d0] dddd LT-\u10d6\u10d4",sameElse:"L"},relativeTime:{future:function(n){return/(\u10ec\u10d0\u10db\u10d8|\u10ec\u10e3\u10d7\u10d8|\u10e1\u10d0\u10d0\u10d7\u10d8|\u10ec\u10d4\u10da\u10d8)/.test(n)?n.replace(/\u10d8$/,"\u10e8\u10d8"):n+"\u10e8\u10d8"},past:function(n){return/(\u10ec\u10d0\u10db\u10d8|\u10ec\u10e3\u10d7\u10d8|\u10e1\u10d0\u10d0\u10d7\u10d8|\u10d3\u10e6\u10d4|\u10d7\u10d5\u10d4)/.test(n)?n.replace(/(\u10d8|\u10d4)$/,"\u10d8\u10e1 \u10e3\u10d9\u10d0\u10dc"):/\u10ec\u10d4\u10da\u10d8/.test(n)?n.replace(/\u10ec\u10d4\u10da\u10d8$/,"\u10ec\u10da\u10d8\u10e1 \u10e3\u10d9\u10d0\u10dc"):void 0},s:"\u10e0\u10d0\u10db\u10d3\u10d4\u10dc\u10d8\u10db\u10d4 \u10ec\u10d0\u10db\u10d8",ss:"%d \u10ec\u10d0\u10db\u10d8",m:"\u10ec\u10e3\u10d7\u10d8",mm:"%d \u10ec\u10e3\u10d7\u10d8",h:"\u10e1\u10d0\u10d0\u10d7\u10d8",hh:"%d \u10e1\u10d0\u10d0\u10d7\u10d8",d:"\u10d3\u10e6\u10d4",dd:"%d \u10d3\u10e6\u10d4",M:"\u10d7\u10d5\u10d4",MM:"%d \u10d7\u10d5\u10d4",y:"\u10ec\u10d4\u10da\u10d8",yy:"%d \u10ec\u10d4\u10da\u10d8"},dayOfMonthOrdinalParse:/0|1-\u10da\u10d8|\u10db\u10d4-\d{1,2}|\d{1,2}-\u10d4/,ordinal:function(n){return 0===n?n:1===n?n+"-\u10da\u10d8":n<20||n<=100&&n%20==0||n%100==0?"\u10db\u10d4-"+n:n+"-\u10d4"},week:{dow:1,doy:7}})}(e("PJh5"))},Sjoy:function(n,t,e){!function(n){"use strict";n.defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(n){var t=n%10;return n+(1==~~(n%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")},week:{dow:1,doy:4}})}(e("PJh5"))},T1Dh:function(n,t,e){"use strict";t.a=function(n){return function(t){return 0===n?new o.a:t.lift(new s(n))}};var l=e("TToO"),r=e("OVmG"),i=e("pU/0"),o=e("+3/4"),s=function(){function n(n){if(this.total=n,this.total<0)throw new i.a}return n.prototype.call=function(n,t){return t.subscribe(new a(n,this.total))},n}(),a=function(n){function t(t,e){n.call(this,t),this.total=e,this.ring=new Array,this.count=0}return Object(l.__extends)(t,n),t.prototype._next=function(n){var t=this.ring,e=this.total,l=this.count++;t.length0)for(var e=this.count>=this.total?this.total:this.count,l=this.ring,r=0;r=0;s--)(r=n[s])&&(o=(i<3?r(o):i>3?r(t,e,o):r(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o},t.__param=function(n,t){return function(e,l){t(e,l,n)}},t.__metadata=function(n,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(n,t)},t.__awaiter=function(n,t,e,l){return new(e||(e=Promise))(function(r,i){function o(n){try{a(l.next(n))}catch(n){i(n)}}function s(n){try{a(l.throw(n))}catch(n){i(n)}}function a(n){n.done?r(n.value):new e(function(t){t(n.value)}).then(o,s)}a((l=l.apply(n,t||[])).next())})},t.__generator=function(n,t){var e,l,r,i,o={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(e)throw new TypeError("Generator is already executing.");for(;o;)try{if(e=1,l&&(r=l[2&i[0]?"return":i[0]?"throw":"next"])&&!(r=r.call(l,i[1])).done)return r;switch(l=0,r&&(i=[0,r.value]),i[0]){case 0:case 1:r=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,l=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!(r=(r=o.trys).length>0&&r[r.length-1])&&(6===i[0]||2===i[0])){o=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]1||a(n,t)})})}function a(n,t){try{(e=r[n](t)).value instanceof s?Promise.resolve(e.value.v).then(u,c):d(i[0][2],e)}catch(n){d(i[0][3],n)}var e}function u(n){a("next",n)}function c(n){a("throw",n)}function d(n,t){n(t),i.shift(),i.length&&a(i[0][0],i[0][1])}},t.__asyncDelegator=function(n){var t,e;return t={},l("next"),l("throw",function(n){throw n}),l("return"),t[Symbol.iterator]=function(){return this},t;function l(l,r){n[l]&&(t[l]=function(t){return(e=!e)?{value:s(n[l](t)),done:"return"===l}:r?r(t):t})}},t.__asyncValues=function(n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=n[Symbol.asyncIterator];return t?t.call(n):"function"==typeof i?i(n):n[Symbol.iterator]()},t.__makeTemplateObject=function(n,t){return Object.defineProperty?Object.defineProperty(n,"raw",{value:t}):n.raw=t,n};var l=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,t){n.__proto__=t}||function(n,t){for(var e in t)t.hasOwnProperty(e)&&(n[e]=t[e])},r=Object.assign||function(n){for(var t,e=1,l=arguments.length;e=n.length&&(n=void 0),{value:n&&n[e++],done:!n}}}}function o(n,t){var e="function"==typeof Symbol&&n[Symbol.iterator];if(!e)return n;var l,r,i=e.call(n),o=[];try{for(;(void 0===t||t-- >0)&&!(l=i.next()).done;)o.push(l.value)}catch(n){r={error:n}}finally{try{l&&!l.done&&(e=i.return)&&e.call(i)}finally{if(r)throw r.error}}return o}function s(n){return this instanceof s?(this.v=n,this):new s(n)}},To0v:function(n,t,e){!function(n){"use strict";n.defineLocale("ug-cn",{months:"\u064a\u0627\u0646\u06cb\u0627\u0631_\u0641\u06d0\u06cb\u0631\u0627\u0644_\u0645\u0627\u0631\u062a_\u0626\u0627\u067e\u0631\u06d0\u0644_\u0645\u0627\u064a_\u0626\u0649\u064a\u06c7\u0646_\u0626\u0649\u064a\u06c7\u0644_\u0626\u0627\u06cb\u063a\u06c7\u0633\u062a_\u0633\u06d0\u0646\u062a\u06d5\u0628\u0649\u0631_\u0626\u06c6\u0643\u062a\u06d5\u0628\u0649\u0631_\u0646\u0648\u064a\u0627\u0628\u0649\u0631_\u062f\u06d0\u0643\u0627\u0628\u0649\u0631".split("_"),monthsShort:"\u064a\u0627\u0646\u06cb\u0627\u0631_\u0641\u06d0\u06cb\u0631\u0627\u0644_\u0645\u0627\u0631\u062a_\u0626\u0627\u067e\u0631\u06d0\u0644_\u0645\u0627\u064a_\u0626\u0649\u064a\u06c7\u0646_\u0626\u0649\u064a\u06c7\u0644_\u0626\u0627\u06cb\u063a\u06c7\u0633\u062a_\u0633\u06d0\u0646\u062a\u06d5\u0628\u0649\u0631_\u0626\u06c6\u0643\u062a\u06d5\u0628\u0649\u0631_\u0646\u0648\u064a\u0627\u0628\u0649\u0631_\u062f\u06d0\u0643\u0627\u0628\u0649\u0631".split("_"),weekdays:"\u064a\u06d5\u0643\u0634\u06d5\u0646\u0628\u06d5_\u062f\u06c8\u0634\u06d5\u0646\u0628\u06d5_\u0633\u06d5\u064a\u0634\u06d5\u0646\u0628\u06d5_\u0686\u0627\u0631\u0634\u06d5\u0646\u0628\u06d5_\u067e\u06d5\u064a\u0634\u06d5\u0646\u0628\u06d5_\u062c\u06c8\u0645\u06d5_\u0634\u06d5\u0646\u0628\u06d5".split("_"),weekdaysShort:"\u064a\u06d5_\u062f\u06c8_\u0633\u06d5_\u0686\u0627_\u067e\u06d5_\u062c\u06c8_\u0634\u06d5".split("_"),weekdaysMin:"\u064a\u06d5_\u062f\u06c8_\u0633\u06d5_\u0686\u0627_\u067e\u06d5_\u062c\u06c8_\u0634\u06d5".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649",LLL:"YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649\u060c HH:mm",LLLL:"dddd\u060c YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649\u060c HH:mm"},meridiemParse:/\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5|\u0633\u06d5\u06be\u06d5\u0631|\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646|\u0686\u06c8\u0634|\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646|\u0643\u06d5\u0686/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5"===t||"\u0633\u06d5\u06be\u06d5\u0631"===t||"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646"===t?n:"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646"===t||"\u0643\u06d5\u0686"===t?n+12:n>=11?n:n+12},meridiem:function(n,t,e){var l=100*n+t;return l<600?"\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5":l<900?"\u0633\u06d5\u06be\u06d5\u0631":l<1130?"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646":l<1230?"\u0686\u06c8\u0634":l<1800?"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646":"\u0643\u06d5\u0686"},calendar:{sameDay:"[\u0628\u06c8\u06af\u06c8\u0646 \u0633\u0627\u0626\u06d5\u062a] LT",nextDay:"[\u0626\u06d5\u062a\u06d5 \u0633\u0627\u0626\u06d5\u062a] LT",nextWeek:"[\u0643\u06d0\u0644\u06d5\u0631\u0643\u0649] dddd [\u0633\u0627\u0626\u06d5\u062a] LT",lastDay:"[\u062a\u06c6\u0646\u06c8\u06af\u06c8\u0646] LT",lastWeek:"[\u0626\u0627\u0644\u062f\u0649\u0646\u0642\u0649] dddd [\u0633\u0627\u0626\u06d5\u062a] LT",sameElse:"L"},relativeTime:{future:"%s \u0643\u06d0\u064a\u0649\u0646",past:"%s \u0628\u06c7\u0631\u06c7\u0646",s:"\u0646\u06d5\u0686\u0686\u06d5 \u0633\u06d0\u0643\u0648\u0646\u062a",ss:"%d \u0633\u06d0\u0643\u0648\u0646\u062a",m:"\u0628\u0649\u0631 \u0645\u0649\u0646\u06c7\u062a",mm:"%d \u0645\u0649\u0646\u06c7\u062a",h:"\u0628\u0649\u0631 \u0633\u0627\u0626\u06d5\u062a",hh:"%d \u0633\u0627\u0626\u06d5\u062a",d:"\u0628\u0649\u0631 \u0643\u06c8\u0646",dd:"%d \u0643\u06c8\u0646",M:"\u0628\u0649\u0631 \u0626\u0627\u064a",MM:"%d \u0626\u0627\u064a",y:"\u0628\u0649\u0631 \u064a\u0649\u0644",yy:"%d \u064a\u0649\u0644"},dayOfMonthOrdinalParse:/\d{1,2}(-\u0643\u06c8\u0646\u0649|-\u0626\u0627\u064a|-\u06be\u06d5\u067e\u062a\u06d5)/,ordinal:function(n,t){switch(t){case"d":case"D":case"DDD":return n+"-\u0643\u06c8\u0646\u0649";case"w":case"W":return n+"-\u06be\u06d5\u067e\u062a\u06d5";default:return n}},preparse:function(n){return n.replace(/\u060c/g,",")},postformat:function(n){return n.replace(/,/g,"\u060c")},week:{dow:1,doy:7}})}(e("PJh5"))},Tqun:function(n,t,e){!function(n){"use strict";n.defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(n){var t=n%10;return n+(1==~~(n%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}})}(e("PJh5"))},Uter:function(n,t,e){const l=e("X3l8").Buffer;n.exports=function(n){if(n.length>=255)throw new TypeError("Alphabet too long");const t=new Uint8Array(256);t.fill(255);for(let l=0;l>>0,c=new Uint8Array(u);for(;n[o];){let l=t[n.charCodeAt(o)];if(255===l)return;let r=0;for(let n=u-1;(0!==l||r>>0)%256>>>0,l=l/256>>>0;if(0!==l)throw new Error("Non-zero carry");a=r,o++}if(" "===n[o])return;let d=u-a;for(;d!==u&&0===c[d];)d++;const h=l.allocUnsafe(s+(u-d));h.fill(0,0,s);let p=s;for(;d!==u;)h[p++]=c[d++];return h}return{encode:function(t){if(!l.isBuffer(t))throw new TypeError("Expected Buffer");if(0===t.length)return"";let i=0,s=0,a=0;const u=t.length;for(;a!==u&&0===t[a];)a++,i++;const c=(u-a)*o+1>>>0,d=new Uint8Array(c);for(;a!==u;){let n=t[a],l=0;for(let t=c-1;(0!==n||l>>0)%e>>>0,n=n/e>>>0;if(0!==n)throw new Error("Non-zero carry");s=l,a++}let h=c-s;for(;h!==c&&0===d[h];)h++;let p=r.repeat(i);for(;h1?new t(n,l):1===r?new i.a(n[0],l):new o.a(l)},t.dispatch=function(n){var t=n.array,e=n.index,l=n.subscriber;e>=n.count?l.complete():(l.next(t[e]),l.closed||(n.index=e+1,this.schedule(n)))},t.prototype._subscribe=function(n){var e=this.array,l=e.length,r=this.scheduler;if(r)return r.schedule(t.dispatch,0,{array:e,index:0,count:l,subscriber:n});for(var i=0;i=11?n:n+12},meridiem:function(n,t,e){var l=100*n+t;return l<600?"\u51cc\u6668":l<900?"\u65e9\u4e0a":l<1130?"\u4e0a\u5348":l<1230?"\u4e2d\u5348":l<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u5468)/,ordinal:function(n,t){switch(t){case"d":case"D":case"DDD":return n+"\u65e5";case"M":return n+"\u6708";case"w":case"W":return n+"\u5468";default:return n}},relativeTime:{future:"%s\u5185",past:"%s\u524d",s:"\u51e0\u79d2",ss:"%d \u79d2",m:"1 \u5206\u949f",mm:"%d \u5206\u949f",h:"1 \u5c0f\u65f6",hh:"%d \u5c0f\u65f6",d:"1 \u5929",dd:"%d \u5929",M:"1 \u4e2a\u6708",MM:"%d \u4e2a\u6708",y:"1 \u5e74",yy:"%d \u5e74"},week:{dow:1,doy:4}})}(e("PJh5"))},WT6e:function(n,t,e){"use strict";(function(n){e.d(t,"g",function(){return ot}),e.d(t,"V",function(){return $n}),e.d(t,"Y",function(){return nt}),e.d(t,"U",function(){return et}),e.d(t,"A",function(){return tt}),e.d(t,"c",function(){return hn}),e.d(t,"E",function(){return _n}),e.d(t,"D",function(){return mn}),e.d(t,"b",function(){return gn}),e.d(t,"d",function(){return cn}),e.d(t,"e",function(){return dn}),e.d(t,"X",function(){return Ot}),e.d(t,"P",function(){return Un}),e.d(t,"_0",function(){return qn}),e.d(t,"w",function(){return Kt}),e.d(t,"f",function(){return ne}),e.d(t,"o",function(){return Rn}),e.d(t,"n",function(){return sn}),e.d(t,"J",function(){return ee}),e.d(t,"K",function(){return te}),e.d(t,"a",function(){return _}),e.d(t,"k",function(){return m}),e.d(t,"t",function(){return y}),e.d(t,"F",function(){return g}),e.d(t,"S",function(){return b}),e.d(t,"Q",function(){return v}),e.d(t,"W",function(){return j}),e.d(t,"s",function(){return F}),e.d(t,"r",function(){return a}),e.d(t,"p",function(){return x}),e.d(t,"C",function(){return M}),e.d(t,"q",function(){return k}),e.d(t,"L",function(){return S}),e.d(t,"B",function(){return Hn}),e.d(t,"G",function(){return ct}),e.d(t,"H",function(){return at}),e.d(t,"I",function(){return ut}),e.d(t,"i",function(){return vn}),e.d(t,"j",function(){return Tn}),e.d(t,"l",function(){return dt}),e.d(t,"x",function(){return An}),e.d(t,"z",function(){return Dn}),e.d(t,"y",function(){return ht}),e.d(t,"M",function(){return mt}),e.d(t,"N",function(){return ft}),e.d(t,"O",function(){return yt}),e.d(t,"R",function(){return bt}),e.d(t,"m",function(){return wt}),e.d(t,"h",function(){return vt}),e.d(t,"u",function(){return zt}),e.d(t,"v",function(){return Ut}),e.d(t,"T",function(){return Pt}),e.d(t,"Z",function(){return Qt}),e.d(t,"_13",function(){return At}),e.d(t,"_2",function(){return yn}),e.d(t,"_1",function(){return Ln}),e.d(t,"_10",function(){return L}),e.d(t,"_16",function(){return E}),e.d(t,"_30",function(){return Y}),e.d(t,"_14",function(){return un}),e.d(t,"_15",function(){return an}),e.d(t,"_3",function(){return Qe}),e.d(t,"_4",function(){return Ke}),e.d(t,"_5",function(){return _l}),e.d(t,"_6",function(){return wi}),e.d(t,"_7",function(){return ve}),e.d(t,"_8",function(){return Hl}),e.d(t,"_9",function(){return Xe}),e.d(t,"_12",function(){return qe}),e.d(t,"_18",function(){return ol}),e.d(t,"_19",function(){return il}),e.d(t,"_21",function(){return or}),e.d(t,"_22",function(){return Sl}),e.d(t,"_25",function(){return Nl}),e.d(t,"_28",function(){return Fl}),e.d(t,"_24",function(){return ur}),e.d(t,"_26",function(){return cr}),e.d(t,"_27",function(){return ar}),e.d(t,"_29",function(){return tr}),e.d(t,"_31",function(){return hr}),e.d(t,"_32",function(){return ge}),e.d(t,"_33",function(){return _r}),e.d(t,"_17",function(){return Xt}),e.d(t,"_20",function(){return Zt}),e.d(t,"_23",function(){return $t}),e.d(t,"_11",function(){return pn});var l=e("TToO"),r=e("YaPU"),i=e("/nXB"),o=e("Rf9G"),s=e("g5jc"),a=function(){function n(n){this._desc=n,this.ngMetadataName="InjectionToken"}return n.prototype.toString=function(){return"InjectionToken "+this._desc},n}(),u="__annotations__",c="__paramaters__",d="__prop__metadata__";function h(n,t,e,l){var r=p(t);function i(n){if(this instanceof i)return r.call(this,n),this;var t=new i(n),e=function(n){return(n.hasOwnProperty(u)?n[u]:Object.defineProperty(n,u,{value:[]})[u]).push(t),n};return l&&l(e),e}return e&&(i.prototype=Object.create(e.prototype)),i.prototype.ngMetadataName=n,i.annotationCls=i,i}function p(n){return function(){for(var t=[],e=0;e ");else if("object"==typeof t){var r=[];for(var i in t)if(t.hasOwnProperty(i)){var o=t[i];r.push(i+":"+("string"==typeof o?JSON.stringify(o):Y(o)))}l="{"+r.join(", ")+"}"}return"StaticInjectorError"+(e?"("+e+")":"")+"["+l+"]: "+n.replace(J,"\n ")}function $(n,t){return new Error(Z(n,t))}var nn="ngDebugContext",tn="ngOriginalError",en="ngErrorLogger";function ln(n){return n[nn]}function rn(n){return n[tn]}function on(n){for(var t=[],e=1;e0)n._bootstrapComponents.forEach(function(n){return t.bootstrap(n)});else{if(!n.instance.ngDoBootstrap)throw new Error("The module "+Y(n.instance.constructor)+' was bootstrapped, but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. Please define one of these.');n.instance.ngDoBootstrap(t)}this._modules.push(n)},n.prototype.onDestroy=function(n){this._destroyListeners.push(n)},Object.defineProperty(n.prototype,"injector",{get:function(){return this._injector},enumerable:!0,configurable:!0}),n.prototype.destroy=function(){if(this._destroyed)throw new Error("The platform has already been destroyed!");this._modules.slice().forEach(function(n){return n.destroy()}),this._destroyListeners.forEach(function(n){return n()}),this._destroyed=!0},Object.defineProperty(n.prototype,"destroyed",{get:function(){return this._destroyed},enumerable:!0,configurable:!0}),n}();function it(n,t){return Array.isArray(t)?t.reduce(it,n):Object(l.__assign)({},n,t)}var ot=function(){function n(n,t,e,l,s,a){var u=this;this._zone=n,this._console=t,this._injector=e,this._exceptionHandler=l,this._componentFactoryResolver=s,this._initStatus=a,this._bootstrapListeners=[],this._views=[],this._runningTick=!1,this._enforceNoNewChanges=!1,this._stable=!0,this.componentTypes=[],this.components=[],this._enforceNoNewChanges=nt(),this._zone.onMicrotaskEmpty.subscribe({next:function(){u._zone.run(function(){u.tick()})}});var c=new r.a(function(n){u._stable=u._zone.isStable&&!u._zone.hasPendingMacrotasks&&!u._zone.hasPendingMicrotasks,u._zone.runOutsideAngular(function(){n.next(u._stable),n.complete()})}),d=new r.a(function(n){var t;u._zone.runOutsideAngular(function(){t=u._zone.onStable.subscribe(function(){Hn.assertNotInAngularZone(),A(function(){u._stable||u._zone.hasPendingMacrotasks||u._zone.hasPendingMicrotasks||(u._stable=!0,n.next(!0))})})});var e=u._zone.onUnstable.subscribe(function(){Hn.assertInAngularZone(),u._stable&&(u._stable=!1,u._zone.runOutsideAngular(function(){n.next(!1)}))});return function(){t.unsubscribe(),e.unsubscribe()}});this.isStable=Object(i.a)(c,o.a.call(d))}return n.prototype.bootstrap=function(n,t){var e,l=this;if(!this._initStatus.done)throw new Error("Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.");e=n instanceof xn?n:this._componentFactoryResolver.resolveComponentFactory(n),this.componentTypes.push(e.componentType);var r=e instanceof Pn?null:this._injector.get(Dn),i=e.create(F.NULL,[],t||e.selector,r);i.onDestroy(function(){l._unloadComponent(i)});var o=i.injector.get(Un,null);return o&&i.injector.get(Gn).registerApplication(i.location.nativeElement,o),this._loadComponent(i),nt()&&this._console.log("Angular is running in the development mode. Call enableProdMode() to enable the production mode."),i},n.prototype.tick=function(){var t=this;if(this._runningTick)throw new Error("ApplicationRef.tick is called recursively");var e=n._tickScope();try{this._runningTick=!0,this._views.forEach(function(n){return n.detectChanges()}),this._enforceNoNewChanges&&this._views.forEach(function(n){return n.checkNoChanges()})}catch(n){this._zone.runOutsideAngular(function(){return t._exceptionHandler.handleError(n)})}finally{this._runningTick=!1,In(e)}},n.prototype.attachView=function(n){var t=n;this._views.push(t),t.attachToAppRef(this)},n.prototype.detachView=function(n){var t=n;st(this._views,t),t.detachFromAppRef()},n.prototype._loadComponent=function(n){this.attachView(n.hostView),this.tick(),this.components.push(n),this._injector.get(gn,[]).concat(this._bootstrapListeners).forEach(function(t){return t(n)})},n.prototype._unloadComponent=function(n){this.detachView(n.hostView),st(this.components,n)},n.prototype.ngOnDestroy=function(){this._views.slice().forEach(function(n){return n.destroy()})},Object.defineProperty(n.prototype,"viewCount",{get:function(){return this._views.length},enumerable:!0,configurable:!0}),n._tickScope=jn("ApplicationRef#tick()"),n}();function st(n,t){var e=n.indexOf(t);e>-1&&n.splice(e,1)}var at=function(){},ut=function(){var n={Important:1,DashCase:2};return n[n.Important]="Important",n[n.DashCase]="DashCase",n}(),ct=function(){},dt=function(n){this.nativeElement=n},ht=function(){},pt=function(){function n(){this.dirty=!0,this._results=[],this.changes=new Rn}return n.prototype.map=function(n){return this._results.map(n)},n.prototype.filter=function(n){return this._results.filter(n)},n.prototype.find=function(n){return this._results.find(n)},n.prototype.reduce=function(n,t){return this._results.reduce(n,t)},n.prototype.forEach=function(n){this._results.forEach(n)},n.prototype.some=function(n){return this._results.some(n)},n.prototype.toArray=function(){return this._results.slice()},n.prototype[D()]=function(){return this._results[D()]()},n.prototype.toString=function(){return this._results.toString()},n.prototype.reset=function(n){this._results=function n(t){return t.reduce(function(t,e){var l=Array.isArray(e)?n(e):e;return t.concat(l)},[])}(n),this.dirty=!1,this.length=this._results.length,this.last=this._results[this.length-1],this.first=this._results[0]},n.prototype.notifyOnChanges=function(){this.changes.emit(this)},n.prototype.setDirty=function(){this.dirty=!0},n.prototype.destroy=function(){this.changes.complete(),this.changes.unsubscribe()},n}(),ft=function(){},_t={factoryPathPrefix:"",factoryPathSuffix:".ngfactory"},mt=function(){function n(n,t){this._compiler=n,this._config=t||_t}return n.prototype.load=function(n){return this._compiler instanceof vn?this.loadFactory(n):this.loadAndCompile(n)},n.prototype.loadAndCompile=function(n){var t=this,l=n.split("#"),r=l[0],i=l[1];return void 0===i&&(i="default"),e("Jnfr")(r).then(function(n){return n[i]}).then(function(n){return gt(n,r,i)}).then(function(n){return t._compiler.compileModuleAsync(n)})},n.prototype.loadFactory=function(n){var t=n.split("#"),l=t[0],r=t[1],i="NgFactory";return void 0===r&&(r="default",i=""),e("Jnfr")(this._config.factoryPathPrefix+l+this._config.factoryPathSuffix).then(function(n){return n[r+i]}).then(function(n){return gt(n,l,r)})},n}();function gt(n,t,e){if(!n)throw new Error("Cannot find '"+e+"' in '"+t+"'");return n}var yt=function(){},bt=function(){},vt=function(){},wt=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return Object(l.__extends)(t,n),t}(function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return Object(l.__extends)(t,n),t}(vt)),xt=function(){function n(n,t,e){this._debugContext=e,this.nativeNode=n,t&&t instanceof Mt?t.addChild(this):this.parent=null,this.listeners=[]}return Object.defineProperty(n.prototype,"injector",{get:function(){return this._debugContext.injector},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"componentInstance",{get:function(){return this._debugContext.component},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"context",{get:function(){return this._debugContext.context},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"references",{get:function(){return this._debugContext.references},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"providerTokens",{get:function(){return this._debugContext.providerTokens},enumerable:!0,configurable:!0}),n}(),Mt=function(n){function t(t,e,l){var r=n.call(this,t,e,l)||this;return r.properties={},r.attributes={},r.classes={},r.styles={},r.childNodes=[],r.nativeElement=t,r}return Object(l.__extends)(t,n),t.prototype.addChild=function(n){n&&(this.childNodes.push(n),n.parent=this)},t.prototype.removeChild=function(n){var t=this.childNodes.indexOf(n);-1!==t&&(n.parent=null,this.childNodes.splice(t,1))},t.prototype.insertChildrenAfter=function(n,t){var e,l=this,r=this.childNodes.indexOf(n);-1!==r&&((e=this.childNodes).splice.apply(e,[r+1,0].concat(t)),t.forEach(function(n){n.parent&&n.parent.removeChild(n),n.parent=l}))},t.prototype.insertBefore=function(n,t){var e=this.childNodes.indexOf(n);-1===e?this.addChild(t):(t.parent&&t.parent.removeChild(t),t.parent=this,this.childNodes.splice(e,0,t))},t.prototype.query=function(n){return this.queryAll(n)[0]||null},t.prototype.queryAll=function(n){var t=[];return kt(this,n,t),t},t.prototype.queryAllNodes=function(n){var t=[];return Ct(this,n,t),t},Object.defineProperty(t.prototype,"children",{get:function(){return this.childNodes.filter(function(n){return n instanceof t})},enumerable:!0,configurable:!0}),t.prototype.triggerEventHandler=function(n,t){this.listeners.forEach(function(e){e.name==n&&e.callback(t)})},t}(xt);function kt(n,t,e){n.childNodes.forEach(function(n){n instanceof Mt&&(t(n)&&e.push(n),kt(n,t,e))})}function Ct(n,t,e){n instanceof Mt&&n.childNodes.forEach(function(n){t(n)&&e.push(n),n instanceof Mt&&Ct(n,t,e)})}var St=new Map;function Ot(n){return St.get(n)||null}function Tt(n){St.set(n.nativeNode,n)}function Lt(n,t){var e=At(n),l=At(t);return e&&l?function(n,t,e){for(var l=n[D()](),r=t[D()]();;){var i=l.next(),o=r.next();if(i.done&&o.done)return!0;if(i.done||o.done)return!1;if(!e(i.value,o.value))return!1}}(n,t,Lt):!(e||!n||"object"!=typeof n&&"function"!=typeof n||l||!t||"object"!=typeof t&&"function"!=typeof t)||E(n,t)}var Pt=function(){function n(n){this.wrapped=n}return n.wrap=function(t){return new n(t)},n}(),Dt=function(){function n(n,t,e){this.previousValue=n,this.currentValue=t,this.firstChange=e}return n.prototype.isFirstChange=function(){return this.firstChange},n}();function At(n){return!!Et(n)&&(Array.isArray(n)||!(n instanceof Map)&&D()in n)}function Et(n){return null!==n&&("function"==typeof n||"object"==typeof n)}var Yt=function(){function n(){}return n.prototype.supports=function(n){return At(n)},n.prototype.create=function(n){return new It(n)},n}(),jt=function(n,t){return t},It=function(){function n(n){this.length=0,this._linkedRecords=null,this._unlinkedRecords=null,this._previousItHead=null,this._itHead=null,this._itTail=null,this._additionsHead=null,this._additionsTail=null,this._movesHead=null,this._movesTail=null,this._removalsHead=null,this._removalsTail=null,this._identityChangesHead=null,this._identityChangesTail=null,this._trackByFn=n||jt}return n.prototype.forEachItem=function(n){var t;for(t=this._itHead;null!==t;t=t._next)n(t)},n.prototype.forEachOperation=function(n){for(var t=this._itHead,e=this._removalsHead,l=0,r=null;t||e;){var i=!e||t&&t.currentIndex=e.length)&&(t=e.length-1),t<0)return null;var l=e[t];return l.viewContainerParent=null,pl(e,t),ce.dirtyParentQueries(l),dl(l),l}function cl(n,t,e){var l=t?Pe(t,t.def.lastRenderRootNode):n.renderElement;Ne(e,2,e.renderer.parentNode(l),e.renderer.nextSibling(l),void 0)}function dl(n){Ne(n,3,null,null,void 0)}function hl(n,t,e){t>=n.length?n.push(e):n.splice(t,0,e)}function pl(n,t){t>=n.length-1?n.pop():n.splice(t,1)}var fl=new Object;function _l(n,t,e,l,r,i){return new ml(n,t,e,l,r,i)}var ml=function(n){function t(t,e,l,r,i,o){var s=n.call(this)||this;return s.selector=t,s.componentType=e,s._inputs=r,s._outputs=i,s.ngContentSelectors=o,s.viewDefFactory=l,s}return Object(l.__extends)(t,n),Object.defineProperty(t.prototype,"inputs",{get:function(){var n=[],t=this._inputs;for(var e in t)n.push({propName:e,templateName:t[e]});return n},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"outputs",{get:function(){var n=[];for(var t in this._outputs)n.push({propName:t,templateName:this._outputs[t]});return n},enumerable:!0,configurable:!0}),t.prototype.create=function(n,t,e,l){if(!l)throw new Error("ngModule should be provided");var r=He(this.viewDefFactory),i=r.nodes[0].element.componentProvider.nodeIndex,o=ce.createRootView(n,t||[],e,r,l,fl),s=se(o,i).instance;return e&&o.renderer.setAttribute(oe(o,0).renderElement,"ng-version",w.full),new gl(o,new wl(o),s)},t}(xn),gl=function(n){function t(t,e,l){var r=n.call(this)||this;return r._view=t,r._viewRef=e,r._component=l,r._elDef=r._view.def.nodes[0],r.hostView=e,r.changeDetectorRef=e,r.instance=l,r}return Object(l.__extends)(t,n),Object.defineProperty(t.prototype,"location",{get:function(){return new dt(oe(this._view,this._elDef.nodeIndex).renderElement)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"injector",{get:function(){return new Cl(this._view,this._elDef)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"componentType",{get:function(){return this._component.constructor},enumerable:!0,configurable:!0}),t.prototype.destroy=function(){this._viewRef.destroy()},t.prototype.onDestroy=function(n){this._viewRef.onDestroy(n)},t}(function(){});function yl(n,t,e){return new bl(n,t,e)}var bl=function(){function n(n,t,e){this._view=n,this._elDef=t,this._data=e,this._embeddedViews=[]}return Object.defineProperty(n.prototype,"element",{get:function(){return new dt(this._data.renderElement)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"injector",{get:function(){return new Cl(this._view,this._elDef)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"parentInjector",{get:function(){for(var n=this._view,t=this._elDef.parent;!t&&n;)t=Le(n),n=n.parent;return n?new Cl(n,t):new Cl(this._view,null)},enumerable:!0,configurable:!0}),n.prototype.clear=function(){for(var n=this._embeddedViews.length-1;n>=0;n--){var t=ul(this._data,n);ce.destroyView(t)}},n.prototype.get=function(n){var t=this._embeddedViews[n];if(t){var e=new wl(t);return e.attachToViewContainerRef(this),e}return null},Object.defineProperty(n.prototype,"length",{get:function(){return this._embeddedViews.length},enumerable:!0,configurable:!0}),n.prototype.createEmbeddedView=function(n,t,e){var l=n.createEmbeddedView(t||{});return this.insert(l,e),l},n.prototype.createComponent=function(n,t,e,l,r){var i=e||this.parentInjector;r||n instanceof Pn||(r=i.get(Dn));var o=n.create(i,l,void 0,r);return this.insert(o.hostView,t),o},n.prototype.insert=function(n,t){if(n.destroyed)throw new Error("Cannot insert a destroyed View in a ViewContainer!");var e,l,r,i,o=n;return r=o._view,i=(e=this._data).viewContainer._embeddedViews,null!==(l=t)&&void 0!==l||(l=i.length),r.viewContainerParent=this._view,hl(i,l,r),function(n,t){var e=Te(t);if(e&&e!==n&&!(16&t.state)){t.state|=16;var l=e.template._projectedViews;l||(l=e.template._projectedViews=[]),l.push(t),function(n,e){if(!(4&e.flags)){t.parent.def.nodeFlags|=4,e.flags|=4;for(var l=e.parent;l;)l.childFlags|=4,l=l.parent}}(0,t.parentNodeDef)}}(e,r),ce.dirtyParentQueries(r),cl(e,l>0?i[l-1]:null,r),o.attachToViewContainerRef(this),n},n.prototype.move=function(n,t){if(n.destroyed)throw new Error("Cannot move a destroyed View in a ViewContainer!");var e,l,r,i,o,s=this._embeddedViews.indexOf(n._view);return r=t,o=(i=(e=this._data).viewContainer._embeddedViews)[l=s],pl(i,l),null==r&&(r=i.length),hl(i,r,o),ce.dirtyParentQueries(o),dl(o),cl(e,r>0?i[r-1]:null,o),n},n.prototype.indexOf=function(n){return this._embeddedViews.indexOf(n._view)},n.prototype.remove=function(n){var t=ul(this._data,n);t&&ce.destroyView(t)},n.prototype.detach=function(n){var t=ul(this._data,n);return t?new wl(t):null},n}();function vl(n){return new wl(n)}var wl=function(){function n(n){this._view=n,this._viewContainerRef=null,this._appRef=null}return Object.defineProperty(n.prototype,"rootNodes",{get:function(){return Ne(this._view,0,void 0,void 0,n=[]),n;var n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"context",{get:function(){return this._view.context},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"destroyed",{get:function(){return 0!=(128&this._view.state)},enumerable:!0,configurable:!0}),n.prototype.markForCheck=function(){Ce(this._view)},n.prototype.detach=function(){this._view.state&=-5},n.prototype.detectChanges=function(){var n=this._view.root.rendererFactory;n.begin&&n.begin();try{ce.checkAndUpdateView(this._view)}finally{n.end&&n.end()}},n.prototype.checkNoChanges=function(){ce.checkNoChangesView(this._view)},n.prototype.reattach=function(){this._view.state|=4},n.prototype.onDestroy=function(n){this._view.disposables||(this._view.disposables=[]),this._view.disposables.push(n)},n.prototype.destroy=function(){this._appRef?this._appRef.detachView(this):this._viewContainerRef&&this._viewContainerRef.detach(this._viewContainerRef.indexOf(this)),ce.destroyView(this._view)},n.prototype.detachFromAppRef=function(){this._appRef=null,dl(this._view),ce.dirtyParentQueries(this._view)},n.prototype.attachToAppRef=function(n){if(this._viewContainerRef)throw new Error("This view is already attached to a ViewContainer!");this._appRef=n},n.prototype.attachToViewContainerRef=function(n){if(this._appRef)throw new Error("This view is already attached directly to the ApplicationRef!");this._viewContainerRef=n},n}();function xl(n,t){return new Ml(n,t)}var Ml=function(n){function t(t,e){var l=n.call(this)||this;return l._parentView=t,l._def=e,l}return Object(l.__extends)(t,n),t.prototype.createEmbeddedView=function(n){return new wl(ce.createEmbeddedView(this._parentView,this._def,this._def.element.template,n))},Object.defineProperty(t.prototype,"elementRef",{get:function(){return new dt(oe(this._parentView,this._def.nodeIndex).renderElement)},enumerable:!0,configurable:!0}),t}(yt);function kl(n,t){return new Cl(n,t)}var Cl=function(){function n(n,t){this.view=n,this.elDef=t}return n.prototype.get=function(n,t){return void 0===t&&(t=F.THROW_IF_NOT_FOUND),ce.resolveDep(this.view,this.elDef,!!this.elDef&&0!=(33554432&this.elDef.flags),{flags:0,token:n,tokenKey:me(n)},t)},n}();function Sl(n,t){var e=n.def.nodes[t];if(1&e.flags){var l=oe(n,e.nodeIndex);return e.element.template?l.template:l.renderElement}if(2&e.flags)return ie(n,e.nodeIndex).renderText;if(20240&e.flags)return se(n,e.nodeIndex).instance;throw new Error("Illegal state: read nodeValue for node index "+t)}function Ol(n){return new Tl(n.renderer)}var Tl=function(){function n(n){this.delegate=n}return n.prototype.selectRootElement=function(n){return this.delegate.selectRootElement(n)},n.prototype.createElement=function(n,t){var e=Ue(t),l=this.delegate.createElement(e[1],e[0]);return n&&this.delegate.appendChild(n,l),l},n.prototype.createViewRoot=function(n){return n},n.prototype.createTemplateAnchor=function(n){var t=this.delegate.createComment("");return n&&this.delegate.appendChild(n,t),t},n.prototype.createText=function(n,t){var e=this.delegate.createText(t);return n&&this.delegate.appendChild(n,e),e},n.prototype.projectNodes=function(n,t){for(var e=0;e0,t.provider.value,t.provider.deps);if(t.outputs.length)for(var l=0;l0,l=t.provider;switch(201347067&t.flags){case 512:return ql(n,t.parent,e,l.value,l.deps);case 1024:return function(n,t,e,l,r){var i=r.length;switch(i){case 0:return l();case 1:return l(Ql(n,t,e,r[0]));case 2:return l(Ql(n,t,e,r[0]),Ql(n,t,e,r[1]));case 3:return l(Ql(n,t,e,r[0]),Ql(n,t,e,r[1]),Ql(n,t,e,r[2]));default:for(var o=Array(i),s=0;s0)u=_,mr(_)||(c=_);else for(;u&&f===u.nodeIndex+u.childCount;){var y=u.parent;y&&(y.childFlags|=u.childFlags,y.childMatchedQueries|=u.childMatchedQueries),c=(u=y)&&mr(u)?u.renderParent:u}}return{factory:null,nodeFlags:o,rootNodeFlags:s,nodeMatchedQueries:a,flags:n,nodes:t,updateDirectives:e||fe,updateRenderer:l||fe,handleEvent:function(n,e,l,r){return t[e].element.handleEvent(n,l,r)},bindingCount:r,outputCount:i,lastRenderRootNode:p}}function mr(n){return 0!=(1&n.flags)&&null===n.element.name}function gr(n,t,e){var l=t.element&&t.element.template;if(l){if(!l.lastRenderRootNode)throw new Error("Illegal State: Embedded templates without nodes are not allowed!");if(l.lastRenderRootNode&&16777216&l.lastRenderRootNode.flags)throw new Error("Illegal State: Last root node of a template can't have embedded views, at index "+t.nodeIndex+"!")}if(20224&t.flags&&0==(1&(n?n.flags:0)))throw new Error("Illegal State: StaticProvider/Directive nodes need to be children of elements or anchors, at index "+t.nodeIndex+"!");if(t.query){if(67108864&t.flags&&(!n||0==(16384&n.flags)))throw new Error("Illegal State: Content Query nodes need to be children of directives, at index "+t.nodeIndex+"!");if(134217728&t.flags&&n)throw new Error("Illegal State: View Query nodes have to be top level nodes, at index "+t.nodeIndex+"!")}if(t.childCount){var r=n?n.nodeIndex+n.childCount:e-1;if(t.nodeIndex<=r&&t.nodeIndex+t.childCount>r)throw new Error("Illegal State: childCount of node leads outside of parent, at index "+t.nodeIndex+"!")}}function yr(n,t,e,l){var r=wr(n.root,n.renderer,n,t,e);return xr(r,n.component,l),Mr(r),r}function br(n,t,e){var l=wr(n,n.renderer,null,null,t);return xr(l,e,e),Mr(l),l}function vr(n,t,e,l){var r,i=t.element.componentRendererType;return r=i?n.root.rendererFactory.createRenderer(l,i):n.root.renderer,wr(n.root,r,n,t.element.componentProvider,e)}function wr(n,t,e,l,r){var i=new Array(r.nodes.length),o=r.outputCount?new Array(r.outputCount):null;return{def:r,parent:e,viewContainerParent:null,parentNodeDef:l,context:null,component:null,nodes:i,state:13,root:n,renderer:t,oldValues:new Array(r.bindingCount),disposables:o,initIndex:-1}}function xr(n,t,e){n.component=t,n.context=e}function Mr(n){var t;De(n)&&(t=oe(n.parent,n.parentNodeDef.parent.nodeIndex).renderElement);for(var e=n.def,l=n.nodes,r=0;r0&&tl(n,t,0,e)&&(p=!0),h>1&&tl(n,t,1,l)&&(p=!0),h>2&&tl(n,t,2,r)&&(p=!0),h>3&&tl(n,t,3,i)&&(p=!0),h>4&&tl(n,t,4,o)&&(p=!0),h>5&&tl(n,t,5,s)&&(p=!0),h>6&&tl(n,t,6,a)&&(p=!0),h>7&&tl(n,t,7,u)&&(p=!0),h>8&&tl(n,t,8,c)&&(p=!0),h>9&&tl(n,t,9,d)&&(p=!0),p}(n,t,e,l,r,i,o,s,a,u,c,d);case 2:return function(n,t,e,l,r,i,o,s,a,u,c,d){var h=!1,p=t.bindings,f=p.length;if(f>0&&Me(n,t,0,e)&&(h=!0),f>1&&Me(n,t,1,l)&&(h=!0),f>2&&Me(n,t,2,r)&&(h=!0),f>3&&Me(n,t,3,i)&&(h=!0),f>4&&Me(n,t,4,o)&&(h=!0),f>5&&Me(n,t,5,s)&&(h=!0),f>6&&Me(n,t,6,a)&&(h=!0),f>7&&Me(n,t,7,u)&&(h=!0),f>8&&Me(n,t,8,c)&&(h=!0),f>9&&Me(n,t,9,d)&&(h=!0),h){var _=t.text.prefix;f>0&&(_+=fr(e,p[0])),f>1&&(_+=fr(l,p[1])),f>2&&(_+=fr(r,p[2])),f>3&&(_+=fr(i,p[3])),f>4&&(_+=fr(o,p[4])),f>5&&(_+=fr(s,p[5])),f>6&&(_+=fr(a,p[6])),f>7&&(_+=fr(u,p[7])),f>8&&(_+=fr(c,p[8])),f>9&&(_+=fr(d,p[9]));var m=ie(n,t.nodeIndex).renderText;n.renderer.setValue(m,_)}return h}(n,t,e,l,r,i,o,s,a,u,c,d);case 16384:return function(n,t,e,l,r,i,o,s,a,u,c,d){var h=se(n,t.nodeIndex),p=h.instance,f=!1,_=void 0,m=t.bindings.length;return m>0&&xe(n,t,0,e)&&(f=!0,_=Xl(n,h,t,0,e,_)),m>1&&xe(n,t,1,l)&&(f=!0,_=Xl(n,h,t,1,l,_)),m>2&&xe(n,t,2,r)&&(f=!0,_=Xl(n,h,t,2,r,_)),m>3&&xe(n,t,3,i)&&(f=!0,_=Xl(n,h,t,3,i,_)),m>4&&xe(n,t,4,o)&&(f=!0,_=Xl(n,h,t,4,o,_)),m>5&&xe(n,t,5,s)&&(f=!0,_=Xl(n,h,t,5,s,_)),m>6&&xe(n,t,6,a)&&(f=!0,_=Xl(n,h,t,6,a,_)),m>7&&xe(n,t,7,u)&&(f=!0,_=Xl(n,h,t,7,u,_)),m>8&&xe(n,t,8,c)&&(f=!0,_=Xl(n,h,t,8,c,_)),m>9&&xe(n,t,9,d)&&(f=!0,_=Xl(n,h,t,9,d,_)),_&&p.ngOnChanges(_),65536&t.flags&&re(n,256,t.nodeIndex)&&p.ngOnInit(),262144&t.flags&&p.ngDoCheck(),f}(n,t,e,l,r,i,o,s,a,u,c,d);case 32:case 64:case 128:return function(n,t,e,l,r,i,o,s,a,u,c,d){var h=t.bindings,p=!1,f=h.length;if(f>0&&Me(n,t,0,e)&&(p=!0),f>1&&Me(n,t,1,l)&&(p=!0),f>2&&Me(n,t,2,r)&&(p=!0),f>3&&Me(n,t,3,i)&&(p=!0),f>4&&Me(n,t,4,o)&&(p=!0),f>5&&Me(n,t,5,s)&&(p=!0),f>6&&Me(n,t,6,a)&&(p=!0),f>7&&Me(n,t,7,u)&&(p=!0),f>8&&Me(n,t,8,c)&&(p=!0),f>9&&Me(n,t,9,d)&&(p=!0),p){var _=ae(n,t.nodeIndex),m=void 0;switch(201347067&t.flags){case 32:m=new Array(h.length),f>0&&(m[0]=e),f>1&&(m[1]=l),f>2&&(m[2]=r),f>3&&(m[3]=i),f>4&&(m[4]=o),f>5&&(m[5]=s),f>6&&(m[6]=a),f>7&&(m[7]=u),f>8&&(m[8]=c),f>9&&(m[9]=d);break;case 64:m={},f>0&&(m[h[0].name]=e),f>1&&(m[h[1].name]=l),f>2&&(m[h[2].name]=r),f>3&&(m[h[3].name]=i),f>4&&(m[h[4].name]=o),f>5&&(m[h[5].name]=s),f>6&&(m[h[6].name]=a),f>7&&(m[h[7].name]=u),f>8&&(m[h[8].name]=c),f>9&&(m[h[9].name]=d);break;case 128:var g=e;switch(f){case 1:m=g.transform(e);break;case 2:m=g.transform(l);break;case 3:m=g.transform(l,r);break;case 4:m=g.transform(l,r,i);break;case 5:m=g.transform(l,r,i,o);break;case 6:m=g.transform(l,r,i,o,s);break;case 7:m=g.transform(l,r,i,o,s,a);break;case 8:m=g.transform(l,r,i,o,s,a,u);break;case 9:m=g.transform(l,r,i,o,s,a,u,c);break;case 10:m=g.transform(l,r,i,o,s,a,u,c,d)}}_.value=m}return p}(n,t,e,l,r,i,o,s,a,u,c,d);default:throw"unreachable"}}(n,t,l,r,i,o,s,a,u,c,d,h):function(n,t,e){switch(201347067&t.flags){case 1:return function(n,t,e){for(var l=!1,r=0;r0&&ke(n,t,0,e),h>1&&ke(n,t,1,l),h>2&&ke(n,t,2,r),h>3&&ke(n,t,3,i),h>4&&ke(n,t,4,o),h>5&&ke(n,t,5,s),h>6&&ke(n,t,6,a),h>7&&ke(n,t,7,u),h>8&&ke(n,t,8,c),h>9&&ke(n,t,9,d)}(n,t,l,r,i,o,s,a,u,c,d,h):function(n,t,e){for(var l=0;l=0;s--)(r=n[s])&&(o=(i<3?r(o):i>3?r(t,e,o):r(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o},f=function(){},_=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return h(t,n),t.prototype.getTranslation=function(n){return Object(r.a)({})},t}(f);_=p([Object(l.q)()],_);var m=function(n){return n&&"function"==typeof n.schedule},g="undefined"!=typeof window?window:"undefined"!=typeof n?n:"undefined"!=typeof self?self:{};function y(n,t){return n(t={exports:{}},t.exports),t.exports}var b="undefined"!=typeof window&&window,v="undefined"!=typeof self&&"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&self,w=b||"undefined"!=typeof g&&g||v,x=w;!function(){if(!w)throw new Error("RxJS could not find any global context (window, self, global)")}();var M,k={root:x},C={isFunction:function(n){return"function"==typeof n}},S={isArray:Array.isArray||function(n){return n&&"number"==typeof n.length}},O=function(n){return null!=n&&"object"==typeof n},T={errorObject:{e:{}}};function L(){try{return M.apply(this,arguments)}catch(n){return T.errorObject.e=n,T.errorObject}}var P=function(n){return M=n,L},D=g&&g.__extends||function(n,t){for(var e in t)t.hasOwnProperty(e)&&(n[e]=t[e]);function l(){this.constructor=n}n.prototype=null===t?Object.create(t):(l.prototype=t.prototype,new l)},A={UnsubscriptionError:function(n){function t(t){n.call(this),this.errors=t;var e=Error.call(this,t?t.length+" errors occurred during unsubscription:\n "+t.map(function(n,t){return t+1+") "+n.toString()}).join("\n "):"");this.name=e.name="UnsubscriptionError",this.stack=e.stack,this.message=e.message}return D(t,n),t}(Error)};function E(n){return n.reduce(function(n,t){return n.concat(t instanceof A.UnsubscriptionError?t.errors:t)},[])}var Y={Subscription:function(){function n(n){this.closed=!1,this._parent=null,this._parents=null,this._subscriptions=null,n&&(this._unsubscribe=n)}var t;return n.prototype.unsubscribe=function(){var n,t=!1;if(!this.closed){var e=this._parent,l=this._parents,r=this._unsubscribe,i=this._subscriptions;this.closed=!0,this._parent=null,this._parents=null,this._subscriptions=null;for(var o=-1,s=l?l.length:0;e;)e.remove(this),e=++o1?new t(n,l):1===r?new J.ScalarObservable(n[0],l):new K.EmptyObservable(l)},t.dispatch=function(n){var t=n.array,e=n.index,l=n.subscriber;e>=n.count?l.complete():(l.next(t[e]),l.closed||(n.index=e+1,this.schedule(n)))},t.prototype._subscribe=function(n){var e=this.array,l=e.length,r=this.scheduler;if(r)return r.schedule(t.dispatch,0,{array:e,index:0,count:l,subscriber:n});for(var i=0;idn?dn:r:r}()),this.arr=n,this.idx=t,this.len=e}return n.prototype[on.iterator]=function(){return this},n.prototype.next=function(){return this.idx=n.length?l.complete():(l.next(t[e]),n.index=e+1,this.schedule(n)))},t.prototype._subscribe=function(n){var e=this.arrayLike,l=this.scheduler,r=e.length;if(l)return l.schedule(t.dispatch,0,{arrayLike:e,index:0,length:r,subscriber:n});for(var i=0;i0?this._next(t.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()},t}(On.OuterSubscriber),Dn=function(n){return n},An=function(n){return void 0===n&&(n=Number.POSITIVE_INFINITY),function(n,t,e){return void 0===e&&(e=Number.POSITIVE_INFINITY),function(l){return"number"==typeof t&&(e=t,t=null),l.lift(new Ln(n,t,e))}}(Dn,null,n)},En={concat:function(){for(var n=[],t=0;t=0;s--)(r=n[s])&&(o=(i<3?r(o):i>3?r(t,e,o):r(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o},jn=function(){},In=function(){function n(){}return n.prototype.handle=function(n){return n.key},n}();In=Yn([Object(l.q)()],In);var Rn=this&&this.__decorate||function(n,t,e,l){var r,i=arguments.length,o=i<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,e):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(n,t,e,l);else for(var s=n.length-1;s>=0;s--)(r=n[s])&&(o=(i<3?r(o):i>3?r(t,e,o):r(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o},Hn=function(){},Nn=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return h(t,n),t.prototype.compile=function(n,t){return n},t.prototype.compileTranslations=function(n,t){return n},t}(Hn);function Fn(n,t){if(n===t)return!0;if(null===n||null===t)return!1;if(n!=n&&t!=t)return!0;var e,l,r,i=typeof n;if(i==typeof t&&"object"==i){if(!Array.isArray(n)){if(Array.isArray(t))return!1;for(l in r=Object.create(null),n){if(!Fn(n[l],t[l]))return!1;r[l]=!0}for(l in t)if(!(l in r)&&"undefined"!=typeof t[l])return!1;return!0}if(!Array.isArray(t))return!1;if((e=n.length)==t.length){for(l=0;l=0;s--)(r=n[s])&&(o=(i<3?r(o):i>3?r(t,e,o):r(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o},zn=function(){},Un=function(n){function t(){var t=n.apply(this,arguments)||this;return t.templateMatcher=/{{\s?([^{}\s]*)\s?}}/g,t}return h(t,n),t.prototype.interpolate=function(n,t){return"string"==typeof n?this.interpolateString(n,t):"function"==typeof n?this.interpolateFunction(n,t):n},t.prototype.getValue=function(n,t){var e=t.split(".");t="";do{t+=e.shift(),!Bn(n)||!Bn(n[t])||"object"!=typeof n[t]&&e.length?e.length?t+=".":n=void 0:(n=n[t],t="")}while(e.length);return n},t.prototype.interpolateFunction=function(n,t){return n(t)},t.prototype.interpolateString=function(n,t){var e=this;return t?n.replace(this.templateMatcher,function(n,l){var r=e.getValue(t,l);return Bn(r)?r:n}):n},t}(zn);Un=Wn([Object(l.q)()],Un);var Gn=function(){return function(){this.currentLang=this.defaultLang,this.translations={},this.langs=[],this.onTranslationChange=new l.o,this.onLangChange=new l.o,this.onDefaultLangChange=new l.o}}(),qn=this&&this.__decorate||function(n,t,e,l){var r,i=arguments.length,o=i<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,e):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(n,t,e,l);else for(var s=n.length-1;s>=0;s--)(r=n[s])&&(o=(i<3?r(o):i>3?r(t,e,o):r(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o},Jn=e("TToO").__metadata,Qn=e("TToO").__param,Kn=new l.r("USE_STORE"),Xn=new l.r("USE_DEFAULT_LANG"),Zn=function(){function n(n,t,e,r,i,o,s){void 0===o&&(o=!0),void 0===s&&(s=!1),this.store=n,this.currentLoader=t,this.compiler=e,this.parser=r,this.missingTranslationHandler=i,this.useDefaultLang=o,this.isolate=s,this.pending=!1,this._onTranslationChange=new l.o,this._onLangChange=new l.o,this._onDefaultLangChange=new l.o,this._langs=[],this._translations={},this._translationRequests={}}return Object.defineProperty(n.prototype,"onTranslationChange",{get:function(){return this.isolate?this._onTranslationChange:this.store.onTranslationChange},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"onLangChange",{get:function(){return this.isolate?this._onLangChange:this.store.onLangChange},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"onDefaultLangChange",{get:function(){return this.isolate?this._onDefaultLangChange:this.store.onDefaultLangChange},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"defaultLang",{get:function(){return this.isolate?this._defaultLang:this.store.defaultLang},set:function(n){this.isolate?this._defaultLang=n:this.store.defaultLang=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"currentLang",{get:function(){return this.isolate?this._currentLang:this.store.currentLang},set:function(n){this.isolate?this._currentLang=n:this.store.currentLang=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"langs",{get:function(){return this.isolate?this._langs:this.store.langs},set:function(n){this.isolate?this._langs=n:this.store.langs=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"translations",{get:function(){return this.isolate?this._translations:this.store.translations},set:function(n){this.isolate?this._translations=n:this.store.translations=n},enumerable:!0,configurable:!0}),n.prototype.setDefaultLang=function(n){var t=this;if(n!==this.defaultLang){var e=this.retrieveTranslations(n);"undefined"!=typeof e?(this.defaultLang||(this.defaultLang=n),e.pipe(Object(d.a)(1)).subscribe(function(e){t.changeDefaultLang(n)})):this.changeDefaultLang(n)}},n.prototype.getDefaultLang=function(){return this.defaultLang},n.prototype.use=function(n){var t=this;if(n===this.currentLang)return Object(r.a)(this.translations[n]);var e=this.retrieveTranslations(n);return"undefined"!=typeof e?(this.currentLang||(this.currentLang=n),e.pipe(Object(d.a)(1)).subscribe(function(e){t.changeLang(n)}),e):(this.changeLang(n),Object(r.a)(this.translations[n]))},n.prototype.retrieveTranslations=function(n){var t;return"undefined"==typeof this.translations[n]&&(this._translationRequests[n]=this._translationRequests[n]||this.getTranslation(n),t=this._translationRequests[n]),t},n.prototype.getTranslation=function(n){var t=this;return this.pending=!0,this.loadingTranslations=this.currentLoader.getTranslation(n).pipe(Object(o.a)()),this.loadingTranslations.pipe(Object(d.a)(1)).subscribe(function(e){t.translations[n]=t.compiler.compileTranslations(e,n),t.updateLangs(),t.pending=!1},function(n){t.pending=!1}),this.loadingTranslations},n.prototype.setTranslation=function(n,t,e){void 0===e&&(e=!1),t=this.compiler.compileTranslations(t,n),this.translations[n]=e&&this.translations[n]?function n(t,e){var l=Object.assign({},t);return Vn(t)&&Vn(e)&&Object.keys(e).forEach(function(r){var i,o;Vn(e[r])?r in t?l[r]=n(t[r],e[r]):Object.assign(l,((i={})[r]=e[r],i)):Object.assign(l,((o={})[r]=e[r],o))}),l}(this.translations[n],t):t,this.updateLangs(),this.onTranslationChange.emit({lang:n,translations:this.translations[n]})},n.prototype.getLangs=function(){return this.langs},n.prototype.addLangs=function(n){var t=this;n.forEach(function(n){-1===t.langs.indexOf(n)&&t.langs.push(n)})},n.prototype.updateLangs=function(){this.addLangs(Object.keys(this.translations))},n.prototype.getParsedResult=function(n,t,e){var l;if(t instanceof Array){for(var i={},o=!1,u=0,d=t;u=0;s--)(r=n[s])&&(o=(i<3?r(o):i>3?r(t,e,o):r(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o},nt=this&&this.__metadata||function(n,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(n,t)},tt=function(){function n(n,t,e){var l=this;this.translateService=n,this.element=t,this._ref=e,this.onTranslationChangeSub||(this.onTranslationChangeSub=this.translateService.onTranslationChange.subscribe(function(n){n.lang===l.translateService.currentLang&&l.checkNodes(!0,n.translations)})),this.onLangChangeSub||(this.onLangChangeSub=this.translateService.onLangChange.subscribe(function(n){l.checkNodes(!0,n.translations)})),this.onDefaultLangChangeSub||(this.onDefaultLangChangeSub=this.translateService.onDefaultLangChange.subscribe(function(n){l.checkNodes(!0)}))}return Object.defineProperty(n.prototype,"translate",{set:function(n){n&&(this.key=n,this.checkNodes())},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"translateParams",{set:function(n){Fn(this.currentParams,n)||(this.currentParams=n,this.checkNodes(!0))},enumerable:!0,configurable:!0}),n.prototype.ngAfterViewChecked=function(){this.checkNodes()},n.prototype.checkNodes=function(n,t){void 0===n&&(n=!1);var e=this.element.nativeElement.childNodes;e.length||(this.setContent(this.element.nativeElement,this.key),e=this.element.nativeElement.childNodes);for(var l=0;l=0;s--)(r=n[s])&&(o=(i<3?r(o):i>3?r(t,e,o):r(t,e))||o);return i>3&&o&&Object.defineProperty(t,e,o),o},lt=this&&this.__metadata||function(n,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(n,t)},rt=function(){function n(n,t){this.translate=n,this._ref=t,this.value=""}return n.prototype.updateValue=function(n,t,e){var l=this,r=function(t){l.value=void 0!==t?t:n,l.lastKey=n,l._ref.markForCheck()};if(e){var i=this.translate.getParsedResult(e,n,t);"function"==typeof i.subscribe?i.subscribe(r):r(i)}this.translate.get(n,t).subscribe(r)},n.prototype.transform=function(n){for(var t,e=this,l=[],r=1;r20?t=40===n||50===n||60===n||80===n||100===n?"fed":"ain":n>0&&(t=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"][n]),n+t},week:{dow:1,doy:4}})}(e("PJh5"))},ZUyn:function(n,t,e){!function(n){"use strict";n.defineLocale("zh-hk",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u51cc\u6668"===t||"\u65e9\u4e0a"===t||"\u4e0a\u5348"===t?n:"\u4e2d\u5348"===t?n>=11?n:n+12:"\u4e0b\u5348"===t||"\u665a\u4e0a"===t?n+12:void 0},meridiem:function(n,t,e){var l=100*n+t;return l<600?"\u51cc\u6668":l<900?"\u65e9\u4e0a":l<1130?"\u4e0a\u5348":l<1230?"\u4e2d\u5348":l<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(n,t){switch(t){case"d":case"D":case"DDD":return n+"\u65e5";case"M":return n+"\u6708";case"w":case"W":return n+"\u9031";default:return n}},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}})}(e("PJh5"))},ZoSI:function(n,t,e){!function(n){"use strict";n.defineLocale("pt",{months:"janeiro_fevereiro_mar\xe7o_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\xe7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\xe1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\xe1b".split("_"),weekdaysMin:"Do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"h\xe1 %s",s:"segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(e("PJh5"))},aM0x:function(n,t,e){!function(n){"use strict";var t={1:"\u09e7",2:"\u09e8",3:"\u09e9",4:"\u09ea",5:"\u09eb",6:"\u09ec",7:"\u09ed",8:"\u09ee",9:"\u09ef",0:"\u09e6"},e={"\u09e7":"1","\u09e8":"2","\u09e9":"3","\u09ea":"4","\u09eb":"5","\u09ec":"6","\u09ed":"7","\u09ee":"8","\u09ef":"9","\u09e6":"0"};n.defineLocale("bn",{months:"\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09c0_\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09bf_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0\u09bf\u09b2_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2\u09be\u0987_\u0986\u0997\u09b8\u09cd\u099f_\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0_\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0_\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0_\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0".split("_"),monthsShort:"\u099c\u09be\u09a8\u09c1_\u09ab\u09c7\u09ac_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2_\u0986\u0997_\u09b8\u09c7\u09aa\u09cd\u099f_\u0985\u0995\u09cd\u099f\u09cb_\u09a8\u09ad\u09c7_\u09a1\u09bf\u09b8\u09c7".split("_"),weekdays:"\u09b0\u09ac\u09bf\u09ac\u09be\u09b0_\u09b8\u09cb\u09ae\u09ac\u09be\u09b0_\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0_\u09ac\u09c1\u09a7\u09ac\u09be\u09b0_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0_\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0_\u09b6\u09a8\u09bf\u09ac\u09be\u09b0".split("_"),weekdaysShort:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997\u09b2_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),weekdaysMin:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9\u0983_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),longDateFormat:{LT:"A h:mm \u09b8\u09ae\u09df",LTS:"A h:mm:ss \u09b8\u09ae\u09df",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u09b8\u09ae\u09df",LLLL:"dddd, D MMMM YYYY, A h:mm \u09b8\u09ae\u09df"},calendar:{sameDay:"[\u0986\u099c] LT",nextDay:"[\u0986\u0997\u09be\u09ae\u09c0\u0995\u09be\u09b2] LT",nextWeek:"dddd, LT",lastDay:"[\u0997\u09a4\u0995\u09be\u09b2] LT",lastWeek:"[\u0997\u09a4] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u09aa\u09b0\u09c7",past:"%s \u0986\u0997\u09c7",s:"\u0995\u09df\u09c7\u0995 \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",ss:"%d \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",m:"\u098f\u0995 \u09ae\u09bf\u09a8\u09bf\u099f",mm:"%d \u09ae\u09bf\u09a8\u09bf\u099f",h:"\u098f\u0995 \u0998\u09a8\u09cd\u099f\u09be",hh:"%d \u0998\u09a8\u09cd\u099f\u09be",d:"\u098f\u0995 \u09a6\u09bf\u09a8",dd:"%d \u09a6\u09bf\u09a8",M:"\u098f\u0995 \u09ae\u09be\u09b8",MM:"%d \u09ae\u09be\u09b8",y:"\u098f\u0995 \u09ac\u099b\u09b0",yy:"%d \u09ac\u099b\u09b0"},preparse:function(n){return n.replace(/[\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09e6]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u09b0\u09be\u09a4|\u09b8\u0995\u09be\u09b2|\u09a6\u09c1\u09aa\u09c1\u09b0|\u09ac\u09bf\u0995\u09be\u09b2|\u09b0\u09be\u09a4/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u09b0\u09be\u09a4"===t&&n>=4||"\u09a6\u09c1\u09aa\u09c1\u09b0"===t&&n<5||"\u09ac\u09bf\u0995\u09be\u09b2"===t?n+12:n},meridiem:function(n,t,e){return n<4?"\u09b0\u09be\u09a4":n<10?"\u09b8\u0995\u09be\u09b2":n<17?"\u09a6\u09c1\u09aa\u09c1\u09b0":n<20?"\u09ac\u09bf\u0995\u09be\u09b2":"\u09b0\u09be\u09a4"},week:{dow:0,doy:6}})}(e("PJh5"))},aqvp:function(n,t,e){!function(n){"use strict";function t(n,t,e){var l=n+" ";switch(e){case"ss":return l+(1===n?"sekunda":2===n||3===n||4===n?"sekunde":"sekundi");case"m":return t?"jedna minuta":"jedne minute";case"mm":return l+(1===n?"minuta":2===n||3===n||4===n?"minute":"minuta");case"h":return t?"jedan sat":"jednog sata";case"hh":return l+(1===n?"sat":2===n||3===n||4===n?"sata":"sati");case"dd":return l+(1===n?"dan":"dana");case"MM":return l+(1===n?"mjesec":2===n||3===n||4===n?"mjeseca":"mjeseci");case"yy":return l+(1===n?"godina":2===n||3===n||4===n?"godine":"godina")}}n.defineLocale("bs",{months:"januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010der u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[pro\u0161lu] dddd [u] LT";case 6:return"[pro\u0161le] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[pro\u0161li] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:t,m:t,mm:t,h:t,hh:t,d:"dan",dd:t,M:"mjesec",MM:t,y:"godinu",yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e("PJh5"))},bXQP:function(n,t,e){!function(n){"use strict";n.defineLocale("fr-ca",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(n,t){switch(t){default:case"M":case"Q":case"D":case"DDD":case"d":return n+(1===n?"er":"e");case"w":case"W":return n+(1===n?"re":"e")}}})}(e("PJh5"))},c1x4:function(n,t,e){!function(n){"use strict";var t={words:{ss:["\u0441\u0435\u043a\u0443\u043d\u0434\u0430","\u0441\u0435\u043a\u0443\u043d\u0434\u0435","\u0441\u0435\u043a\u0443\u043d\u0434\u0438"],m:["\u0458\u0435\u0434\u0430\u043d \u043c\u0438\u043d\u0443\u0442","\u0458\u0435\u0434\u043d\u0435 \u043c\u0438\u043d\u0443\u0442\u0435"],mm:["\u043c\u0438\u043d\u0443\u0442","\u043c\u0438\u043d\u0443\u0442\u0435","\u043c\u0438\u043d\u0443\u0442\u0430"],h:["\u0458\u0435\u0434\u0430\u043d \u0441\u0430\u0442","\u0458\u0435\u0434\u043d\u043e\u0433 \u0441\u0430\u0442\u0430"],hh:["\u0441\u0430\u0442","\u0441\u0430\u0442\u0430","\u0441\u0430\u0442\u0438"],dd:["\u0434\u0430\u043d","\u0434\u0430\u043d\u0430","\u0434\u0430\u043d\u0430"],MM:["\u043c\u0435\u0441\u0435\u0446","\u043c\u0435\u0441\u0435\u0446\u0430","\u043c\u0435\u0441\u0435\u0446\u0438"],yy:["\u0433\u043e\u0434\u0438\u043d\u0430","\u0433\u043e\u0434\u0438\u043d\u0435","\u0433\u043e\u0434\u0438\u043d\u0430"]},correctGrammaticalCase:function(n,t){return 1===n?t[0]:n>=2&&n<=4?t[1]:t[2]},translate:function(n,e,l){var r=t.words[l];return 1===l.length?e?r[0]:r[1]:n+" "+t.correctGrammaticalCase(n,r)}};n.defineLocale("sr-cyrl",{months:"\u0458\u0430\u043d\u0443\u0430\u0440_\u0444\u0435\u0431\u0440\u0443\u0430\u0440_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440_\u043e\u043a\u0442\u043e\u0431\u0430\u0440_\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440_\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440".split("_"),monthsShort:"\u0458\u0430\u043d._\u0444\u0435\u0431._\u043c\u0430\u0440._\u0430\u043f\u0440._\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433._\u0441\u0435\u043f._\u043e\u043a\u0442._\u043d\u043e\u0432._\u0434\u0435\u0446.".split("_"),monthsParseExact:!0,weekdays:"\u043d\u0435\u0434\u0435\u0459\u0430_\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a_\u0443\u0442\u043e\u0440\u0430\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a_\u043f\u0435\u0442\u0430\u043a_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434._\u043f\u043e\u043d._\u0443\u0442\u043e._\u0441\u0440\u0435._\u0447\u0435\u0442._\u043f\u0435\u0442._\u0441\u0443\u0431.".split("_"),weekdaysMin:"\u043d\u0435_\u043f\u043e_\u0443\u0442_\u0441\u0440_\u0447\u0435_\u043f\u0435_\u0441\u0443".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[\u0434\u0430\u043d\u0430\u0441 \u0443] LT",nextDay:"[\u0441\u0443\u0442\u0440\u0430 \u0443] LT",nextWeek:function(){switch(this.day()){case 0:return"[\u0443] [\u043d\u0435\u0434\u0435\u0459\u0443] [\u0443] LT";case 3:return"[\u0443] [\u0441\u0440\u0435\u0434\u0443] [\u0443] LT";case 6:return"[\u0443] [\u0441\u0443\u0431\u043e\u0442\u0443] [\u0443] LT";case 1:case 2:case 4:case 5:return"[\u0443] dddd [\u0443] LT"}},lastDay:"[\u0458\u0443\u0447\u0435 \u0443] LT",lastWeek:function(){return["[\u043f\u0440\u043e\u0448\u043b\u0435] [\u043d\u0435\u0434\u0435\u0459\u0435] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u0443\u0442\u043e\u0440\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u0435] [\u0441\u0440\u0435\u0434\u0435] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u0447\u0435\u0442\u0432\u0440\u0442\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u043f\u0435\u0442\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u0435] [\u0441\u0443\u0431\u043e\u0442\u0435] [\u0443] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"\u043f\u0440\u0435 %s",s:"\u043d\u0435\u043a\u043e\u043b\u0438\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:t.translate,m:t.translate,mm:t.translate,h:t.translate,hh:t.translate,d:"\u0434\u0430\u043d",dd:t.translate,M:"\u043c\u0435\u0441\u0435\u0446",MM:t.translate,y:"\u0433\u043e\u0434\u0438\u043d\u0443",yy:t.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e("PJh5"))},cQXm:function(n,t,e){"use strict";t.a=function(n){return n&&"function"!=typeof n.subscribe&&"function"==typeof n.then}},"ce/b":function(n,t,e){"use strict";t.a=function(){for(var n=[],t=0;t=100?100:null])},week:{dow:1,doy:7}})}(e("PJh5"))},etqZ:function(n,t,e){"use strict";e.d(t,"a",function(){return l});var l=function(n){var t=n.Symbol;if("function"==typeof t)return t.iterator||(t.iterator=t("iterator polyfill")),t.iterator;var e=n.Set;if(e&&"function"==typeof(new e)["@@iterator"])return"@@iterator";var l=n.Map;if(l)for(var r=Object.getOwnPropertyNames(l.prototype),i=0;i=2&&n<=4?t[1]:t[2]},translate:function(n,e,l){var r=t.words[l];return 1===l.length?e?r[0]:r[1]:n+" "+t.correctGrammaticalCase(n,r)}};n.defineLocale("sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljak_utorak_sreda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010de u] LT",lastWeek:function(){return["[pro\u0161le] [nedelje] [u] LT","[pro\u0161log] [ponedeljka] [u] LT","[pro\u0161log] [utorka] [u] LT","[pro\u0161le] [srede] [u] LT","[pro\u0161log] [\u010detvrtka] [u] LT","[pro\u0161log] [petka] [u] LT","[pro\u0161le] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",ss:t.translate,m:t.translate,mm:t.translate,h:t.translate,hh:t.translate,d:"dan",dd:t.translate,M:"mesec",MM:t.translate,y:"godinu",yy:t.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e("PJh5"))},f9aG:function(n,t,e){"use strict";t.a=function(){for(var n=[],t=0;t=20?"ste":"de")},week:{dow:1,doy:4}})}(e("PJh5"))},gEQe:function(n,t,e){!function(n){"use strict";var t={1:"\u0ce7",2:"\u0ce8",3:"\u0ce9",4:"\u0cea",5:"\u0ceb",6:"\u0cec",7:"\u0ced",8:"\u0cee",9:"\u0cef",0:"\u0ce6"},e={"\u0ce7":"1","\u0ce8":"2","\u0ce9":"3","\u0cea":"4","\u0ceb":"5","\u0cec":"6","\u0ced":"7","\u0cee":"8","\u0cef":"9","\u0ce6":"0"};n.defineLocale("kn",{months:"\u0c9c\u0ca8\u0cb5\u0cb0\u0cbf_\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cbf_\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd_\u0c8f\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd_\u0cae\u0cc6\u0cd5_\u0c9c\u0cc2\u0ca8\u0ccd_\u0c9c\u0cc1\u0cb2\u0cc6\u0cd6_\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd_\u0cb8\u0cc6\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd_\u0c85\u0c95\u0ccd\u0c9f\u0cc6\u0cc2\u0cd5\u0cac\u0cb0\u0ccd_\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd_\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd".split("_"),monthsShort:"\u0c9c\u0ca8_\u0cab\u0cc6\u0cac\u0ccd\u0cb0_\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd_\u0c8f\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd_\u0cae\u0cc6\u0cd5_\u0c9c\u0cc2\u0ca8\u0ccd_\u0c9c\u0cc1\u0cb2\u0cc6\u0cd6_\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd_\u0cb8\u0cc6\u0caa\u0ccd\u0c9f\u0cc6\u0c82_\u0c85\u0c95\u0ccd\u0c9f\u0cc6\u0cc2\u0cd5_\u0ca8\u0cb5\u0cc6\u0c82_\u0ca1\u0cbf\u0cb8\u0cc6\u0c82".split("_"),monthsParseExact:!0,weekdays:"\u0cad\u0cbe\u0ca8\u0cc1\u0cb5\u0cbe\u0cb0_\u0cb8\u0cc6\u0cc2\u0cd5\u0cae\u0cb5\u0cbe\u0cb0_\u0cae\u0c82\u0c97\u0cb3\u0cb5\u0cbe\u0cb0_\u0cac\u0cc1\u0ca7\u0cb5\u0cbe\u0cb0_\u0c97\u0cc1\u0cb0\u0cc1\u0cb5\u0cbe\u0cb0_\u0cb6\u0cc1\u0c95\u0ccd\u0cb0\u0cb5\u0cbe\u0cb0_\u0cb6\u0ca8\u0cbf\u0cb5\u0cbe\u0cb0".split("_"),weekdaysShort:"\u0cad\u0cbe\u0ca8\u0cc1_\u0cb8\u0cc6\u0cc2\u0cd5\u0cae_\u0cae\u0c82\u0c97\u0cb3_\u0cac\u0cc1\u0ca7_\u0c97\u0cc1\u0cb0\u0cc1_\u0cb6\u0cc1\u0c95\u0ccd\u0cb0_\u0cb6\u0ca8\u0cbf".split("_"),weekdaysMin:"\u0cad\u0cbe_\u0cb8\u0cc6\u0cc2\u0cd5_\u0cae\u0c82_\u0cac\u0cc1_\u0c97\u0cc1_\u0cb6\u0cc1_\u0cb6".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0c87\u0c82\u0ca6\u0cc1] LT",nextDay:"[\u0ca8\u0cbe\u0cb3\u0cc6] LT",nextWeek:"dddd, LT",lastDay:"[\u0ca8\u0cbf\u0ca8\u0ccd\u0ca8\u0cc6] LT",lastWeek:"[\u0c95\u0cc6\u0cc2\u0ca8\u0cc6\u0caf] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0ca8\u0c82\u0ca4\u0cb0",past:"%s \u0cb9\u0cbf\u0c82\u0ca6\u0cc6",s:"\u0c95\u0cc6\u0cb2\u0cb5\u0cc1 \u0c95\u0ccd\u0cb7\u0ca3\u0c97\u0cb3\u0cc1",ss:"%d \u0cb8\u0cc6\u0c95\u0cc6\u0c82\u0ca1\u0cc1\u0c97\u0cb3\u0cc1",m:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca8\u0cbf\u0cae\u0cbf\u0cb7",mm:"%d \u0ca8\u0cbf\u0cae\u0cbf\u0cb7",h:"\u0c92\u0c82\u0ca6\u0cc1 \u0c97\u0c82\u0c9f\u0cc6",hh:"%d \u0c97\u0c82\u0c9f\u0cc6",d:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca6\u0cbf\u0ca8",dd:"%d \u0ca6\u0cbf\u0ca8",M:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca4\u0cbf\u0c82\u0c97\u0cb3\u0cc1",MM:"%d \u0ca4\u0cbf\u0c82\u0c97\u0cb3\u0cc1",y:"\u0c92\u0c82\u0ca6\u0cc1 \u0cb5\u0cb0\u0ccd\u0cb7",yy:"%d \u0cb5\u0cb0\u0ccd\u0cb7"},preparse:function(n){return n.replace(/[\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0ce6]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf|\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6|\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8|\u0cb8\u0c82\u0c9c\u0cc6/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf"===t?n<4?n:n+12:"\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6"===t?n:"\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8"===t?n>=10?n:n+12:"\u0cb8\u0c82\u0c9c\u0cc6"===t?n+12:void 0},meridiem:function(n,t,e){return n<4?"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf":n<10?"\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6":n<17?"\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8":n<20?"\u0cb8\u0c82\u0c9c\u0cc6":"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf"},dayOfMonthOrdinalParse:/\d{1,2}(\u0ca8\u0cc6\u0cd5)/,ordinal:function(n){return n+"\u0ca8\u0cc6\u0cd5"},week:{dow:0,doy:6}})}(e("PJh5"))},gEU3:function(n,t,e){!function(n){"use strict";n.defineLocale("mi",{months:"Kohi-t\u0101te_Hui-tanguru_Pout\u016b-te-rangi_Paenga-wh\u0101wh\u0101_Haratua_Pipiri_H\u014dngoingoi_Here-turi-k\u014dk\u0101_Mahuru_Whiringa-\u0101-nuku_Whiringa-\u0101-rangi_Hakihea".split("_"),monthsShort:"Kohi_Hui_Pou_Pae_Hara_Pipi_H\u014dngoi_Here_Mahu_Whi-nu_Whi-ra_Haki".split("_"),monthsRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,weekdays:"R\u0101tapu_Mane_T\u016brei_Wenerei_T\u0101ite_Paraire_H\u0101tarei".split("_"),weekdaysShort:"Ta_Ma_T\u016b_We_T\u0101i_Pa_H\u0101".split("_"),weekdaysMin:"Ta_Ma_T\u016b_We_T\u0101i_Pa_H\u0101".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [i] HH:mm",LLLL:"dddd, D MMMM YYYY [i] HH:mm"},calendar:{sameDay:"[i teie mahana, i] LT",nextDay:"[apopo i] LT",nextWeek:"dddd [i] LT",lastDay:"[inanahi i] LT",lastWeek:"dddd [whakamutunga i] LT",sameElse:"L"},relativeTime:{future:"i roto i %s",past:"%s i mua",s:"te h\u0113kona ruarua",ss:"%d h\u0113kona",m:"he meneti",mm:"%d meneti",h:"te haora",hh:"%d haora",d:"he ra",dd:"%d ra",M:"he marama",MM:"%d marama",y:"he tau",yy:"%d tau"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(e("PJh5"))},gIN1:function(n,t,e){"use strict";t.a=function(){}},gUgh:function(n,t,e){!function(n){"use strict";n.defineLocale("tet",{months:"Janeiru_Fevereiru_Marsu_Abril_Maiu_Ju\xf1u_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu".split("_"),weekdaysShort:"Dom_Seg_Ters_Kua_Kint_Sest_Sab".split("_"),weekdaysMin:"Do_Seg_Te_Ku_Ki_Ses_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Ohin iha] LT",nextDay:"[Aban iha] LT",nextWeek:"dddd [iha] LT",lastDay:"[Horiseik iha] LT",lastWeek:"dddd [semana kotuk] [iha] LT",sameElse:"L"},relativeTime:{future:"iha %s",past:"%s liuba",s:"minutu balun",ss:"minutu %d",m:"minutu ida",mm:"minutu %d",h:"oras ida",hh:"oras %d",d:"loron ida",dd:"loron %d",M:"fulan ida",MM:"fulan %d",y:"tinan ida",yy:"tinan %d"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(n){var t=n%10;return n+(1==~~(n%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")},week:{dow:1,doy:4}})}(e("PJh5"))},hPuz:function(n,t,e){!function(n){"use strict";n.defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(n){var t=n%10;return n+(1==~~(n%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")},week:{dow:1,doy:4}})}(e("PJh5"))},hng5:function(n,t,e){!function(n){"use strict";n.defineLocale("bm",{months:"Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_M\u025bkalo_Zuw\u025bnkalo_Zuluyekalo_Utikalo_S\u025btanburukalo_\u0254kut\u0254burukalo_Nowanburukalo_Desanburukalo".split("_"),monthsShort:"Zan_Few_Mar_Awi_M\u025b_Zuw_Zul_Uti_S\u025bt_\u0254ku_Now_Des".split("_"),weekdays:"Kari_Nt\u025bn\u025bn_Tarata_Araba_Alamisa_Juma_Sibiri".split("_"),weekdaysShort:"Kar_Nt\u025b_Tar_Ara_Ala_Jum_Sib".split("_"),weekdaysMin:"Ka_Nt_Ta_Ar_Al_Ju_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"MMMM [tile] D [san] YYYY",LLL:"MMMM [tile] D [san] YYYY [l\u025br\u025b] HH:mm",LLLL:"dddd MMMM [tile] D [san] YYYY [l\u025br\u025b] HH:mm"},calendar:{sameDay:"[Bi l\u025br\u025b] LT",nextDay:"[Sini l\u025br\u025b] LT",nextWeek:"dddd [don l\u025br\u025b] LT",lastDay:"[Kunu l\u025br\u025b] LT",lastWeek:"dddd [t\u025bm\u025bnen l\u025br\u025b] LT",sameElse:"L"},relativeTime:{future:"%s k\u0254n\u0254",past:"a b\u025b %s b\u0254",s:"sanga dama dama",ss:"sekondi %d",m:"miniti kelen",mm:"miniti %d",h:"l\u025br\u025b kelen",hh:"l\u025br\u025b %d",d:"tile kelen",dd:"tile %d",M:"kalo kelen",MM:"kalo %d",y:"san kelen",yy:"san %d"},week:{dow:1,doy:4}})}(e("PJh5"))},iNtv:function(n,t,e){!function(n){"use strict";function t(n,t,e,l){var r={s:["viensas secunds","'iensas secunds"],ss:[n+" secunds",n+" secunds"],m:["'n m\xedut","'iens m\xedut"],mm:[n+" m\xeduts",n+" m\xeduts"],h:["'n \xfeora","'iensa \xfeora"],hh:[n+" \xfeoras",n+" \xfeoras"],d:["'n ziua","'iensa ziua"],dd:[n+" ziuas",n+" ziuas"],M:["'n mes","'iens mes"],MM:[n+" mesen",n+" mesen"],y:["'n ar","'iens ar"],yy:[n+" ars",n+" ars"]};return l?r[e][0]:t?r[e][0]:r[e][1]}n.defineLocale("tzl",{months:"Januar_Fevraglh_Mar\xe7_Avr\xefu_Mai_G\xfcn_Julia_Guscht_Setemvar_Listop\xe4ts_Noemvar_Zecemvar".split("_"),monthsShort:"Jan_Fev_Mar_Avr_Mai_G\xfcn_Jul_Gus_Set_Lis_Noe_Zec".split("_"),weekdays:"S\xfaladi_L\xfane\xe7i_Maitzi_M\xe1rcuri_Xh\xfaadi_Vi\xe9ner\xe7i_S\xe1turi".split("_"),weekdaysShort:"S\xfal_L\xfan_Mai_M\xe1r_Xh\xfa_Vi\xe9_S\xe1t".split("_"),weekdaysMin:"S\xfa_L\xfa_Ma_M\xe1_Xh_Vi_S\xe1".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"D. MMMM [dallas] YYYY",LLL:"D. MMMM [dallas] YYYY HH.mm",LLLL:"dddd, [li] D. MMMM [dallas] YYYY HH.mm"},meridiemParse:/d\'o|d\'a/i,isPM:function(n){return"d'o"===n.toLowerCase()},meridiem:function(n,t,e){return n>11?e?"d'o":"D'O":e?"d'a":"D'A"},calendar:{sameDay:"[oxhi \xe0] LT",nextDay:"[dem\xe0 \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[ieiri \xe0] LT",lastWeek:"[s\xfcr el] dddd [lasteu \xe0] LT",sameElse:"L"},relativeTime:{future:"osprei %s",past:"ja%s",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},"j+vx":function(n,t,e){!function(n){"use strict";var t={0:"-\u0448\u0456",1:"-\u0448\u0456",2:"-\u0448\u0456",3:"-\u0448\u0456",4:"-\u0448\u0456",5:"-\u0448\u0456",6:"-\u0448\u044b",7:"-\u0448\u0456",8:"-\u0448\u0456",9:"-\u0448\u044b",10:"-\u0448\u044b",20:"-\u0448\u044b",30:"-\u0448\u044b",40:"-\u0448\u044b",50:"-\u0448\u0456",60:"-\u0448\u044b",70:"-\u0448\u0456",80:"-\u0448\u0456",90:"-\u0448\u044b",100:"-\u0448\u0456"};n.defineLocale("kk",{months:"\u049b\u0430\u04a3\u0442\u0430\u0440_\u0430\u049b\u043f\u0430\u043d_\u043d\u0430\u0443\u0440\u044b\u0437_\u0441\u04d9\u0443\u0456\u0440_\u043c\u0430\u043c\u044b\u0440_\u043c\u0430\u0443\u0441\u044b\u043c_\u0448\u0456\u043b\u0434\u0435_\u0442\u0430\u043c\u044b\u0437_\u049b\u044b\u0440\u043a\u04af\u0439\u0435\u043a_\u049b\u0430\u0437\u0430\u043d_\u049b\u0430\u0440\u0430\u0448\u0430_\u0436\u0435\u043b\u0442\u043e\u049b\u0441\u0430\u043d".split("_"),monthsShort:"\u049b\u0430\u04a3_\u0430\u049b\u043f_\u043d\u0430\u0443_\u0441\u04d9\u0443_\u043c\u0430\u043c_\u043c\u0430\u0443_\u0448\u0456\u043b_\u0442\u0430\u043c_\u049b\u044b\u0440_\u049b\u0430\u0437_\u049b\u0430\u0440_\u0436\u0435\u043b".split("_"),weekdays:"\u0436\u0435\u043a\u0441\u0435\u043d\u0431\u0456_\u0434\u04af\u0439\u0441\u0435\u043d\u0431\u0456_\u0441\u0435\u0439\u0441\u0435\u043d\u0431\u0456_\u0441\u04d9\u0440\u0441\u0435\u043d\u0431\u0456_\u0431\u0435\u0439\u0441\u0435\u043d\u0431\u0456_\u0436\u04b1\u043c\u0430_\u0441\u0435\u043d\u0431\u0456".split("_"),weekdaysShort:"\u0436\u0435\u043a_\u0434\u04af\u0439_\u0441\u0435\u0439_\u0441\u04d9\u0440_\u0431\u0435\u0439_\u0436\u04b1\u043c_\u0441\u0435\u043d".split("_"),weekdaysMin:"\u0436\u043a_\u0434\u0439_\u0441\u0439_\u0441\u0440_\u0431\u0439_\u0436\u043c_\u0441\u043d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0411\u04af\u0433\u0456\u043d \u0441\u0430\u0493\u0430\u0442] LT",nextDay:"[\u0415\u0440\u0442\u0435\u04a3 \u0441\u0430\u0493\u0430\u0442] LT",nextWeek:"dddd [\u0441\u0430\u0493\u0430\u0442] LT",lastDay:"[\u041a\u0435\u0448\u0435 \u0441\u0430\u0493\u0430\u0442] LT",lastWeek:"[\u04e8\u0442\u043a\u0435\u043d \u0430\u043f\u0442\u0430\u043d\u044b\u04a3] dddd [\u0441\u0430\u0493\u0430\u0442] LT",sameElse:"L"},relativeTime:{future:"%s \u0456\u0448\u0456\u043d\u0434\u0435",past:"%s \u0431\u04b1\u0440\u044b\u043d",s:"\u0431\u0456\u0440\u043d\u0435\u0448\u0435 \u0441\u0435\u043a\u0443\u043d\u0434",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434",m:"\u0431\u0456\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u0431\u0456\u0440 \u0441\u0430\u0493\u0430\u0442",hh:"%d \u0441\u0430\u0493\u0430\u0442",d:"\u0431\u0456\u0440 \u043a\u04af\u043d",dd:"%d \u043a\u04af\u043d",M:"\u0431\u0456\u0440 \u0430\u0439",MM:"%d \u0430\u0439",y:"\u0431\u0456\u0440 \u0436\u044b\u043b",yy:"%d \u0436\u044b\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0448\u0456|\u0448\u044b)/,ordinal:function(n){return n+(t[n]||t[n%10]||t[n>=100?100:null])},week:{dow:1,doy:7}})}(e("PJh5"))},j8cJ:function(n,t,e){!function(n){"use strict";n.defineLocale("ar-kw",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062a\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062a\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:0,doy:12}})}(e("PJh5"))},jxEH:function(n,t,e){!function(n){"use strict";var t={ss:"sekundes_sekund\u0113m_sekunde_sekundes".split("_"),m:"min\u016btes_min\u016bt\u0113m_min\u016bte_min\u016btes".split("_"),mm:"min\u016btes_min\u016bt\u0113m_min\u016bte_min\u016btes".split("_"),h:"stundas_stund\u0101m_stunda_stundas".split("_"),hh:"stundas_stund\u0101m_stunda_stundas".split("_"),d:"dienas_dien\u0101m_diena_dienas".split("_"),dd:"dienas_dien\u0101m_diena_dienas".split("_"),M:"m\u0113ne\u0161a_m\u0113ne\u0161iem_m\u0113nesis_m\u0113ne\u0161i".split("_"),MM:"m\u0113ne\u0161a_m\u0113ne\u0161iem_m\u0113nesis_m\u0113ne\u0161i".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")};function e(n,t,e){return e?t%10==1&&t%100!=11?n[2]:n[3]:t%10==1&&t%100!=11?n[0]:n[1]}function l(n,l,r){return n+" "+e(t[r],n,l)}function r(n,l,r){return e(t[r],n,l)}n.defineLocale("lv",{months:"janv\u0101ris_febru\u0101ris_marts_apr\u012blis_maijs_j\u016bnijs_j\u016blijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_j\u016bn_j\u016bl_aug_sep_okt_nov_dec".split("_"),weekdays:"sv\u0113tdiena_pirmdiena_otrdiena_tre\u0161diena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[\u0160odien pulksten] LT",nextDay:"[R\u012bt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pag\u0101ju\u0161\u0101] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"p\u0113c %s",past:"pirms %s",s:function(n,t){return t?"da\u017eas sekundes":"da\u017e\u0101m sekund\u0113m"},ss:l,m:r,mm:l,h:r,hh:l,d:r,dd:l,M:r,MM:l,y:r,yy:l},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},"k+5o":function(n,t,e){!function(n){"use strict";var t={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'\xfcnc\xfc",4:"'\xfcnc\xfc",100:"'\xfcnc\xfc",6:"'nc\u0131",9:"'uncu",10:"'uncu",30:"'uncu",60:"'\u0131nc\u0131",90:"'\u0131nc\u0131"};n.defineLocale("tr",{months:"Ocak_\u015eubat_Mart_Nisan_May\u0131s_Haziran_Temmuz_A\u011fustos_Eyl\xfcl_Ekim_Kas\u0131m_Aral\u0131k".split("_"),monthsShort:"Oca_\u015eub_Mar_Nis_May_Haz_Tem_A\u011fu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Sal\u0131_\xc7ar\u015famba_Per\u015fembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pts_Sal_\xc7ar_Per_Cum_Cts".split("_"),weekdaysMin:"Pz_Pt_Sa_\xc7a_Pe_Cu_Ct".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bug\xfcn saat] LT",nextDay:"[yar\u0131n saat] LT",nextWeek:"[gelecek] dddd [saat] LT",lastDay:"[d\xfcn] LT",lastWeek:"[ge\xe7en] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s \xf6nce",s:"birka\xe7 saniye",ss:"%d saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir g\xfcn",dd:"%d g\xfcn",M:"bir ay",MM:"%d ay",y:"bir y\u0131l",yy:"%d y\u0131l"},ordinal:function(n,e){switch(e){case"d":case"D":case"Do":case"DD":return n;default:if(0===n)return n+"'\u0131nc\u0131";var l=n%10;return n+(t[l]||t[n%100-l]||t[n>=100?100:null])}},week:{dow:1,doy:7}})}(e("PJh5"))},krPU:function(n,t,e){!function(n){"use strict";n.defineLocale("tzm-latn",{months:"innayr_br\u02e4ayr\u02e4_mar\u02e4s\u02e4_ibrir_mayyw_ywnyw_ywlywz_\u0263w\u0161t_\u0161wtanbir_kt\u02e4wbr\u02e4_nwwanbir_dwjnbir".split("_"),monthsShort:"innayr_br\u02e4ayr\u02e4_mar\u02e4s\u02e4_ibrir_mayyw_ywnyw_ywlywz_\u0263w\u0161t_\u0161wtanbir_kt\u02e4wbr\u02e4_nwwanbir_dwjnbir".split("_"),weekdays:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),weekdaysShort:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),weekdaysMin:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[asdkh g] LT",nextDay:"[aska g] LT",nextWeek:"dddd [g] LT",lastDay:"[assant g] LT",lastWeek:"dddd [g] LT",sameElse:"L"},relativeTime:{future:"dadkh s yan %s",past:"yan %s",s:"imik",ss:"%d imik",m:"minu\u1e0d",mm:"%d minu\u1e0d",h:"sa\u025ba",hh:"%d tassa\u025bin",d:"ass",dd:"%d ossan",M:"ayowr",MM:"%d iyyirn",y:"asgas",yy:"%d isgasn"},week:{dow:6,doy:12}})}(e("PJh5"))},lAP5:function(n,t,e){"use strict";t.a=function(n){return n}},lOED:function(n,t,e){!function(n){"use strict";n.defineLocale("bg",{months:"\u044f\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u044f\u043d\u0440_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u044f\u0434\u0430_\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a_\u043f\u0435\u0442\u044a\u043a_\u0441\u044a\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u044f_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u044a\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[\u0414\u043d\u0435\u0441 \u0432] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432] LT",nextWeek:"dddd [\u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0430\u0442\u0430] dddd [\u0432] LT";case 1:case 2:case 4:case 5:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0438\u044f] dddd [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0441\u043b\u0435\u0434 %s",past:"\u043f\u0440\u0435\u0434\u0438 %s",s:"\u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u043d\u0438",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0430",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0435\u0432|\u0435\u043d|\u0442\u0438|\u0432\u0438|\u0440\u0438|\u043c\u0438)/,ordinal:function(n){var t=n%10,e=n%100;return 0===n?n+"-\u0435\u0432":0===e?n+"-\u0435\u043d":e>10&&e<20?n+"-\u0442\u0438":1===t?n+"-\u0432\u0438":2===t?n+"-\u0440\u0438":7===t||8===t?n+"-\u043c\u0438":n+"-\u0442\u0438"},week:{dow:1,doy:7}})}(e("PJh5"))},m7yE:function(n,t,e){!function(n){"use strict";var t="pagh_wa\u2019_cha\u2019_wej_loS_vagh_jav_Soch_chorgh_Hut".split("_");function e(n,e,l,r){var i=function(n){var e=Math.floor(n%1e3/100),l=Math.floor(n%100/10),r=n%10,i="";return e>0&&(i+=t[e]+"vatlh"),l>0&&(i+=(""!==i?" ":"")+t[l]+"maH"),r>0&&(i+=(""!==i?" ":"")+t[r]),""===i?"pagh":i}(n);switch(l){case"ss":return i+" lup";case"mm":return i+" tup";case"hh":return i+" rep";case"dd":return i+" jaj";case"MM":return i+" jar";case"yy":return i+" DIS"}}n.defineLocale("tlh",{months:"tera\u2019 jar wa\u2019_tera\u2019 jar cha\u2019_tera\u2019 jar wej_tera\u2019 jar loS_tera\u2019 jar vagh_tera\u2019 jar jav_tera\u2019 jar Soch_tera\u2019 jar chorgh_tera\u2019 jar Hut_tera\u2019 jar wa\u2019maH_tera\u2019 jar wa\u2019maH wa\u2019_tera\u2019 jar wa\u2019maH cha\u2019".split("_"),monthsShort:"jar wa\u2019_jar cha\u2019_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa\u2019maH_jar wa\u2019maH wa\u2019_jar wa\u2019maH cha\u2019".split("_"),monthsParseExact:!0,weekdays:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysShort:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysMin:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[DaHjaj] LT",nextDay:"[wa\u2019leS] LT",nextWeek:"LLL",lastDay:"[wa\u2019Hu\u2019] LT",lastWeek:"LLL",sameElse:"L"},relativeTime:{future:function(n){var t=n;return-1!==n.indexOf("jaj")?t.slice(0,-3)+"leS":-1!==n.indexOf("jar")?t.slice(0,-3)+"waQ":-1!==n.indexOf("DIS")?t.slice(0,-3)+"nem":t+" pIq"},past:function(n){var t=n;return-1!==n.indexOf("jaj")?t.slice(0,-3)+"Hu\u2019":-1!==n.indexOf("jar")?t.slice(0,-3)+"wen":-1!==n.indexOf("DIS")?t.slice(0,-3)+"ben":t+" ret"},s:"puS lup",ss:e,m:"wa\u2019 tup",mm:e,h:"wa\u2019 rep",hh:e,d:"wa\u2019 jaj",dd:e,M:"wa\u2019 jar",MM:e,y:"wa\u2019 DIS",yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},nE8X:function(n,t,e){!function(n){"use strict";n.defineLocale("lo",{months:"\u0ea1\u0eb1\u0e87\u0e81\u0ead\u0e99_\u0e81\u0eb8\u0ea1\u0e9e\u0eb2_\u0ea1\u0eb5\u0e99\u0eb2_\u0ec0\u0ea1\u0eaa\u0eb2_\u0e9e\u0eb6\u0e94\u0eaa\u0eb0\u0e9e\u0eb2_\u0ea1\u0eb4\u0e96\u0eb8\u0e99\u0eb2_\u0e81\u0ecd\u0ea5\u0eb0\u0e81\u0ebb\u0e94_\u0eaa\u0eb4\u0e87\u0eab\u0eb2_\u0e81\u0eb1\u0e99\u0e8d\u0eb2_\u0e95\u0eb8\u0ea5\u0eb2_\u0e9e\u0eb0\u0e88\u0eb4\u0e81_\u0e97\u0eb1\u0e99\u0ea7\u0eb2".split("_"),monthsShort:"\u0ea1\u0eb1\u0e87\u0e81\u0ead\u0e99_\u0e81\u0eb8\u0ea1\u0e9e\u0eb2_\u0ea1\u0eb5\u0e99\u0eb2_\u0ec0\u0ea1\u0eaa\u0eb2_\u0e9e\u0eb6\u0e94\u0eaa\u0eb0\u0e9e\u0eb2_\u0ea1\u0eb4\u0e96\u0eb8\u0e99\u0eb2_\u0e81\u0ecd\u0ea5\u0eb0\u0e81\u0ebb\u0e94_\u0eaa\u0eb4\u0e87\u0eab\u0eb2_\u0e81\u0eb1\u0e99\u0e8d\u0eb2_\u0e95\u0eb8\u0ea5\u0eb2_\u0e9e\u0eb0\u0e88\u0eb4\u0e81_\u0e97\u0eb1\u0e99\u0ea7\u0eb2".split("_"),weekdays:"\u0ead\u0eb2\u0e97\u0eb4\u0e94_\u0e88\u0eb1\u0e99_\u0ead\u0eb1\u0e87\u0e84\u0eb2\u0e99_\u0e9e\u0eb8\u0e94_\u0e9e\u0eb0\u0eab\u0eb1\u0e94_\u0eaa\u0eb8\u0e81_\u0ec0\u0eaa\u0ebb\u0eb2".split("_"),weekdaysShort:"\u0e97\u0eb4\u0e94_\u0e88\u0eb1\u0e99_\u0ead\u0eb1\u0e87\u0e84\u0eb2\u0e99_\u0e9e\u0eb8\u0e94_\u0e9e\u0eb0\u0eab\u0eb1\u0e94_\u0eaa\u0eb8\u0e81_\u0ec0\u0eaa\u0ebb\u0eb2".split("_"),weekdaysMin:"\u0e97_\u0e88_\u0ead\u0e84_\u0e9e_\u0e9e\u0eab_\u0eaa\u0e81_\u0eaa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"\u0ea7\u0eb1\u0e99dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0e95\u0ead\u0e99\u0ec0\u0e8a\u0ebb\u0ec9\u0eb2|\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87/,isPM:function(n){return"\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87"===n},meridiem:function(n,t,e){return n<12?"\u0e95\u0ead\u0e99\u0ec0\u0e8a\u0ebb\u0ec9\u0eb2":"\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87"},calendar:{sameDay:"[\u0ea1\u0eb7\u0ec9\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",nextDay:"[\u0ea1\u0eb7\u0ec9\u0ead\u0eb7\u0ec8\u0e99\u0ec0\u0ea7\u0ea5\u0eb2] LT",nextWeek:"[\u0ea7\u0eb1\u0e99]dddd[\u0edc\u0ec9\u0eb2\u0ec0\u0ea7\u0ea5\u0eb2] LT",lastDay:"[\u0ea1\u0eb7\u0ec9\u0ea7\u0eb2\u0e99\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",lastWeek:"[\u0ea7\u0eb1\u0e99]dddd[\u0ec1\u0ea5\u0ec9\u0ea7\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",sameElse:"L"},relativeTime:{future:"\u0ead\u0eb5\u0e81 %s",past:"%s\u0e9c\u0ec8\u0eb2\u0e99\u0ea1\u0eb2",s:"\u0e9a\u0ecd\u0ec8\u0ec0\u0e97\u0ebb\u0ec8\u0eb2\u0ec3\u0e94\u0ea7\u0eb4\u0e99\u0eb2\u0e97\u0eb5",ss:"%d \u0ea7\u0eb4\u0e99\u0eb2\u0e97\u0eb5",m:"1 \u0e99\u0eb2\u0e97\u0eb5",mm:"%d \u0e99\u0eb2\u0e97\u0eb5",h:"1 \u0e8a\u0ebb\u0ec8\u0ea7\u0ec2\u0ea1\u0e87",hh:"%d \u0e8a\u0ebb\u0ec8\u0ea7\u0ec2\u0ea1\u0e87",d:"1 \u0ea1\u0eb7\u0ec9",dd:"%d \u0ea1\u0eb7\u0ec9",M:"1 \u0ec0\u0e94\u0eb7\u0ead\u0e99",MM:"%d \u0ec0\u0e94\u0eb7\u0ead\u0e99",y:"1 \u0e9b\u0eb5",yy:"%d \u0e9b\u0eb5"},dayOfMonthOrdinalParse:/(\u0e97\u0eb5\u0ec8)\d{1,2}/,ordinal:function(n){return"\u0e97\u0eb5\u0ec8"+n}})}(e("PJh5"))},nLOz:function(n,t,e){!function(n){"use strict";n.defineLocale("gd",{months:["Am Faoilleach","An Gearran","Am M\xe0rt","An Giblean","An C\xe8itean","An t-\xd2gmhios","An t-Iuchar","An L\xf9nastal","An t-Sultain","An D\xe0mhair","An t-Samhain","An D\xf9bhlachd"],monthsShort:["Faoi","Gear","M\xe0rt","Gibl","C\xe8it","\xd2gmh","Iuch","L\xf9n","Sult","D\xe0mh","Samh","D\xf9bh"],monthsParseExact:!0,weekdays:["Did\xf2mhnaich","Diluain","Dim\xe0irt","Diciadain","Diardaoin","Dihaoine","Disathairne"],weekdaysShort:["Did","Dil","Dim","Dic","Dia","Dih","Dis"],weekdaysMin:["D\xf2","Lu","M\xe0","Ci","Ar","Ha","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[An-diugh aig] LT",nextDay:"[A-m\xe0ireach aig] LT",nextWeek:"dddd [aig] LT",lastDay:"[An-d\xe8 aig] LT",lastWeek:"dddd [seo chaidh] [aig] LT",sameElse:"L"},relativeTime:{future:"ann an %s",past:"bho chionn %s",s:"beagan diogan",ss:"%d diogan",m:"mionaid",mm:"%d mionaidean",h:"uair",hh:"%d uairean",d:"latha",dd:"%d latha",M:"m\xecos",MM:"%d m\xecosan",y:"bliadhna",yy:"%d bliadhna"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(n){return n+(1===n?"d":n%10==2?"na":"mh")},week:{dow:1,doy:4}})}(e("PJh5"))},nS2h:function(n,t,e){!function(n){"use strict";var t="nolla yksi kaksi kolme nelj\xe4 viisi kuusi seitsem\xe4n kahdeksan yhdeks\xe4n".split(" "),e=["nolla","yhden","kahden","kolmen","nelj\xe4n","viiden","kuuden",t[7],t[8],t[9]];function l(n,l,r,i){var o="";switch(r){case"s":return i?"muutaman sekunnin":"muutama sekunti";case"ss":return i?"sekunnin":"sekuntia";case"m":return i?"minuutin":"minuutti";case"mm":o=i?"minuutin":"minuuttia";break;case"h":return i?"tunnin":"tunti";case"hh":o=i?"tunnin":"tuntia";break;case"d":return i?"p\xe4iv\xe4n":"p\xe4iv\xe4";case"dd":o=i?"p\xe4iv\xe4n":"p\xe4iv\xe4\xe4";break;case"M":return i?"kuukauden":"kuukausi";case"MM":o=i?"kuukauden":"kuukautta";break;case"y":return i?"vuoden":"vuosi";case"yy":o=i?"vuoden":"vuotta"}return function(n,l){return n<10?l?e[n]:t[n]:n}(n,i)+" "+o}n.defineLocale("fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kes\xe4kuu_hein\xe4kuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kes\xe4_hein\xe4_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[t\xe4n\xe4\xe4n] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s p\xe4\xe4st\xe4",past:"%s sitten",s:l,ss:l,m:l,mm:l,h:l,hh:l,d:l,dd:l,M:l,MM:l,y:l,yy:l},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},ntHu:function(n,t,e){!function(n){"use strict";function t(n,t,e){var l,r;return"m"===e?t?"\u0445\u0432\u0438\u043b\u0438\u043d\u0430":"\u0445\u0432\u0438\u043b\u0438\u043d\u0443":"h"===e?t?"\u0433\u043e\u0434\u0438\u043d\u0430":"\u0433\u043e\u0434\u0438\u043d\u0443":n+" "+(l=+n,r={ss:t?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u0438_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u0438_\u0441\u0435\u043a\u0443\u043d\u0434",mm:t?"\u0445\u0432\u0438\u043b\u0438\u043d\u0430_\u0445\u0432\u0438\u043b\u0438\u043d\u0438_\u0445\u0432\u0438\u043b\u0438\u043d":"\u0445\u0432\u0438\u043b\u0438\u043d\u0443_\u0445\u0432\u0438\u043b\u0438\u043d\u0438_\u0445\u0432\u0438\u043b\u0438\u043d",hh:t?"\u0433\u043e\u0434\u0438\u043d\u0430_\u0433\u043e\u0434\u0438\u043d\u0438_\u0433\u043e\u0434\u0438\u043d":"\u0433\u043e\u0434\u0438\u043d\u0443_\u0433\u043e\u0434\u0438\u043d\u0438_\u0433\u043e\u0434\u0438\u043d",dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u0456_\u0434\u043d\u0456\u0432",MM:"\u043c\u0456\u0441\u044f\u0446\u044c_\u043c\u0456\u0441\u044f\u0446\u0456_\u043c\u0456\u0441\u044f\u0446\u0456\u0432",yy:"\u0440\u0456\u043a_\u0440\u043e\u043a\u0438_\u0440\u043e\u043a\u0456\u0432"}[e].split("_"),l%10==1&&l%100!=11?r[0]:l%10>=2&&l%10<=4&&(l%100<10||l%100>=20)?r[1]:r[2])}function e(n){return function(){return n+"\u043e"+(11===this.hours()?"\u0431":"")+"] LT"}}n.defineLocale("uk",{months:{format:"\u0441\u0456\u0447\u043d\u044f_\u043b\u044e\u0442\u043e\u0433\u043e_\u0431\u0435\u0440\u0435\u0437\u043d\u044f_\u043a\u0432\u0456\u0442\u043d\u044f_\u0442\u0440\u0430\u0432\u043d\u044f_\u0447\u0435\u0440\u0432\u043d\u044f_\u043b\u0438\u043f\u043d\u044f_\u0441\u0435\u0440\u043f\u043d\u044f_\u0432\u0435\u0440\u0435\u0441\u043d\u044f_\u0436\u043e\u0432\u0442\u043d\u044f_\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430_\u0433\u0440\u0443\u0434\u043d\u044f".split("_"),standalone:"\u0441\u0456\u0447\u0435\u043d\u044c_\u043b\u044e\u0442\u0438\u0439_\u0431\u0435\u0440\u0435\u0437\u0435\u043d\u044c_\u043a\u0432\u0456\u0442\u0435\u043d\u044c_\u0442\u0440\u0430\u0432\u0435\u043d\u044c_\u0447\u0435\u0440\u0432\u0435\u043d\u044c_\u043b\u0438\u043f\u0435\u043d\u044c_\u0441\u0435\u0440\u043f\u0435\u043d\u044c_\u0432\u0435\u0440\u0435\u0441\u0435\u043d\u044c_\u0436\u043e\u0432\u0442\u0435\u043d\u044c_\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434_\u0433\u0440\u0443\u0434\u0435\u043d\u044c".split("_")},monthsShort:"\u0441\u0456\u0447_\u043b\u044e\u0442_\u0431\u0435\u0440_\u043a\u0432\u0456\u0442_\u0442\u0440\u0430\u0432_\u0447\u0435\u0440\u0432_\u043b\u0438\u043f_\u0441\u0435\u0440\u043f_\u0432\u0435\u0440_\u0436\u043e\u0432\u0442_\u043b\u0438\u0441\u0442_\u0433\u0440\u0443\u0434".split("_"),weekdays:function(n,t){var e={nominative:"\u043d\u0435\u0434\u0456\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a_\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a_\u0441\u0435\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0435\u0440_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u044f_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),accusative:"\u043d\u0435\u0434\u0456\u043b\u044e_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a_\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a_\u0441\u0435\u0440\u0435\u0434\u0443_\u0447\u0435\u0442\u0432\u0435\u0440_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u044e_\u0441\u0443\u0431\u043e\u0442\u0443".split("_"),genitive:"\u043d\u0435\u0434\u0456\u043b\u0456_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043a\u0430_\u0432\u0456\u0432\u0442\u043e\u0440\u043a\u0430_\u0441\u0435\u0440\u0435\u0434\u0438_\u0447\u0435\u0442\u0432\u0435\u0440\u0433\u0430_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u0456_\u0441\u0443\u0431\u043e\u0442\u0438".split("_")};return n?e[/(\[[\u0412\u0432\u0423\u0443]\]) ?dddd/.test(t)?"accusative":/\[?(?:\u043c\u0438\u043d\u0443\u043b\u043e\u0457|\u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u0457)? ?\] ?dddd/.test(t)?"genitive":"nominative"][n.day()]:e.nominative},weekdaysShort:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0440.",LLL:"D MMMM YYYY \u0440., HH:mm",LLLL:"dddd, D MMMM YYYY \u0440., HH:mm"},calendar:{sameDay:e("[\u0421\u044c\u043e\u0433\u043e\u0434\u043d\u0456 "),nextDay:e("[\u0417\u0430\u0432\u0442\u0440\u0430 "),lastDay:e("[\u0412\u0447\u043e\u0440\u0430 "),nextWeek:e("[\u0423] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return e("[\u041c\u0438\u043d\u0443\u043b\u043e\u0457] dddd [").call(this);case 1:case 2:case 4:return e("[\u041c\u0438\u043d\u0443\u043b\u043e\u0433\u043e] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"%s \u0442\u043e\u043c\u0443",s:"\u0434\u0435\u043a\u0456\u043b\u044c\u043a\u0430 \u0441\u0435\u043a\u0443\u043d\u0434",ss:t,m:t,mm:t,h:"\u0433\u043e\u0434\u0438\u043d\u0443",hh:t,d:"\u0434\u0435\u043d\u044c",dd:t,M:"\u043c\u0456\u0441\u044f\u0446\u044c",MM:t,y:"\u0440\u0456\u043a",yy:t},meridiemParse:/\u043d\u043e\u0447\u0456|\u0440\u0430\u043d\u043a\u0443|\u0434\u043d\u044f|\u0432\u0435\u0447\u043e\u0440\u0430/,isPM:function(n){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u043e\u0440\u0430)$/.test(n)},meridiem:function(n,t,e){return n<4?"\u043d\u043e\u0447\u0456":n<12?"\u0440\u0430\u043d\u043a\u0443":n<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u043e\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0439|\u0433\u043e)/,ordinal:function(n,t){switch(t){case"M":case"d":case"DDD":case"w":case"W":return n+"-\u0439";case"D":return n+"-\u0433\u043e";default:return n}},week:{dow:1,doy:7}})}(e("PJh5"))},oCzW:function(n,t,e){!function(n){"use strict";n.defineLocale("mt",{months:"Jannar_Frar_Marzu_April_Mejju_\u0120unju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Di\u010bembru".split("_"),monthsShort:"Jan_Fra_Mar_Apr_Mej_\u0120un_Lul_Aww_Set_Ott_Nov_Di\u010b".split("_"),weekdays:"Il-\u0126add_It-Tnejn_It-Tlieta_L-Erbg\u0127a_Il-\u0126amis_Il-\u0120img\u0127a_Is-Sibt".split("_"),weekdaysShort:"\u0126ad_Tne_Tli_Erb_\u0126am_\u0120im_Sib".split("_"),weekdaysMin:"\u0126a_Tn_Tl_Er_\u0126a_\u0120i_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Illum fil-]LT",nextDay:"[G\u0127ada fil-]LT",nextWeek:"dddd [fil-]LT",lastDay:"[Il-biera\u0127 fil-]LT",lastWeek:"dddd [li g\u0127adda] [fil-]LT",sameElse:"L"},relativeTime:{future:"f\u2019 %s",past:"%s ilu",s:"ftit sekondi",ss:"%d sekondi",m:"minuta",mm:"%d minuti",h:"sieg\u0127a",hh:"%d sieg\u0127at",d:"\u0121urnata",dd:"%d \u0121ranet",M:"xahar",MM:"%d xhur",y:"sena",yy:"%d sni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(e("PJh5"))},oo1B:function(n,t,e){!function(n){"use strict";n.defineLocale("ml",{months:"\u0d1c\u0d28\u0d41\u0d35\u0d30\u0d3f_\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41\u0d35\u0d30\u0d3f_\u0d2e\u0d3e\u0d7c\u0d1a\u0d4d\u0d1a\u0d4d_\u0d0f\u0d2a\u0d4d\u0d30\u0d3f\u0d7d_\u0d2e\u0d47\u0d2f\u0d4d_\u0d1c\u0d42\u0d7a_\u0d1c\u0d42\u0d32\u0d48_\u0d13\u0d17\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d4d_\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02\u0d2c\u0d7c_\u0d12\u0d15\u0d4d\u0d1f\u0d4b\u0d2c\u0d7c_\u0d28\u0d35\u0d02\u0d2c\u0d7c_\u0d21\u0d3f\u0d38\u0d02\u0d2c\u0d7c".split("_"),monthsShort:"\u0d1c\u0d28\u0d41._\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41._\u0d2e\u0d3e\u0d7c._\u0d0f\u0d2a\u0d4d\u0d30\u0d3f._\u0d2e\u0d47\u0d2f\u0d4d_\u0d1c\u0d42\u0d7a_\u0d1c\u0d42\u0d32\u0d48._\u0d13\u0d17._\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31._\u0d12\u0d15\u0d4d\u0d1f\u0d4b._\u0d28\u0d35\u0d02._\u0d21\u0d3f\u0d38\u0d02.".split("_"),monthsParseExact:!0,weekdays:"\u0d1e\u0d3e\u0d2f\u0d31\u0d3e\u0d34\u0d4d\u0d1a_\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d3e\u0d34\u0d4d\u0d1a_\u0d1a\u0d4a\u0d35\u0d4d\u0d35\u0d3e\u0d34\u0d4d\u0d1a_\u0d2c\u0d41\u0d27\u0d28\u0d3e\u0d34\u0d4d\u0d1a_\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d3e\u0d34\u0d4d\u0d1a_\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a_\u0d36\u0d28\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a".split("_"),weekdaysShort:"\u0d1e\u0d3e\u0d2f\u0d7c_\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d7e_\u0d1a\u0d4a\u0d35\u0d4d\u0d35_\u0d2c\u0d41\u0d27\u0d7b_\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d02_\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f_\u0d36\u0d28\u0d3f".split("_"),weekdaysMin:"\u0d1e\u0d3e_\u0d24\u0d3f_\u0d1a\u0d4a_\u0d2c\u0d41_\u0d35\u0d4d\u0d2f\u0d3e_\u0d35\u0d46_\u0d36".split("_"),longDateFormat:{LT:"A h:mm -\u0d28\u0d41",LTS:"A h:mm:ss -\u0d28\u0d41",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm -\u0d28\u0d41",LLLL:"dddd, D MMMM YYYY, A h:mm -\u0d28\u0d41"},calendar:{sameDay:"[\u0d07\u0d28\u0d4d\u0d28\u0d4d] LT",nextDay:"[\u0d28\u0d3e\u0d33\u0d46] LT",nextWeek:"dddd, LT",lastDay:"[\u0d07\u0d28\u0d4d\u0d28\u0d32\u0d46] LT",lastWeek:"[\u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d",past:"%s \u0d2e\u0d41\u0d7b\u0d2a\u0d4d",s:"\u0d05\u0d7d\u0d2a \u0d28\u0d3f\u0d2e\u0d3f\u0d37\u0d19\u0d4d\u0d19\u0d7e",ss:"%d \u0d38\u0d46\u0d15\u0d4d\u0d15\u0d7b\u0d21\u0d4d",m:"\u0d12\u0d30\u0d41 \u0d2e\u0d3f\u0d28\u0d3f\u0d31\u0d4d\u0d31\u0d4d",mm:"%d \u0d2e\u0d3f\u0d28\u0d3f\u0d31\u0d4d\u0d31\u0d4d",h:"\u0d12\u0d30\u0d41 \u0d2e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d42\u0d7c",hh:"%d \u0d2e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d42\u0d7c",d:"\u0d12\u0d30\u0d41 \u0d26\u0d3f\u0d35\u0d38\u0d02",dd:"%d \u0d26\u0d3f\u0d35\u0d38\u0d02",M:"\u0d12\u0d30\u0d41 \u0d2e\u0d3e\u0d38\u0d02",MM:"%d \u0d2e\u0d3e\u0d38\u0d02",y:"\u0d12\u0d30\u0d41 \u0d35\u0d7c\u0d37\u0d02",yy:"%d \u0d35\u0d7c\u0d37\u0d02"},meridiemParse:/\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f|\u0d30\u0d3e\u0d35\u0d3f\u0d32\u0d46|\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d|\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02|\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f/i,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f"===t&&n>=4||"\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d"===t||"\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02"===t?n+12:n},meridiem:function(n,t,e){return n<4?"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f":n<12?"\u0d30\u0d3e\u0d35\u0d3f\u0d32\u0d46":n<17?"\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d":n<20?"\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02":"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f"}})}(e("PJh5"))},ooba:function(n,t,e){!function(n){"use strict";n.defineLocale("ms",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(n,t){return 12===n&&(n=0),"pagi"===t?n:"tengahari"===t?n>=11?n:n+12:"petang"===t||"malam"===t?n+12:void 0},meridiem:function(n,t,e){return n<11?"pagi":n<15?"tengahari":n<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}(e("PJh5"))},"pU/0":function(n,t,e){"use strict";e.d(t,"a",function(){return r});var l=e("TToO"),r=function(n){function t(){var t=n.call(this,"argument out of range");this.name=t.name="ArgumentOutOfRangeError",this.stack=t.stack,this.message=t.message}return Object(l.__extends)(t,n),t}(Error)},pfs9:function(n,t,e){!function(n){"use strict";var t={1:"\u0a67",2:"\u0a68",3:"\u0a69",4:"\u0a6a",5:"\u0a6b",6:"\u0a6c",7:"\u0a6d",8:"\u0a6e",9:"\u0a6f",0:"\u0a66"},e={"\u0a67":"1","\u0a68":"2","\u0a69":"3","\u0a6a":"4","\u0a6b":"5","\u0a6c":"6","\u0a6d":"7","\u0a6e":"8","\u0a6f":"9","\u0a66":"0"};n.defineLocale("pa-in",{months:"\u0a1c\u0a28\u0a35\u0a30\u0a40_\u0a2b\u0a3c\u0a30\u0a35\u0a30\u0a40_\u0a2e\u0a3e\u0a30\u0a1a_\u0a05\u0a2a\u0a4d\u0a30\u0a48\u0a32_\u0a2e\u0a08_\u0a1c\u0a42\u0a28_\u0a1c\u0a41\u0a32\u0a3e\u0a08_\u0a05\u0a17\u0a38\u0a24_\u0a38\u0a24\u0a70\u0a2c\u0a30_\u0a05\u0a15\u0a24\u0a42\u0a2c\u0a30_\u0a28\u0a35\u0a70\u0a2c\u0a30_\u0a26\u0a38\u0a70\u0a2c\u0a30".split("_"),monthsShort:"\u0a1c\u0a28\u0a35\u0a30\u0a40_\u0a2b\u0a3c\u0a30\u0a35\u0a30\u0a40_\u0a2e\u0a3e\u0a30\u0a1a_\u0a05\u0a2a\u0a4d\u0a30\u0a48\u0a32_\u0a2e\u0a08_\u0a1c\u0a42\u0a28_\u0a1c\u0a41\u0a32\u0a3e\u0a08_\u0a05\u0a17\u0a38\u0a24_\u0a38\u0a24\u0a70\u0a2c\u0a30_\u0a05\u0a15\u0a24\u0a42\u0a2c\u0a30_\u0a28\u0a35\u0a70\u0a2c\u0a30_\u0a26\u0a38\u0a70\u0a2c\u0a30".split("_"),weekdays:"\u0a10\u0a24\u0a35\u0a3e\u0a30_\u0a38\u0a4b\u0a2e\u0a35\u0a3e\u0a30_\u0a2e\u0a70\u0a17\u0a32\u0a35\u0a3e\u0a30_\u0a2c\u0a41\u0a27\u0a35\u0a3e\u0a30_\u0a35\u0a40\u0a30\u0a35\u0a3e\u0a30_\u0a38\u0a3c\u0a41\u0a71\u0a15\u0a30\u0a35\u0a3e\u0a30_\u0a38\u0a3c\u0a28\u0a40\u0a1a\u0a30\u0a35\u0a3e\u0a30".split("_"),weekdaysShort:"\u0a10\u0a24_\u0a38\u0a4b\u0a2e_\u0a2e\u0a70\u0a17\u0a32_\u0a2c\u0a41\u0a27_\u0a35\u0a40\u0a30_\u0a38\u0a3c\u0a41\u0a15\u0a30_\u0a38\u0a3c\u0a28\u0a40".split("_"),weekdaysMin:"\u0a10\u0a24_\u0a38\u0a4b\u0a2e_\u0a2e\u0a70\u0a17\u0a32_\u0a2c\u0a41\u0a27_\u0a35\u0a40\u0a30_\u0a38\u0a3c\u0a41\u0a15\u0a30_\u0a38\u0a3c\u0a28\u0a40".split("_"),longDateFormat:{LT:"A h:mm \u0a35\u0a1c\u0a47",LTS:"A h:mm:ss \u0a35\u0a1c\u0a47",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0a35\u0a1c\u0a47",LLLL:"dddd, D MMMM YYYY, A h:mm \u0a35\u0a1c\u0a47"},calendar:{sameDay:"[\u0a05\u0a1c] LT",nextDay:"[\u0a15\u0a32] LT",nextWeek:"dddd, LT",lastDay:"[\u0a15\u0a32] LT",lastWeek:"[\u0a2a\u0a3f\u0a1b\u0a32\u0a47] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0a35\u0a3f\u0a71\u0a1a",past:"%s \u0a2a\u0a3f\u0a1b\u0a32\u0a47",s:"\u0a15\u0a41\u0a1d \u0a38\u0a15\u0a3f\u0a70\u0a1f",ss:"%d \u0a38\u0a15\u0a3f\u0a70\u0a1f",m:"\u0a07\u0a15 \u0a2e\u0a3f\u0a70\u0a1f",mm:"%d \u0a2e\u0a3f\u0a70\u0a1f",h:"\u0a07\u0a71\u0a15 \u0a18\u0a70\u0a1f\u0a3e",hh:"%d \u0a18\u0a70\u0a1f\u0a47",d:"\u0a07\u0a71\u0a15 \u0a26\u0a3f\u0a28",dd:"%d \u0a26\u0a3f\u0a28",M:"\u0a07\u0a71\u0a15 \u0a2e\u0a39\u0a40\u0a28\u0a3e",MM:"%d \u0a2e\u0a39\u0a40\u0a28\u0a47",y:"\u0a07\u0a71\u0a15 \u0a38\u0a3e\u0a32",yy:"%d \u0a38\u0a3e\u0a32"},preparse:function(n){return n.replace(/[\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0a66]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u0a30\u0a3e\u0a24|\u0a38\u0a35\u0a47\u0a30|\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30|\u0a38\u0a3c\u0a3e\u0a2e/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0a30\u0a3e\u0a24"===t?n<4?n:n+12:"\u0a38\u0a35\u0a47\u0a30"===t?n:"\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30"===t?n>=10?n:n+12:"\u0a38\u0a3c\u0a3e\u0a2e"===t?n+12:void 0},meridiem:function(n,t,e){return n<4?"\u0a30\u0a3e\u0a24":n<10?"\u0a38\u0a35\u0a47\u0a30":n<17?"\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30":n<20?"\u0a38\u0a3c\u0a3e\u0a2e":"\u0a30\u0a3e\u0a24"},week:{dow:0,doy:6}})}(e("PJh5"))},rIuo:function(n,t,e){!function(n){"use strict";var t=["\u0796\u07ac\u0782\u07aa\u0787\u07a6\u0783\u07a9","\u078a\u07ac\u0784\u07b0\u0783\u07aa\u0787\u07a6\u0783\u07a9","\u0789\u07a7\u0783\u07a8\u0797\u07aa","\u0787\u07ad\u0795\u07b0\u0783\u07a9\u078d\u07aa","\u0789\u07ad","\u0796\u07ab\u0782\u07b0","\u0796\u07aa\u078d\u07a6\u0787\u07a8","\u0787\u07af\u078e\u07a6\u0790\u07b0\u0793\u07aa","\u0790\u07ac\u0795\u07b0\u0793\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa","\u0787\u07ae\u0786\u07b0\u0793\u07af\u0784\u07a6\u0783\u07aa","\u0782\u07ae\u0788\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa","\u0791\u07a8\u0790\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa"],e=["\u0787\u07a7\u078b\u07a8\u0787\u07b0\u078c\u07a6","\u0780\u07af\u0789\u07a6","\u0787\u07a6\u0782\u07b0\u078e\u07a7\u0783\u07a6","\u0784\u07aa\u078b\u07a6","\u0784\u07aa\u0783\u07a7\u0790\u07b0\u078a\u07a6\u078c\u07a8","\u0780\u07aa\u0786\u07aa\u0783\u07aa","\u0780\u07ae\u0782\u07a8\u0780\u07a8\u0783\u07aa"];n.defineLocale("dv",{months:t,monthsShort:t,weekdays:e,weekdaysShort:e,weekdaysMin:"\u0787\u07a7\u078b\u07a8_\u0780\u07af\u0789\u07a6_\u0787\u07a6\u0782\u07b0_\u0784\u07aa\u078b\u07a6_\u0784\u07aa\u0783\u07a7_\u0780\u07aa\u0786\u07aa_\u0780\u07ae\u0782\u07a8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0789\u0786|\u0789\u078a/,isPM:function(n){return"\u0789\u078a"===n},meridiem:function(n,t,e){return n<12?"\u0789\u0786":"\u0789\u078a"},calendar:{sameDay:"[\u0789\u07a8\u0787\u07a6\u078b\u07aa] LT",nextDay:"[\u0789\u07a7\u078b\u07a6\u0789\u07a7] LT",nextWeek:"dddd LT",lastDay:"[\u0787\u07a8\u0787\u07b0\u0794\u07ac] LT",lastWeek:"[\u078a\u07a7\u0787\u07a8\u078c\u07aa\u0788\u07a8] dddd LT",sameElse:"L"},relativeTime:{future:"\u078c\u07ac\u0783\u07ad\u078e\u07a6\u0787\u07a8 %s",past:"\u0786\u07aa\u0783\u07a8\u0782\u07b0 %s",s:"\u0790\u07a8\u0786\u07aa\u0782\u07b0\u078c\u07aa\u0786\u07ae\u0785\u07ac\u0787\u07b0",ss:"d% \u0790\u07a8\u0786\u07aa\u0782\u07b0\u078c\u07aa",m:"\u0789\u07a8\u0782\u07a8\u0793\u07ac\u0787\u07b0",mm:"\u0789\u07a8\u0782\u07a8\u0793\u07aa %d",h:"\u078e\u07a6\u0791\u07a8\u0787\u07a8\u0783\u07ac\u0787\u07b0",hh:"\u078e\u07a6\u0791\u07a8\u0787\u07a8\u0783\u07aa %d",d:"\u078b\u07aa\u0788\u07a6\u0780\u07ac\u0787\u07b0",dd:"\u078b\u07aa\u0788\u07a6\u0790\u07b0 %d",M:"\u0789\u07a6\u0780\u07ac\u0787\u07b0",MM:"\u0789\u07a6\u0790\u07b0 %d",y:"\u0787\u07a6\u0780\u07a6\u0783\u07ac\u0787\u07b0",yy:"\u0787\u07a6\u0780\u07a6\u0783\u07aa %d"},preparse:function(n){return n.replace(/\u060c/g,",")},postformat:function(n){return n.replace(/,/g,"\u060c")},week:{dow:7,doy:12}})}(e("PJh5"))},rtsW:function(n,t,e){!function(n){"use strict";var t={1:"\u0ae7",2:"\u0ae8",3:"\u0ae9",4:"\u0aea",5:"\u0aeb",6:"\u0aec",7:"\u0aed",8:"\u0aee",9:"\u0aef",0:"\u0ae6"},e={"\u0ae7":"1","\u0ae8":"2","\u0ae9":"3","\u0aea":"4","\u0aeb":"5","\u0aec":"6","\u0aed":"7","\u0aee":"8","\u0aef":"9","\u0ae6":"0"};n.defineLocale("gu",{months:"\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1\u0a86\u0ab0\u0ac0_\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1\u0a86\u0ab0\u0ac0_\u0aae\u0abe\u0ab0\u0acd\u0a9a_\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2_\u0aae\u0ac7_\u0a9c\u0ac2\u0aa8_\u0a9c\u0ac1\u0ab2\u0abe\u0a88_\u0a91\u0a97\u0ab8\u0acd\u0a9f_\u0ab8\u0aaa\u0acd\u0a9f\u0ac7\u0aae\u0acd\u0aac\u0ab0_\u0a91\u0a95\u0acd\u0a9f\u0acd\u0aac\u0ab0_\u0aa8\u0ab5\u0ac7\u0aae\u0acd\u0aac\u0ab0_\u0aa1\u0abf\u0ab8\u0ac7\u0aae\u0acd\u0aac\u0ab0".split("_"),monthsShort:"\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1._\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1._\u0aae\u0abe\u0ab0\u0acd\u0a9a_\u0a8f\u0aaa\u0acd\u0ab0\u0abf._\u0aae\u0ac7_\u0a9c\u0ac2\u0aa8_\u0a9c\u0ac1\u0ab2\u0abe._\u0a91\u0a97._\u0ab8\u0aaa\u0acd\u0a9f\u0ac7._\u0a91\u0a95\u0acd\u0a9f\u0acd._\u0aa8\u0ab5\u0ac7._\u0aa1\u0abf\u0ab8\u0ac7.".split("_"),monthsParseExact:!0,weekdays:"\u0ab0\u0ab5\u0abf\u0ab5\u0abe\u0ab0_\u0ab8\u0acb\u0aae\u0ab5\u0abe\u0ab0_\u0aae\u0a82\u0a97\u0ab3\u0ab5\u0abe\u0ab0_\u0aac\u0ac1\u0aa7\u0acd\u0ab5\u0abe\u0ab0_\u0a97\u0ac1\u0ab0\u0ac1\u0ab5\u0abe\u0ab0_\u0ab6\u0ac1\u0a95\u0acd\u0ab0\u0ab5\u0abe\u0ab0_\u0ab6\u0aa8\u0abf\u0ab5\u0abe\u0ab0".split("_"),weekdaysShort:"\u0ab0\u0ab5\u0abf_\u0ab8\u0acb\u0aae_\u0aae\u0a82\u0a97\u0ab3_\u0aac\u0ac1\u0aa7\u0acd_\u0a97\u0ac1\u0ab0\u0ac1_\u0ab6\u0ac1\u0a95\u0acd\u0ab0_\u0ab6\u0aa8\u0abf".split("_"),weekdaysMin:"\u0ab0_\u0ab8\u0acb_\u0aae\u0a82_\u0aac\u0ac1_\u0a97\u0ac1_\u0ab6\u0ac1_\u0ab6".split("_"),longDateFormat:{LT:"A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",LTS:"A h:mm:ss \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",LLLL:"dddd, D MMMM YYYY, A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7"},calendar:{sameDay:"[\u0a86\u0a9c] LT",nextDay:"[\u0a95\u0abe\u0ab2\u0ac7] LT",nextWeek:"dddd, LT",lastDay:"[\u0a97\u0a87\u0a95\u0abe\u0ab2\u0ac7] LT",lastWeek:"[\u0aaa\u0abe\u0a9b\u0ab2\u0abe] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0aae\u0abe",past:"%s \u0aaa\u0ac7\u0ab9\u0ab2\u0abe",s:"\u0a85\u0aae\u0ac1\u0a95 \u0aaa\u0ab3\u0acb",ss:"%d \u0ab8\u0ac7\u0a95\u0a82\u0aa1",m:"\u0a8f\u0a95 \u0aae\u0abf\u0aa8\u0abf\u0a9f",mm:"%d \u0aae\u0abf\u0aa8\u0abf\u0a9f",h:"\u0a8f\u0a95 \u0a95\u0ab2\u0abe\u0a95",hh:"%d \u0a95\u0ab2\u0abe\u0a95",d:"\u0a8f\u0a95 \u0aa6\u0abf\u0ab5\u0ab8",dd:"%d \u0aa6\u0abf\u0ab5\u0ab8",M:"\u0a8f\u0a95 \u0aae\u0ab9\u0abf\u0aa8\u0acb",MM:"%d \u0aae\u0ab9\u0abf\u0aa8\u0acb",y:"\u0a8f\u0a95 \u0ab5\u0ab0\u0acd\u0ab7",yy:"%d \u0ab5\u0ab0\u0acd\u0ab7"},preparse:function(n){return n.replace(/[\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0ae6]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u0ab0\u0abe\u0aa4|\u0aac\u0aaa\u0acb\u0ab0|\u0ab8\u0ab5\u0abe\u0ab0|\u0ab8\u0abe\u0a82\u0a9c/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0ab0\u0abe\u0aa4"===t?n<4?n:n+12:"\u0ab8\u0ab5\u0abe\u0ab0"===t?n:"\u0aac\u0aaa\u0acb\u0ab0"===t?n>=10?n:n+12:"\u0ab8\u0abe\u0a82\u0a9c"===t?n+12:void 0},meridiem:function(n,t,e){return n<4?"\u0ab0\u0abe\u0aa4":n<10?"\u0ab8\u0ab5\u0abe\u0ab0":n<17?"\u0aac\u0aaa\u0acb\u0ab0":n<20?"\u0ab8\u0abe\u0a82\u0a9c":"\u0ab0\u0abe\u0aa4"},week:{dow:0,doy:6}})}(e("PJh5"))},rxKx:function(n,t,e){var l;!function(r,i,o,s){"use strict";var a,u=["","webkit","Moz","MS","ms","o"],c=i.createElement("div"),d="function",h=Math.round,p=Math.abs,f=Date.now;function _(n,t,e){return setTimeout(x(n,e),t)}function m(n,t,e){return!!Array.isArray(n)&&(g(n,e[t],e),!0)}function g(n,t,e){var l;if(n)if(n.forEach)n.forEach(t,e);else if(n.length!==s)for(l=0;l\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",i=r.console&&(r.console.warn||r.console.log);return i&&i.call(r.console,l,e),n.apply(this,arguments)}}a="function"!=typeof Object.assign?function(n){if(n===s||null===n)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(n),e=1;e-1}function L(n){return n.trim().split(/\s+/g)}function P(n,t,e){if(n.indexOf&&!e)return n.indexOf(t);for(var l=0;le[t]}):l.sort()),l}function E(n,t){for(var e,l,r=t[0].toUpperCase()+t.slice(1),i=0;i1&&!e.firstMultiple?e.firstMultiple=tn(t):1===r&&(e.firstMultiple=!1);var i=e.firstInput,o=e.firstMultiple,a=o?o.center:i.center,u=t.center=en(l);t.timeStamp=f(),t.deltaTime=t.timeStamp-i.timeStamp,t.angle=sn(a,u),t.distance=on(a,u),function(n,t){var e=t.center,l=n.offsetDelta||{},r=n.prevDelta||{},i=n.prevInput||{};t.eventType!==F&&i.eventType!==B||(r=n.prevDelta={x:i.deltaX||0,y:i.deltaY||0},l=n.offsetDelta={x:e.x,y:e.y}),t.deltaX=r.x+(e.x-l.x),t.deltaY=r.y+(e.y-l.y)}(e,t),t.offsetDirection=rn(t.deltaX,t.deltaY);var c,d,h=ln(t.deltaTime,t.deltaX,t.deltaY);t.overallVelocityX=h.x,t.overallVelocityY=h.y,t.overallVelocity=p(h.x)>p(h.y)?h.x:h.y,t.scale=o?(c=o.pointers,on((d=l)[0],d[1],Z)/on(c[0],c[1],Z)):1,t.rotation=o?function(n,t){return sn(l[1],l[0],Z)+sn(n[1],n[0],Z)}(o.pointers):0,t.maxPointers=e.prevInput?t.pointers.length>e.prevInput.maxPointers?t.pointers.length:e.prevInput.maxPointers:t.pointers.length,function(n,t){var e,l,r,i,o=n.lastInterval||t,a=t.timeStamp-o.timeStamp;if(t.eventType!=V&&(a>N||o.velocity===s)){var u=t.deltaX-o.deltaX,c=t.deltaY-o.deltaY,d=ln(a,u,c);l=d.x,r=d.y,e=p(d.x)>p(d.y)?d.x:d.y,i=rn(u,c),n.lastInterval=t}else e=o.velocity,l=o.velocityX,r=o.velocityY,i=o.direction;t.velocity=e,t.velocityX=l,t.velocityY=r,t.direction=i}(e,t);var _=n.element;O(t.srcEvent.target,_)&&(_=t.srcEvent.target),t.target=_}(n,e),n.emit("hammer.input",e),n.recognize(e),n.session.prevInput=e}function tn(n){for(var t=[],e=0;e=p(t)?n<0?z:U:t<0?G:q}function on(n,t,e){e||(e=X);var l=t[e[0]]-n[e[0]],r=t[e[1]]-n[e[1]];return Math.sqrt(l*l+r*r)}function sn(n,t,e){return e||(e=X),180*Math.atan2(t[e[1]]-n[e[1]],t[e[0]]-n[e[0]])/Math.PI}$.prototype={handler:function(){},init:function(){this.evEl&&C(this.element,this.evEl,this.domHandler),this.evTarget&&C(this.target,this.evTarget,this.domHandler),this.evWin&&C(j(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&S(this.element,this.evEl,this.domHandler),this.evTarget&&S(this.target,this.evTarget,this.domHandler),this.evWin&&S(j(this.element),this.evWin,this.domHandler)}};var an={mousedown:F,mousemove:2,mouseup:B},un="mousedown",cn="mousemove mouseup";function dn(){this.evEl=un,this.evWin=cn,this.pressed=!1,$.apply(this,arguments)}w(dn,$,{handler:function(n){var t=an[n.type];t&F&&0===n.button&&(this.pressed=!0),2&t&&1!==n.which&&(t=B),this.pressed&&(t&B&&(this.pressed=!1),this.callback(this.manager,t,{pointers:[n],changedPointers:[n],pointerType:"mouse",srcEvent:n}))}});var hn={pointerdown:F,pointermove:2,pointerup:B,pointercancel:V,pointerout:V},pn={2:"touch",3:"pen",4:"mouse",5:"kinect"},fn="pointerdown",_n="pointermove pointerup pointercancel";function mn(){this.evEl=fn,this.evWin=_n,$.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}r.MSPointerEvent&&!r.PointerEvent&&(fn="MSPointerDown",_n="MSPointerMove MSPointerUp MSPointerCancel"),w(mn,$,{handler:function(n){var t=this.store,e=!1,l=n.type.toLowerCase().replace("ms",""),r=hn[l],i=pn[n.pointerType]||n.pointerType,o="touch"==i,s=P(t,n.pointerId,"pointerId");r&F&&(0===n.button||o)?s<0&&(t.push(n),s=t.length-1):r&(B|V)&&(e=!0),s<0||(t[s]=n,this.callback(this.manager,r,{pointers:t,changedPointers:[n],pointerType:i,srcEvent:n}),e&&t.splice(s,1))}});var gn={touchstart:F,touchmove:2,touchend:B,touchcancel:V},yn="touchstart",bn="touchstart touchmove touchend touchcancel";function vn(){this.evTarget=yn,this.evWin=bn,this.started=!1,$.apply(this,arguments)}w(vn,$,{handler:function(n){var t=gn[n.type];if(t===F&&(this.started=!0),this.started){var e=(function(n,t){var e=D(n.touches),l=D(n.changedTouches);return t&(B|V)&&(e=A(e.concat(l),"identifier",!0)),[e,l]}).call(this,n,t);t&(B|V)&&e[0].length-e[1].length==0&&(this.started=!1),this.callback(this.manager,t,{pointers:e[0],changedPointers:e[1],pointerType:"touch",srcEvent:n})}}});var wn={touchstart:F,touchmove:2,touchend:B,touchcancel:V},xn="touchstart touchmove touchend touchcancel";function Mn(){this.evTarget=xn,this.targetIds={},$.apply(this,arguments)}w(Mn,$,{handler:function(n){var t=wn[n.type],e=(function(n,t){var e=D(n.touches),l=this.targetIds;if(t&(2|F)&&1===e.length)return l[e[0].identifier]=!0,[e,e];var r,i,o=D(n.changedTouches),s=[],a=this.target;if(i=e.filter(function(n){return O(n.target,a)}),t===F)for(r=0;r-1&&l.splice(n,1)},kn)}}w(Cn,$,{handler:function(n,t,e){var l="mouse"==e.pointerType;if(!(l&&e.sourceCapabilities&&e.sourceCapabilities.firesTouchEvents)){if("touch"==e.pointerType)(function(n,t){n&F?(this.primaryTouch=t.changedPointers[0].identifier,Sn.call(this,t)):n&(B|V)&&Sn.call(this,t)}).call(this,t,e);else if(l&&(function(n){for(var t=n.srcEvent.clientX,e=n.srcEvent.clientY,l=0;l-1&&this.requireFail.splice(t,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(n){return!!this.simultaneous[n.id]},emit:function(n){var t=this,e=this.state;function l(e){t.manager.emit(e,n)}e=Yn&&l(t.options.event+Hn(e))},tryEmit:function(n){if(this.canEmit())return this.emit(n);this.state=32},canEmit:function(){for(var n=0;nt.threshold&&r&t.direction},attrTest:function(n){return Bn.prototype.attrTest.call(this,n)&&(this.state&An||!(this.state&An)&&this.directionTest(n))},emit:function(n){this.pX=n.deltaX,this.pY=n.deltaY;var t=Nn(n.direction);t&&(n.additionalEvent=this.options.event+t),this._super.emit.call(this,n)}}),w(Wn,Bn,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return["none"]},attrTest:function(n){return this._super.attrTest.call(this,n)&&(Math.abs(n.scale-1)>this.options.threshold||this.state&An)},emit:function(n){1!==n.scale&&(n.additionalEvent=this.options.event+(n.scale<1?"in":"out")),this._super.emit.call(this,n)}}),w(zn,Rn,{defaults:{event:"press",pointers:1,time:251,threshold:9},getTouchAction:function(){return["auto"]},process:function(n){var t=this.options,e=n.pointers.length===t.pointers,l=n.distancet.time;if(this._input=n,!l||!e||n.eventType&(B|V)&&!r)this.reset();else if(n.eventType&F)this.reset(),this._timer=_(function(){this.state=jn,this.tryEmit()},t.time,this);else if(n.eventType&B)return jn;return 32},reset:function(){clearTimeout(this._timer)},emit:function(n){this.state===jn&&(n&&n.eventType&B?this.manager.emit(this.options.event+"up",n):(this._input.timeStamp=f(),this.manager.emit(this.options.event,this._input)))}}),w(Un,Bn,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return["none"]},attrTest:function(n){return this._super.attrTest.call(this,n)&&(Math.abs(n.rotation)>this.options.threshold||this.state&An)}}),w(Gn,Bn,{defaults:{event:"swipe",threshold:10,velocity:.3,direction:J|Q,pointers:1},getTouchAction:function(){return Vn.prototype.getTouchAction.call(this)},attrTest:function(n){var t,e=this.options.direction;return e&(J|Q)?t=n.overallVelocity:e&J?t=n.overallVelocityX:e&Q&&(t=n.overallVelocityY),this._super.attrTest.call(this,n)&&e&n.offsetDirection&&n.distance>this.options.threshold&&n.maxPointers==this.options.pointers&&p(t)>this.options.velocity&&n.eventType&B},emit:function(n){var t=Nn(n.offsetDirection);t&&this.manager.emit(this.options.event+t,n),this.manager.emit(this.options.event,n)}}),w(qn,Rn,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function(){return["manipulation"]},process:function(n){var t=this.options,e=n.pointers.length===t.pointers,l=n.distance1&&n<5&&1!=~~(n/10)}function r(n,t,e,r){var i=n+" ";switch(e){case"s":return t||r?"p\xe1r sekund":"p\xe1r sekundami";case"ss":return t||r?i+(l(n)?"sekundy":"sekund"):i+"sekundami";case"m":return t?"minuta":r?"minutu":"minutou";case"mm":return t||r?i+(l(n)?"minuty":"minut"):i+"minutami";case"h":return t?"hodina":r?"hodinu":"hodinou";case"hh":return t||r?i+(l(n)?"hodiny":"hodin"):i+"hodinami";case"d":return t||r?"den":"dnem";case"dd":return t||r?i+(l(n)?"dny":"dn\xed"):i+"dny";case"M":return t||r?"m\u011bs\xedc":"m\u011bs\xedcem";case"MM":return t||r?i+(l(n)?"m\u011bs\xedce":"m\u011bs\xedc\u016f"):i+"m\u011bs\xedci";case"y":return t||r?"rok":"rokem";case"yy":return t||r?i+(l(n)?"roky":"let"):i+"lety"}}n.defineLocale("cs",{months:t,monthsShort:e,monthsParse:function(n,t){var e,l=[];for(e=0;e<12;e++)l[e]=new RegExp("^"+n[e]+"$|^"+t[e]+"$","i");return l}(t,e),shortMonthsParse:function(n){var t,e=[];for(t=0;t<12;t++)e[t]=new RegExp("^"+n[t]+"$","i");return e}(e),longMonthsParse:function(n){var t,e=[];for(t=0;t<12;t++)e[t]=new RegExp("^"+n[t]+"$","i");return e}(t),weekdays:"ned\u011ble_pond\u011bl\xed_\xfater\xfd_st\u0159eda_\u010dtvrtek_p\xe1tek_sobota".split("_"),weekdaysShort:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),weekdaysMin:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[z\xedtra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v ned\u011bli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve st\u0159edu v] LT";case 4:return"[ve \u010dtvrtek v] LT";case 5:return"[v p\xe1tek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[v\u010dera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou ned\u011bli v] LT";case 1:case 2:return"[minul\xe9] dddd [v] LT";case 3:return"[minulou st\u0159edu v] LT";case 4:case 5:return"[minul\xfd] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"p\u0159ed %s",s:r,ss:r,m:r,mm:r,h:r,hh:r,d:r,dd:r,M:r,MM:r,y:r,yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},svD2:function(n,t,e){!function(n){"use strict";var t={words:{ss:["sekund","sekunda","sekundi"],m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mjesec","mjeseca","mjeseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(n,t){return 1===n?t[0]:n>=2&&n<=4?t[1]:t[2]},translate:function(n,e,l){var r=t.words[l];return 1===l.length?e?r[0]:r[1]:n+" "+t.correctGrammaticalCase(n,r)}};n.defineLocale("me",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sjutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010de u] LT",lastWeek:function(){return["[pro\u0161le] [nedjelje] [u] LT","[pro\u0161log] [ponedjeljka] [u] LT","[pro\u0161log] [utorka] [u] LT","[pro\u0161le] [srijede] [u] LT","[pro\u0161log] [\u010detvrtka] [u] LT","[pro\u0161log] [petka] [u] LT","[pro\u0161le] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"nekoliko sekundi",ss:t.translate,m:t.translate,mm:t.translate,h:t.translate,hh:t.translate,d:"dan",dd:t.translate,M:"mjesec",MM:t.translate,y:"godinu",yy:t.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e("PJh5"))},t7NR:function(n,t,e){"use strict";e.d(t,"a",function(){return l});var l={closed:!0,next:function(n){},error:function(n){throw n},complete:function(){}}},tLDX:function(n,t,e){"use strict";e.d(t,"a",function(){return r});var l=e("AMGY").a.Symbol,r="function"==typeof l&&"function"==typeof l.for?l.for("rxSubscriber"):"@@rxSubscriber"},tZ2B:function(n,t,e){"use strict";e.d(t,"a",function(){return r});var l=e("TToO"),r=function(n){function t(){n.apply(this,arguments)}return Object(l.__extends)(t,n),t.prototype.notifyNext=function(n,t,e,l,r){this.destination.next(t)},t.prototype.notifyError=function(n,t){this.destination.error(n)},t.prototype.notifyComplete=function(n){this.destination.complete()},t}(e("OVmG").a)},tkWw:function(n,t,e){!function(n){"use strict";n.defineLocale("ar-dz",{months:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u0623\u062d_\u0625\u062b_\u062b\u0644\u0627_\u0623\u0631_\u062e\u0645_\u062c\u0645_\u0633\u0628".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:0,doy:4}})}(e("PJh5"))},tzHd:function(n,t,e){!function(n){"use strict";n.defineLocale("fr",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|)/,ordinal:function(n,t){switch(t){case"D":return n+(1===n?"er":"");default:case"M":case"Q":case"DDD":case"d":return n+(1===n?"er":"e");case"w":case"W":return n+(1===n?"re":"e")}},week:{dow:1,doy:4}})}(e("PJh5"))},uSe8:function(n,t,e){!function(n){"use strict";var t=["\u062c\u0646\u0648\u0631\u06cc","\u0641\u0631\u0648\u0631\u06cc","\u0645\u0627\u0631\u0686","\u0627\u067e\u0631\u06cc\u0644","\u0645\u0626\u06cc","\u062c\u0648\u0646","\u062c\u0648\u0644\u0627\u0626\u06cc","\u0627\u06af\u0633\u062a","\u0633\u062a\u0645\u0628\u0631","\u0627\u06a9\u062a\u0648\u0628\u0631","\u0646\u0648\u0645\u0628\u0631","\u062f\u0633\u0645\u0628\u0631"],e=["\u0627\u062a\u0648\u0627\u0631","\u067e\u06cc\u0631","\u0645\u0646\u06af\u0644","\u0628\u062f\u06be","\u062c\u0645\u0639\u0631\u0627\u062a","\u062c\u0645\u0639\u06c1","\u06c1\u0641\u062a\u06c1"];n.defineLocale("ur",{months:t,monthsShort:t,weekdays:e,weekdaysShort:e,weekdaysMin:e,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd\u060c D MMMM YYYY HH:mm"},meridiemParse:/\u0635\u0628\u062d|\u0634\u0627\u0645/,isPM:function(n){return"\u0634\u0627\u0645"===n},meridiem:function(n,t,e){return n<12?"\u0635\u0628\u062d":"\u0634\u0627\u0645"},calendar:{sameDay:"[\u0622\u062c \u0628\u0648\u0642\u062a] LT",nextDay:"[\u06a9\u0644 \u0628\u0648\u0642\u062a] LT",nextWeek:"dddd [\u0628\u0648\u0642\u062a] LT",lastDay:"[\u06af\u0630\u0634\u062a\u06c1 \u0631\u0648\u0632 \u0628\u0648\u0642\u062a] LT",lastWeek:"[\u06af\u0630\u0634\u062a\u06c1] dddd [\u0628\u0648\u0642\u062a] LT",sameElse:"L"},relativeTime:{future:"%s \u0628\u0639\u062f",past:"%s \u0642\u0628\u0644",s:"\u0686\u0646\u062f \u0633\u06cc\u06a9\u0646\u0688",ss:"%d \u0633\u06cc\u06a9\u0646\u0688",m:"\u0627\u06cc\u06a9 \u0645\u0646\u0679",mm:"%d \u0645\u0646\u0679",h:"\u0627\u06cc\u06a9 \u06af\u06be\u0646\u0679\u06c1",hh:"%d \u06af\u06be\u0646\u0679\u06d2",d:"\u0627\u06cc\u06a9 \u062f\u0646",dd:"%d \u062f\u0646",M:"\u0627\u06cc\u06a9 \u0645\u0627\u06c1",MM:"%d \u0645\u0627\u06c1",y:"\u0627\u06cc\u06a9 \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(n){return n.replace(/\u060c/g,",")},postformat:function(n){return n.replace(/,/g,"\u060c")},week:{dow:1,doy:4}})}(e("PJh5"))},ujcs:function(n,t){t.read=function(n,t,e,l,r){var i,o,s=8*r-l-1,a=(1<>1,c=-7,d=e?r-1:0,h=e?-1:1,p=n[t+d];for(d+=h,i=p&(1<<-c)-1,p>>=-c,c+=s;c>0;i=256*i+n[t+d],d+=h,c-=8);for(o=i&(1<<-c)-1,i>>=-c,c+=l;c>0;o=256*o+n[t+d],d+=h,c-=8);if(0===i)i=1-u;else{if(i===a)return o?NaN:1/0*(p?-1:1);o+=Math.pow(2,l),i-=u}return(p?-1:1)*o*Math.pow(2,i-l)},t.write=function(n,t,e,l,r,i){var o,s,a,u=8*i-r-1,c=(1<>1,h=23===r?Math.pow(2,-24)-Math.pow(2,-77):0,p=l?0:i-1,f=l?1:-1,_=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(a=Math.pow(2,-o))<1&&(o--,a*=2),(t+=o+d>=1?h/a:h*Math.pow(2,1-d))*a>=2&&(o++,a/=2),o+d>=c?(s=0,o=c):o+d>=1?(s=(t*a-1)*Math.pow(2,r),o+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,r),o=0));r>=8;n[e+p]=255&s,p+=f,s/=256,r-=8);for(o=o<0;n[e+p]=255&o,p+=f,o/=256,u-=8);n[e+p-f]|=128*_}},ulq9:function(n,t,e){!function(n){"use strict";function t(n,t,e){var l,r;return"m"===e?t?"\u043c\u0438\u043d\u0443\u0442\u0430":"\u043c\u0438\u043d\u0443\u0442\u0443":n+" "+(l=+n,r={ss:t?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434",mm:t?"\u043c\u0438\u043d\u0443\u0442\u0430_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442":"\u043c\u0438\u043d\u0443\u0442\u0443_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442",hh:"\u0447\u0430\u0441_\u0447\u0430\u0441\u0430_\u0447\u0430\u0441\u043e\u0432",dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u044f_\u0434\u043d\u0435\u0439",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u0430_\u043c\u0435\u0441\u044f\u0446\u0435\u0432",yy:"\u0433\u043e\u0434_\u0433\u043e\u0434\u0430_\u043b\u0435\u0442"}[e].split("_"),l%10==1&&l%100!=11?r[0]:l%10>=2&&l%10<=4&&(l%100<10||l%100>=20)?r[1]:r[2])}var e=[/^\u044f\u043d\u0432/i,/^\u0444\u0435\u0432/i,/^\u043c\u0430\u0440/i,/^\u0430\u043f\u0440/i,/^\u043c\u0430[\u0439\u044f]/i,/^\u0438\u044e\u043d/i,/^\u0438\u044e\u043b/i,/^\u0430\u0432\u0433/i,/^\u0441\u0435\u043d/i,/^\u043e\u043a\u0442/i,/^\u043d\u043e\u044f/i,/^\u0434\u0435\u043a/i];n.defineLocale("ru",{months:{format:"\u044f\u043d\u0432\u0430\u0440\u044f_\u0444\u0435\u0432\u0440\u0430\u043b\u044f_\u043c\u0430\u0440\u0442\u0430_\u0430\u043f\u0440\u0435\u043b\u044f_\u043c\u0430\u044f_\u0438\u044e\u043d\u044f_\u0438\u044e\u043b\u044f_\u0430\u0432\u0433\u0443\u0441\u0442\u0430_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f_\u043e\u043a\u0442\u044f\u0431\u0440\u044f_\u043d\u043e\u044f\u0431\u0440\u044f_\u0434\u0435\u043a\u0430\u0431\u0440\u044f".split("_"),standalone:"\u044f\u043d\u0432\u0430\u0440\u044c_\u0444\u0435\u0432\u0440\u0430\u043b\u044c_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b\u044c_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c_\u043e\u043a\u0442\u044f\u0431\u0440\u044c_\u043d\u043e\u044f\u0431\u0440\u044c_\u0434\u0435\u043a\u0430\u0431\u0440\u044c".split("_")},monthsShort:{format:"\u044f\u043d\u0432._\u0444\u0435\u0432\u0440._\u043c\u0430\u0440._\u0430\u043f\u0440._\u043c\u0430\u044f_\u0438\u044e\u043d\u044f_\u0438\u044e\u043b\u044f_\u0430\u0432\u0433._\u0441\u0435\u043d\u0442._\u043e\u043a\u0442._\u043d\u043e\u044f\u0431._\u0434\u0435\u043a.".split("_"),standalone:"\u044f\u043d\u0432._\u0444\u0435\u0432\u0440._\u043c\u0430\u0440\u0442_\u0430\u043f\u0440._\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433._\u0441\u0435\u043d\u0442._\u043e\u043a\u0442._\u043d\u043e\u044f\u0431._\u0434\u0435\u043a.".split("_")},weekdays:{standalone:"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0435\u0440\u0433_\u043f\u044f\u0442\u043d\u0438\u0446\u0430_\u0441\u0443\u0431\u0431\u043e\u0442\u0430".split("_"),format:"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0443_\u0447\u0435\u0442\u0432\u0435\u0440\u0433_\u043f\u044f\u0442\u043d\u0438\u0446\u0443_\u0441\u0443\u0431\u0431\u043e\u0442\u0443".split("_"),isFormat:/\[ ?[\u0412\u0432] ?(?:\u043f\u0440\u043e\u0448\u043b\u0443\u044e|\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e|\u044d\u0442\u0443)? ?\] ?dddd/},weekdaysShort:"\u0432\u0441_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u0432\u0441_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),monthsParse:e,longMonthsParse:e,shortMonthsParse:e,monthsRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044c\u044f]|\u044f\u043d\u0432\.?|\u0444\u0435\u0432\u0440\u0430\u043b[\u044c\u044f]|\u0444\u0435\u0432\u0440?\.?|\u043c\u0430\u0440\u0442\u0430?|\u043c\u0430\u0440\.?|\u0430\u043f\u0440\u0435\u043b[\u044c\u044f]|\u0430\u043f\u0440\.?|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d[\u044c\u044f]|\u0438\u044e\u043d\.?|\u0438\u044e\u043b[\u044c\u044f]|\u0438\u044e\u043b\.?|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0430\u0432\u0433\.?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044c\u044f]|\u0441\u0435\u043d\u0442?\.?|\u043e\u043a\u0442\u044f\u0431\u0440[\u044c\u044f]|\u043e\u043a\u0442\.?|\u043d\u043e\u044f\u0431\u0440[\u044c\u044f]|\u043d\u043e\u044f\u0431?\.?|\u0434\u0435\u043a\u0430\u0431\u0440[\u044c\u044f]|\u0434\u0435\u043a\.?)/i,monthsShortRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044c\u044f]|\u044f\u043d\u0432\.?|\u0444\u0435\u0432\u0440\u0430\u043b[\u044c\u044f]|\u0444\u0435\u0432\u0440?\.?|\u043c\u0430\u0440\u0442\u0430?|\u043c\u0430\u0440\.?|\u0430\u043f\u0440\u0435\u043b[\u044c\u044f]|\u0430\u043f\u0440\.?|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d[\u044c\u044f]|\u0438\u044e\u043d\.?|\u0438\u044e\u043b[\u044c\u044f]|\u0438\u044e\u043b\.?|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0430\u0432\u0433\.?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044c\u044f]|\u0441\u0435\u043d\u0442?\.?|\u043e\u043a\u0442\u044f\u0431\u0440[\u044c\u044f]|\u043e\u043a\u0442\.?|\u043d\u043e\u044f\u0431\u0440[\u044c\u044f]|\u043d\u043e\u044f\u0431?\.?|\u0434\u0435\u043a\u0430\u0431\u0440[\u044c\u044f]|\u0434\u0435\u043a\.?)/i,monthsStrictRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044f\u044c]|\u0444\u0435\u0432\u0440\u0430\u043b[\u044f\u044c]|\u043c\u0430\u0440\u0442\u0430?|\u0430\u043f\u0440\u0435\u043b[\u044f\u044c]|\u043c\u0430[\u044f\u0439]|\u0438\u044e\u043d[\u044f\u044c]|\u0438\u044e\u043b[\u044f\u044c]|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044f\u044c]|\u043e\u043a\u0442\u044f\u0431\u0440[\u044f\u044c]|\u043d\u043e\u044f\u0431\u0440[\u044f\u044c]|\u0434\u0435\u043a\u0430\u0431\u0440[\u044f\u044c])/i,monthsShortStrictRegex:/^(\u044f\u043d\u0432\.|\u0444\u0435\u0432\u0440?\.|\u043c\u0430\u0440[\u0442.]|\u0430\u043f\u0440\.|\u043c\u0430[\u044f\u0439]|\u0438\u044e\u043d[\u044c\u044f.]|\u0438\u044e\u043b[\u044c\u044f.]|\u0430\u0432\u0433\.|\u0441\u0435\u043d\u0442?\.|\u043e\u043a\u0442\.|\u043d\u043e\u044f\u0431?\.|\u0434\u0435\u043a\.)/i,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0433.",LLL:"D MMMM YYYY \u0433., H:mm",LLLL:"dddd, D MMMM YYYY \u0433., H:mm"},calendar:{sameDay:"[\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0432] LT",nextDay:"[\u0417\u0430\u0432\u0442\u0440\u0430 \u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432] LT",nextWeek:function(n){if(n.week()===this.week())return 2===this.day()?"[\u0412\u043e] dddd [\u0432] LT":"[\u0412] dddd [\u0432] LT";switch(this.day()){case 0:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435] dddd [\u0432] LT";case 1:case 2:case 4:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439] dddd [\u0432] LT";case 3:case 5:case 6:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e] dddd [\u0432] LT"}},lastWeek:function(n){if(n.week()===this.week())return 2===this.day()?"[\u0412\u043e] dddd [\u0432] LT":"[\u0412] dddd [\u0432] LT";switch(this.day()){case 0:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0435] dddd [\u0432] LT";case 1:case 2:case 4:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0439] dddd [\u0432] LT";case 3:case 5:case 6:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u0443\u044e] dddd [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0447\u0435\u0440\u0435\u0437 %s",past:"%s \u043d\u0430\u0437\u0430\u0434",s:"\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434",ss:t,m:t,mm:t,h:"\u0447\u0430\u0441",hh:t,d:"\u0434\u0435\u043d\u044c",dd:t,M:"\u043c\u0435\u0441\u044f\u0446",MM:t,y:"\u0433\u043e\u0434",yy:t},meridiemParse:/\u043d\u043e\u0447\u0438|\u0443\u0442\u0440\u0430|\u0434\u043d\u044f|\u0432\u0435\u0447\u0435\u0440\u0430/i,isPM:function(n){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u0435\u0440\u0430)$/.test(n)},meridiem:function(n,t,e){return n<4?"\u043d\u043e\u0447\u0438":n<12?"\u0443\u0442\u0440\u0430":n<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u0435\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0439|\u0433\u043e|\u044f)/,ordinal:function(n,t){switch(t){case"M":case"d":case"DDD":return n+"-\u0439";case"D":return n+"-\u0433\u043e";case"w":case"W":return n+"-\u044f";default:return n}},week:{dow:1,doy:4}})}(e("PJh5"))},uotZ:function(n,t,e){var l;!function(r){"use strict";var i,o=/^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i,s=Math.ceil,a=Math.floor,u="[BigNumber Error] ",c=u+"Number primitive has more than 15 significant digits: ",d=1e14,h=14,p=9007199254740991,f=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],_=1e7;function m(n){var t=0|n;return n>0||n===t?t:t-1}function g(n){for(var t,e,l=1,r=n.length,i=n[0]+"";lu^e?1:-1;for(s=(a=r.length)<(u=i.length)?a:u,o=0;oi[o]^e?1:-1;return a==u?0:a>u^e?1:-1}function b(n,t,e,l){if(ne||n!==(n<0?s(n):a(n)))throw Error(u+(l||"Argument")+("number"==typeof n?ne?" out of range: ":" not an integer: ":" not a primitive number: ")+n)}function v(n){return"[object Array]"==Object.prototype.toString.call(n)}function w(n){var t=n.c.length-1;return m(n.e/h)==t&&n.c[t]%2!=0}function x(n,t){return(n.length>1?n.charAt(0)+"."+n.slice(1):n)+(t<0?"e":"e+")+t}function M(n,t,e){var l,r;if(t<0){for(r=e+".";++t;r+=e);n=r+n}else if(++t>(l=n.length)){for(r=e,t-=l;--t;r+=e);n+=r}else t=10;d/=10,u++);return g.e=u,void(g.c=[n])}m=n+""}else{if(!o.test(m=n+""))return r(g,m,f);g.s=45==m.charCodeAt(0)?(m=m.slice(1),-1):1}(u=m.indexOf("."))>-1&&(m=m.replace(".","")),(d=m.search(/e/i))>0?(u<0&&(u=d),u+=+m.slice(d+1),m=m.substring(0,d)):u<0&&(u=m.length)}else{if(b(t,2,B.length,"Base"),m=n+"",10==t)return G(g=new V(n instanceof V?n:m),D+g.e+1,A);if(f="number"==typeof n){if(0*n!=0)return r(g,m,f,t);if(g.s=1/n<0?(m=m.slice(1),-1):1,V.DEBUG&&m.replace(/^0\.0*|\./,"").length>15)throw Error(c+n);f=!1}else g.s=45===m.charCodeAt(0)?(m=m.slice(1),-1):1;for(e=B.slice(0,t),u=d=0,_=m.length;d<_;d++)if(e.indexOf(i=m.charAt(d))<0){if("."==i){if(d>u){u=_;continue}}else if(!s&&(m==m.toUpperCase()&&(m=m.toLowerCase())||m==m.toLowerCase()&&(m=m.toUpperCase()))){s=!0,d=-1,u=0;continue}return r(g,n+"",f,t)}(u=(m=l(m,t,10,g.s)).indexOf("."))>-1?m=m.replace(".",""):u=m.length}for(d=0;48===m.charCodeAt(d);d++);for(_=m.length;48===m.charCodeAt(--_););if(m=m.slice(d,++_)){if(_-=d,f&&V.DEBUG&&_>15&&(n>p||n!==a(n)))throw Error(c+g.s*n);if((u=u-d-1)>I)g.c=g.e=null;else if(us){if(--t>0)for(a+=".";t--;a+="0");}else if((t+=i-s)>0)for(i+1==s&&(a+=".");t--;a+="0");return n.s<0&&r?"-"+a:a}function z(n,t){var e,l,r=0;for(v(n[0])&&(n=n[0]),e=new V(n[0]);++r=10;r/=10,l++);return(e=l+e*h-1)>I?n.c=n.e=null:e=10;u/=10,r++);if((i=t-r)<0)i+=h,_=(c=m[p=0])/g[r-(o=t)-1]%10|0;else if((p=s((i+1)/h))>=m.length){if(!l)break n;for(;m.length<=p;m.push(0));c=_=0,r=1,o=(i%=h)-h+1}else{for(c=u=m[p],r=1;u>=10;u/=10,r++);_=(o=(i%=h)-h+r)<0?0:c/g[r-o-1]%10|0}if(l=l||t<0||null!=m[p+1]||(o<0?c:c%g[r-o-1]),l=e<4?(_||l)&&(0==e||e==(n.s<0?3:2)):_>5||5==_&&(4==e||l||6==e&&(i>0?o>0?c/g[r-o]:0:m[p-1])%10&1||e==(n.s<0?8:7)),t<1||!m[0])return m.length=0,l?(m[0]=g[(h-(t-=n.e+1)%h)%h],n.e=-t||0):m[0]=n.e=0,n;if(0==i?(m.length=p,u=1,p--):(m.length=p+1,u=g[h-i],m[p]=o>0?a(c/g[r-o]%g[o])*u:0),l)for(;;){if(0==p){for(i=1,o=m[0];o>=10;o/=10,i++);for(o=m[0]+=u,u=1;o>=10;o/=10,u++);i!=u&&(n.e++,m[0]==d&&(m[0]=1));break}if(m[p]+=u,m[p]!=d)break;m[p--]=0,u=1}for(i=m.length;0===m[--i];m.pop());}n.e>I?n.c=n.e=null:n.e>>11))>=9e15?(e=crypto.getRandomValues(new Uint32Array(2)),t[c]=e[0],t[c+1]=e[1]):(d.push(o%1e14),c+=2);c=r/2}else{if(!crypto.randomBytes)throw R=!1,Error(u+"crypto unavailable");for(t=crypto.randomBytes(r*=7);c=9e15?crypto.randomBytes(7).copy(t,c):(d.push(o%1e14),c+=7);c=r/7}if(!R)for(;c=10;o/=10,c++);ce-1&&(null==o[r+1]&&(o[r+1]=0),o[r+1]+=o[r]/e|0,o[r]%=e)}return o.reverse()}return function(t,l,r,i,o){var s,a,u,c,d,h,p,f,_=t.indexOf("."),m=D,y=A;for(_>=0&&(c=N,N=0,t=t.replace(".",""),h=(f=new V(l)).pow(t.length-_),N=c,f.c=n(M(g(h.c),h.e,"0"),10,r,"0123456789"),f.e=f.c.length),u=c=(p=n(t,l,r,o?(s=B,"0123456789"):(s="0123456789",B))).length;0==p[--c];p.pop());if(!p[0])return s.charAt(0);if(_<0?--u:(h.c=p,h.e=u,h.s=i,p=(h=e(h,f,m,y,r)).c,d=h.r,u=h.e),_=p[a=u+m+1],c=r/2,d=d||a<0||null!=p[a+1],d=y<4?(null!=_||d)&&(0==y||y==(h.s<0?3:2)):_>c||_==c&&(4==y||d||6==y&&1&p[a-1]||y==(h.s<0?8:7)),a<1||!p[0])t=d?M(s.charAt(1),-m,s.charAt(0)):s.charAt(0);else{if(p.length=a,d)for(--r;++p[--a]>r;)p[a]=0,a||(++u,p=[1].concat(p));for(c=p.length;!p[--c];);for(_=0,t="";_<=c;t+=s.charAt(p[_++]));t=M(t,u,s.charAt(0))}return t}}(),e=function(){function n(n,t,e){var l,r,i,o,s=0,a=n.length,u=t%_,c=t/_|0;for(n=n.slice();a--;)s=((r=u*(i=n[a]%_)+(l=c*i+(o=n[a]/_|0)*u)%_*_+s)/e|0)+(l/_|0)+c*o,n[a]=r%e;return s&&(n=[s].concat(n)),n}function t(n,t,e,l){var r,i;if(e!=l)i=e>l?1:-1;else for(r=i=0;rt[r]?1:-1;break}return i}function e(n,t,e,l){for(var r=0;e--;)n[e]-=r,n[e]=(r=n[e]1;n.splice(0,1));}return function(l,r,i,o,s){var u,c,p,f,_,g,y,b,v,w,x,M,k,C,S,O,T,L=l.s==r.s?1:-1,P=l.c,D=r.c;if(!(P&&P[0]&&D&&D[0]))return new V(l.s&&r.s&&(P?!D||P[0]!=D[0]:D)?P&&0==P[0]||!D?0*L:L/0:NaN);for(v=(b=new V(L)).c=[],L=i+(c=l.e-r.e)+1,s||(s=d,c=m(l.e/h)-m(r.e/h),L=L/h|0),p=0;D[p]==(P[p]||0);p++);if(D[p]>(P[p]||0)&&c--,L<0)v.push(1),f=!0;else{for(C=P.length,O=D.length,p=0,L+=2,(_=a(s/(D[0]+1)))>1&&(D=n(D,_,s),P=n(P,_,s),O=D.length,C=P.length),k=O,x=(w=P.slice(0,O)).length;x=s/2&&S++;do{if(_=0,(u=t(D,w,O,x))<0){if(M=w[0],O!=x&&(M=M*s+(w[1]||0)),(_=a(M/S))>1)for(_>=s&&(_=s-1),y=(g=n(D,_,s)).length,x=w.length;1==t(g,w,y,x);)_--,e(g,O=10;L/=10,p++);G(b,i+(b.e=p+c*h-1)+1,o,f)}else b.e=c,b.r=+f;return b}}(),k=/^(-?)0([xbo])(?=\w[\w.]*$)/i,C=/^([^.]+)\.$/,S=/^\.([^.]+)$/,O=/^-?(Infinity|NaN)$/,T=/^\s*\+(?=[\w.])|^\s+|\s+$/g,r=function(n,t,e,l){var r,i=e?t:t.replace(T,"");if(O.test(i))n.s=isNaN(i)?null:i<0?-1:1,n.c=n.e=null;else{if(!e&&(i=i.replace(k,function(n,t,e){return r="x"==(e=e.toLowerCase())?16:"b"==e?2:8,l&&l!=r?n:t}),l&&(r=l,i=i.replace(C,"$1").replace(S,"0.$1")),t!=i))return new V(i,r);if(V.DEBUG)throw Error(u+"Not a"+(l?" base "+l:"")+" number: "+t);n.c=n.e=n.s=null}},L.absoluteValue=L.abs=function(){var n=new V(this);return n.s<0&&(n.s=1),n},L.comparedTo=function(n,t){return y(this,new V(n,t))},L.decimalPlaces=L.dp=function(n,t){var e,l,r,i=this;if(null!=n)return b(n,0,1e9),null==t?t=A:b(t,0,8),G(new V(i),n+i.e+1,t);if(!(e=i.c))return null;if(l=((r=e.length-1)-m(this.e/h))*h,r=e[r])for(;r%10==0;r/=10,l--);return l<0&&(l=0),l},L.dividedBy=L.div=function(n,t){return e(this,new V(n,t),D,A)},L.dividedToIntegerBy=L.idiv=function(n,t){return e(this,new V(n,t),0,1)},L.exponentiatedBy=L.pow=function(n,t){var e,l,r,i,o,c,d,p=this;if((n=new V(n)).c&&!n.isInteger())throw Error(u+"Exponent not an integer: "+n);if(null!=t&&(t=new V(t)),i=n.e>14,!p.c||!p.c[0]||1==p.c[0]&&!p.e&&1==p.c.length||!n.c||!n.c[0])return d=new V(Math.pow(+p.valueOf(),i?2-w(n):+n)),t?d.mod(t):d;if(o=n.s<0,t){if(t.c?!t.c[0]:!t.s)return new V(NaN);(l=!o&&p.isInteger()&&t.isInteger())&&(p=p.mod(t))}else{if(n.e>9&&(p.e>0||p.e<-1||(0==p.e?p.c[0]>1||i&&p.c[1]>=24e7:p.c[0]<8e13||i&&p.c[0]<=9999975e7)))return r=p.s<0&&w(n)?-0:0,p.e>-1&&(r=1/r),new V(o?1/r:r);N&&(r=s(N/h+2))}for(i?(e=new V(.5),c=w(n)):c=n%2,o&&(n.s=1),d=new V(P);;){if(c){if(!(d=d.times(p)).c)break;r?d.c.length>r&&(d.c.length=r):l&&(d=d.mod(t))}if(i){if(G(n=n.times(e),n.e+1,1),!n.c[0])break;i=n.e>14,c=w(n)}else{if(!(n=a(n/2)))break;c=n%2}p=p.times(p),r?p.c&&p.c.length>r&&(p.c.length=r):l&&(p=p.mod(t))}return l?d:(o&&(d=P.div(d)),t?d.mod(t):r?G(d,N,A,void 0):d)},L.integerValue=function(n){var t=new V(this);return null==n?n=A:b(n,0,8),G(t,t.e+1,n)},L.isEqualTo=L.eq=function(n,t){return 0===y(this,new V(n,t))},L.isFinite=function(){return!!this.c},L.isGreaterThan=L.gt=function(n,t){return y(this,new V(n,t))>0},L.isGreaterThanOrEqualTo=L.gte=function(n,t){return 1===(t=y(this,new V(n,t)))||0===t},L.isInteger=function(){return!!this.c&&m(this.e/h)>this.c.length-2},L.isLessThan=L.lt=function(n,t){return y(this,new V(n,t))<0},L.isLessThanOrEqualTo=L.lte=function(n,t){return-1===(t=y(this,new V(n,t)))||0===t},L.isNaN=function(){return!this.s},L.isNegative=function(){return this.s<0},L.isPositive=function(){return this.s>0},L.isZero=function(){return!!this.c&&0==this.c[0]},L.minus=function(n,t){var e,l,r,i,o=this,s=o.s;if(t=(n=new V(n,t)).s,!s||!t)return new V(NaN);if(s!=t)return n.s=-t,o.plus(n);var a=o.e/h,u=n.e/h,c=o.c,p=n.c;if(!a||!u){if(!c||!p)return c?(n.s=-t,n):new V(p?o:NaN);if(!c[0]||!p[0])return p[0]?(n.s=-t,n):new V(c[0]?o:3==A?-0:0)}if(a=m(a),u=m(u),c=c.slice(),s=a-u){for((i=s<0)?(s=-s,r=c):(u=a,r=p),r.reverse(),t=s;t--;r.push(0));r.reverse()}else for(l=(i=(s=c.length)<(t=p.length))?s:t,s=t=0;t0)for(;t--;c[e++]=0);for(t=d-1;l>s;){if(c[--l]=0;){for(e=0,f=M[r]%v,g=M[r]/v|0,i=r+(o=a);i>r;)e=((u=f*(u=x[--o]%v)+(s=g*u+(c=x[o]/v|0)*f)%v*v+y[i]+e)/b|0)+(s/v|0)+g*c,y[i--]=u%b;y[i]=e}return e?++l:y.splice(0,1),U(n,y,l)},L.negated=function(){var n=new V(this);return n.s=-n.s||null,n},L.plus=function(n,t){var e,l=this,r=l.s;if(t=(n=new V(n,t)).s,!r||!t)return new V(NaN);if(r!=t)return n.s=-t,l.minus(n);var i=l.e/h,o=n.e/h,s=l.c,a=n.c;if(!i||!o){if(!s||!a)return new V(r/0);if(!s[0]||!a[0])return a[0]?n:new V(s[0]?l:0*r)}if(i=m(i),o=m(o),s=s.slice(),r=i-o){for(r>0?(o=i,e=a):(r=-r,e=s),e.reverse();r--;e.push(0));e.reverse()}for((r=s.length)-(t=a.length)<0&&(e=a,a=s,s=e,t=r),r=0;t;)r=(s[--t]=s[t]+a[t]+r)/d|0,s[t]=d===s[t]?0:s[t]%d;return r&&(s=[r].concat(s),++o),U(n,s,o)},L.precision=L.sd=function(n,t){var e,l,r,i=this;if(null!=n&&n!==!!n)return b(n,1,1e9),null==t?t=A:b(t,0,8),G(new V(i),n,t);if(!(e=i.c))return null;if(l=(r=e.length-1)*h+1,r=e[r]){for(;r%10==0;r/=10,l--);for(r=e[0];r>=10;r/=10,l++);}return n&&i.e+1>l&&(l=i.e+1),l},L.shiftedBy=function(n){return b(n,-p,p),this.times("1e"+n)},L.squareRoot=L.sqrt=function(){var n,t,l,r,i,o=this,s=o.c,a=o.s,u=o.e,c=D+4,d=new V("0.5");if(1!==a||!s||!s[0])return new V(!a||a<0&&(!s||s[0])?NaN:s?o:1/0);if(0==(a=Math.sqrt(+o))||a==1/0?(((t=g(s)).length+u)%2==0&&(t+="0"),a=Math.sqrt(t),u=m((u+1)/2)-(u<0||u%2),l=new V(t=a==1/0?"1e"+u:(t=a.toExponential()).slice(0,t.indexOf("e")+1)+u)):l=new V(a+""),l.c[0])for((a=(u=l.e)+c)<3&&(a=0);;)if(l=d.times((i=l).plus(e(o,i,c,1))),g(i.c).slice(0,a)===(t=g(l.c)).slice(0,a)){if(l.e0&&h>0){for(a=d.substr(0,l=h%i||i);l0&&(a+=s+d.slice(l)),c&&(a="-"+a)}e=u?a+F.decimalSeparator+((o=+F.fractionGroupSize)?u.replace(new RegExp("\\d{"+o+"}\\B","g"),"$&"+F.fractionGroupSeparator):u):a}return e},L.toFraction=function(n){var t,l,r,i,o,s,a,c,d,p,_,m,y=this,b=y.c;if(null!=n&&(!(c=new V(n)).isInteger()&&(c.c||1!==c.s)||c.lt(P)))throw Error(u+"Argument "+(c.isInteger()?"out of range: ":"not an integer: ")+n);if(!b)return y.toString();for(l=new V(P),p=r=new V(P),i=d=new V(P),m=g(b),s=l.e=m.length-y.e-1,l.c[0]=f[(a=s%h)<0?h+a:a],n=!n||c.comparedTo(l)>0?s>0?l:p:c,a=I,I=1/0,c=new V(m),d.c[0]=0;_=e(c,l,0,1),1!=(o=r.plus(_.times(i))).comparedTo(n);)r=i,i=o,p=d.plus(_.times(o=p)),d=o,l=c.minus(_.times(o=l)),c=o;return o=e(n.minus(r),i,0,1),d=d.plus(o.times(p)),r=r.plus(o.times(i)),d.s=p.s=y.s,t=e(p,i,s*=2,A).minus(y).abs().comparedTo(e(d,r,s,A).minus(y).abs())<1?[p.toString(),i.toString()]:[d.toString(),r.toString()],I=a,t},L.toNumber=function(){return+this},L.toPrecision=function(n,t){return null!=n&&b(n,1,1e9),W(this,n,t,2)},L.toString=function(n){var t,e=this,r=e.s,i=e.e;return null===i?r?(t="Infinity",r<0&&(t="-"+t)):t="NaN":(t=g(e.c),null==n?t=i<=E||i>=Y?x(t,i):M(t,i,"0"):(b(n,2,B.length,"Base"),t=l(M(t,i,"0"),10,n,r,!0)),r<0&&e.c[0]&&(t="-"+t)),t},L.valueOf=L.toJSON=function(){var n,t=this,e=t.e;return null===e?t.toString():(n=g(t.c),n=e<=E||e>=Y?x(n,e):M(n,e,"0"),t.s<0?"-"+n:n)},L._isBigNumber=!0,null!=t&&V.set(t),V}()).default=i.BigNumber=i,void 0===(l=(function(){return i}).call(t,e,t,n))||(n.exports=l)}()},upln:function(n,t,e){!function(n){"use strict";function t(n){return n%100==11||n%10!=1}function e(n,e,l,r){var i=n+" ";switch(l){case"s":return e||r?"nokkrar sek\xfandur":"nokkrum sek\xfandum";case"ss":return t(n)?i+(e||r?"sek\xfandur":"sek\xfandum"):i+"sek\xfanda";case"m":return e?"m\xedn\xfata":"m\xedn\xfatu";case"mm":return t(n)?i+(e||r?"m\xedn\xfatur":"m\xedn\xfatum"):e?i+"m\xedn\xfata":i+"m\xedn\xfatu";case"hh":return t(n)?i+(e||r?"klukkustundir":"klukkustundum"):i+"klukkustund";case"d":return e?"dagur":r?"dag":"degi";case"dd":return t(n)?e?i+"dagar":i+(r?"daga":"d\xf6gum"):e?i+"dagur":i+(r?"dag":"degi");case"M":return e?"m\xe1nu\xf0ur":r?"m\xe1nu\xf0":"m\xe1nu\xf0i";case"MM":return t(n)?e?i+"m\xe1nu\xf0ir":i+(r?"m\xe1nu\xf0i":"m\xe1nu\xf0um"):e?i+"m\xe1nu\xf0ur":i+(r?"m\xe1nu\xf0":"m\xe1nu\xf0i");case"y":return e||r?"\xe1r":"\xe1ri";case"yy":return t(n)?i+(e||r?"\xe1r":"\xe1rum"):i+(e||r?"\xe1r":"\xe1ri")}}n.defineLocale("is",{months:"jan\xfaar_febr\xfaar_mars_apr\xedl_ma\xed_j\xfan\xed_j\xfal\xed_\xe1g\xfast_september_okt\xf3ber_n\xf3vember_desember".split("_"),monthsShort:"jan_feb_mar_apr_ma\xed_j\xfan_j\xfal_\xe1g\xfa_sep_okt_n\xf3v_des".split("_"),weekdays:"sunnudagur_m\xe1nudagur_\xferi\xf0judagur_mi\xf0vikudagur_fimmtudagur_f\xf6studagur_laugardagur".split("_"),weekdaysShort:"sun_m\xe1n_\xferi_mi\xf0_fim_f\xf6s_lau".split("_"),weekdaysMin:"Su_M\xe1_\xder_Mi_Fi_F\xf6_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd, D. MMMM YYYY [kl.] H:mm"},calendar:{sameDay:"[\xed dag kl.] LT",nextDay:"[\xe1 morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\xed g\xe6r kl.] LT",lastWeek:"[s\xed\xf0asta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s s\xed\xf0an",s:e,ss:e,m:e,mm:e,h:"klukkustund",hh:e,d:e,dd:e,M:e,MM:e,y:e,yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))},uslO:function(n,t,e){var l={"./af":"3CJN","./af.js":"3CJN","./ar":"3MVc","./ar-dz":"tkWw","./ar-dz.js":"tkWw","./ar-kw":"j8cJ","./ar-kw.js":"j8cJ","./ar-ly":"wPpW","./ar-ly.js":"wPpW","./ar-ma":"dURR","./ar-ma.js":"dURR","./ar-sa":"7OnE","./ar-sa.js":"7OnE","./ar-tn":"BEem","./ar-tn.js":"BEem","./ar.js":"3MVc","./az":"eHwN","./az.js":"eHwN","./be":"3hfc","./be.js":"3hfc","./bg":"lOED","./bg.js":"lOED","./bm":"hng5","./bm.js":"hng5","./bn":"aM0x","./bn.js":"aM0x","./bo":"w2Hs","./bo.js":"w2Hs","./br":"OSsP","./br.js":"OSsP","./bs":"aqvp","./bs.js":"aqvp","./ca":"wIgY","./ca.js":"wIgY","./cs":"ssxj","./cs.js":"ssxj","./cv":"N3vo","./cv.js":"N3vo","./cy":"ZFGz","./cy.js":"ZFGz","./da":"YBA/","./da.js":"YBA/","./de":"DOkx","./de-at":"8v14","./de-at.js":"8v14","./de-ch":"Frex","./de-ch.js":"Frex","./de.js":"DOkx","./dv":"rIuo","./dv.js":"rIuo","./el":"CFqe","./el.js":"CFqe","./en-au":"Sjoy","./en-au.js":"Sjoy","./en-ca":"Tqun","./en-ca.js":"Tqun","./en-gb":"hPuz","./en-gb.js":"hPuz","./en-ie":"ALEw","./en-ie.js":"ALEw","./en-il":"QZk1","./en-il.js":"QZk1","./en-nz":"dyB6","./en-nz.js":"dyB6","./eo":"Nd3h","./eo.js":"Nd3h","./es":"LT9G","./es-do":"7MHZ","./es-do.js":"7MHZ","./es-us":"INcR","./es-us.js":"INcR","./es.js":"LT9G","./et":"XlWM","./et.js":"XlWM","./eu":"sqLM","./eu.js":"sqLM","./fa":"2pmY","./fa.js":"2pmY","./fi":"nS2h","./fi.js":"nS2h","./fo":"OVPi","./fo.js":"OVPi","./fr":"tzHd","./fr-ca":"bXQP","./fr-ca.js":"bXQP","./fr-ch":"VK9h","./fr-ch.js":"VK9h","./fr.js":"tzHd","./fy":"g7KF","./fy.js":"g7KF","./gd":"nLOz","./gd.js":"nLOz","./gl":"FuaP","./gl.js":"FuaP","./gom-latn":"+27R","./gom-latn.js":"+27R","./gu":"rtsW","./gu.js":"rtsW","./he":"Nzt2","./he.js":"Nzt2","./hi":"ETHv","./hi.js":"ETHv","./hr":"V4qH","./hr.js":"V4qH","./hu":"xne+","./hu.js":"xne+","./hy-am":"GrS7","./hy-am.js":"GrS7","./id":"yRTJ","./id.js":"yRTJ","./is":"upln","./is.js":"upln","./it":"FKXc","./it.js":"FKXc","./ja":"ORgI","./ja.js":"ORgI","./jv":"JwiF","./jv.js":"JwiF","./ka":"RnJI","./ka.js":"RnJI","./kk":"j+vx","./kk.js":"j+vx","./km":"5j66","./km.js":"5j66","./kn":"gEQe","./kn.js":"gEQe","./ko":"eBB/","./ko.js":"eBB/","./ky":"6cf8","./ky.js":"6cf8","./lb":"z3hR","./lb.js":"z3hR","./lo":"nE8X","./lo.js":"nE8X","./lt":"/6P1","./lt.js":"/6P1","./lv":"jxEH","./lv.js":"jxEH","./me":"svD2","./me.js":"svD2","./mi":"gEU3","./mi.js":"gEU3","./mk":"Ab7C","./mk.js":"Ab7C","./ml":"oo1B","./ml.js":"oo1B","./mr":"5vPg","./mr.js":"5vPg","./ms":"ooba","./ms-my":"G++c","./ms-my.js":"G++c","./ms.js":"ooba","./mt":"oCzW","./mt.js":"oCzW","./my":"F+2e","./my.js":"F+2e","./nb":"FlzV","./nb.js":"FlzV","./ne":"/mhn","./ne.js":"/mhn","./nl":"3K28","./nl-be":"Bp2f","./nl-be.js":"Bp2f","./nl.js":"3K28","./nn":"C7av","./nn.js":"C7av","./pa-in":"pfs9","./pa-in.js":"pfs9","./pl":"7LV+","./pl.js":"7LV+","./pt":"ZoSI","./pt-br":"AoDM","./pt-br.js":"AoDM","./pt.js":"ZoSI","./ro":"wT5f","./ro.js":"wT5f","./ru":"ulq9","./ru.js":"ulq9","./sd":"fW1y","./sd.js":"fW1y","./se":"5Omq","./se.js":"5Omq","./si":"Lgqo","./si.js":"Lgqo","./sk":"OUMt","./sk.js":"OUMt","./sl":"2s1U","./sl.js":"2s1U","./sq":"V0td","./sq.js":"V0td","./sr":"f4W3","./sr-cyrl":"c1x4","./sr-cyrl.js":"c1x4","./sr.js":"f4W3","./ss":"7Q8x","./ss.js":"7Q8x","./sv":"Fpqq","./sv.js":"Fpqq","./sw":"DSXN","./sw.js":"DSXN","./ta":"+7/x","./ta.js":"+7/x","./te":"Nlnz","./te.js":"Nlnz","./tet":"gUgh","./tet.js":"gUgh","./tg":"5SNd","./tg.js":"5SNd","./th":"XzD+","./th.js":"XzD+","./tl-ph":"3LKG","./tl-ph.js":"3LKG","./tlh":"m7yE","./tlh.js":"m7yE","./tr":"k+5o","./tr.js":"k+5o","./tzl":"iNtv","./tzl.js":"iNtv","./tzm":"FRPF","./tzm-latn":"krPU","./tzm-latn.js":"krPU","./tzm.js":"FRPF","./ug-cn":"To0v","./ug-cn.js":"To0v","./uk":"ntHu","./uk.js":"ntHu","./ur":"uSe8","./ur.js":"uSe8","./uz":"XU1s","./uz-latn":"/bsm","./uz-latn.js":"/bsm","./uz.js":"XU1s","./vi":"0X8Q","./vi.js":"0X8Q","./x-pseudo":"e/KL","./x-pseudo.js":"e/KL","./yo":"YXlc","./yo.js":"YXlc","./zh-cn":"Vz2w","./zh-cn.js":"Vz2w","./zh-hk":"ZUyn","./zh-hk.js":"ZUyn","./zh-tw":"BbgG","./zh-tw.js":"BbgG"};function r(n){return e(i(n))}function i(n){var t=l[n];if(!(t+1))throw new Error("Cannot find module '"+n+"'.");return t}r.keys=function(){return Object.keys(l)},r.resolve=i,n.exports=r,r.id="uslO"},w2Hs:function(n,t,e){!function(n){"use strict";var t={1:"\u0f21",2:"\u0f22",3:"\u0f23",4:"\u0f24",5:"\u0f25",6:"\u0f26",7:"\u0f27",8:"\u0f28",9:"\u0f29",0:"\u0f20"},e={"\u0f21":"1","\u0f22":"2","\u0f23":"3","\u0f24":"4","\u0f25":"5","\u0f26":"6","\u0f27":"7","\u0f28":"8","\u0f29":"9","\u0f20":"0"};n.defineLocale("bo",{months:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f44\u0f0b\u0f54\u0f7c_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f66\u0f74\u0f58\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f5e\u0f72\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f63\u0f94\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0fb2\u0f74\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f42\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f45\u0f72\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54".split("_"),monthsShort:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f44\u0f0b\u0f54\u0f7c_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f66\u0f74\u0f58\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f5e\u0f72\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f63\u0f94\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0fb2\u0f74\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f42\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f45\u0f72\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54".split("_"),weekdays:"\u0f42\u0f5f\u0f60\u0f0b\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f42\u0f5f\u0f60\u0f0b\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),weekdaysShort:"\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),weekdaysMin:"\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0f51\u0f72\u0f0b\u0f62\u0f72\u0f44] LT",nextDay:"[\u0f66\u0f44\u0f0b\u0f49\u0f72\u0f53] LT",nextWeek:"[\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f55\u0fb2\u0f42\u0f0b\u0f62\u0f97\u0f7a\u0f66\u0f0b\u0f58], LT",lastDay:"[\u0f41\u0f0b\u0f66\u0f44] LT",lastWeek:"[\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f55\u0fb2\u0f42\u0f0b\u0f58\u0f50\u0f60\u0f0b\u0f58] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0f63\u0f0b",past:"%s \u0f66\u0f94\u0f53\u0f0b\u0f63",s:"\u0f63\u0f58\u0f0b\u0f66\u0f44",ss:"%d \u0f66\u0f90\u0f62\u0f0b\u0f46\u0f0d",m:"\u0f66\u0f90\u0f62\u0f0b\u0f58\u0f0b\u0f42\u0f45\u0f72\u0f42",mm:"%d \u0f66\u0f90\u0f62\u0f0b\u0f58",h:"\u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51\u0f0b\u0f42\u0f45\u0f72\u0f42",hh:"%d \u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51",d:"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f45\u0f72\u0f42",dd:"%d \u0f49\u0f72\u0f53\u0f0b",M:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f45\u0f72\u0f42",MM:"%d \u0f5f\u0fb3\u0f0b\u0f56",y:"\u0f63\u0f7c\u0f0b\u0f42\u0f45\u0f72\u0f42",yy:"%d \u0f63\u0f7c"},preparse:function(n){return n.replace(/[\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u0f20]/g,function(n){return e[n]})},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]})},meridiemParse:/\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c|\u0f5e\u0f7c\u0f42\u0f66\u0f0b\u0f40\u0f66|\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44|\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42|\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c/,meridiemHour:function(n,t){return 12===n&&(n=0),"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c"===t&&n>=4||"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44"===t&&n<5||"\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42"===t?n+12:n},meridiem:function(n,t,e){return n<4?"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c":n<10?"\u0f5e\u0f7c\u0f42\u0f66\u0f0b\u0f40\u0f66":n<17?"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44":n<20?"\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42":"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c"},week:{dow:0,doy:6}})}(e("PJh5"))},wIgY:function(n,t,e){!function(n){"use strict";n.defineLocale("ca",{months:{standalone:"gener_febrer_mar\xe7_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),format:"de gener_de febrer_de mar\xe7_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._mar\xe7_abr._maig_juny_jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dt_dc_dj_dv_ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a les] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a les] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[dem\xe0 a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"d'aqu\xed %s",past:"fa %s",s:"uns segons",ss:"%d segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|\xe8|a)/,ordinal:function(n,t){var e=1===n?"r":2===n?"n":3===n?"r":4===n?"t":"\xe8";return"w"!==t&&"W"!==t||(e="a"),n+e},week:{dow:1,doy:4}})}(e("PJh5"))},wPpW:function(n,t,e){!function(n){"use strict";var t={1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},e=function(n){return 0===n?0:1===n?1:2===n?2:n%100>=3&&n%100<=10?3:n%100>=11?4:5},l={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},r=function(n){return function(t,r,i,o){var s=e(t),a=l[n][e(t)];return 2===s&&(a=a[r?0:1]),a.replace(/%d/i,t)}},i=["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0648","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];n.defineLocale("ar-ly",{months:i,monthsShort:i,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(n){return"\u0645"===n},meridiem:function(n,t,e){return n<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:r("s"),ss:r("s"),m:r("m"),mm:r("m"),h:r("h"),hh:r("h"),d:r("d"),dd:r("d"),M:r("M"),MM:r("M"),y:r("y"),yy:r("y")},preparse:function(n){return n.replace(/\u060c/g,",")},postformat:function(n){return n.replace(/\d/g,function(n){return t[n]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}})}(e("PJh5"))},wT5f:function(n,t,e){!function(n){"use strict";function t(n,t,e){var l=" ";return(n%100>=20||n>=100&&n%100==0)&&(l=" de "),n+l+{ss:"secunde",mm:"minute",hh:"ore",dd:"zile",MM:"luni",yy:"ani"}[e]}n.defineLocale("ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"duminic\u0103_luni_mar\u021bi_miercuri_joi_vineri_s\xe2mb\u0103t\u0103".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_S\xe2m".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_S\xe2".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[m\xe2ine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s \xeen urm\u0103",s:"c\xe2teva secunde",ss:t,m:"un minut",mm:t,h:"o or\u0103",hh:t,d:"o zi",dd:t,M:"o lun\u0103",MM:t,y:"un an",yy:t},week:{dow:1,doy:7}})}(e("PJh5"))},x35b:function(n,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var l=e("WT6e"),r={nodeUrl:"/api/",production:!0,tellerUrl:"https://event.skycoin.com/api/",swaplab:{apiKey:"w4bxe2tbf9beb72r",activateTestMode:!1,endStatusInError:!1}},i=(e("rxKx"),e("TToO")),o=e("YaPU"),s=function(){},a=new l.r("Location Initialized"),u=function(){},c=new l.r("appBaseHref"),d=function(){function n(t){var e=this;this._subject=new l.o,this._platformStrategy=t;var r=this._platformStrategy.getBaseHref();this._baseHref=n.stripTrailingSlash(h(r)),this._platformStrategy.onPopState(function(n){e._subject.emit({url:e.path(!0),pop:!0,type:n.type})})}return n.prototype.path=function(n){return void 0===n&&(n=!1),this.normalize(this._platformStrategy.path(n))},n.prototype.isCurrentPathEqualTo=function(t,e){return void 0===e&&(e=""),this.path()==this.normalize(t+n.normalizeQueryParams(e))},n.prototype.normalize=function(t){return n.stripTrailingSlash(function(n,t){return n&&t.startsWith(n)?t.substring(n.length):t}(this._baseHref,h(t)))},n.prototype.prepareExternalUrl=function(n){return n&&"/"!==n[0]&&(n="/"+n),this._platformStrategy.prepareExternalUrl(n)},n.prototype.go=function(n,t){void 0===t&&(t=""),this._platformStrategy.pushState(null,"",n,t)},n.prototype.replaceState=function(n,t){void 0===t&&(t=""),this._platformStrategy.replaceState(null,"",n,t)},n.prototype.forward=function(){this._platformStrategy.forward()},n.prototype.back=function(){this._platformStrategy.back()},n.prototype.subscribe=function(n,t,e){return this._subject.subscribe({next:n,error:t,complete:e})},n.normalizeQueryParams=function(n){return n&&"?"!==n[0]?"?"+n:n},n.joinWithSlash=function(n,t){if(0==n.length)return t;if(0==t.length)return n;var e=0;return n.endsWith("/")&&e++,t.startsWith("/")&&e++,2==e?n+t.substring(1):1==e?n+t:n+"/"+t},n.stripTrailingSlash=function(n){var t=n.match(/#|\?|$/),e=t&&t.index||n.length;return n.slice(0,e-("/"===n[e-1]?1:0))+n.slice(e)},n}();function h(n){return n.replace(/\/index.html$/,"")}var p=function(n){function t(t,e){var l=n.call(this)||this;return l._platformLocation=t,l._baseHref="",null!=e&&(l._baseHref=e),l}return Object(i.__extends)(t,n),t.prototype.onPopState=function(n){this._platformLocation.onPopState(n),this._platformLocation.onHashChange(n)},t.prototype.getBaseHref=function(){return this._baseHref},t.prototype.path=function(n){void 0===n&&(n=!1);var t=this._platformLocation.hash;return null==t&&(t="#"),t.length>0?t.substring(1):t},t.prototype.prepareExternalUrl=function(n){var t=d.joinWithSlash(this._baseHref,n);return t.length>0?"#"+t:t},t.prototype.pushState=function(n,t,e,l){var r=this.prepareExternalUrl(e+d.normalizeQueryParams(l));0==r.length&&(r=this._platformLocation.pathname),this._platformLocation.pushState(n,t,r)},t.prototype.replaceState=function(n,t,e,l){var r=this.prepareExternalUrl(e+d.normalizeQueryParams(l));0==r.length&&(r=this._platformLocation.pathname),this._platformLocation.replaceState(n,t,r)},t.prototype.forward=function(){this._platformLocation.forward()},t.prototype.back=function(){this._platformLocation.back()},t}(u),f=function(n){function t(t,e){var l=n.call(this)||this;if(l._platformLocation=t,null==e&&(e=l._platformLocation.getBaseHrefFromDOM()),null==e)throw new Error("No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.");return l._baseHref=e,l}return Object(i.__extends)(t,n),t.prototype.onPopState=function(n){this._platformLocation.onPopState(n),this._platformLocation.onHashChange(n)},t.prototype.getBaseHref=function(){return this._baseHref},t.prototype.prepareExternalUrl=function(n){return d.joinWithSlash(this._baseHref,n)},t.prototype.path=function(n){void 0===n&&(n=!1);var t=this._platformLocation.pathname+d.normalizeQueryParams(this._platformLocation.search),e=this._platformLocation.hash;return e&&n?""+t+e:t},t.prototype.pushState=function(n,t,e,l){var r=this.prepareExternalUrl(e+d.normalizeQueryParams(l));this._platformLocation.pushState(n,t,r)},t.prototype.replaceState=function(n,t,e,l){var r=this.prepareExternalUrl(e+d.normalizeQueryParams(l));this._platformLocation.replaceState(n,t,r)},t.prototype.forward=function(){this._platformLocation.forward()},t.prototype.back=function(){this._platformLocation.back()},t}(u),_={AOA:[,"Kz"],ARS:[,"$"],AUD:["A$","$"],BAM:[,"KM"],BBD:[,"$"],BDT:[,"\u09f3"],BMD:[,"$"],BND:[,"$"],BOB:[,"Bs"],BRL:["R$"],BSD:[,"$"],BWP:[,"P"],BYN:[,"\u0440."],BZD:[,"$"],CAD:["CA$","$"],CLP:[,"$"],CNY:["CN\xa5","\xa5"],COP:[,"$"],CRC:[,"\u20a1"],CUC:[,"$"],CUP:[,"$"],CZK:[,"K\u010d"],DKK:[,"kr"],DOP:[,"$"],EGP:[,"E\xa3"],ESP:[,"\u20a7"],EUR:["\u20ac"],FJD:[,"$"],FKP:[,"\xa3"],GBP:["\xa3"],GEL:[,"\u20be"],GIP:[,"\xa3"],GNF:[,"FG"],GTQ:[,"Q"],GYD:[,"$"],HKD:["HK$","$"],HNL:[,"L"],HRK:[,"kn"],HUF:[,"Ft"],IDR:[,"Rp"],ILS:["\u20aa"],INR:["\u20b9"],ISK:[,"kr"],JMD:[,"$"],JPY:["\xa5"],KHR:[,"\u17db"],KMF:[,"CF"],KPW:[,"\u20a9"],KRW:["\u20a9"],KYD:[,"$"],KZT:[,"\u20b8"],LAK:[,"\u20ad"],LBP:[,"L\xa3"],LKR:[,"Rs"],LRD:[,"$"],LTL:[,"Lt"],LVL:[,"Ls"],MGA:[,"Ar"],MMK:[,"K"],MNT:[,"\u20ae"],MUR:[,"Rs"],MXN:["MX$","$"],MYR:[,"RM"],NAD:[,"$"],NGN:[,"\u20a6"],NIO:[,"C$"],NOK:[,"kr"],NPR:[,"Rs"],NZD:["NZ$","$"],PHP:[,"\u20b1"],PKR:[,"Rs"],PLN:[,"z\u0142"],PYG:[,"\u20b2"],RON:[,"lei"],RUB:[,"\u20bd"],RUR:[,"\u0440."],RWF:[,"RF"],SBD:[,"$"],SEK:[,"kr"],SGD:[,"$"],SHP:[,"\xa3"],SRD:[,"$"],SSP:[,"\xa3"],STD:[,"Db"],SYP:[,"\xa3"],THB:[,"\u0e3f"],TOP:[,"T$"],TRY:[,"\u20ba"],TTD:[,"$"],TWD:["NT$","$"],UAH:[,"\u20b4"],USD:["$"],UYU:[,"$"],VEF:[,"Bs"],VND:["\u20ab"],XAF:["FCFA"],XCD:["EC$","$"],XOF:["CFA"],XPF:["CFPF"],ZAR:[,"R"],ZMW:[,"ZK"]},m=["en",[["a","p"],["AM","PM"]],[["AM","PM"],,],[["S","M","T","W","T","F","S"],["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["Su","Mo","Tu","We","Th","Fr","Sa"]],,[["J","F","M","A","M","J","J","A","S","O","N","D"],["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],["January","February","March","April","May","June","July","August","September","October","November","December"]],,[["B","A"],["BC","AD"],["Before Christ","Anno Domini"]],0,[6,0],["M/d/yy","MMM d, y","MMMM d, y","EEEE, MMMM d, y"],["h:mm a","h:mm:ss a","h:mm:ss a z","h:mm:ss a zzzz"],["{1}, {0}",,"{1} 'at' {0}"],[".",",",";","%","+","-","E","\xd7","\u2030","\u221e","NaN",":"],["#,##0.###","#,##0%","\xa4#,##0.00","#E0"],"$","US Dollar",function(n){var t=Math.floor(Math.abs(n)),e=n.toString().replace(/^[^.]*\.?/,"").length;return 1===t&&0===e?1:5}],g={},y=function(){var n={Decimal:0,Percent:1,Currency:2,Scientific:3};return n[n.Decimal]="Decimal",n[n.Percent]="Percent",n[n.Currency]="Currency",n[n.Scientific]="Scientific",n}(),b=function(){var n={Zero:0,One:1,Two:2,Few:3,Many:4,Other:5};return n[n.Zero]="Zero",n[n.One]="One",n[n.Two]="Two",n[n.Few]="Few",n[n.Many]="Many",n[n.Other]="Other",n}(),v=function(){var n={Decimal:0,Group:1,List:2,PercentSign:3,PlusSign:4,MinusSign:5,Exponential:6,SuperscriptingExponent:7,PerMille:8,Infinity:9,NaN:10,TimeSeparator:11,CurrencyDecimal:12,CurrencyGroup:13};return n[n.Decimal]="Decimal",n[n.Group]="Group",n[n.List]="List",n[n.PercentSign]="PercentSign",n[n.PlusSign]="PlusSign",n[n.MinusSign]="MinusSign",n[n.Exponential]="Exponential",n[n.SuperscriptingExponent]="SuperscriptingExponent",n[n.PerMille]="PerMille",n[n.Infinity]="Infinity",n[n.NaN]="NaN",n[n.TimeSeparator]="TimeSeparator",n[n.CurrencyDecimal]="CurrencyDecimal",n[n.CurrencyGroup]="CurrencyGroup",n}();function w(n,t){var e=x(n),l=e[13][t];if("undefined"==typeof l){if(t===v.CurrencyDecimal)return e[13][v.Decimal];if(t===v.CurrencyGroup)return e[13][v.Group]}return l}function x(n){var t=n.toLowerCase().replace(/_/g,"-"),e=g[t];if(e)return e;var l=t.split("-")[0];if(e=g[l])return e;if("en"===l)return m;throw new Error('Missing locale data for the locale "'+n+'".')}var M=new l.r("UseV4Plurals"),k=function(){},C=function(n){function t(t,e){var l=n.call(this)||this;return l.locale=t,l.deprecatedPluralFn=e,l}return Object(i.__extends)(t,n),t.prototype.getPluralCategory=function(n,t){switch(this.deprecatedPluralFn?this.deprecatedPluralFn(t||this.locale,n):function(n){return x(n)[17]}(t||this.locale)(n)){case b.Zero:return"zero";case b.One:return"one";case b.Two:return"two";case b.Few:return"few";case b.Many:return"many";default:return"other"}},t}(k);function S(n,t){t=encodeURIComponent(t);for(var e=0,l=n.split(";");e-1&&(o=o.replace(V,"")),(l=o.search(/e/i))>0?(e<0&&(e=l),e+=+o.slice(l+1),o=o.substring(0,l)):e<0&&(e=o.length),l=0;o.charAt(l)===W;l++);if(l===(i=o.length))t=[0],e=1;else{for(i--;o.charAt(i)===W;)i--;for(e-=l,t=[],r=0;l<=i;l++,r++)t[r]=+o.charAt(l)}return e>B&&(t=t.splice(0,B-1),s=e-1,e=1),{digits:t,exponent:s,integerLen:e}}(i);e===y.Percent&&(d=function(n){if(0===n.digits[0])return n;var t=n.digits.length-n.integerLen;return n.exponent?n.exponent+=2:(0===t?n.digits.push(0,0):1===t&&n.digits.push(0),n.integerLen+=2),n}(d));var h=a.minInt,p=a.minFrac,f=a.maxFrac;if(l){var _=l.match(F);if(null===_)return o.error=l+" is not a valid digit info",o;var m=_[1],g=_[3],b=_[5];null!=m&&(h=K(m)),null!=g&&(p=K(g)),null!=b?f=K(b):null!=g&&p>f&&(f=p)}!function(n,t,e){if(t>e)throw new Error("The minimum number of digits after fraction ("+t+") is higher than the maximum ("+e+").");var l=n.digits,r=l.length-n.integerLen,i=Math.min(Math.max(t,r),e),o=i+n.integerLen,s=l[o];if(o>0){l.splice(Math.max(n.integerLen,o));for(var a=o;a=5)if(o-1<0){for(var c=0;c>o;c--)l.unshift(0),n.integerLen++;l.unshift(1),n.integerLen++}else l[o-1]++;for(;r=h?l.pop():d=!1),t>=10?1:0},0);p&&(l.unshift(p),n.integerLen++)}(d,p,f);var M=d.digits,k=d.integerLen,C=d.exponent,S=[];for(c=M.every(function(n){return!n});k0?S=M.splice(k,M.length):(S=M,M=[0]);var O=[];for(M.length>=a.lgSize&&O.unshift(M.splice(-a.lgSize,M.length).join(""));M.length>a.gSize;)O.unshift(M.splice(-a.gSize,M.length).join(""));M.length&&O.unshift(M.join("")),u=O.join(w(t,r?v.CurrencyGroup:v.Group)),S.length&&(u+=w(t,r?v.CurrencyDecimal:v.Decimal)+S.join("")),C&&(u+=w(t,v.Exponential)+"+"+C)}else u=w(t,v.Infinity);return u=i<0&&!c?a.negPre+u+a.negSuf:a.posPre+u+a.posSuf,e===y.Currency&&null!==r?(o.str=u.replace(q,r).replace(q,""),o):e===y.Percent?(o.str=u.replace(new RegExp(J,"g"),w(t,v.PercentSign)),o):(o.str=u,o)}function K(n){var t=parseInt(n);if(isNaN(t))throw new Error("Invalid integer literal when parsing "+n);return t}var X=function(){function n(){}return n.prototype.createSubscription=function(n,t){return n.subscribe({next:t,error:function(n){throw n}})},n.prototype.dispose=function(n){n.unsubscribe()},n.prototype.onDestroy=function(n){n.unsubscribe()},n}(),Z=new(function(){function n(){}return n.prototype.createSubscription=function(n,t){return n.then(t,function(n){throw n})},n.prototype.dispose=function(n){},n.prototype.onDestroy=function(n){},n}()),$=new X,nn=function(){function n(n){this._ref=n,this._latestValue=null,this._latestReturnedValue=null,this._subscription=null,this._obj=null,this._strategy=null}return n.prototype.ngOnDestroy=function(){this._subscription&&this._dispose()},n.prototype.transform=function(n){return this._obj?n!==this._obj?(this._dispose(),this.transform(n)):this._latestValue===this._latestReturnedValue?this._latestReturnedValue:(this._latestReturnedValue=this._latestValue,l.T.wrap(this._latestValue)):(n&&this._subscribe(n),this._latestReturnedValue=this._latestValue,this._latestValue)},n.prototype._subscribe=function(n){var t=this;this._obj=n,this._strategy=this._selectStrategy(n),this._subscription=this._strategy.createSubscription(n,function(e){return t._updateLatestValue(n,e)})},n.prototype._selectStrategy=function(t){if(Object(l._15)(t))return Z;if(Object(l._14)(t))return $;throw N(n,t)},n.prototype._dispose=function(){this._strategy.dispose(this._subscription),this._latestValue=null,this._latestReturnedValue=null,this._subscription=null,this._obj=null},n.prototype._updateLatestValue=function(n,t){n===this._obj&&(this._latestValue=t,this._ref.markForCheck())},n}(),tn=function(){function n(n){this._locale=n}return n.prototype.transform=function(t,e,l){if(rn(t))return null;var r=Q(t,l=l||this._locale,y.Decimal,e),i=r.str,o=r.error;if(o)throw N(n,o);return i},n}(),en=function(){function n(n){this._locale=n}return n.prototype.transform=function(t,e,l){if(rn(t))return null;var r=Q(t,l=l||this._locale,y.Percent,e),i=r.str,o=r.error;if(o)throw N(n,o);return i},n}(),ln=function(){function n(n){this._locale=n}return n.prototype.transform=function(t,e,l,r,i){if(void 0===l&&(l="symbol"),rn(t))return null;i=i||this._locale,"boolean"==typeof l&&(console&&console.warn&&console.warn('Warning: the currency pipe has been changed in Angular v5. The symbolDisplay option (third parameter) is now a string instead of a boolean. The accepted values are "code", "symbol" or "symbol-narrow".'),l=l?"symbol":"code");var o=e||"USD";"code"!==l&&(o=function(n,t){var e=_[n]||[],r=e[1];return"narrow"==("symbol"===l?"wide":"narrow")&&"string"==typeof r?r:e[0]||n}(o));var s=Q(t,i,y.Currency,r,o),a=s.str,u=s.error;if(u)throw N(n,u);return a},n}();function rn(n){return null==n||""===n||n!=n}var on=function(){},sn=new l.r("DocumentToken"),an=null;function un(){return an}var cn,dn={class:"className",innerHtml:"innerHTML",readonly:"readOnly",tabindex:"tabIndex"},hn={"\b":"Backspace","\t":"Tab","\x7f":"Delete","\x1b":"Escape",Del:"Delete",Esc:"Escape",Left:"ArrowLeft",Right:"ArrowRight",Up:"ArrowUp",Down:"ArrowDown",Menu:"ContextMenu",Scroll:"ScrollLock",Win:"OS"},pn={A:"1",B:"2",C:"3",D:"4",E:"5",F:"6",G:"7",H:"8",I:"9",J:"*",K:"+",M:"-",N:".",O:"/","`":"0","\x90":"NumLock"};l._10.Node&&(cn=l._10.Node.prototype.contains||function(n){return!!(16&this.compareDocumentPosition(n))});var fn,_n=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return Object(i.__extends)(t,n),t.prototype.parse=function(n){throw new Error("parse not implemented")},t.makeCurrent=function(){var n;n=new t,an||(an=n)},t.prototype.hasProperty=function(n,t){return t in n},t.prototype.setProperty=function(n,t,e){n[t]=e},t.prototype.getProperty=function(n,t){return n[t]},t.prototype.invoke=function(n,t,e){var l;(l=n)[t].apply(l,e)},t.prototype.logError=function(n){window.console&&(console.error?console.error(n):console.log(n))},t.prototype.log=function(n){window.console&&window.console.log&&window.console.log(n)},t.prototype.logGroup=function(n){window.console&&window.console.group&&window.console.group(n)},t.prototype.logGroupEnd=function(){window.console&&window.console.groupEnd&&window.console.groupEnd()},Object.defineProperty(t.prototype,"attrToPropMap",{get:function(){return dn},enumerable:!0,configurable:!0}),t.prototype.contains=function(n,t){return cn.call(n,t)},t.prototype.querySelector=function(n,t){return n.querySelector(t)},t.prototype.querySelectorAll=function(n,t){return n.querySelectorAll(t)},t.prototype.on=function(n,t,e){n.addEventListener(t,e,!1)},t.prototype.onAndCancel=function(n,t,e){return n.addEventListener(t,e,!1),function(){n.removeEventListener(t,e,!1)}},t.prototype.dispatchEvent=function(n,t){n.dispatchEvent(t)},t.prototype.createMouseEvent=function(n){var t=this.getDefaultDocument().createEvent("MouseEvent");return t.initEvent(n,!0,!0),t},t.prototype.createEvent=function(n){var t=this.getDefaultDocument().createEvent("Event");return t.initEvent(n,!0,!0),t},t.prototype.preventDefault=function(n){n.preventDefault(),n.returnValue=!1},t.prototype.isPrevented=function(n){return n.defaultPrevented||null!=n.returnValue&&!n.returnValue},t.prototype.getInnerHTML=function(n){return n.innerHTML},t.prototype.getTemplateContent=function(n){return"content"in n&&this.isTemplateElement(n)?n.content:null},t.prototype.getOuterHTML=function(n){return n.outerHTML},t.prototype.nodeName=function(n){return n.nodeName},t.prototype.nodeValue=function(n){return n.nodeValue},t.prototype.type=function(n){return n.type},t.prototype.content=function(n){return this.hasProperty(n,"content")?n.content:n},t.prototype.firstChild=function(n){return n.firstChild},t.prototype.nextSibling=function(n){return n.nextSibling},t.prototype.parentElement=function(n){return n.parentNode},t.prototype.childNodes=function(n){return n.childNodes},t.prototype.childNodesAsList=function(n){for(var t=n.childNodes,e=new Array(t.length),l=0;l0},t.prototype.tagName=function(n){return n.tagName},t.prototype.attributeMap=function(n){for(var t=new Map,e=n.attributes,l=0;l0;s||(s=n[o]=[]);var u=Xn(t)?Zone.root:Zone.current;if(0===s.length)s.push({zone:u,handler:i});else{for(var c=!1,d=0;d-1},t}(Pn),rt=["alt","control","meta","shift"],it={alt:function(n){return n.altKey},control:function(n){return n.ctrlKey},meta:function(n){return n.metaKey},shift:function(n){return n.shiftKey}},ot=function(n){function t(t){return n.call(this,t)||this}return Object(i.__extends)(t,n),t.prototype.supports=function(n){return null!=t.parseEventName(n)},t.prototype.addEventListener=function(n,e,l){var r=t.parseEventName(e),i=t.eventCallback(r.fullKey,l,this.manager.getZone());return this.manager.getZone().runOutsideAngular(function(){return un().onAndCancel(n,r.domEventName,i)})},t.parseEventName=function(n){var e=n.toLowerCase().split("."),l=e.shift();if(0===e.length||"keydown"!==l&&"keyup"!==l)return null;var r=t._normalizeKey(e.pop()),i="";if(rt.forEach(function(n){var t=e.indexOf(n);t>-1&&(e.splice(t,1),i+=n+".")}),i+=r,0!=e.length||0===r.length)return null;var o={};return o.domEventName=l,o.fullKey=i,o},t.getEventFullKey=function(n){var t="",e=un().getEventKey(n);return" "===(e=e.toLowerCase())?e="space":"."===e&&(e="dot"),rt.forEach(function(l){l!=e&&(0,it[l])(n)&&(t+=l+".")}),t+=e},t.eventCallback=function(n,e,l){return function(r){t.getEventFullKey(r)===n&&l.runGuarded(function(){return e(r)})}},t._normalizeKey=function(n){switch(n){case"esc":return"escape";default:return n}},t}(Pn),st=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,at=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;function ut(n){return(n=String(n)).match(st)||n.match(at)?n:(Object(l.Y)()&&un().log("WARNING: sanitizing unsafe URL value "+n+" (see http://g.co/ng/security#xss)"),"unsafe:"+n)}var ct=null,dt=null;function ht(n){for(var t={},e=0,l=n.split(",");e")):this.sanitizedSomething=!0},n.prototype.endElement=function(n){var t=dt.nodeName(n).toLowerCase();yt.hasOwnProperty(t)&&!ft.hasOwnProperty(t)&&(this.buf.push(""))},n.prototype.chars=function(n){this.buf.push(St(n))},n}();function Mt(n,t){if(t&&dt.contains(n,t))throw new Error("Failed to sanitize html because the element is clobbered: "+dt.getOuterHTML(n));return t}var kt=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,Ct=/([^\#-~ |!])/g;function St(n){return n.replace(/&/g,"&").replace(kt,function(n){return"&#"+(1024*(n.charCodeAt(0)-55296)+(n.charCodeAt(1)-56320)+65536)+";"}).replace(Ct,function(n){return"&#"+n.charCodeAt(0)+";"}).replace(//g,">")}function Ot(n){dt.attributeMap(n).forEach(function(t,e){"xmlns:ns1"!==e&&0!==e.indexOf("ns1:")||dt.removeAttribute(n,e)});for(var t=0,e=dt.childNodesAsList(n);t0){var l=n.slice(0,t),r=n.slice(t+1).trim();e.set(l,r)}}),e},n.prototype.append=function(n,t){var e=this.getAll(n);null===e?this.set(n,t):e.push(t)},n.prototype.delete=function(n){var t=n.toLowerCase();this._normalizedNames.delete(t),this._headers.delete(t)},n.prototype.forEach=function(n){var t=this;this._headers.forEach(function(e,l){return n(e,t._normalizedNames.get(l),t._headers)})},n.prototype.get=function(n){var t=this.getAll(n);return null===t?null:t.length>0?t[0]:null},n.prototype.has=function(n){return this._headers.has(n.toLowerCase())},n.prototype.keys=function(){return Array.from(this._normalizedNames.values())},n.prototype.set=function(n,t){Array.isArray(t)?t.length&&this._headers.set(n.toLowerCase(),[t.join(",")]):this._headers.set(n.toLowerCase(),[t]),this.mayBeSetNormalizedName(n)},n.prototype.values=function(){return Array.from(this._headers.values())},n.prototype.toJSON=function(){var n=this,t={};return this._headers.forEach(function(e,l){var r=[];e.forEach(function(n){return r.push.apply(r,n.split(","))}),t[n._normalizedNames.get(l)]=r}),t},n.prototype.getAll=function(n){return this.has(n)&&this._headers.get(n.toLowerCase())||null},n.prototype.entries=function(){throw new Error('"entries" method is not implemented on Headers class')},n.prototype.mayBeSetNormalizedName=function(n){var t=n.toLowerCase();this._normalizedNames.has(t)||this._normalizedNames.set(t,n)},n}(),Jt=function(){function n(n){void 0===n&&(n={});var t=n.body,e=n.status,l=n.headers,r=n.statusText,i=n.type,o=n.url;this.body=null!=t?t:null,this.status=null!=e?e:null,this.headers=null!=l?l:null,this.statusText=null!=r?r:null,this.type=null!=i?i:null,this.url=null!=o?o:null}return n.prototype.merge=function(t){return new n({body:t&&null!=t.body?t.body:this.body,status:t&&null!=t.status?t.status:this.status,headers:t&&null!=t.headers?t.headers:this.headers,statusText:t&&null!=t.statusText?t.statusText:this.statusText,type:t&&null!=t.type?t.type:this.type,url:t&&null!=t.url?t.url:this.url})},n}(),Qt=function(n){function t(){return n.call(this,{status:200,statusText:"Ok",type:zt.Default,headers:new qt})||this}return Object(i.__extends)(t,n),t}(Jt),Kt=function(){};function Xt(n){if("string"!=typeof n)return n;switch(n.toUpperCase()){case"GET":return Wt.Get;case"POST":return Wt.Post;case"PUT":return Wt.Put;case"DELETE":return Wt.Delete;case"OPTIONS":return Wt.Options;case"HEAD":return Wt.Head;case"PATCH":return Wt.Patch}throw new Error('Invalid request method. The method "'+n+'" is not supported.')}var Zt=function(n){return n>=200&&n<300},$t=function(){function n(){}return n.prototype.encodeKey=function(n){return ne(n)},n.prototype.encodeValue=function(n){return ne(n)},n}();function ne(n){return encodeURIComponent(n).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/gi,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%2B/gi,"+").replace(/%3D/gi,"=").replace(/%3F/gi,"?").replace(/%2F/gi,"/")}var te=function(){function n(n,t){void 0===n&&(n=""),void 0===t&&(t=new $t),this.rawParams=n,this.queryEncoder=t,this.paramsMap=function(n){void 0===n&&(n="");var t=new Map;return n.length>0&&n.split("&").forEach(function(n){var e=n.indexOf("="),l=-1==e?[n,""]:[n.slice(0,e),n.slice(e+1)],r=l[0],i=l[1],o=t.get(r)||[];o.push(i),t.set(r,o)}),t}(n)}return n.prototype.clone=function(){var t=new n("",this.queryEncoder);return t.appendAll(this),t},n.prototype.has=function(n){return this.paramsMap.has(n)},n.prototype.get=function(n){var t=this.paramsMap.get(n);return Array.isArray(t)?t[0]:null},n.prototype.getAll=function(n){return this.paramsMap.get(n)||[]},n.prototype.set=function(n,t){if(void 0!==t&&null!==t){var e=this.paramsMap.get(n)||[];e.length=0,e.push(t),this.paramsMap.set(n,e)}else this.delete(n)},n.prototype.setAll=function(n){var t=this;n.paramsMap.forEach(function(n,e){var l=t.paramsMap.get(e)||[];l.length=0,l.push(n[0]),t.paramsMap.set(e,l)})},n.prototype.append=function(n,t){if(void 0!==t&&null!==t){var e=this.paramsMap.get(n)||[];e.push(t),this.paramsMap.set(n,e)}},n.prototype.appendAll=function(n){var t=this;n.paramsMap.forEach(function(n,e){for(var l=t.paramsMap.get(e)||[],r=0;r=200&&e.status<=299,e.statusText=t.statusText,e.headers=t.headers,e.type=t.type,e.url=t.url,e}return Object(i.__extends)(t,n),t.prototype.toString=function(){return"Response with status: "+this.status+" "+this.statusText+" for URL: "+this.url},t}(ee),re=/^\)\]\}',?\n/,ie=function(){function n(n,t,e){var l=this;this.request=n,this.response=new o.a(function(r){var i=t.build();i.open(Wt[n.method].toUpperCase(),n.url),null!=n.withCredentials&&(i.withCredentials=n.withCredentials);var o=function(){var t=1223===i.status?204:i.status,l=null;204!==t&&"string"==typeof(l="undefined"==typeof i.response?i.responseText:i.response)&&(l=l.replace(re,"")),0===t&&(t=l?200:0);var o,s=qt.fromResponseHeaderString(i.getAllResponseHeaders()),a=("responseURL"in(o=i)?o.responseURL:/^X-Request-URL:/m.test(o.getAllResponseHeaders())?o.getResponseHeader("X-Request-URL"):null)||n.url,u=new Jt({body:l,status:t,headers:s,statusText:i.statusText||"OK",url:a});null!=e&&(u=e.merge(u));var c=new le(u);if(c.ok=Zt(t),c.ok)return r.next(c),void r.complete();r.error(c)},s=function(n){var t=new Jt({body:n,type:zt.Error,status:i.status,statusText:i.statusText});null!=e&&(t=e.merge(t)),r.error(new le(t))};if(l.setDetectedContentType(n,i),null==n.headers&&(n.headers=new qt),n.headers.has("Accept")||n.headers.append("Accept","application/json, text/plain, */*"),n.headers.forEach(function(n,t){return i.setRequestHeader(t,n.join(","))}),null!=n.responseType&&null!=i.responseType)switch(n.responseType){case Gt.ArrayBuffer:i.responseType="arraybuffer";break;case Gt.Json:i.responseType="json";break;case Gt.Text:i.responseType="text";break;case Gt.Blob:i.responseType="blob";break;default:throw new Error("The selected responseType is not supported")}return i.addEventListener("load",o),i.addEventListener("error",s),i.send(l.request.getBody()),function(){i.removeEventListener("load",o),i.removeEventListener("error",s),i.abort()}})}return n.prototype.setDetectedContentType=function(n,t){if(null==n.headers||null==n.headers.get("Content-Type"))switch(n.contentType){case Ut.NONE:break;case Ut.JSON:t.setRequestHeader("content-type","application/json");break;case Ut.FORM:t.setRequestHeader("content-type","application/x-www-form-urlencoded;charset=UTF-8");break;case Ut.TEXT:t.setRequestHeader("content-type","text/plain");break;case Ut.BLOB:var e=n.blob();e.type&&t.setRequestHeader("content-type",e.type)}},n}(),oe=function(){function n(n,t){void 0===n&&(n="XSRF-TOKEN"),void 0===t&&(t="X-XSRF-TOKEN"),this._cookieName=n,this._headerName=t}return n.prototype.configureRequest=function(n){var t=un().getCookie(this._cookieName);t&&n.headers.set(this._headerName,t)},n}(),se=function(){function n(n,t,e){this._browserXHR=n,this._baseResponseOptions=t,this._xsrfStrategy=e}return n.prototype.createConnection=function(n){return this._xsrfStrategy.configureRequest(n),new ie(n,this._browserXHR,this._baseResponseOptions)},n}(),ae=function(){function n(n){void 0===n&&(n={});var t=n.method,e=n.headers,l=n.body,r=n.url,i=n.search,o=n.params,s=n.withCredentials,a=n.responseType;this.method=null!=t?Xt(t):null,this.headers=null!=e?e:null,this.body=null!=l?l:null,this.url=null!=r?r:null,this.params=this._mergeSearchParams(o||i),this.withCredentials=null!=s?s:null,this.responseType=null!=a?a:null}return Object.defineProperty(n.prototype,"search",{get:function(){return this.params},set:function(n){this.params=n},enumerable:!0,configurable:!0}),n.prototype.merge=function(t){return new n({method:t&&null!=t.method?t.method:this.method,headers:t&&null!=t.headers?t.headers:new qt(this.headers),body:t&&null!=t.body?t.body:this.body,url:t&&null!=t.url?t.url:this.url,params:t&&this._mergeSearchParams(t.params||t.search),withCredentials:t&&null!=t.withCredentials?t.withCredentials:this.withCredentials,responseType:t&&null!=t.responseType?t.responseType:this.responseType})},n.prototype._mergeSearchParams=function(n){return n?n instanceof te?n.clone():"string"==typeof n?new te(n):this._parseParams(n):this.params},n.prototype._parseParams=function(n){var t=this;void 0===n&&(n={});var e=new te;return Object.keys(n).forEach(function(l){var r=n[l];Array.isArray(r)?r.forEach(function(n){return t._appendParam(l,n,e)}):t._appendParam(l,r,e)}),e},n.prototype._appendParam=function(n,t,e){"string"!=typeof t&&(t=JSON.stringify(t)),e.append(n,t)},n}(),ue=function(n){function t(){return n.call(this,{method:Wt.Get,headers:new qt})||this}return Object(i.__extends)(t,n),t}(ae),ce=function(n){function t(t){var e=n.call(this)||this,l=t.url;e.url=t.url;var r,i=t.params||t.search;if(i&&(r="object"!=typeof i||i instanceof te?i.toString():function(n){var t=new te;return Object.keys(n).forEach(function(e){var l=n[e];l&&Array.isArray(l)?l.forEach(function(n){return t.append(e,n.toString())}):t.append(e,l.toString())}),t}(i).toString()).length>0){var o="?";-1!=e.url.indexOf("?")&&(o="&"==e.url[e.url.length-1]?"":"&"),e.url=l+o+r}return e._body=t.body,e.method=Xt(t.method),e.headers=new qt(t.headers),e.contentType=e.detectContentType(),e.withCredentials=t.withCredentials,e.responseType=t.responseType,e}return Object(i.__extends)(t,n),t.prototype.detectContentType=function(){switch(this.headers.get("content-type")){case"application/json":return Ut.JSON;case"application/x-www-form-urlencoded":return Ut.FORM;case"multipart/form-data":return Ut.FORM_DATA;case"text/plain":case"text/html":return Ut.TEXT;case"application/octet-stream":return this._body instanceof _e?Ut.ARRAY_BUFFER:Ut.BLOB;default:return this.detectContentTypeFromBody()}},t.prototype.detectContentTypeFromBody=function(){return null==this._body?Ut.NONE:this._body instanceof te?Ut.FORM:this._body instanceof pe?Ut.FORM_DATA:this._body instanceof fe?Ut.BLOB:this._body instanceof _e?Ut.ARRAY_BUFFER:this._body&&"object"==typeof this._body?Ut.JSON:Ut.TEXT},t.prototype.getBody=function(){switch(this.contentType){case Ut.JSON:case Ut.FORM:return this.text();case Ut.FORM_DATA:return this._body;case Ut.TEXT:return this.text();case Ut.BLOB:return this.blob();case Ut.ARRAY_BUFFER:return this.arrayBuffer();default:return null}},t}(ee),de=function(){},he="object"==typeof window?window:de,pe=he.FormData||de,fe=he.Blob||de,_e=he.ArrayBuffer||de;function me(n,t){return n.createConnection(t).response}function ge(n,t,e,l){return n.merge(new ae(t?{method:t.method||e,url:t.url||l,search:t.search,params:t.params,headers:t.headers,body:t.body,withCredentials:t.withCredentials,responseType:t.responseType}:{method:e,url:l}))}var ye=function(){function n(n,t){this._backend=n,this._defaultOptions=t}return n.prototype.request=function(n,t){var e;if("string"==typeof n)e=me(this._backend,new ce(ge(this._defaultOptions,t,Wt.Get,n)));else{if(!(n instanceof ce))throw new Error("First argument must be a url string or Request instance.");e=me(this._backend,n)}return e},n.prototype.get=function(n,t){return this.request(new ce(ge(this._defaultOptions,t,Wt.Get,n)))},n.prototype.post=function(n,t,e){return this.request(new ce(ge(this._defaultOptions.merge(new ae({body:t})),e,Wt.Post,n)))},n.prototype.put=function(n,t,e){return this.request(new ce(ge(this._defaultOptions.merge(new ae({body:t})),e,Wt.Put,n)))},n.prototype.delete=function(n,t){return this.request(new ce(ge(this._defaultOptions,t,Wt.Delete,n)))},n.prototype.patch=function(n,t,e){return this.request(new ce(ge(this._defaultOptions.merge(new ae({body:t})),e,Wt.Patch,n)))},n.prototype.head=function(n,t){return this.request(new ce(ge(this._defaultOptions,t,Wt.Head,n)))},n.prototype.options=function(n,t){return this.request(new ce(ge(this._defaultOptions,t,Wt.Options,n)))},n}();function be(){return new oe}function ve(n,t){return new ye(n,t)}var we=function(){},xe=function(n){function t(t,e){n.call(this),this.error=t,this.scheduler=e}return Object(i.__extends)(t,n),t.create=function(n,e){return new t(n,e)},t.dispatch=function(n){n.subscriber.error(n.error)},t.prototype._subscribe=function(n){var e=this.error,l=this.scheduler;if(n.syncErrorThrowable=!0,l)return l.schedule(t.dispatch,0,{error:e,subscriber:n});n.error(e)},t}(o.a).create;o.a.throw=xe;var Me=e("tZ2B"),ke=e("PIsA");function Ce(n){return function(t){var e=new Se(n),l=t.lift(e);return e.caught=l}}var Se=function(){function n(n){this.selector=n}return n.prototype.call=function(n,t){return t.subscribe(new Oe(n,this.selector,this.caught))},n}(),Oe=function(n){function t(t,e,l){n.call(this,t),this.selector=e,this.caught=l}return Object(i.__extends)(t,n),t.prototype.error=function(t){if(!this.isStopped){var e=void 0;try{e=this.selector(t,this.caught)}catch(t){return void n.prototype.error.call(this,t)}this._unsubscribeAndRecycle(),this.add(Object(ke.a)(this,e))}},t}(Me.a);function Te(n){return Ce(n)(this)}o.a.prototype.catch=Te,o.a.prototype._catch=Te;var Le=e("HdCx");function Pe(n,t){return Object(Le.a)(n,t)(this)}o.a.prototype.map=Pe;var De=e("YKDW"),Ae=e("uotZ"),Ee=e.n(Ae),Ye=function(){function n(n,t){this.http=n,this.translate=t,this.url=r.nodeUrl}return n.prototype.getTransactions=function(n){var t=n.map(function(n){return n.address}).join(",");return this.post("transactions",{addrs:t,verbose:!0}).map(function(n){return n.map(function(n){return{addresses:[],balance:new Ae.BigNumber(0),block:n.status.block_seq,confirmed:n.status.confirmed,timestamp:n.txn.timestamp,txid:n.txn.txid,inputs:n.txn.inputs,outputs:n.txn.outputs}})})},n.prototype.getVersion=function(){return this.get("version")},n.prototype.generateSeed=function(n){return void 0===n&&(n=128),this.get("wallet/newSeed",{entropy:n}).map(function(n){return n.seed})},n.prototype.getHealth=function(){return this.get("health")},n.prototype.getWallets=function(){return this.get("wallets").map(function(n){var t=[];return n.forEach(function(n){var e={label:n.meta.label,filename:n.meta.filename,coins:null,hours:null,addresses:[],encrypted:n.meta.encrypted};n.entries&&(e.addresses=n.entries.map(function(n){return{address:n.address,coins:null,hours:null,confirmed:!0}})),t.push(e)}),t})},n.prototype.getWalletSeed=function(n,t){return this.post("wallet/seed",{id:n.filename,password:t}).map(function(n){return n.seed})},n.prototype.postWalletCreate=function(n,t,e,l,r){var i={label:n,seed:t,scan:e,type:r};return l&&(i.password=l,i.encrypt=!0),this.post("wallet/create",i).map(function(n){return{label:n.meta.label,filename:n.meta.filename,coins:null,hours:null,addresses:n.entries.map(function(n){return{address:n.address,coins:null,hours:null,confirmed:!0}}),encrypted:n.meta.encrypted}})},n.prototype.postWalletNewAddress=function(n,t,e){var l=new Object;return l.id=n.filename,l.num=t,e&&(l.password=e),this.post("wallet/newAddress",l).map(function(n){var t=[];return n.addresses.forEach(function(n){t.push({address:n,coins:null,hours:null})}),t})},n.prototype.postWalletToggleEncryption=function(n,t){return this.post("wallet/"+(n.encrypted?"decrypt":"encrypt"),{id:n.filename,password:t})},n.prototype.get=function(n,t,e,l){var r=this;return void 0===t&&(t=null),void 0===e&&(e={}),void 0===l&&(l=!1),this.http.get(this.getUrl(n,t,l),this.returnRequestOptions(e)).map(function(n){return n.json()}).catch(function(n){return r.processConnectionError(n)})},n.prototype.getCsrf=function(){return this.get("csrf").map(function(n){return n.csrf_token})},n.prototype.post=function(n,t,e,l){var r=this;return void 0===t&&(t={}),void 0===e&&(e={}),void 0===l&&(l=!1),this.getCsrf().first().flatMap(function(i){return e.csrf=i,l&&(e.json=!0),r.http.post(r.getUrl(n,null,l),e.json||l?JSON.stringify(t):r.getQueryString(t),r.returnRequestOptions(e)).map(function(n){return n.json()}).catch(function(n){return r.processConnectionError(n)})})},n.prototype.returnRequestOptions=function(n){var t=new ae;return t.headers=this.getHeaders(n),n.csrf&&t.headers.append("X-CSRF-Token",n.csrf),t},n.prototype.getHeaders=function(n){var t=new qt;return t.append("Content-Type",n.json?"application/json":"application/x-www-form-urlencoded"),t},n.prototype.getQueryString=function(n){return void 0===n&&(n=null),n?Object.keys(n).reduce(function(t,e){return t.push(e+"="+encodeURIComponent(n[e])),t},[]).join("&"):""},n.prototype.getUrl=function(n,t,e){return void 0===t&&(t=null),void 0===e&&(e=!1),n.startsWith("/")&&(n=n.substr(1,n.length-1)),this.url+(e?"v2/":"v1/")+n+"?"+this.getQueryString(t)},n.prototype.processConnectionError=function(n,t){if(void 0===t&&(t=!1),n){if("string"==typeof n._body)return o.a.throw(n);if(n.error&&"string"==typeof n.error)return n._body=n.error,o.a.throw(n);if(n.message)return n._body=n.message,o.a.throw(n)}var e=Error(this.translate.instant(t?"hardware-wallet.errors.daemon-connection":"service.api.server-error"));return e._body=e.message,o.a.throw(e)},n}(),je=e("+3/4"),Ie=e("BX3T"),Re=function(n){function t(t,e){n.call(this),this.sources=t,this.resultSelector=e}return Object(i.__extends)(t,n),t.create=function(){for(var n=[],e=0;e=0}o.a.prototype.mergeMap=tl,o.a.prototype.flatMap=tl;var ll=e("AMGY"),rl=e("VwZZ"),il=function(n){function t(t,e){n.call(this,t,e),this.scheduler=t,this.work=e,this.pending=!1}return Object(i.__extends)(t,n),t.prototype.schedule=function(n,t){if(void 0===t&&(t=0),this.closed)return this;this.state=n,this.pending=!0;var e=this.id,l=this.scheduler;return null!=e&&(this.id=this.recycleAsyncId(l,e,t)),this.delay=t,this.id=this.id||this.requestAsyncId(l,this.id,t),this},t.prototype.requestAsyncId=function(n,t,e){return void 0===e&&(e=0),ll.a.setInterval(n.flush.bind(n,this),e)},t.prototype.recycleAsyncId=function(n,t,e){if(void 0===e&&(e=0),null!==e&&this.delay===e&&!1===this.pending)return t;ll.a.clearInterval(t)},t.prototype.execute=function(n,t){if(this.closed)return new Error("executing a cancelled action");this.pending=!1;var e=this._execute(n,t);if(e)return e;!1===this.pending&&null!=this.id&&(this.id=this.recycleAsyncId(this.scheduler,this.id,null))},t.prototype._execute=function(n,t){var e=!1,l=void 0;try{this.work(n)}catch(n){e=!0,l=!!n&&n||new Error(n)}if(e)return this.unsubscribe(),l},t.prototype._unsubscribe=function(){var n=this.id,t=this.scheduler,e=t.actions,l=e.indexOf(this);this.work=null,this.state=null,this.pending=!1,this.scheduler=null,-1!==l&&e.splice(l,1),null!=n&&(this.id=this.recycleAsyncId(t,n,null)),this.delay=null},t}(function(n){function t(t,e){n.call(this)}return Object(i.__extends)(t,n),t.prototype.schedule=function(n,t){return void 0===t&&(t=0),this},t}(rl.a)),ol=function(n){function t(){n.apply(this,arguments),this.actions=[],this.active=!1,this.scheduled=void 0}return Object(i.__extends)(t,n),t.prototype.flush=function(n){var t=this.actions;if(this.active)t.push(n);else{var e;this.active=!0;do{if(e=n.execute(n.state,n.delay))break}while(n=t.shift());if(this.active=!1,e){for(;n=t.shift();)n.unsubscribe();throw e}}},t}(function(){function n(t,e){void 0===e&&(e=n.now),this.SchedulerAction=t,this.now=e}return n.prototype.schedule=function(n,t,e){return void 0===t&&(t=0),new this.SchedulerAction(this,n).schedule(e,t)},n.now=Date.now?Date.now:function(){return+new Date},n}()),sl=new ol(il),al=e("1Q68");function ul(n){return n instanceof Date&&!isNaN(+n)}var cl=function(n){function t(t,e,l){void 0===t&&(t=0),n.call(this),this.period=-1,this.dueTime=0,el(e)?this.period=Number(e)<1?1:Number(e):Object(al.a)(e)&&(l=e),Object(al.a)(l)||(l=sl),this.scheduler=l,this.dueTime=ul(t)?+t-this.scheduler.now():t}return Object(i.__extends)(t,n),t.create=function(n,e,l){return void 0===n&&(n=0),new t(n,e,l)},t.dispatch=function(n){var t=n.index,e=n.period,l=n.subscriber;if(l.next(t),!l.closed){if(-1===e)return l.complete();n.index=t+1,this.schedule(n,e)}},t.prototype._subscribe=function(n){return this.scheduler.schedule(t.dispatch,this.dueTime,{index:0,period:this.period,subscriber:n})},t}(o.a).create;o.a.timer=cl;var dl=e("Veqx"),hl=e("etqZ"),pl=function(){function n(n){this.project=n}return n.prototype.call=function(n,t){return t.subscribe(new fl(n,this.project))},n}(),fl=function(n){function t(t,e,l){void 0===l&&(l=Object.create(null)),n.call(this,t),this.iterators=[],this.active=0,this.project="function"==typeof e?e:null,this.values=l}return Object(i.__extends)(t,n),t.prototype._next=function(n){var t=this.iterators;Object(Ie.a)(n)?t.push(new ml(n)):t.push("function"==typeof n[hl.a]?new _l(n[hl.a]()):new gl(this.destination,this,n))},t.prototype._complete=function(){var n=this.iterators,t=n.length;if(0!==t){this.active=t;for(var e=0;ethis.index},n.prototype.hasCompleted=function(){return this.array.length===this.index},n}(),gl=function(n){function t(t,e,l){n.call(this,t),this.parent=e,this.observable=l,this.stillUnsubscribed=!0,this.buffer=[],this.isComplete=!1}return Object(i.__extends)(t,n),t.prototype[hl.a]=function(){return this},t.prototype.next=function(){var n=this.buffer;return 0===n.length&&this.isComplete?{value:null,done:!0}:{value:n.shift(),done:!1}},t.prototype.hasValue=function(){return this.buffer.length>0},t.prototype.hasCompleted=function(){return 0===this.buffer.length&&this.isComplete},t.prototype.notifyComplete=function(){this.buffer.length>0?(this.isComplete=!0,this.parent.notifyInactive()):this.destination.complete()},t.prototype.notifyNext=function(n,t,e,l,r){this.buffer.push(t),this.parent.checkIterators()},t.prototype.subscribe=function(n,t){return Object(ke.a)(this,this.observable,this,t)},t}(Me.a);o.a.zip=function(){for(var n=[],t=0;t0?n.prototype.schedule.call(this,t,e):(this.delay=e,this.state=t,this.scheduler.flush(this),this)},t.prototype.execute=function(t,e){return e>0||this.closed?n.prototype.execute.call(this,t,e):this._execute(t,e)},t.prototype.requestAsyncId=function(t,e,l){return void 0===l&&(l=0),null!==l&&l>0||null===l&&this.delay>0?n.prototype.requestAsyncId.call(this,t,e,l):t.flush(this)},t}(il),vl=new(function(n){function t(){n.apply(this,arguments)}return Object(i.__extends)(t,n),t}(ol))(bl),wl=function(){function n(n,t,e){this.kind=n,this.value=t,this.error=e,this.hasValue="N"===n}return n.prototype.observe=function(n){switch(this.kind){case"N":return n.next&&n.next(this.value);case"E":return n.error&&n.error(this.error);case"C":return n.complete&&n.complete()}},n.prototype.do=function(n,t,e){switch(this.kind){case"N":return n&&n(this.value);case"E":return t&&t(this.error);case"C":return e&&e()}},n.prototype.accept=function(n,t,e){return n&&"function"==typeof n.next?this.observe(n):this.do(n,t,e)},n.prototype.toObservable=function(){switch(this.kind){case"N":return o.a.of(this.value);case"E":return o.a.throw(this.error);case"C":return o.a.empty()}throw new Error("unexpected notification kind value")},n.createNext=function(t){return"undefined"!=typeof t?new n("N",t):n.undefinedValueNotification},n.createError=function(t){return new n("E",void 0,t)},n.createComplete=function(){return n.completeNotification},n.completeNotification=new n("C"),n.undefinedValueNotification=new n("N",void 0),n}(),xl=function(n){function t(t,e,l){void 0===l&&(l=0),n.call(this,t),this.scheduler=e,this.delay=l}return Object(i.__extends)(t,n),t.dispatch=function(n){n.notification.observe(n.destination),this.unsubscribe()},t.prototype.scheduleMessage=function(n){this.add(this.scheduler.schedule(t.dispatch,this.delay,new Ml(n,this.destination)))},t.prototype._next=function(n){this.scheduleMessage(wl.createNext(n))},t.prototype._error=function(n){this.scheduleMessage(wl.createError(n))},t.prototype._complete=function(){this.scheduleMessage(wl.createComplete())},t}(Be.a),Ml=function(n,t){this.notification=n,this.destination=t},kl=e("x6VL"),Cl=e("1Bqh"),Sl=function(n){function t(t,e,l){void 0===t&&(t=Number.POSITIVE_INFINITY),void 0===e&&(e=Number.POSITIVE_INFINITY),n.call(this),this.scheduler=l,this._events=[],this._bufferSize=t<1?1:t,this._windowTime=e<1?1:e}return Object(i.__extends)(t,n),t.prototype.next=function(t){var e=this._getNow();this._events.push(new Ol(e,t)),this._trimBufferThenGetEvents(),n.prototype.next.call(this,t)},t.prototype._subscribe=function(n){var t,e=this._trimBufferThenGetEvents(),l=this.scheduler;if(this.closed)throw new kl.a;this.hasError?t=rl.a.EMPTY:this.isStopped?t=rl.a.EMPTY:(this.observers.push(n),t=new Cl.a(this,n)),l&&n.add(n=new xl(n,l));for(var r=e.length,i=0;it&&(i=Math.max(i,r-t)),i>0&&l.splice(0,i),l},t}(yl.a),Ol=function(n,t){this.time=n,this.value=t},Tl=function(n){function t(t){n.call(this),this._value=t}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!0,configurable:!0}),t.prototype._subscribe=function(t){var e=n.prototype._subscribe.call(this,t);return e&&!e.closed&&t.next(this._value),e},t.prototype.getValue=function(){if(this.hasError)throw this.thrownError;if(this.closed)throw new kl.a;return this._value},t.prototype.next=function(t){n.prototype.next.call(this,this._value=t)},t}(yl.a),Ll={otcEnabled:!1,maxHardwareWalletAddresses:1,useHwWalletDaemon:!0,urlForHwWalletVersionChecking:"https://version.skycoin.com/skywallet/version.txt",hwWalletDownloadUrlAndPrefix:"https://downloads.skycoin.com/skywallet/skywallet-firmware-v",urlForVersionChecking:"https://version.skycoin.com/skycoin/version.txt",walletDownloadUrl:"https://www.skycoin.com/downloads/",uriSpecificatioPrefix:"skycoin",languages:[{code:"en",name:"English",iconName:"en.png"},{code:"zh",name:"\u4e2d\u6587",iconName:"zh.png"},{code:"es",name:"Espa\xf1ol",iconName:"es.png"}],defaultLanguage:"en"},Pl=new l.r("cdk-dir-doc"),Dl=function(){return function(n){this.value="ltr",this.change=new l.o,n&&(this.value=(n.body?n.body.dir:null)||(n.documentElement?n.documentElement.dir:null)||"ltr")}}(),Al=function(){};function El(n){return null!=n&&""+n!="false"}function Yl(n,t){return void 0===t&&(t=0),isNaN(parseFloat(n))||isNaN(Number(n))?t:Number(n)}var jl,Il,Rl="undefined"!=typeof Intl&&Intl.v8BreakIterator,Hl=function(){return function(){this.isBrowser="object"==typeof document&&!!document,this.EDGE=this.isBrowser&&/(edge)/i.test(navigator.userAgent),this.TRIDENT=this.isBrowser&&/(msie|trident)/i.test(navigator.userAgent),this.BLINK=this.isBrowser&&!(!window.chrome&&!Rl)&&!!CSS&&!this.EDGE&&!this.TRIDENT,this.WEBKIT=this.isBrowser&&/AppleWebKit/i.test(navigator.userAgent)&&!this.BLINK&&!this.EDGE&&!this.TRIDENT,this.IOS=this.isBrowser&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,this.FIREFOX=this.isBrowser&&/(firefox|minefield)/i.test(navigator.userAgent),this.ANDROID=this.isBrowser&&/android/i.test(navigator.userAgent)&&!this.TRIDENT,this.SAFARI=this.isBrowser&&/safari/i.test(navigator.userAgent)&&this.WEBKIT}}();function Nl(){if(null==jl&&"undefined"!=typeof window)try{window.addEventListener("test",null,Object.defineProperty({},"passive",{get:function(){return jl=!0}}))}finally{jl=jl||!1}return jl}var Fl=["color","button","checkbox","date","datetime-local","email","file","hidden","image","month","number","password","radio","range","reset","search","submit","tel","text","time","url","week"];function Bl(){if(Il)return Il;if("object"!=typeof document||!document)return Il=new Set(Fl);var n=document.createElement("input");return Il=new Set(Fl.filter(function(t){return n.setAttribute("type",t),n.type===t}))}var Vl=function(){},Wl=new l.r("mat-sanity-checks"),zl=function(){function n(n){this._sanityChecksEnabled=n,this._hasDoneGlobalChecks=!1,this._hasCheckedHammer=!1,this._document="object"==typeof document&&document?document:null,this._window="object"==typeof window&&window?window:null,this._areChecksEnabled()&&!this._hasDoneGlobalChecks&&(this._checkDoctypeIsDefined(),this._checkThemeIsPresent(),this._hasDoneGlobalChecks=!0)}return n.prototype._areChecksEnabled=function(){return this._sanityChecksEnabled&&Object(l.Y)()&&!this._isTestEnv()},n.prototype._isTestEnv=function(){return this._window&&(this._window.__karma__||this._window.jasmine)},n.prototype._checkDoctypeIsDefined=function(){this._document&&!this._document.doctype&&console.warn("Current document does not have a doctype. This may cause some Angular Material components not to behave as expected.")},n.prototype._checkThemeIsPresent=function(){if(this._document&&"function"==typeof getComputedStyle){var n=this._document.createElement("div");n.classList.add("mat-theme-loaded-marker"),this._document.body.appendChild(n);var t=getComputedStyle(n);t&&"none"!==t.display&&console.warn("Could not find Angular Material core theme. Most Material components may not work as expected. For more info refer to the theming guide: https://material.angular.io/guide/theming"),this._document.body.removeChild(n)}},n.prototype._checkHammerIsAvailable=function(){!this._hasCheckedHammer&&this._window&&(this._areChecksEnabled()&&!this._window.Hammer&&console.warn("Could not find HammerJS. Certain Angular Material components may not work correctly."),this._hasCheckedHammer=!0)},n}();function Ul(n){return function(n){function t(){for(var t=[],e=0;e=0},n.prototype.isFocusable=function(n){return function(n){return!function(n){return function(n){return"input"==n.nodeName.toLowerCase()}(n)&&"hidden"==n.type}(n)&&(function(n){var t=n.nodeName.toLowerCase();return"input"===t||"select"===t||"button"===t||"textarea"===t}(n)||function(n){return function(n){return"a"==n.nodeName.toLowerCase()}(n)&&n.hasAttribute("href")}(n)||n.hasAttribute("contenteditable")||wr(n))}(n)&&!this.isDisabled(n)&&this.isVisible(n)},n}();function wr(n){if(!n.hasAttribute("tabindex")||void 0===n.tabIndex)return!1;var t=n.getAttribute("tabindex");return"-32768"!=t&&!(!t||isNaN(parseInt(t,10)))}function xr(n){if(!wr(n))return null;var t=parseInt(n.getAttribute("tabindex")||"",10);return isNaN(t)?-1:t}var Mr=function(){function n(n,t,e,l,r){void 0===r&&(r=!1),this._element=n,this._checker=t,this._ngZone=e,this._document=l,this._enabled=!0,r||this.attachAnchors()}return Object.defineProperty(n.prototype,"enabled",{get:function(){return this._enabled},set:function(n){this._enabled=n,this._startAnchor&&this._endAnchor&&(this._startAnchor.tabIndex=this._endAnchor.tabIndex=this._enabled?0:-1)},enumerable:!0,configurable:!0}),n.prototype.destroy=function(){this._startAnchor&&this._startAnchor.parentNode&&this._startAnchor.parentNode.removeChild(this._startAnchor),this._endAnchor&&this._endAnchor.parentNode&&this._endAnchor.parentNode.removeChild(this._endAnchor),this._startAnchor=this._endAnchor=null},n.prototype.attachAnchors=function(){var n=this;this._startAnchor||(this._startAnchor=this._createAnchor()),this._endAnchor||(this._endAnchor=this._createAnchor()),this._ngZone.runOutsideAngular(function(){n._startAnchor.addEventListener("focus",function(){n.focusLastTabbableElement()}),n._endAnchor.addEventListener("focus",function(){n.focusFirstTabbableElement()}),n._element.parentNode&&(n._element.parentNode.insertBefore(n._startAnchor,n._element),n._element.parentNode.insertBefore(n._endAnchor,n._element.nextSibling))})},n.prototype.focusInitialElementWhenReady=function(){var n=this;return new Promise(function(t){n._executeOnStable(function(){return t(n.focusInitialElement())})})},n.prototype.focusFirstTabbableElementWhenReady=function(){var n=this;return new Promise(function(t){n._executeOnStable(function(){return t(n.focusFirstTabbableElement())})})},n.prototype.focusLastTabbableElementWhenReady=function(){var n=this;return new Promise(function(t){n._executeOnStable(function(){return t(n.focusLastTabbableElement())})})},n.prototype._getRegionBoundary=function(n){for(var t=this._element.querySelectorAll("[cdk-focus-region-"+n+"], [cdkFocusRegion"+n+"], [cdk-focus-"+n+"]"),e=0;e=0;e--){var l=1===t[e].nodeType?this._getLastTabbableElement(t[e]):null;if(l)return l}return null},n.prototype._createAnchor=function(){var n=this._document.createElement("div");return n.tabIndex=this._enabled?0:-1,n.classList.add("cdk-visually-hidden"),n.classList.add("cdk-focus-trap-anchor"),n},n.prototype._executeOnStable=function(n){this._ngZone.isStable?n():this._ngZone.onStable.asObservable().pipe(Object(_r.a)(1)).subscribe(n)},n}(),kr=function(){function n(n,t,e){this._checker=n,this._ngZone=t,this._document=e}return n.prototype.create=function(n,t){return void 0===t&&(t=!1),new Mr(n,this._checker,this._ngZone,this._document,t)},n}(),Cr=function(){function n(n){this._items=n,this._activeItemIndex=-1,this._wrap=!1,this._letterKeyStream=new yl.a,this._typeaheadSubscription=rl.a.EMPTY,this._pressedLetters=[],this.tabOut=new yl.a,this.change=new yl.a}return n.prototype.withWrap=function(){return this._wrap=!0,this},n.prototype.withTypeAhead=function(n){var t=this;if(void 0===n&&(n=200),this._items.length&&this._items.some(function(n){return"function"!=typeof n.getLabel}))throw Error("ListKeyManager items in typeahead mode must implement the `getLabel` method.");return this._typeaheadSubscription.unsubscribe(),this._typeaheadSubscription=this._letterKeyStream.pipe(Ve(function(n){return t._pressedLetters.push(n)}),mr(n),Ge(function(){return t._pressedLetters.length>0}),Object(Le.a)(function(){return t._pressedLetters.join("")})).subscribe(function(n){for(var e=t._items.toArray(),l=1;l=65&&t<=90||t>=48&&t<=91)&&this._letterKeyStream.next(String.fromCharCode(t)))}this._pressedLetters=[],n.preventDefault()},Object.defineProperty(n.prototype,"activeItemIndex",{get:function(){return this._activeItemIndex},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"activeItem",{get:function(){return this._activeItem},enumerable:!0,configurable:!0}),n.prototype.setFirstItemActive=function(){this._setActiveItemByIndex(0,1)},n.prototype.setLastItemActive=function(){this._setActiveItemByIndex(this._items.length-1,-1)},n.prototype.setNextItemActive=function(){this._activeItemIndex<0?this.setFirstItemActive():this._setActiveItemByDelta(1)},n.prototype.setPreviousItemActive=function(){this._activeItemIndex<0&&this._wrap?this.setLastItemActive():this._setActiveItemByDelta(-1)},n.prototype.updateActiveItemIndex=function(n){this._activeItemIndex=n},n.prototype._setActiveItemByDelta=function(n,t){void 0===t&&(t=this._items.toArray()),this._wrap?this._setActiveInWrapMode(n,t):this._setActiveInDefaultMode(n,t)},n.prototype._setActiveInWrapMode=function(n,t){this._activeItemIndex=(this._activeItemIndex+n+t.length)%t.length,t[this._activeItemIndex].disabled?this._setActiveInWrapMode(n,t):this.setActiveItem(this._activeItemIndex)},n.prototype._setActiveInDefaultMode=function(n,t){this._setActiveItemByIndex(this._activeItemIndex+n,n,t)},n.prototype._setActiveItemByIndex=function(n,t,e){if(void 0===e&&(e=this._items.toArray()),e[n]){for(;e[n].disabled;)if(!e[n+=t])return;this.setActiveItem(n)}},n}(),Sr=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return Object(i.__extends)(t,n),t.prototype.setActiveItem=function(t){this.activeItem&&this.activeItem.setInactiveStyles(),n.prototype.setActiveItem.call(this,t),this.activeItem&&this.activeItem.setActiveStyles()},t}(Cr);function Or(n,t){return(n.getAttribute(t)||"").match(/\S+/g)||[]}var Tr=0,Lr=new Map,Pr=null,Dr=function(){function n(n){this._document=n}return n.prototype.describe=function(n,t){t.trim()&&(Lr.has(t)||this._createMessageElement(t),this._isElementDescribedByMessage(n,t)||this._addMessageReference(n,t))},n.prototype.removeDescription=function(n,t){if(t.trim()){this._isElementDescribedByMessage(n,t)&&this._removeMessageReference(n,t);var e=Lr.get(t);e&&0===e.referenceCount&&this._deleteMessageElement(t),Pr&&0===Pr.childNodes.length&&this._deleteMessagesContainer()}},n.prototype.ngOnDestroy=function(){for(var n=this._document.querySelectorAll("[cdk-describedby-host]"),t=0;t0?t._scrolled.pipe(qr(n)).subscribe(e):t._scrolled.subscribe(e);return t._scrolledCount++,function(){l.unsubscribe(),t._scrolledCount--,t._globalSubscription&&!t._scrolledCount&&(t._globalSubscription.unsubscribe(),t._globalSubscription=null)}}):Object(Fe.a)()},n.prototype.ancestorScrolled=function(n,t){var e=this.getAncestorScrollContainers(n);return this.scrolled(t).pipe(Ge(function(n){return!n||e.indexOf(n)>-1}))},n.prototype.getAncestorScrollContainers=function(n){var t=this,e=[];return this.scrollContainers.forEach(function(l,r){t._scrollableContainsElement(r,n)&&e.push(r)}),e},n.prototype._scrollableContainsElement=function(n,t){var e=t.nativeElement,l=n.getElementRef().nativeElement;do{if(e==l)return!0}while(e=e.parentElement);return!1},n.prototype._addGlobalListener=function(){var n=this;this._globalSubscription=this._ngZone.runOutsideAngular(function(){return zr(window.document,"scroll").subscribe(function(){return n._scrolled.next()})})},n}();function Kr(n,t,e){return n||new Qr(t,e)}var Xr=function(){function n(n,t){var e=this;this._change=n.isBrowser?t.runOutsideAngular(function(){return Object(Jr.a)(zr(window,"resize"),zr(window,"orientationchange"))}):Object(Fe.a)(),this._invalidateCache=this.change().subscribe(function(){return e._updateViewportSize()})}return n.prototype.ngOnDestroy=function(){this._invalidateCache.unsubscribe()},n.prototype.getViewportSize=function(){return this._viewportSize||this._updateViewportSize(),{width:this._viewportSize.width,height:this._viewportSize.height}},n.prototype.getViewportRect=function(){var n=this.getViewportScrollPosition(),t=this.getViewportSize(),e=t.width,l=t.height;return{top:n.top,left:n.left,bottom:n.top+l,right:n.left+e,height:l,width:e}},n.prototype.getViewportScrollPosition=function(){var n=document.documentElement.getBoundingClientRect();return{top:-n.top||document.body.scrollTop||window.scrollY||document.documentElement.scrollTop||0,left:-n.left||document.body.scrollLeft||window.scrollX||document.documentElement.scrollLeft||0}},n.prototype.change=function(n){return void 0===n&&(n=20),n>0?this._change.pipe(qr(n)):this._change},n.prototype._updateViewportSize=function(){this._viewportSize={width:window.innerWidth,height:window.innerHeight}},n}();function Zr(n,t,e){return n||new Xr(t,e)}var $r=function(){};function ni(){throw Error("Host already has a portal attached")}var ti=function(){function n(){}return n.prototype.attach=function(n){return null==n&&function(){throw Error("Attempting to attach a portal to a null PortalOutlet")}(),n.hasAttached()&&ni(),this._attachedHost=n,n.attach(this)},n.prototype.detach=function(){var n=this._attachedHost;null==n?function(){throw Error("Attempting to detach a portal that is not attached to a host")}():(this._attachedHost=null,n.detach())},Object.defineProperty(n.prototype,"isAttached",{get:function(){return null!=this._attachedHost},enumerable:!0,configurable:!0}),n.prototype.setAttachedHost=function(n){this._attachedHost=n},n}(),ei=function(n){function t(t,e,l){var r=n.call(this)||this;return r.component=t,r.viewContainerRef=e,r.injector=l,r}return Object(i.__extends)(t,n),t}(ti),li=function(n){function t(t,e,l){var r=n.call(this)||this;return r.templateRef=t,r.viewContainerRef=e,l&&(r.context=l),r}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"origin",{get:function(){return this.templateRef.elementRef},enumerable:!0,configurable:!0}),t.prototype.attach=function(t,e){return void 0===e&&(e=this.context),this.context=e,n.prototype.attach.call(this,t)},t.prototype.detach=function(){return this.context=void 0,n.prototype.detach.call(this)},t}(ti),ri=function(){function n(){this._isDisposed=!1}return n.prototype.hasAttached=function(){return!!this._attachedPortal},n.prototype.attach=function(n){return n||function(){throw Error("Must provide a portal to attach")}(),this.hasAttached()&&ni(),this._isDisposed&&function(){throw Error("This PortalOutlet has already been disposed")}(),n instanceof ei?(this._attachedPortal=n,this.attachComponentPortal(n)):n instanceof li?(this._attachedPortal=n,this.attachTemplatePortal(n)):void function(){throw Error("Attempting to attach an unknown Portal type. BasePortalOutlet accepts either a ComponentPortal or a TemplatePortal.")}()},n.prototype.detach=function(){this._attachedPortal&&(this._attachedPortal.setAttachedHost(null),this._attachedPortal=null),this._invokeDisposeFn()},n.prototype.dispose=function(){this.hasAttached()&&this.detach(),this._invokeDisposeFn(),this._isDisposed=!0},n.prototype.setDisposeFn=function(n){this._disposeFn=n},n.prototype._invokeDisposeFn=function(){this._disposeFn&&(this._disposeFn(),this._disposeFn=null)},n}(),ii=function(n){function t(t,e,l,r){var i=n.call(this)||this;return i._hostDomElement=t,i._componentFactoryResolver=e,i._appRef=l,i._defaultInjector=r,i}return Object(i.__extends)(t,n),t.prototype.attachComponentPortal=function(n){var t,e=this,l=this._componentFactoryResolver.resolveComponentFactory(n.component);return n.viewContainerRef?(t=n.viewContainerRef.createComponent(l,n.viewContainerRef.length,n.injector||n.viewContainerRef.parentInjector),this.setDisposeFn(function(){return t.destroy()})):(t=l.create(n.injector||this._defaultInjector),this._appRef.attachView(t.hostView),this.setDisposeFn(function(){e._appRef.detachView(t.hostView),t.destroy()})),this._hostDomElement.appendChild(this._getComponentRootNode(t)),t},t.prototype.attachTemplatePortal=function(n){var t=this,e=n.viewContainerRef,l=e.createEmbeddedView(n.templateRef,n.context);return l.detectChanges(),l.rootNodes.forEach(function(n){return t._hostDomElement.appendChild(n)}),this.setDisposeFn(function(){var n=e.indexOf(l);-1!==n&&e.remove(n)}),l},t.prototype.dispose=function(){n.prototype.dispose.call(this),null!=this._hostDomElement.parentNode&&this._hostDomElement.parentNode.removeChild(this._hostDomElement)},t.prototype._getComponentRootNode=function(n){return n.hostView.rootNodes[0]},t}(ri),oi=function(n){function t(t,e){var l=n.call(this)||this;return l._componentFactoryResolver=t,l._viewContainerRef=e,l._isInitialized=!1,l}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"_deprecatedPortal",{get:function(){return this.portal},set:function(n){this.portal=n},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_deprecatedPortalHost",{get:function(){return this.portal},set:function(n){this.portal=n},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"portal",{get:function(){return this._attachedPortal},set:function(t){(!this.hasAttached()||t||this._isInitialized)&&(this.hasAttached()&&n.prototype.detach.call(this),t&&n.prototype.attach.call(this,t),this._attachedPortal=t)},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){this._isInitialized=!0},t.prototype.ngOnDestroy=function(){n.prototype.dispose.call(this),this._attachedPortal=null},t.prototype.attachComponentPortal=function(t){t.setAttachedHost(this);var e=null!=t.viewContainerRef?t.viewContainerRef:this._viewContainerRef,l=this._componentFactoryResolver.resolveComponentFactory(t.component),r=e.createComponent(l,e.length,t.injector||e.parentInjector);return n.prototype.setDisposeFn.call(this,function(){return r.destroy()}),this._attachedPortal=t,r},t.prototype.attachTemplatePortal=function(t){var e=this;t.setAttachedHost(this);var l=this._viewContainerRef.createEmbeddedView(t.templateRef,t.context);return n.prototype.setDisposeFn.call(this,function(){return e._viewContainerRef.clear()}),this._attachedPortal=t,l},t}(ri),si=function(){},ai=function(){function n(n,t){this._parentInjector=n,this._customTokens=t}return n.prototype.get=function(n,t){var e=this._customTokens.get(n);return"undefined"!=typeof e?e:this._parentInjector.get(n,t)},n}(),ui=function(){function n(){}return n.prototype.enable=function(){},n.prototype.disable=function(){},n.prototype.attach=function(){},n}(),ci=function(){return function(n){var t=this;this.scrollStrategy=new ui,this.panelClass="",this.hasBackdrop=!1,this.backdropClass="cdk-overlay-dark-backdrop",this.direction="ltr",n&&Object.keys(n).forEach(function(e){return t[e]=n[e]})}}(),di=function(n,t,e,l){this.offsetX=e,this.offsetY=l,this.originX=n.originX,this.originY=n.originY,this.overlayX=t.overlayX,this.overlayY=t.overlayY};function hi(){return Error("Scroll strategy has already been attached.")}var pi=function(){function n(n,t){this._scrollDispatcher=n,this._ngZone=t,this._scrollSubscription=null}return n.prototype.attach=function(n){if(this._overlayRef)throw hi();this._overlayRef=n},n.prototype.enable=function(){var n=this;this._scrollSubscription||(this._scrollSubscription=this._scrollDispatcher.scrolled(0).subscribe(function(){n._ngZone.run(function(){n.disable(),n._overlayRef.hasAttached()&&n._overlayRef.detach()})}))},n.prototype.disable=function(){this._scrollSubscription&&(this._scrollSubscription.unsubscribe(),this._scrollSubscription=null)},n}(),fi=function(){function n(n){this._viewportRuler=n,this._previousHTMLStyles={top:"",left:""},this._isEnabled=!1}return n.prototype.attach=function(){},n.prototype.enable=function(){if(this._canBeEnabled()){var n=document.documentElement;this._previousScrollPosition=this._viewportRuler.getViewportScrollPosition(),this._previousHTMLStyles.left=n.style.left||"",this._previousHTMLStyles.top=n.style.top||"",n.style.left=-this._previousScrollPosition.left+"px",n.style.top=-this._previousScrollPosition.top+"px",n.classList.add("cdk-global-scrollblock"),this._isEnabled=!0}},n.prototype.disable=function(){if(this._isEnabled){var n=document.documentElement,t=document.body,e=n.style.scrollBehavior||"",l=t.style.scrollBehavior||"";this._isEnabled=!1,n.style.left=this._previousHTMLStyles.left,n.style.top=this._previousHTMLStyles.top,n.classList.remove("cdk-global-scrollblock"),n.style.scrollBehavior=t.style.scrollBehavior="auto",window.scroll(this._previousScrollPosition.left,this._previousScrollPosition.top),n.style.scrollBehavior=e,t.style.scrollBehavior=l}},n.prototype._canBeEnabled=function(){if(document.documentElement.classList.contains("cdk-global-scrollblock")||this._isEnabled)return!1;var n=document.body,t=this._viewportRuler.getViewportSize();return n.scrollHeight>t.height||n.scrollWidth>t.width},n}();function _i(n,t){return t.some(function(t){return n.bottomt.bottom||n.rightt.right})}function mi(n,t){return t.some(function(t){return n.topt.bottom||n.leftt.right})}var gi=function(){function n(n,t,e,l){this._scrollDispatcher=n,this._viewportRuler=t,this._ngZone=e,this._config=l,this._scrollSubscription=null}return n.prototype.attach=function(n){if(this._overlayRef)throw hi();this._overlayRef=n},n.prototype.enable=function(){var n=this;this._scrollSubscription||(this._scrollSubscription=this._scrollDispatcher.scrolled(this._config?this._config.scrollThrottle:0).subscribe(function(){if(n._overlayRef.updatePosition(),n._config&&n._config.autoClose){var t=n._overlayRef.overlayElement.getBoundingClientRect(),e=n._viewportRuler.getViewportSize(),l=e.width,r=e.height;_i(t,[{width:l,height:r,bottom:r,right:l,top:0,left:0}])&&(n.disable(),n._ngZone.run(function(){return n._overlayRef.detach()}))}}))},n.prototype.disable=function(){this._scrollSubscription&&(this._scrollSubscription.unsubscribe(),this._scrollSubscription=null)},n}(),yi=function(){return function(n,t,e){var l=this;this._scrollDispatcher=n,this._viewportRuler=t,this._ngZone=e,this.noop=function(){return new ui},this.close=function(){return new pi(l._scrollDispatcher,l._ngZone)},this.block=function(){return new fi(l._viewportRuler)},this.reposition=function(n){return new gi(l._scrollDispatcher,l._viewportRuler,l._ngZone,n)}}}(),bi=function(){function n(n,t,e,l,r){this._portalOutlet=n,this._pane=t,this._config=e,this._ngZone=l,this._keyboardDispatcher=r,this._backdropElement=null,this._backdropClick=new yl.a,this._attachments=new yl.a,this._detachments=new yl.a,this._keydownEvents=new yl.a,e.scrollStrategy&&e.scrollStrategy.attach(this)}return Object.defineProperty(n.prototype,"overlayElement",{get:function(){return this._pane},enumerable:!0,configurable:!0}),n.prototype.attach=function(n){var t=this,e=this._portalOutlet.attach(n);return this._config.positionStrategy&&this._config.positionStrategy.attach(this),this._updateStackingOrder(),this._updateElementSize(),this._updateElementDirection(),this._config.scrollStrategy&&this._config.scrollStrategy.enable(),this._ngZone.onStable.asObservable().pipe(Object(_r.a)(1)).subscribe(function(){t.updatePosition()}),this._togglePointerEvents(!0),this._config.hasBackdrop&&this._attachBackdrop(),this._config.panelClass&&(Array.isArray(this._config.panelClass)?this._config.panelClass.forEach(function(n){return t._pane.classList.add(n)}):this._pane.classList.add(this._config.panelClass)),this._attachments.next(),this._keyboardDispatcher.add(this),e},n.prototype.detach=function(){if(this.hasAttached()){this.detachBackdrop(),this._togglePointerEvents(!1),this._config.positionStrategy&&this._config.positionStrategy.detach&&this._config.positionStrategy.detach(),this._config.scrollStrategy&&this._config.scrollStrategy.disable();var n=this._portalOutlet.detach();return this._detachments.next(),this._keyboardDispatcher.remove(this),n}},n.prototype.dispose=function(){var n=this.hasAttached();this._config.positionStrategy&&this._config.positionStrategy.dispose(),this._config.scrollStrategy&&this._config.scrollStrategy.disable(),this.detachBackdrop(),this._keyboardDispatcher.remove(this),this._portalOutlet.dispose(),this._attachments.complete(),this._backdropClick.complete(),this._keydownEvents.complete(),n&&this._detachments.next(),this._detachments.complete()},n.prototype.hasAttached=function(){return this._portalOutlet.hasAttached()},n.prototype.backdropClick=function(){return this._backdropClick.asObservable()},n.prototype.attachments=function(){return this._attachments.asObservable()},n.prototype.detachments=function(){return this._detachments.asObservable()},n.prototype.keydownEvents=function(){return this._keydownEvents.asObservable()},n.prototype.getConfig=function(){return this._config},n.prototype.updatePosition=function(){this._config.positionStrategy&&this._config.positionStrategy.apply()},n.prototype.updateSize=function(n){this._config=Object(i.__assign)({},this._config,n),this._updateElementSize()},n.prototype.setDirection=function(n){this._config=Object(i.__assign)({},this._config,{direction:n}),this._updateElementDirection()},n.prototype._updateElementDirection=function(){this._pane.setAttribute("dir",this._config.direction)},n.prototype._updateElementSize=function(){(this._config.width||0===this._config.width)&&(this._pane.style.width=vi(this._config.width)),(this._config.height||0===this._config.height)&&(this._pane.style.height=vi(this._config.height)),(this._config.minWidth||0===this._config.minWidth)&&(this._pane.style.minWidth=vi(this._config.minWidth)),(this._config.minHeight||0===this._config.minHeight)&&(this._pane.style.minHeight=vi(this._config.minHeight)),(this._config.maxWidth||0===this._config.maxWidth)&&(this._pane.style.maxWidth=vi(this._config.maxWidth)),(this._config.maxHeight||0===this._config.maxHeight)&&(this._pane.style.maxHeight=vi(this._config.maxHeight))},n.prototype._togglePointerEvents=function(n){this._pane.style.pointerEvents=n?"auto":"none"},n.prototype._attachBackdrop=function(){var n=this;this._backdropElement=document.createElement("div"),this._backdropElement.classList.add("cdk-overlay-backdrop"),this._config.backdropClass&&this._backdropElement.classList.add(this._config.backdropClass),this._pane.parentElement.insertBefore(this._backdropElement,this._pane),this._backdropElement.addEventListener("click",function(){return n._backdropClick.next(null)}),this._ngZone.runOutsideAngular(function(){requestAnimationFrame(function(){n._backdropElement&&n._backdropElement.classList.add("cdk-overlay-backdrop-showing")})})},n.prototype._updateStackingOrder=function(){this._pane.nextSibling&&this._pane.parentNode.appendChild(this._pane)},n.prototype.detachBackdrop=function(){var n=this,t=this._backdropElement;if(t){var e=function(){t&&t.parentNode&&t.parentNode.removeChild(t),n._backdropElement==t&&(n._backdropElement=null)};t.classList.remove("cdk-overlay-backdrop-showing"),this._config.backdropClass&&t.classList.remove(this._config.backdropClass),t.addEventListener("transitionend",e),t.style.pointerEvents="none",this._ngZone.runOutsideAngular(function(){setTimeout(e,500)})}},n}();function vi(n){return"string"==typeof n?n:n+"px"}var wi=function(){function n(n,t,e,l,r){this._connectedTo=e,this._viewportRuler=l,this._document=r,this._dir="ltr",this._offsetX=0,this._offsetY=0,this.scrollables=[],this._resizeSubscription=rl.a.EMPTY,this._preferredPositions=[],this._applied=!1,this._positionLocked=!1,this._onPositionChange=new yl.a,this._origin=this._connectedTo.nativeElement,this.withFallbackPosition(n,t)}return Object.defineProperty(n.prototype,"_isRtl",{get:function(){return"rtl"===this._dir},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"onPositionChange",{get:function(){return this._onPositionChange.asObservable()},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"positions",{get:function(){return this._preferredPositions},enumerable:!0,configurable:!0}),n.prototype.attach=function(n){var t=this;this._overlayRef=n,this._pane=n.overlayElement,this._resizeSubscription.unsubscribe(),this._resizeSubscription=this._viewportRuler.change().subscribe(function(){return t.apply()})},n.prototype.dispose=function(){this._applied=!1,this._resizeSubscription.unsubscribe()},n.prototype.detach=function(){this._applied=!1,this._resizeSubscription.unsubscribe()},n.prototype.apply=function(){if(this._applied&&this._positionLocked&&this._lastConnectedPosition)this.recalculateLastPosition();else{this._applied=!0;for(var n,t,e=this._pane,l=this._origin.getBoundingClientRect(),r=e.getBoundingClientRect(),i=this._viewportRuler.getViewportSize(),o=0,s=this._preferredPositions;o-1&&this._attachedOverlays.splice(t,1),0===this._attachedOverlays.length&&this._unsubscribeFromKeydownEvents()},n.prototype._subscribeToKeydownEvents=function(){var n=this,t=zr(this._document.body,"keydown");this._keydownEventSubscription=t.pipe(Ge(function(){return!!n._attachedOverlays.length})).subscribe(function(t){n._selectOverlayFromEvent(t)._keydownEvents.next(t)})},n.prototype._unsubscribeFromKeydownEvents=function(){this._keydownEventSubscription&&(this._keydownEventSubscription.unsubscribe(),this._keydownEventSubscription=null)},n.prototype._selectOverlayFromEvent=function(n){return this._attachedOverlays.find(function(t){return t.overlayElement===n.target||t.overlayElement.contains(n.target)})||this._attachedOverlays[this._attachedOverlays.length-1]},n}();function Ci(n,t){return n||new ki(t)}var Si=function(){function n(n){this._document=n}return n.prototype.ngOnDestroy=function(){this._containerElement&&this._containerElement.parentNode&&this._containerElement.parentNode.removeChild(this._containerElement)},n.prototype.getContainerElement=function(){return this._containerElement||this._createContainer(),this._containerElement},n.prototype._createContainer=function(){var n=this._document.createElement("div");n.classList.add("cdk-overlay-container"),this._document.body.appendChild(n),this._containerElement=n},n}();function Oi(n,t){return n||new Si(t)}var Ti=0,Li=new ci,Pi=function(){function n(n,t,e,l,r,i,o,s,a){this.scrollStrategies=n,this._overlayContainer=t,this._componentFactoryResolver=e,this._positionBuilder=l,this._keyboardDispatcher=r,this._appRef=i,this._injector=o,this._ngZone=s,this._document=a}return n.prototype.create=function(n){void 0===n&&(n=Li);var t=this._createPaneElement(),e=this._createPortalOutlet(t);return new bi(e,t,n,this._ngZone,this._keyboardDispatcher)},n.prototype.position=function(){return this._positionBuilder},n.prototype._createPaneElement=function(){var n=this._document.createElement("div");return n.id="cdk-overlay-"+Ti++,n.classList.add("cdk-overlay-pane"),this._overlayContainer.getContainerElement().appendChild(n),n},n.prototype._createPortalOutlet=function(n){return new ii(n,this._componentFactoryResolver,this._appRef,this._injector)},n}(),Di=[new di({originX:"start",originY:"bottom"},{overlayX:"start",overlayY:"top"}),new di({originX:"start",originY:"top"},{overlayX:"start",overlayY:"bottom"}),new di({originX:"end",originY:"top"},{overlayX:"end",overlayY:"bottom"}),new di({originX:"end",originY:"bottom"},{overlayX:"end",overlayY:"top"})],Ai=new l.r("cdk-connected-overlay-scroll-strategy");function Ei(n){return function(){return n.scrollStrategies.reposition()}}var Yi=function(n){this.elementRef=n},ji=function(){function n(n,t,e,r,i){this._overlay=n,this._scrollStrategy=r,this._dir=i,this._hasBackdrop=!1,this._backdropSubscription=rl.a.EMPTY,this._positionSubscription=rl.a.EMPTY,this._offsetX=0,this._offsetY=0,this.scrollStrategy=this._scrollStrategy(),this.open=!1,this.backdropClick=new l.o,this.positionChange=new l.o,this.attach=new l.o,this.detach=new l.o,this._templatePortal=new li(t,e)}return Object.defineProperty(n.prototype,"offsetX",{get:function(){return this._offsetX},set:function(n){this._offsetX=n,this._position&&this._position.withOffsetX(n)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"offsetY",{get:function(){return this._offsetY},set:function(n){this._offsetY=n,this._position&&this._position.withOffsetY(n)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"hasBackdrop",{get:function(){return this._hasBackdrop},set:function(n){this._hasBackdrop=El(n)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedOrigin",{get:function(){return this.origin},set:function(n){this.origin=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedPositions",{get:function(){return this.positions},set:function(n){this.positions=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedOffsetX",{get:function(){return this.offsetX},set:function(n){this.offsetX=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedOffsetY",{get:function(){return this.offsetY},set:function(n){this.offsetY=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedWidth",{get:function(){return this.width},set:function(n){this.width=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedHeight",{get:function(){return this.height},set:function(n){this.height=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedMinWidth",{get:function(){return this.minWidth},set:function(n){this.minWidth=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedMinHeight",{get:function(){return this.minHeight},set:function(n){this.minHeight=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedBackdropClass",{get:function(){return this.backdropClass},set:function(n){this.backdropClass=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedScrollStrategy",{get:function(){return this.scrollStrategy},set:function(n){this.scrollStrategy=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedOpen",{get:function(){return this.open},set:function(n){this.open=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_deprecatedHasBackdrop",{get:function(){return this.hasBackdrop},set:function(n){this.hasBackdrop=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"overlayRef",{get:function(){return this._overlayRef},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"dir",{get:function(){return this._dir?this._dir.value:"ltr"},enumerable:!0,configurable:!0}),n.prototype.ngOnDestroy=function(){this._destroyOverlay()},n.prototype.ngOnChanges=function(n){(n.open||n._deprecatedOpen)&&(this.open?this._attachOverlay():this._detachOverlay())},n.prototype._createOverlay=function(){this.positions&&this.positions.length||(this.positions=Di),this._overlayRef=this._overlay.create(this._buildConfig())},n.prototype._buildConfig=function(){var n=this._position=this._createPositionStrategy(),t=new ci({positionStrategy:n,scrollStrategy:this.scrollStrategy,hasBackdrop:this.hasBackdrop});return(this.width||0===this.width)&&(t.width=this.width),(this.height||0===this.height)&&(t.height=this.height),(this.minWidth||0===this.minWidth)&&(t.minWidth=this.minWidth),(this.minHeight||0===this.minHeight)&&(t.minHeight=this.minHeight),this.backdropClass&&(t.backdropClass=this.backdropClass),t},n.prototype._createPositionStrategy=function(){var n=this.positions[0],t={originX:n.originX,originY:n.originY},e={overlayX:n.overlayX,overlayY:n.overlayY},l=this._overlay.position().connectedTo(this.origin.elementRef,t,e).withOffsetX(this.offsetX).withOffsetY(this.offsetY);return this._handlePositionChanges(l),l},n.prototype._handlePositionChanges=function(n){for(var t=this,e=1;e0&&e[0].time-l.now()<=0;)e.shift().notification.observe(r);if(e.length>0){var i=Math.max(0,e[0].time-l.now());this.schedule(n,i)}else t.active=!1},t.prototype._schedule=function(n){this.active=!0,this.add(n.schedule(t.dispatch,this.delay,{source:this,destination:this.destination,scheduler:n}))},t.prototype.scheduleNotification=function(n){if(!0!==this.errored){var t=this.scheduler,e=new Bi(t.now()+this.delay,n);this.queue.push(e),!1===this.active&&this._schedule(t)}},t.prototype._next=function(n){this.scheduleNotification(wl.createNext(n))},t.prototype._error=function(n){this.errored=!0,this.queue=[],this.destination.error(n)},t.prototype._complete=function(){this.scheduleNotification(wl.createComplete())},t}(Be.a),Bi=function(n,t){this.time=n,this.notification=t},Vi=function(n){function t(t,e){n.call(this),this.promise=t,this.scheduler=e}return Object(i.__extends)(t,n),t.create=function(n,e){return new t(n,e)},t.prototype._subscribe=function(n){var t=this,e=this.promise,l=this.scheduler;if(null==l)this._isScalar?n.closed||(n.next(this.value),n.complete()):e.then(function(e){t.value=e,t._isScalar=!0,n.closed||(n.next(e),n.complete())},function(t){n.closed||n.error(t)}).then(null,function(n){ll.a.setTimeout(function(){throw n})});else if(this._isScalar){if(!n.closed)return l.schedule(Wi,0,{value:this.value,subscriber:n})}else e.then(function(e){t.value=e,t._isScalar=!0,n.closed||n.add(l.schedule(Wi,0,{value:e,subscriber:n}))},function(t){n.closed||n.add(l.schedule(zi,0,{err:t,subscriber:n}))}).then(null,function(n){ll.a.setTimeout(function(){throw n})})},t}(o.a);function Wi(n){var t=n.subscriber;t.closed||(t.next(n.value),t.complete())}function zi(n){var t=n.subscriber;t.closed||t.error(n.err)}var Ui=Vi.create,Gi=function(){function n(){}return Object.defineProperty(n.prototype,"value",{get:function(){return this.control?this.control.value:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"valid",{get:function(){return this.control?this.control.valid:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"invalid",{get:function(){return this.control?this.control.invalid:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"pending",{get:function(){return this.control?this.control.pending:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"disabled",{get:function(){return this.control?this.control.disabled:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"enabled",{get:function(){return this.control?this.control.enabled:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"errors",{get:function(){return this.control?this.control.errors:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"pristine",{get:function(){return this.control?this.control.pristine:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"dirty",{get:function(){return this.control?this.control.dirty:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"touched",{get:function(){return this.control?this.control.touched:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"status",{get:function(){return this.control?this.control.status:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"untouched",{get:function(){return this.control?this.control.untouched:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"statusChanges",{get:function(){return this.control?this.control.statusChanges:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"valueChanges",{get:function(){return this.control?this.control.valueChanges:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"path",{get:function(){return null},enumerable:!0,configurable:!0}),n.prototype.reset=function(n){void 0===n&&(n=void 0),this.control&&this.control.reset(n)},n.prototype.hasError=function(n,t){return!!this.control&&this.control.hasError(n,t)},n.prototype.getError=function(n,t){return this.control?this.control.getError(n,t):null},n}(),qi=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"formDirective",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"path",{get:function(){return null},enumerable:!0,configurable:!0}),t}(Gi);function Ji(n){return null==n||0===n.length}var Qi=new l.r("NgValidators"),Ki=/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/,Xi=function(){function n(){}return n.min=function(n){return function(t){if(Ji(t.value)||Ji(n))return null;var e=parseFloat(t.value);return!isNaN(e)&&en?{max:{max:n,actual:t.value}}:null}},n.required=function(n){return Ji(n.value)?{required:!0}:null},n.requiredTrue=function(n){return!0===n.value?null:{required:!0}},n.email=function(n){return Ki.test(n.value)?null:{email:!0}},n.minLength=function(n){return function(t){if(Ji(t.value))return null;var e=t.value?t.value.length:0;return en?{maxlength:{requiredLength:n,actualLength:e}}:null}},n.pattern=function(t){return t?("string"==typeof t?(l="^"+t+"$",e=new RegExp(l)):(l=t.toString(),e=t),function(n){if(Ji(n.value))return null;var t=n.value;return e.test(t)?null:{pattern:{requiredPattern:l,actualValue:t}}}):n.nullValidator;var e,l},n.nullValidator=function(n){return null},n.compose=function(n){if(!n)return null;var t=n.filter(Zi);return 0==t.length?null:function(n){return no(function(n,e){return t.map(function(t){return t(n)})}(n))}},n.composeAsync=function(n){if(!n)return null;var t=n.filter(Zi);return 0==t.length?null:function(n){var e=function(n,e){return t.map(function(t){return t(n)})}(n).map($i);return Pe.call(Ne(e),no)}},n}();function Zi(n){return null!=n}function $i(n){var t=Object(l._15)(n)?Ui(n):n;if(!Object(l._14)(t))throw new Error("Expected validator to return Promise or Observable.");return t}function no(n){var t=n.reduce(function(n,t){return null!=t?Object(i.__assign)({},n,t):n},{});return 0===Object.keys(t).length?null:t}var to=new l.r("NgValueAccessor"),eo=function(){function n(n,t){this._renderer=n,this._elementRef=t,this.onChange=function(n){},this.onTouched=function(){}}return n.prototype.writeValue=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"checked",n)},n.prototype.registerOnChange=function(n){this.onChange=n},n.prototype.registerOnTouched=function(n){this.onTouched=n},n.prototype.setDisabledState=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",n)},n}(),lo=new l.r("CompositionEventMode"),ro=function(){function n(n,t,e){var l;this._renderer=n,this._elementRef=t,this._compositionMode=e,this.onChange=function(n){},this.onTouched=function(){},this._composing=!1,null==this._compositionMode&&(this._compositionMode=(l=un()?un().getUserAgent():"",!/android (\d+)/.test(l.toLowerCase())))}return n.prototype.writeValue=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"value",null==n?"":n)},n.prototype.registerOnChange=function(n){this.onChange=n},n.prototype.registerOnTouched=function(n){this.onTouched=n},n.prototype.setDisabledState=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",n)},n.prototype._handleInput=function(n){(!this._compositionMode||this._compositionMode&&!this._composing)&&this.onChange(n)},n.prototype._compositionStart=function(){this._composing=!0},n.prototype._compositionEnd=function(n){this._composing=!1,this._compositionMode&&this.onChange(n)},n}();function io(n){return n.validate?function(t){return n.validate(t)}:n}function oo(n){return n.validate?function(t){return n.validate(t)}:n}var so=function(){function n(n,t){this._renderer=n,this._elementRef=t,this.onChange=function(n){},this.onTouched=function(){}}return n.prototype.writeValue=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"value",null==n?"":n)},n.prototype.registerOnChange=function(n){this.onChange=function(t){n(""==t?null:parseFloat(t))}},n.prototype.registerOnTouched=function(n){this.onTouched=n},n.prototype.setDisabledState=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",n)},n}();function ao(){throw new Error("unimplemented")}var uo=function(n){function t(){var t=null!==n&&n.apply(this,arguments)||this;return t._parent=null,t.name=null,t.valueAccessor=null,t._rawValidators=[],t._rawAsyncValidators=[],t}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"validator",{get:function(){return ao()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"asyncValidator",{get:function(){return ao()},enumerable:!0,configurable:!0}),t}(Gi),co=function(){function n(){this._accessors=[]}return n.prototype.add=function(n,t){this._accessors.push([n,t])},n.prototype.remove=function(n){for(var t=this._accessors.length-1;t>=0;--t)if(this._accessors[t][1]===n)return void this._accessors.splice(t,1)},n.prototype.select=function(n){var t=this;this._accessors.forEach(function(e){t._isSameGroup(e,n)&&e[1]!==n&&e[1].fireUncheck(n.value)})},n.prototype._isSameGroup=function(n,t){return!!n[0].control&&n[0]._parent===t._control._parent&&n[1].name===t.name},n}(),ho=function(){function n(n,t,e,l){this._renderer=n,this._elementRef=t,this._registry=e,this._injector=l,this.onChange=function(){},this.onTouched=function(){}}return n.prototype.ngOnInit=function(){this._control=this._injector.get(uo),this._checkName(),this._registry.add(this._control,this)},n.prototype.ngOnDestroy=function(){this._registry.remove(this)},n.prototype.writeValue=function(n){this._state=n===this.value,this._renderer.setProperty(this._elementRef.nativeElement,"checked",this._state)},n.prototype.registerOnChange=function(n){var t=this;this._fn=n,this.onChange=function(){n(t.value),t._registry.select(t)}},n.prototype.fireUncheck=function(n){this.writeValue(n)},n.prototype.registerOnTouched=function(n){this.onTouched=n},n.prototype.setDisabledState=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",n)},n.prototype._checkName=function(){this.name&&this.formControlName&&this.name!==this.formControlName&&this._throwNameError(),!this.name&&this.formControlName&&(this.name=this.formControlName)},n.prototype._throwNameError=function(){throw new Error('\n If you define both a name and a formControlName attribute on your radio button, their values\n must match. Ex: \n ')},n}(),po=function(){function n(n,t){this._renderer=n,this._elementRef=t,this.onChange=function(n){},this.onTouched=function(){}}return n.prototype.writeValue=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"value",parseFloat(n))},n.prototype.registerOnChange=function(n){this.onChange=function(t){n(""==t?null:parseFloat(t))}},n.prototype.registerOnTouched=function(n){this.onTouched=n},n.prototype.setDisabledState=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",n)},n}();function fo(n,t){return null==n?""+t:(t&&"object"==typeof t&&(t="Object"),(n+": "+t).slice(0,50))}var _o=function(){function n(n,t){this._renderer=n,this._elementRef=t,this._optionMap=new Map,this._idCounter=0,this.onChange=function(n){},this.onTouched=function(){},this._compareWith=l._16}return Object.defineProperty(n.prototype,"compareWith",{set:function(n){if("function"!=typeof n)throw new Error("compareWith must be a function, but received "+JSON.stringify(n));this._compareWith=n},enumerable:!0,configurable:!0}),n.prototype.writeValue=function(n){this.value=n;var t=this._getOptionId(n);null==t&&this._renderer.setProperty(this._elementRef.nativeElement,"selectedIndex",-1);var e=fo(t,n);this._renderer.setProperty(this._elementRef.nativeElement,"value",e)},n.prototype.registerOnChange=function(n){var t=this;this.onChange=function(e){t.value=t._getOptionValue(e),n(t.value)}},n.prototype.registerOnTouched=function(n){this.onTouched=n},n.prototype.setDisabledState=function(n){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",n)},n.prototype._registerOption=function(){return(this._idCounter++).toString()},n.prototype._getOptionId=function(n){for(var t=0,e=Array.from(this._optionMap.keys());t-1)}}else t=function(n,t){n._setSelected(!1)};this._optionMap.forEach(t)},n.prototype.registerOnChange=function(n){var t=this;this.onChange=function(e){var l=[];if(e.hasOwnProperty("selectedOptions"))for(var r=e.selectedOptions,i=0;i1?"path: '"+n.path.join(" -> ")+"'":n.path[0]?"name: '"+n.path+"'":"unspecified name attribute",new Error(t+" "+e)}function So(n){return null!=n?Xi.compose(n.map(io)):null}function Oo(n){return null!=n?Xi.composeAsync(n.map(oo)):null}var To=[eo,po,so,_o,yo,ho];function Lo(n,t){n._syncPendingControls(),t.forEach(function(n){var t=n.control;"submit"===t.updateOn&&t._pendingChange&&(n.viewToModelUpdate(t._pendingValue),t._pendingChange=!1)})}function Po(n,t){var e=n.indexOf(t);e>-1&&n.splice(e,1)}var Do=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return Object(i.__extends)(t,n),t.prototype.ngOnInit=function(){this._checkParentType(),this.formDirective.addFormGroup(this)},t.prototype.ngOnDestroy=function(){this.formDirective&&this.formDirective.removeFormGroup(this)},Object.defineProperty(t.prototype,"control",{get:function(){return this.formDirective.getFormGroup(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"path",{get:function(){return vo(this.name,this._parent)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"formDirective",{get:function(){return this._parent?this._parent.formDirective:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"validator",{get:function(){return So(this._validators)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"asyncValidator",{get:function(){return Oo(this._asyncValidators)},enumerable:!0,configurable:!0}),t.prototype._checkParentType=function(){},t}(qi),Ao=function(){function n(n){this._cd=n}return Object.defineProperty(n.prototype,"ngClassUntouched",{get:function(){return!!this._cd.control&&this._cd.control.untouched},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"ngClassTouched",{get:function(){return!!this._cd.control&&this._cd.control.touched},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"ngClassPristine",{get:function(){return!!this._cd.control&&this._cd.control.pristine},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"ngClassDirty",{get:function(){return!!this._cd.control&&this._cd.control.dirty},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"ngClassValid",{get:function(){return!!this._cd.control&&this._cd.control.valid},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"ngClassInvalid",{get:function(){return!!this._cd.control&&this._cd.control.invalid},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"ngClassPending",{get:function(){return!!this._cd.control&&this._cd.control.pending},enumerable:!0,configurable:!0}),n}(),Eo=function(n){function t(t){return n.call(this,t)||this}return Object(i.__extends)(t,n),t}(Ao),Yo=function(n){function t(t){return n.call(this,t)||this}return Object(i.__extends)(t,n),t}(Ao);function jo(n){var t=Ro(n)?n.validators:n;return Array.isArray(t)?So(t):t||null}function Io(n,t){var e=Ro(t)?t.asyncValidators:n;return Array.isArray(e)?Oo(e):e||null}function Ro(n){return null!=n&&!Array.isArray(n)&&"object"==typeof n}var Ho=function(){function n(n,t){this.validator=n,this.asyncValidator=t,this._onCollectionChange=function(){},this.pristine=!0,this.touched=!1,this._onDisabledChange=[]}return Object.defineProperty(n.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"valid",{get:function(){return"VALID"===this.status},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"invalid",{get:function(){return"INVALID"===this.status},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"pending",{get:function(){return"PENDING"==this.status},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"disabled",{get:function(){return"DISABLED"===this.status},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"enabled",{get:function(){return"DISABLED"!==this.status},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"dirty",{get:function(){return!this.pristine},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"untouched",{get:function(){return!this.touched},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"updateOn",{get:function(){return this._updateOn?this._updateOn:this.parent?this.parent.updateOn:"change"},enumerable:!0,configurable:!0}),n.prototype.setValidators=function(n){this.validator=jo(n)},n.prototype.setAsyncValidators=function(n){this.asyncValidator=Io(n)},n.prototype.clearValidators=function(){this.validator=null},n.prototype.clearAsyncValidators=function(){this.asyncValidator=null},n.prototype.markAsTouched=function(n){void 0===n&&(n={}),this.touched=!0,this._parent&&!n.onlySelf&&this._parent.markAsTouched(n)},n.prototype.markAsUntouched=function(n){void 0===n&&(n={}),this.touched=!1,this._pendingTouched=!1,this._forEachChild(function(n){n.markAsUntouched({onlySelf:!0})}),this._parent&&!n.onlySelf&&this._parent._updateTouched(n)},n.prototype.markAsDirty=function(n){void 0===n&&(n={}),this.pristine=!1,this._parent&&!n.onlySelf&&this._parent.markAsDirty(n)},n.prototype.markAsPristine=function(n){void 0===n&&(n={}),this.pristine=!0,this._pendingDirty=!1,this._forEachChild(function(n){n.markAsPristine({onlySelf:!0})}),this._parent&&!n.onlySelf&&this._parent._updatePristine(n)},n.prototype.markAsPending=function(n){void 0===n&&(n={}),this.status="PENDING",this._parent&&!n.onlySelf&&this._parent.markAsPending(n)},n.prototype.disable=function(n){void 0===n&&(n={}),this.status="DISABLED",this.errors=null,this._forEachChild(function(n){n.disable({onlySelf:!0})}),this._updateValue(),!1!==n.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._updateAncestors(!!n.onlySelf),this._onDisabledChange.forEach(function(n){return n(!0)})},n.prototype.enable=function(n){void 0===n&&(n={}),this.status="VALID",this._forEachChild(function(n){n.enable({onlySelf:!0})}),this.updateValueAndValidity({onlySelf:!0,emitEvent:n.emitEvent}),this._updateAncestors(!!n.onlySelf),this._onDisabledChange.forEach(function(n){return n(!1)})},n.prototype._updateAncestors=function(n){this._parent&&!n&&(this._parent.updateValueAndValidity(),this._parent._updatePristine(),this._parent._updateTouched())},n.prototype.setParent=function(n){this._parent=n},n.prototype.updateValueAndValidity=function(n){void 0===n&&(n={}),this._setInitialStatus(),this._updateValue(),this.enabled&&(this._cancelExistingSubscription(),this.errors=this._runValidator(),this.status=this._calculateStatus(),"VALID"!==this.status&&"PENDING"!==this.status||this._runAsyncValidator(n.emitEvent)),!1!==n.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._parent&&!n.onlySelf&&this._parent.updateValueAndValidity(n)},n.prototype._updateTreeValidity=function(n){void 0===n&&(n={emitEvent:!0}),this._forEachChild(function(t){return t._updateTreeValidity(n)}),this.updateValueAndValidity({onlySelf:!0,emitEvent:n.emitEvent})},n.prototype._setInitialStatus=function(){this.status=this._allControlsDisabled()?"DISABLED":"VALID"},n.prototype._runValidator=function(){return this.validator?this.validator(this):null},n.prototype._runAsyncValidator=function(n){var t=this;if(this.asyncValidator){this.status="PENDING";var e=$i(this.asyncValidator(this));this._asyncValidationSubscription=e.subscribe(function(e){return t.setErrors(e,{emitEvent:n})})}},n.prototype._cancelExistingSubscription=function(){this._asyncValidationSubscription&&this._asyncValidationSubscription.unsubscribe()},n.prototype.setErrors=function(n,t){void 0===t&&(t={}),this.errors=n,this._updateControlsErrors(!1!==t.emitEvent)},n.prototype.get=function(n){return function(n,t,e){return null==t?null:(t instanceof Array||(t=t.split(".")),t instanceof Array&&0===t.length?null:t.reduce(function(n,t){return n instanceof Fo?n.controls[t]||null:n instanceof Bo&&n.at(t)||null},n))}(this,n)},n.prototype.getError=function(n,t){var e=t?this.get(t):this;return e&&e.errors?e.errors[n]:null},n.prototype.hasError=function(n,t){return!!this.getError(n,t)},Object.defineProperty(n.prototype,"root",{get:function(){for(var n=this;n._parent;)n=n._parent;return n},enumerable:!0,configurable:!0}),n.prototype._updateControlsErrors=function(n){this.status=this._calculateStatus(),n&&this.statusChanges.emit(this.status),this._parent&&this._parent._updateControlsErrors(n)},n.prototype._initObservables=function(){this.valueChanges=new l.o,this.statusChanges=new l.o},n.prototype._calculateStatus=function(){return this._allControlsDisabled()?"DISABLED":this.errors?"INVALID":this._anyControlsHaveStatus("PENDING")?"PENDING":this._anyControlsHaveStatus("INVALID")?"INVALID":"VALID"},n.prototype._anyControlsHaveStatus=function(n){return this._anyControls(function(t){return t.status===n})},n.prototype._anyControlsDirty=function(){return this._anyControls(function(n){return n.dirty})},n.prototype._anyControlsTouched=function(){return this._anyControls(function(n){return n.touched})},n.prototype._updatePristine=function(n){void 0===n&&(n={}),this.pristine=!this._anyControlsDirty(),this._parent&&!n.onlySelf&&this._parent._updatePristine(n)},n.prototype._updateTouched=function(n){void 0===n&&(n={}),this.touched=this._anyControlsTouched(),this._parent&&!n.onlySelf&&this._parent._updateTouched(n)},n.prototype._isBoxedValue=function(n){return"object"==typeof n&&null!==n&&2===Object.keys(n).length&&"value"in n&&"disabled"in n},n.prototype._registerOnCollectionChange=function(n){this._onCollectionChange=n},n.prototype._setUpdateStrategy=function(n){Ro(n)&&null!=n.updateOn&&(this._updateOn=n.updateOn)},n}(),No=function(n){function t(t,e,l){void 0===t&&(t=null);var r=n.call(this,jo(e),Io(l,e))||this;return r._onChange=[],r._applyFormState(t),r._setUpdateStrategy(e),r.updateValueAndValidity({onlySelf:!0,emitEvent:!1}),r._initObservables(),r}return Object(i.__extends)(t,n),t.prototype.setValue=function(n,t){var e=this;void 0===t&&(t={}),this.value=this._pendingValue=n,this._onChange.length&&!1!==t.emitModelToViewChange&&this._onChange.forEach(function(n){return n(e.value,!1!==t.emitViewToModelChange)}),this.updateValueAndValidity(t)},t.prototype.patchValue=function(n,t){void 0===t&&(t={}),this.setValue(n,t)},t.prototype.reset=function(n,t){void 0===n&&(n=null),void 0===t&&(t={}),this._applyFormState(n),this.markAsPristine(t),this.markAsUntouched(t),this.setValue(this.value,t),this._pendingChange=!1},t.prototype._updateValue=function(){},t.prototype._anyControls=function(n){return!1},t.prototype._allControlsDisabled=function(){return this.disabled},t.prototype.registerOnChange=function(n){this._onChange.push(n)},t.prototype._clearChangeFns=function(){this._onChange=[],this._onDisabledChange=[],this._onCollectionChange=function(){}},t.prototype.registerOnDisabledChange=function(n){this._onDisabledChange.push(n)},t.prototype._forEachChild=function(n){},t.prototype._syncPendingControls=function(){return!("submit"!==this.updateOn||(this._pendingDirty&&this.markAsDirty(),this._pendingTouched&&this.markAsTouched(),!this._pendingChange)||(this.setValue(this._pendingValue,{onlySelf:!0,emitModelToViewChange:!1}),0))},t.prototype._applyFormState=function(n){this._isBoxedValue(n)?(this.value=this._pendingValue=n.value,n.disabled?this.disable({onlySelf:!0,emitEvent:!1}):this.enable({onlySelf:!0,emitEvent:!1})):this.value=this._pendingValue=n},t}(Ho),Fo=function(n){function t(t,e,l){var r=n.call(this,jo(e),Io(l,e))||this;return r.controls=t,r._initObservables(),r._setUpdateStrategy(e),r._setUpControls(),r.updateValueAndValidity({onlySelf:!0,emitEvent:!1}),r}return Object(i.__extends)(t,n),t.prototype.registerControl=function(n,t){return this.controls[n]?this.controls[n]:(this.controls[n]=t,t.setParent(this),t._registerOnCollectionChange(this._onCollectionChange),t)},t.prototype.addControl=function(n,t){this.registerControl(n,t),this.updateValueAndValidity(),this._onCollectionChange()},t.prototype.removeControl=function(n){this.controls[n]&&this.controls[n]._registerOnCollectionChange(function(){}),delete this.controls[n],this.updateValueAndValidity(),this._onCollectionChange()},t.prototype.setControl=function(n,t){this.controls[n]&&this.controls[n]._registerOnCollectionChange(function(){}),delete this.controls[n],t&&this.registerControl(n,t),this.updateValueAndValidity(),this._onCollectionChange()},t.prototype.contains=function(n){return this.controls.hasOwnProperty(n)&&this.controls[n].enabled},t.prototype.setValue=function(n,t){var e=this;void 0===t&&(t={}),this._checkAllValuesPresent(n),Object.keys(n).forEach(function(l){e._throwIfControlMissing(l),e.controls[l].setValue(n[l],{onlySelf:!0,emitEvent:t.emitEvent})}),this.updateValueAndValidity(t)},t.prototype.patchValue=function(n,t){var e=this;void 0===t&&(t={}),Object.keys(n).forEach(function(l){e.controls[l]&&e.controls[l].patchValue(n[l],{onlySelf:!0,emitEvent:t.emitEvent})}),this.updateValueAndValidity(t)},t.prototype.reset=function(n,t){void 0===n&&(n={}),void 0===t&&(t={}),this._forEachChild(function(e,l){e.reset(n[l],{onlySelf:!0,emitEvent:t.emitEvent})}),this.updateValueAndValidity(t),this._updatePristine(t),this._updateTouched(t)},t.prototype.getRawValue=function(){return this._reduceChildren({},function(n,t,e){return n[e]=t instanceof No?t.value:t.getRawValue(),n})},t.prototype._syncPendingControls=function(){var n=this._reduceChildren(!1,function(n,t){return!!t._syncPendingControls()||n});return n&&this.updateValueAndValidity({onlySelf:!0}),n},t.prototype._throwIfControlMissing=function(n){if(!Object.keys(this.controls).length)throw new Error("\n There are no form controls registered with this group yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");if(!this.controls[n])throw new Error("Cannot find form control with name: "+n+".")},t.prototype._forEachChild=function(n){var t=this;Object.keys(this.controls).forEach(function(e){return n(t.controls[e],e)})},t.prototype._setUpControls=function(){var n=this;this._forEachChild(function(t){t.setParent(n),t._registerOnCollectionChange(n._onCollectionChange)})},t.prototype._updateValue=function(){this.value=this._reduceValue()},t.prototype._anyControls=function(n){var t=this,e=!1;return this._forEachChild(function(l,r){e=e||t.contains(r)&&n(l)}),e},t.prototype._reduceValue=function(){var n=this;return this._reduceChildren({},function(t,e,l){return(e.enabled||n.disabled)&&(t[l]=e.value),t})},t.prototype._reduceChildren=function(n,t){var e=n;return this._forEachChild(function(n,l){e=t(e,n,l)}),e},t.prototype._allControlsDisabled=function(){for(var n=0,t=Object.keys(this.controls);n0||this.disabled},t.prototype._checkAllValuesPresent=function(n){this._forEachChild(function(t,e){if(void 0===n[e])throw new Error("Must supply a value for form control with name: '"+e+"'.")})},t}(Ho),Bo=function(n){function t(t,e,l){var r=n.call(this,jo(e),Io(l,e))||this;return r.controls=t,r._initObservables(),r._setUpdateStrategy(e),r._setUpControls(),r.updateValueAndValidity({onlySelf:!0,emitEvent:!1}),r}return Object(i.__extends)(t,n),t.prototype.at=function(n){return this.controls[n]},t.prototype.push=function(n){this.controls.push(n),this._registerControl(n),this.updateValueAndValidity(),this._onCollectionChange()},t.prototype.insert=function(n,t){this.controls.splice(n,0,t),this._registerControl(t),this.updateValueAndValidity(),this._onCollectionChange()},t.prototype.removeAt=function(n){this.controls[n]&&this.controls[n]._registerOnCollectionChange(function(){}),this.controls.splice(n,1),this.updateValueAndValidity(),this._onCollectionChange()},t.prototype.setControl=function(n,t){this.controls[n]&&this.controls[n]._registerOnCollectionChange(function(){}),this.controls.splice(n,1),t&&(this.controls.splice(n,0,t),this._registerControl(t)),this.updateValueAndValidity(),this._onCollectionChange()},Object.defineProperty(t.prototype,"length",{get:function(){return this.controls.length},enumerable:!0,configurable:!0}),t.prototype.setValue=function(n,t){var e=this;void 0===t&&(t={}),this._checkAllValuesPresent(n),n.forEach(function(n,l){e._throwIfControlMissing(l),e.at(l).setValue(n,{onlySelf:!0,emitEvent:t.emitEvent})}),this.updateValueAndValidity(t)},t.prototype.patchValue=function(n,t){var e=this;void 0===t&&(t={}),n.forEach(function(n,l){e.at(l)&&e.at(l).patchValue(n,{onlySelf:!0,emitEvent:t.emitEvent})}),this.updateValueAndValidity(t)},t.prototype.reset=function(n,t){void 0===n&&(n=[]),void 0===t&&(t={}),this._forEachChild(function(e,l){e.reset(n[l],{onlySelf:!0,emitEvent:t.emitEvent})}),this.updateValueAndValidity(t),this._updatePristine(t),this._updateTouched(t)},t.prototype.getRawValue=function(){return this.controls.map(function(n){return n instanceof No?n.value:n.getRawValue()})},t.prototype._syncPendingControls=function(){var n=this.controls.reduce(function(n,t){return!!t._syncPendingControls()||n},!1);return n&&this.updateValueAndValidity({onlySelf:!0}),n},t.prototype._throwIfControlMissing=function(n){if(!this.controls.length)throw new Error("\n There are no form controls registered with this array yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");if(!this.at(n))throw new Error("Cannot find form control at index "+n)},t.prototype._forEachChild=function(n){this.controls.forEach(function(t,e){n(t,e)})},t.prototype._updateValue=function(){var n=this;this.value=this.controls.filter(function(t){return t.enabled||n.disabled}).map(function(n){return n.value})},t.prototype._anyControls=function(n){return this.controls.some(function(t){return t.enabled&&n(t)})},t.prototype._setUpControls=function(){var n=this;this._forEachChild(function(t){return n._registerControl(t)})},t.prototype._checkAllValuesPresent=function(n){this._forEachChild(function(t,e){if(void 0===n[e])throw new Error("Must supply a value for form control at index: "+e+".")})},t.prototype._allControlsDisabled=function(){for(var n=0,t=this.controls;n0||this.disabled},t.prototype._registerControl=function(n){n.setParent(this),n._registerOnCollectionChange(this._onCollectionChange)},t}(Ho),Vo=Promise.resolve(null),Wo=function(n){function t(t,e){var r=n.call(this)||this;return r.submitted=!1,r._directives=[],r.ngSubmit=new l.o,r.form=new Fo({},So(t),Oo(e)),r}return Object(i.__extends)(t,n),t.prototype.ngAfterViewInit=function(){this._setUpdateStrategy()},Object.defineProperty(t.prototype,"formDirective",{get:function(){return this},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"control",{get:function(){return this.form},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"path",{get:function(){return[]},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"controls",{get:function(){return this.form.controls},enumerable:!0,configurable:!0}),t.prototype.addControl=function(n){var t=this;Vo.then(function(){var e=t._findContainer(n.path);n.control=e.registerControl(n.name,n.control),wo(n.control,n),n.control.updateValueAndValidity({emitEvent:!1}),t._directives.push(n)})},t.prototype.getControl=function(n){return this.form.get(n.path)},t.prototype.removeControl=function(n){var t=this;Vo.then(function(){var e=t._findContainer(n.path);e&&e.removeControl(n.name),Po(t._directives,n)})},t.prototype.addFormGroup=function(n){var t=this;Vo.then(function(){var e=t._findContainer(n.path),l=new Fo({});Mo(l,n),e.registerControl(n.name,l),l.updateValueAndValidity({emitEvent:!1})})},t.prototype.removeFormGroup=function(n){var t=this;Vo.then(function(){var e=t._findContainer(n.path);e&&e.removeControl(n.name)})},t.prototype.getFormGroup=function(n){return this.form.get(n.path)},t.prototype.updateModel=function(n,t){var e=this;Vo.then(function(){e.form.get(n.path).setValue(t)})},t.prototype.setValue=function(n){this.control.setValue(n)},t.prototype.onSubmit=function(n){return this.submitted=!0,Lo(this.form,this._directives),this.ngSubmit.emit(n),!1},t.prototype.onReset=function(){this.resetForm()},t.prototype.resetForm=function(n){void 0===n&&(n=void 0),this.form.reset(n),this.submitted=!1},t.prototype._setUpdateStrategy=function(){this.options&&null!=this.options.updateOn&&(this.form._updateOn=this.options.updateOn)},t.prototype._findContainer=function(n){return n.pop(),n.length?this.form.get(n):this.form},t}(qi),zo='\n
\n \n
\n\n In your class:\n\n this.myGroup = new FormGroup({\n firstName: new FormControl()\n });',Uo='\n
\n
\n \n
\n
\n\n In your class:\n\n this.myGroup = new FormGroup({\n person: new FormGroup({ firstName: new FormControl() })\n });',Go=function(){function n(){}return n.controlParentException=function(){throw new Error("formControlName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n "+zo)},n.ngModelGroupException=function(){throw new Error('formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents\n that also have a "form" prefix: formGroupName, formArrayName, or formGroup.\n\n Option 1: Update the parent to be formGroupName (reactive form strategy)\n\n '+Uo+'\n\n Option 2: Use ngModel instead of formControlName (template-driven strategy)\n\n \n
\n
\n \n
\n
')},n.missingFormException=function(){throw new Error("formGroup expects a FormGroup instance. Please pass one in.\n\n Example:\n\n "+zo)},n.groupParentException=function(){throw new Error("formGroupName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n "+Uo)},n.arrayParentException=function(){throw new Error('formArrayName must be used with a parent formGroup directive. You\'ll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n \n
\n
\n
\n \n
\n
\n
\n\n In your class:\n\n this.cityArray = new FormArray([new FormControl(\'SF\')]);\n this.myGroup = new FormGroup({\n cities: this.cityArray\n });')},n.disabledAttrWarning=function(){console.warn("\n It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true\n when you set up this control in your component class, the disabled attribute will actually be set in the DOM for\n you. We recommend using this approach to avoid 'changed after checked' errors.\n \n Example: \n form = new FormGroup({\n first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),\n last: new FormControl('Drew', Validators.required)\n });\n ")},n}(),qo=function(n){function t(t,e){var r=n.call(this)||this;return r._validators=t,r._asyncValidators=e,r.submitted=!1,r.directives=[],r.form=null,r.ngSubmit=new l.o,r}return Object(i.__extends)(t,n),t.prototype.ngOnChanges=function(n){this._checkFormPresent(),n.hasOwnProperty("form")&&(this._updateValidators(),this._updateDomValue(),this._updateRegistrations())},Object.defineProperty(t.prototype,"formDirective",{get:function(){return this},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"control",{get:function(){return this.form},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"path",{get:function(){return[]},enumerable:!0,configurable:!0}),t.prototype.addControl=function(n){var t=this.form.get(n.path);return wo(t,n),t.updateValueAndValidity({emitEvent:!1}),this.directives.push(n),t},t.prototype.getControl=function(n){return this.form.get(n.path)},t.prototype.removeControl=function(n){Po(this.directives,n)},t.prototype.addFormGroup=function(n){var t=this.form.get(n.path);Mo(t,n),t.updateValueAndValidity({emitEvent:!1})},t.prototype.removeFormGroup=function(n){},t.prototype.getFormGroup=function(n){return this.form.get(n.path)},t.prototype.addFormArray=function(n){var t=this.form.get(n.path);Mo(t,n),t.updateValueAndValidity({emitEvent:!1})},t.prototype.removeFormArray=function(n){},t.prototype.getFormArray=function(n){return this.form.get(n.path)},t.prototype.updateModel=function(n,t){this.form.get(n.path).setValue(t)},t.prototype.onSubmit=function(n){return this.submitted=!0,Lo(this.form,this.directives),this.ngSubmit.emit(n),!1},t.prototype.onReset=function(){this.resetForm()},t.prototype.resetForm=function(n){void 0===n&&(n=void 0),this.form.reset(n),this.submitted=!1},t.prototype._updateDomValue=function(){var n=this;this.directives.forEach(function(t){var e=n.form.get(t.path);t.control!==e&&(function(n,t){t.valueAccessor.registerOnChange(function(){return ko(t)}),t.valueAccessor.registerOnTouched(function(){return ko(t)}),t._rawValidators.forEach(function(n){n.registerOnValidatorChange&&n.registerOnValidatorChange(null)}),t._rawAsyncValidators.forEach(function(n){n.registerOnValidatorChange&&n.registerOnValidatorChange(null)}),n&&n._clearChangeFns()}(t.control,t),e&&wo(e,t),t.control=e)}),this.form._updateTreeValidity({emitEvent:!1})},t.prototype._updateRegistrations=function(){var n=this;this.form._registerOnCollectionChange(function(){return n._updateDomValue()}),this._oldForm&&this._oldForm._registerOnCollectionChange(function(){}),this._oldForm=this.form},t.prototype._updateValidators=function(){var n=So(this._validators);this.form.validator=Xi.compose([this.form.validator,n]);var t=Oo(this._asyncValidators);this.form.asyncValidator=Xi.composeAsync([this.form.asyncValidator,t])},t.prototype._checkFormPresent=function(){this.form||Go.missingFormException()},t}(qi),Jo=function(n){function t(t,e,l){var r=n.call(this)||this;return r._parent=t,r._validators=e,r._asyncValidators=l,r}return Object(i.__extends)(t,n),t.prototype._checkParentType=function(){Ko(this._parent)&&Go.groupParentException()},t}(Do),Qo=function(n){function t(t,e,l){var r=n.call(this)||this;return r._parent=t,r._validators=e,r._asyncValidators=l,r}return Object(i.__extends)(t,n),t.prototype.ngOnInit=function(){this._checkParentType(),this.formDirective.addFormArray(this)},t.prototype.ngOnDestroy=function(){this.formDirective&&this.formDirective.removeFormArray(this)},Object.defineProperty(t.prototype,"control",{get:function(){return this.formDirective.getFormArray(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"formDirective",{get:function(){return this._parent?this._parent.formDirective:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"path",{get:function(){return vo(this.name,this._parent)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"validator",{get:function(){return So(this._validators)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"asyncValidator",{get:function(){return Oo(this._asyncValidators)},enumerable:!0,configurable:!0}),t.prototype._checkParentType=function(){Ko(this._parent)&&Go.arrayParentException()},t}(qi);function Ko(n){return!(n instanceof Jo||n instanceof qo||n instanceof Qo)}var Xo=function(n){function t(t,e,r,i){var o=n.call(this)||this;return o._added=!1,o.update=new l.o,o._parent=t,o._rawValidators=e||[],o._rawAsyncValidators=r||[],o.valueAccessor=function(n,t){if(!t)return null;var e=void 0,l=void 0,r=void 0;return t.forEach(function(t){var i;t.constructor===ro?e=t:(i=t,To.some(function(n){return i.constructor===n})?(l&&Co(n,"More than one built-in value accessor matches form control with"),l=t):(r&&Co(n,"More than one custom value accessor matches form control with"),r=t))}),r||l||e||(Co(n,"No valid value accessor for form control with"),null)}(o,i),o}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"isDisabled",{set:function(n){Go.disabledAttrWarning()},enumerable:!0,configurable:!0}),t.prototype.ngOnChanges=function(n){this._added||this._setUpControl(),function(n,t){if(!n.hasOwnProperty("model"))return!1;var e=n.model;return!!e.isFirstChange()||!Object(l._16)(t,e.currentValue)}(n,this.viewModel)&&(this.viewModel=this.model,this.formDirective.updateModel(this,this.model))},t.prototype.ngOnDestroy=function(){this.formDirective&&this.formDirective.removeControl(this)},t.prototype.viewToModelUpdate=function(n){this.viewModel=n,this.update.emit(n)},Object.defineProperty(t.prototype,"path",{get:function(){return vo(this.name,this._parent)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"formDirective",{get:function(){return this._parent?this._parent.formDirective:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"validator",{get:function(){return So(this._rawValidators)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"asyncValidator",{get:function(){return Oo(this._rawAsyncValidators)},enumerable:!0,configurable:!0}),t.prototype._checkParentType=function(){!(this._parent instanceof Jo)&&this._parent instanceof Do?Go.ngModelGroupException():this._parent instanceof Jo||this._parent instanceof qo||this._parent instanceof Qo||Go.controlParentException()},t.prototype._setUpControl=function(){this._checkParentType(),this.control=this.formDirective.addControl(this),this.control.disabled&&this.valueAccessor.setDisabledState&&this.valueAccessor.setDisabledState(!0),this._added=!0},t}(uo),Zo=function(){function n(){}return Object.defineProperty(n.prototype,"required",{get:function(){return this._required},set:function(n){this._required=null!=n&&!1!==n&&""+n!="false",this._onChange&&this._onChange()},enumerable:!0,configurable:!0}),n.prototype.validate=function(n){return this.required?Xi.required(n):null},n.prototype.registerOnValidatorChange=function(n){this._onChange=n},n}(),$o=function(){function n(){}return n.prototype.ngOnChanges=function(n){"maxlength"in n&&(this._createValidator(),this._onChange&&this._onChange())},n.prototype.validate=function(n){return null!=this.maxlength?this._validator(n):null},n.prototype.registerOnValidatorChange=function(n){this._onChange=n},n.prototype._createValidator=function(){this._validator=Xi.maxLength(parseInt(this.maxlength,10))},n}(),ns=function(){function n(){}return n.prototype.group=function(n,t){void 0===t&&(t=null);var e=this._reduceControls(n);return new Fo(e,null!=t?t.validator:null,null!=t?t.asyncValidator:null)},n.prototype.control=function(n,t,e){return new No(n,t,e)},n.prototype.array=function(n,t,e){var l=this,r=n.map(function(n){return l._createControl(n)});return new Bo(r,t,e)},n.prototype._reduceControls=function(n){var t=this,e={};return Object.keys(n).forEach(function(l){e[l]=t._createControl(n[l])}),e},n.prototype._createControl=function(n){return n instanceof No||n instanceof Fo||n instanceof Bo?n:Array.isArray(n)?this.control(n[0],n.length>1?n[1]:null,n.length>2?n[2]:null):this.control(n)},n}(),ts=function(){},es=function(){},ls=function(){},rs=function(){},is="*";function os(n,t){return void 0===t&&(t=null),{type:2,steps:n,options:t}}function ss(n){return{type:6,styles:n,offset:null}}function as(n){Promise.resolve(null).then(n)}var us=function(){function n(){this._onDoneFns=[],this._onStartFns=[],this._onDestroyFns=[],this._started=!1,this._destroyed=!1,this._finished=!1,this.parentPlayer=null,this.totalTime=0}return n.prototype._onFinish=function(){this._finished||(this._finished=!0,this._onDoneFns.forEach(function(n){return n()}),this._onDoneFns=[])},n.prototype.onStart=function(n){this._onStartFns.push(n)},n.prototype.onDone=function(n){this._onDoneFns.push(n)},n.prototype.onDestroy=function(n){this._onDestroyFns.push(n)},n.prototype.hasStarted=function(){return this._started},n.prototype.init=function(){},n.prototype.play=function(){this.hasStarted()||(this._onStart(),this.triggerMicrotask()),this._started=!0},n.prototype.triggerMicrotask=function(){var n=this;as(function(){return n._onFinish()})},n.prototype._onStart=function(){this._onStartFns.forEach(function(n){return n()}),this._onStartFns=[]},n.prototype.pause=function(){},n.prototype.restart=function(){},n.prototype.finish=function(){this._onFinish()},n.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.hasStarted()||this._onStart(),this.finish(),this._onDestroyFns.forEach(function(n){return n()}),this._onDestroyFns=[])},n.prototype.reset=function(){},n.prototype.setPosition=function(n){},n.prototype.getPosition=function(){return 0},n.prototype.triggerCallback=function(n){var t="start"==n?this._onStartFns:this._onDoneFns;t.forEach(function(n){return n()}),t.length=0},n}(),cs=function(){function n(n){var t=this;this._onDoneFns=[],this._onStartFns=[],this._finished=!1,this._started=!1,this._destroyed=!1,this._onDestroyFns=[],this.parentPlayer=null,this.totalTime=0,this.players=n;var e=0,l=0,r=0,i=this.players.length;0==i?as(function(){return t._onFinish()}):this.players.forEach(function(n){n.onDone(function(){++e==i&&t._onFinish()}),n.onDestroy(function(){++l==i&&t._onDestroy()}),n.onStart(function(){++r==i&&t._onStart()})}),this.totalTime=this.players.reduce(function(n,t){return Math.max(n,t.totalTime)},0)}return n.prototype._onFinish=function(){this._finished||(this._finished=!0,this._onDoneFns.forEach(function(n){return n()}),this._onDoneFns=[])},n.prototype.init=function(){this.players.forEach(function(n){return n.init()})},n.prototype.onStart=function(n){this._onStartFns.push(n)},n.prototype._onStart=function(){this.hasStarted()||(this._started=!0,this._onStartFns.forEach(function(n){return n()}),this._onStartFns=[])},n.prototype.onDone=function(n){this._onDoneFns.push(n)},n.prototype.onDestroy=function(n){this._onDestroyFns.push(n)},n.prototype.hasStarted=function(){return this._started},n.prototype.play=function(){this.parentPlayer||this.init(),this._onStart(),this.players.forEach(function(n){return n.play()})},n.prototype.pause=function(){this.players.forEach(function(n){return n.pause()})},n.prototype.restart=function(){this.players.forEach(function(n){return n.restart()})},n.prototype.finish=function(){this._onFinish(),this.players.forEach(function(n){return n.finish()})},n.prototype.destroy=function(){this._onDestroy()},n.prototype._onDestroy=function(){this._destroyed||(this._destroyed=!0,this._onFinish(),this.players.forEach(function(n){return n.destroy()}),this._onDestroyFns.forEach(function(n){return n()}),this._onDestroyFns=[])},n.prototype.reset=function(){this.players.forEach(function(n){return n.reset()}),this._destroyed=!1,this._finished=!1,this._started=!1},n.prototype.setPosition=function(n){var t=n*this.totalTime;this.players.forEach(function(n){var e=n.totalTime?Math.min(1,t/n.totalTime):1;n.setPosition(e)})},n.prototype.getPosition=function(){var n=0;return this.players.forEach(function(t){var e=t.getPosition();n=Math.min(e,n)}),n},n.prototype.beforeDestroy=function(){this.players.forEach(function(n){n.beforeDestroy&&n.beforeDestroy()})},n.prototype.triggerCallback=function(n){var t="start"==n?this._onStartFns:this._onDoneFns;t.forEach(function(n){return n()}),t.length=0},n}(),ds="!",hs=e("TILf"),ps=e("N4j0"),fs=e("cQXm"),_s=function(n){function t(t,e){if(n.call(this),this.scheduler=e,null==t)throw new Error("iterator cannot be null.");this.iterator=ys(t)}return Object(i.__extends)(t,n),t.create=function(n,e){return new t(n,e)},t.dispatch=function(n){var t=n.index,e=n.iterator,l=n.subscriber;if(n.hasError)l.error(n.error);else{var r=e.next();r.done?l.complete():(l.next(r.value),n.index=t+1,l.closed?"function"==typeof e.return&&e.return():this.schedule(n))}},t.prototype._subscribe=function(n){var e=this.iterator,l=this.scheduler;if(l)return l.schedule(t.dispatch,0,{index:0,iterator:e,subscriber:n});for(;;){var r=e.next();if(r.done){n.complete();break}if(n.next(r.value),n.closed){"function"==typeof e.return&&e.return();break}}},t}(o.a),ms=function(){function n(n,t,e){void 0===t&&(t=0),void 0===e&&(e=n.length),this.str=n,this.idx=t,this.len=e}return n.prototype[hl.a]=function(){return this},n.prototype.next=function(){return this.idxbs?bs:r:r}()),this.arr=n,this.idx=t,this.len=e}return n.prototype[hl.a]=function(){return this},n.prototype.next=function(){return this.idx=n.length?l.complete():(l.next(t[e]),n.index=e+1,this.schedule(n)))},t.prototype._subscribe=function(n){var e=this.arrayLike,l=this.scheduler,r=e.length;if(l)return l.schedule(t.dispatch,0,{arrayLike:e,index:0,length:r,subscriber:n});for(var i=0;i1?new dl.a(n,e):new je.a(e),t)}}var Os=function(){};function Ts(n){return Error("A hint was already declared for 'align=\""+n+"\"'.")}var Ls=0,Ps=function(){function n(n,t,e){this._elementRef=n,this._changeDetectorRef=t,this.color="primary",this._showAlwaysAnimate=!1,this._subscriptAnimationState="",this._hintLabel="",this._hintLabelId="mat-hint-"+Ls++,this._labelOptions=e||{},this.floatLabel=this._labelOptions.float||"auto"}return Object.defineProperty(n.prototype,"dividerColor",{get:function(){return this.color},set:function(n){this.color=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"hideRequiredMarker",{get:function(){return this._hideRequiredMarker},set:function(n){this._hideRequiredMarker=El(n)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_shouldAlwaysFloat",{get:function(){return"always"===this._floatLabel&&!this._showAlwaysAnimate},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_canLabelFloat",{get:function(){return"never"!==this._floatLabel},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"hintLabel",{get:function(){return this._hintLabel},set:function(n){this._hintLabel=n,this._processHints()},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"floatPlaceholder",{get:function(){return this._floatLabel},set:function(n){this.floatLabel=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"floatLabel",{get:function(){return this._floatLabel},set:function(n){n!==this._floatLabel&&(this._floatLabel=n||this._labelOptions.float||"auto",this._changeDetectorRef.markForCheck())},enumerable:!0,configurable:!0}),n.prototype.ngAfterContentInit=function(){var n=this;this._validateControlChild(),this._control.controlType&&this._elementRef.nativeElement.classList.add("mat-form-field-type-"+this._control.controlType),this._control.stateChanges.pipe(Ss(null)).subscribe(function(){n._validatePlaceholders(),n._syncDescribedByIds(),n._changeDetectorRef.markForCheck()});var t=this._control.ngControl;t&&t.valueChanges&&t.valueChanges.subscribe(function(){n._changeDetectorRef.markForCheck()}),this._hintChildren.changes.pipe(Ss(null)).subscribe(function(){n._processHints(),n._changeDetectorRef.markForCheck()}),this._errorChildren.changes.pipe(Ss(null)).subscribe(function(){n._syncDescribedByIds(),n._changeDetectorRef.markForCheck()})},n.prototype.ngAfterContentChecked=function(){this._validateControlChild()},n.prototype.ngAfterViewInit=function(){this._subscriptAnimationState="enter",this._changeDetectorRef.detectChanges()},n.prototype._shouldForward=function(n){var t=this._control?this._control.ngControl:null;return t&&t[n]},n.prototype._hasPlaceholder=function(){return!(!this._control.placeholder&&!this._placeholderChild)},n.prototype._hasLabel=function(){return!!this._labelChild},n.prototype._shouldLabelFloat=function(){return this._canLabelFloat&&(this._control.shouldLabelFloat||this._control.shouldPlaceholderFloat||this._shouldAlwaysFloat)},n.prototype._hideControlPlaceholder=function(){return!this._hasLabel()||!this._shouldLabelFloat()},n.prototype._hasFloatingLabel=function(){return this._hasLabel()||this._hasPlaceholder()},n.prototype._getDisplayedMessages=function(){return this._errorChildren&&this._errorChildren.length>0&&this._control.errorState?"error":"hint"},n.prototype._animateAndLockLabel=function(){var n=this;this._hasFloatingLabel()&&this._canLabelFloat&&(this._showAlwaysAnimate=!0,this._floatLabel="always",zr(this._label.nativeElement,"transitionend").pipe(Object(_r.a)(1)).subscribe(function(){n._showAlwaysAnimate=!1}),this._changeDetectorRef.markForCheck())},n.prototype._validatePlaceholders=function(){if(this._control.placeholder&&this._placeholderChild)throw Error("Placeholder attribute and child element were both specified.")},n.prototype._processHints=function(){this._validateHints(),this._syncDescribedByIds()},n.prototype._validateHints=function(){var n,t,e=this;this._hintChildren&&this._hintChildren.forEach(function(l){if("start"==l.align){if(n||e.hintLabel)throw Ts("start");n=l}else if("end"==l.align){if(t)throw Ts("end");t=l}})},n.prototype._syncDescribedByIds=function(){if(this._control){var n=[];if("hint"===this._getDisplayedMessages()){var t=this._hintChildren?this._hintChildren.find(function(n){return"start"===n.align}):null,e=this._hintChildren?this._hintChildren.find(function(n){return"end"===n.align}):null;t?n.push(t.id):this._hintLabel&&n.push(this._hintLabelId),e&&n.push(e.id)}else this._errorChildren&&(n=this._errorChildren.map(function(n){return n.id}));this._control.setDescribedByIds(n)}},n.prototype._validateControlChild=function(){if(!this._control)throw Error("mat-form-field must contain a MatFormFieldControl.")},n}(),Ds=function(){},As=0,Es=function(){function n(n,t){this._changeDetectorRef=n,this._elementRef=t,this.showPanel=!1,this._isOpen=!1,this.displayWith=null,this.optionSelected=new l.o,this._classList={},this.id="mat-autocomplete-"+As++}return Object.defineProperty(n.prototype,"isOpen",{get:function(){return this._isOpen&&this.showPanel},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"classList",{set:function(n){var t=this;n&&n.length&&(n.split(" ").forEach(function(n){return t._classList[n.trim()]=!0}),this._elementRef.nativeElement.className="")},enumerable:!0,configurable:!0}),n.prototype.ngAfterContentInit=function(){this._keyManager=new Sr(this.options).withWrap(),this._setVisibility()},n.prototype._setScrollTop=function(n){this.panel&&(this.panel.nativeElement.scrollTop=n)},n.prototype._getScrollTop=function(){return this.panel?this.panel.nativeElement.scrollTop:0},n.prototype._setVisibility=function(){this.showPanel=!!this.options.length,this._classList["mat-autocomplete-visible"]=this.showPanel,this._classList["mat-autocomplete-hidden"]=!this.showPanel,this._changeDetectorRef.markForCheck()},n.prototype._emitSelectEvent=function(n){var t=new function(n,t){this.source=n,this.option=t}(this,n);this.optionSelected.emit(t)},n}(),Ys=new l.r("mat-autocomplete-scroll-strategy");function js(n){return function(){return n.scrollStrategies.reposition()}}var Is=function(){function n(n,t,e,l,r,i,o,s,a){this._element=n,this._overlay=t,this._viewContainerRef=e,this._zone=l,this._changeDetectorRef=r,this._scrollStrategy=i,this._dir=o,this._formField=s,this._document=a,this._panelOpen=!1,this._manuallyFloatingLabel=!1,this._escapeEventStream=new yl.a,this._onChange=function(){},this._onTouched=function(){}}return n.prototype.ngOnDestroy=function(){this._destroyPanel(),this._escapeEventStream.complete()},Object.defineProperty(n.prototype,"panelOpen",{get:function(){return this._panelOpen&&this.autocomplete.showPanel},enumerable:!0,configurable:!0}),n.prototype.openPanel=function(){this._attachOverlay(),this._floatLabel()},n.prototype.closePanel=function(){this._resetLabel(),this._panelOpen&&(this.autocomplete._isOpen=this._panelOpen=!1,this._overlayRef&&this._overlayRef.hasAttached()&&(this._overlayRef.detach(),this._closingActionsSubscription.unsubscribe()),this._changeDetectorRef.detectChanges())},Object.defineProperty(n.prototype,"panelClosingActions",{get:function(){var n=this;return Object(Jr.a)(this.optionSelections,this.autocomplete._keyManager.tabOut.pipe(Ge(function(){return n._panelOpen})),this._escapeEventStream,this._outsideClickStream,this._overlayRef?this._overlayRef.detachments().pipe(Ge(function(){return n._panelOpen})):Object(Fe.a)())},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"optionSelections",{get:function(){return Jr.a.apply(void 0,this.autocomplete.options.map(function(n){return n.onSelectionChange}))},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"activeOption",{get:function(){return this.autocomplete&&this.autocomplete._keyManager?this.autocomplete._keyManager.activeItem:null},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_outsideClickStream",{get:function(){var n=this;return this._document?Object(Jr.a)(zr(this._document,"click"),zr(this._document,"touchend")).pipe(Ge(function(t){var e=t.target,l=n._formField?n._formField._elementRef.nativeElement:null;return n._panelOpen&&e!==n._element.nativeElement&&(!l||!l.contains(e))&&!!n._overlayRef&&!n._overlayRef.overlayElement.contains(e)})):Object(Fe.a)(null)},enumerable:!0,configurable:!0}),n.prototype.writeValue=function(n){var t=this;Promise.resolve(null).then(function(){return t._setTriggerValue(n)})},n.prototype.registerOnChange=function(n){this._onChange=n},n.prototype.registerOnTouched=function(n){this._onTouched=n},n.prototype.setDisabledState=function(n){this._element.nativeElement.disabled=n},n.prototype._handleKeydown=function(n){var t=n.keyCode;if(27===t&&this.panelOpen)this._resetActiveItem(),this._escapeEventStream.next(),n.stopPropagation();else if(this.activeOption&&13===t&&this.panelOpen)this.activeOption._selectViaInteraction(),this._resetActiveItem(),n.preventDefault();else{var e=this.autocomplete._keyManager.activeItem,l=38===t||40===t;this.panelOpen||9===t?this.autocomplete._keyManager.onKeydown(n):l&&this.openPanel(),(l||this.autocomplete._keyManager.activeItem!==e)&&this._scrollToOption()}},n.prototype._handleInput=function(n){document.activeElement===n.target&&(this._onChange(n.target.value),this.openPanel())},n.prototype._handleFocus=function(){this._element.nativeElement.readOnly||(this._attachOverlay(),this._floatLabel(!0))},n.prototype._floatLabel=function(n){void 0===n&&(n=!1),this._formField&&"auto"===this._formField.floatLabel&&(n?this._formField._animateAndLockLabel():this._formField.floatLabel="always",this._manuallyFloatingLabel=!0)},n.prototype._resetLabel=function(){this._manuallyFloatingLabel&&(this._formField.floatLabel="auto",this._manuallyFloatingLabel=!1)},n.prototype._scrollToOption=function(){var n=this.autocomplete._keyManager.activeItemIndex||0,t=48*(n+pr.countGroupLabelsBeforeOption(n,this.autocomplete.options,this.autocomplete.optionGroups)),e=this.autocomplete._getScrollTop();te+256&&this.autocomplete._setScrollTop(Math.max(0,t-256+48))},n.prototype._subscribeToClosingActions=function(){var n=this,t=this._zone.onStable.asObservable().pipe(Object(_r.a)(1)),e=this.autocomplete.options.changes.pipe(Ve(function(){return n._positionStrategy.recalculateLastPosition()}),Hi(0));return Object(Jr.a)(t,e).pipe(Object(Ri.a)(function(){return n._resetActiveItem(),n.autocomplete._setVisibility(),n.panelClosingActions}),Object(_r.a)(1)).subscribe(function(t){return n._setValueAndClose(t)})},n.prototype._destroyPanel=function(){this._overlayRef&&(this.closePanel(),this._overlayRef.dispose(),this._overlayRef=null)},n.prototype._setTriggerValue=function(n){var t=this.autocomplete&&this.autocomplete.displayWith?this.autocomplete.displayWith(n):n,e=null!=t?t:"";this._formField?this._formField._control.value=e:this._element.nativeElement.value=e},n.prototype._setValueAndClose=function(n){n&&n.source&&(this._clearPreviousSelectedOption(n.source),this._setTriggerValue(n.source.value),this._onChange(n.source.value),this._element.nativeElement.focus(),this.autocomplete._emitSelectEvent(n.source)),this.closePanel()},n.prototype._clearPreviousSelectedOption=function(n){this.autocomplete.options.forEach(function(t){t!=n&&t.selected&&t.deselect()})},n.prototype._attachOverlay=function(){if(!this.autocomplete)throw Error("Attempting to open an undefined instance of `mat-autocomplete`. Make sure that the id passed to the `matAutocomplete` is correct and that you're attempting to open it after the ngAfterContentInit hook.");this._overlayRef?this._overlayRef.updateSize({width:this._getHostWidth()}):(this._portal=new li(this.autocomplete.template,this._viewContainerRef),this._overlayRef=this._overlay.create(this._getOverlayConfig())),this._overlayRef&&!this._overlayRef.hasAttached()&&(this._overlayRef.attach(this._portal),this._closingActionsSubscription=this._subscribeToClosingActions()),this.autocomplete._setVisibility(),this.autocomplete._isOpen=this._panelOpen=!0},n.prototype._getOverlayConfig=function(){return new ci({positionStrategy:this._getOverlayPosition(),scrollStrategy:this._scrollStrategy(),width:this._getHostWidth(),direction:this._dir?this._dir.value:"ltr"})},n.prototype._getOverlayPosition=function(){return this._positionStrategy=this._overlay.position().connectedTo(this._getConnectedElement(),{originX:"start",originY:"bottom"},{overlayX:"start",overlayY:"top"}).withFallbackPosition({originX:"start",originY:"top"},{overlayX:"start",overlayY:"bottom"}),this._positionStrategy},n.prototype._getConnectedElement=function(){return this._formField?this._formField._connectionContainerRef:this._element},n.prototype._getHostWidth=function(){return this._getConnectedElement().nativeElement.getBoundingClientRect().width},n.prototype._resetActiveItem=function(){this.autocomplete._keyManager.setActiveItem(-1)},n}(),Rs=function(){},Hs=function(){},Ns=function(){},Fs=function(){},Bs=function(n){function t(t,e,l){var r=n.call(this,t)||this;return r._platform=e,r._focusMonitor=l,r._isRoundButton=r._hasHostAttributes("mat-fab","mat-mini-fab"),r._isIconButton=r._hasHostAttributes("mat-icon-button"),r._focusMonitor.monitor(r._elementRef.nativeElement,!0),r}return Object(i.__extends)(t,n),t.prototype.ngOnDestroy=function(){this._focusMonitor.stopMonitoring(this._elementRef.nativeElement)},t.prototype.focus=function(){this._getHostElement().focus()},t.prototype._getHostElement=function(){return this._elementRef.nativeElement},t.prototype._isRippleDisabled=function(){return this.disableRipple||this.disabled},t.prototype._hasHostAttributes=function(){for(var n=this,t=[],e=0;e1&&!this._isMulti)throw Error("Cannot pass multiple values into SelectionModel with single-value mode.")},n}(),Us=function(n,t){this.added=n,this.removed=t},Gs=function(){function n(){this._listeners=[]}return n.prototype.notify=function(n,t){for(var e=0,l=this._listeners;e0?this._ngZone.runOutsideAngular(function(){n._debouncer.pipe(mr(n.debounce)).subscribe(function(t){return n.event.emit(t)})}):this._debouncer.subscribe(function(t){return n.event.emit(t)}),this._observer=this._ngZone.runOutsideAngular(function(){return n._mutationObserverFactory.create(function(t){n._debouncer.next(t)})}),this._observer&&this._observer.observe(this._elementRef.nativeElement,{characterData:!0,childList:!0,subtree:!0})},n.prototype.ngOnDestroy=function(){this._observer&&this._observer.disconnect(),this._debouncer.complete()},n}(),Xs=function(){},Zs=new l.r("mat-checkbox-click-action"),$s=0,na=function(){var n={Init:0,Checked:1,Unchecked:2,Indeterminate:3};return n[n.Init]="Init",n[n.Checked]="Checked",n[n.Unchecked]="Unchecked",n[n.Indeterminate]="Indeterminate",n}(),ta=function(n){function t(t,e,r,i,o){var s=n.call(this,t)||this;return s._changeDetectorRef=e,s._focusMonitor=r,s._clickAction=o,s.ariaLabel="",s.ariaLabelledby=null,s._uniqueId="mat-checkbox-"+ ++$s,s.id=s._uniqueId,s.labelPosition="after",s.name=null,s.change=new l.o,s.indeterminateChange=new l.o,s._rippleConfig={centered:!0,radius:25,speedFactor:1.5},s.onTouched=function(){},s._currentAnimationClass="",s._currentCheckState=na.Init,s._checked=!1,s._indeterminate=!1,s._controlValueAccessorChangeFn=function(){},s.tabIndex=parseInt(i)||0,s}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"inputId",{get:function(){return(this.id||this._uniqueId)+"-input"},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"required",{get:function(){return this._required},set:function(n){this._required=El(n)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"align",{get:function(){return"after"==this.labelPosition?"start":"end"},set:function(n){this.labelPosition="start"==n?"after":"before"},enumerable:!0,configurable:!0}),t.prototype.ngAfterViewInit=function(){var n=this;this._focusMonitor.monitor(this._inputElement.nativeElement,!1).subscribe(function(t){return n._onInputFocusChange(t)})},t.prototype.ngOnDestroy=function(){this._focusMonitor.stopMonitoring(this._inputElement.nativeElement)},Object.defineProperty(t.prototype,"checked",{get:function(){return this._checked},set:function(n){n!=this.checked&&(this._checked=n,this._changeDetectorRef.markForCheck())},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"indeterminate",{get:function(){return this._indeterminate},set:function(n){var t=n!=this._indeterminate;this._indeterminate=n,t&&(this._transitionCheckState(this._indeterminate?na.Indeterminate:this.checked?na.Checked:na.Unchecked),this.indeterminateChange.emit(this._indeterminate))},enumerable:!0,configurable:!0}),t.prototype._isRippleDisabled=function(){return this.disableRipple||this.disabled},t.prototype._onLabelTextChange=function(){this._changeDetectorRef.markForCheck()},t.prototype.writeValue=function(n){this.checked=!!n},t.prototype.registerOnChange=function(n){this._controlValueAccessorChangeFn=n},t.prototype.registerOnTouched=function(n){this.onTouched=n},t.prototype.setDisabledState=function(n){this.disabled=n,this._changeDetectorRef.markForCheck()},t.prototype._getAriaChecked=function(){return this.checked?"true":this.indeterminate?"mixed":"false"},t.prototype._transitionCheckState=function(n){var t=this._currentCheckState,e=this._elementRef.nativeElement;t!==n&&(this._currentAnimationClass.length>0&&e.classList.remove(this._currentAnimationClass),this._currentAnimationClass=this._getAnimationClassForCheckStateTransition(t,n),this._currentCheckState=n,this._currentAnimationClass.length>0&&e.classList.add(this._currentAnimationClass))},t.prototype._emitChangeEvent=function(){var n=new function(){};n.source=this,n.checked=this.checked,this._controlValueAccessorChangeFn(this.checked),this.change.emit(n)},t.prototype._onInputFocusChange=function(n){this._focusRipple||"keyboard"!==n?n||(this._removeFocusRipple(),this.onTouched()):this._focusRipple=this._ripple.launch(0,0,Object(i.__assign)({persistent:!0},this._rippleConfig))},t.prototype.toggle=function(){this.checked=!this.checked},t.prototype._onInputClick=function(n){var t=this;n.stopPropagation(),this.disabled||"noop"===this._clickAction?this.disabled||"noop"!==this._clickAction||(this._inputElement.nativeElement.checked=this.checked,this._inputElement.nativeElement.indeterminate=this.indeterminate):(this.indeterminate&&"check"!==this._clickAction&&Promise.resolve().then(function(){t._indeterminate=!1,t.indeterminateChange.emit(t._indeterminate)}),this.toggle(),this._transitionCheckState(this._checked?na.Checked:na.Unchecked),this._emitChangeEvent())},t.prototype.focus=function(){this._focusMonitor.focusVia(this._inputElement.nativeElement,"keyboard")},t.prototype._onInteractionEvent=function(n){n.stopPropagation()},t.prototype._getAnimationClassForCheckStateTransition=function(n,t){var e="";switch(n){case na.Init:if(t===na.Checked)e="unchecked-checked";else{if(t!=na.Indeterminate)return"";e="unchecked-indeterminate"}break;case na.Unchecked:e=t===na.Checked?"unchecked-checked":"unchecked-indeterminate";break;case na.Checked:e=t===na.Unchecked?"checked-unchecked":"checked-indeterminate";break;case na.Indeterminate:e=t===na.Checked?"indeterminate-checked":"indeterminate-unchecked"}return"mat-checkbox-anim-"+e},t.prototype._removeFocusRipple=function(){this._focusRipple&&(this._focusRipple.fadeOut(),this._focusRipple=null)},t}(Jl(Gl(ql(Ul(function(n){this._elementRef=n})),"accent"))),ea=function(){},la=function(n){function t(t){n.call(this),this.observableFactory=t}return Object(i.__extends)(t,n),t.create=function(n){return new t(n)},t.prototype._subscribe=function(n){return new ra(n,this.observableFactory)},t}(o.a),ra=function(n){function t(t,e){n.call(this,t),this.factory=e,this.tryDefer()}return Object(i.__extends)(t,n),t.prototype.tryDefer=function(){try{this._callFactory()}catch(n){this._error(n)}},t.prototype._callFactory=function(){var n=this.factory();n&&this.add(Object(ke.a)(this,n))},t}(Me.a),ia=la.create,oa=function(){this.role="dialog",this.panelClass="",this.hasBackdrop=!0,this.backdropClass="",this.disableClose=!1,this.width="",this.height="",this.maxWidth="80vw",this.data=null,this.direction="ltr",this.ariaDescribedBy=null,this.ariaLabel=null,this.autoFocus=!0};function sa(){throw Error("Attempting to attach dialog content after content is already attached")}var aa=function(n){function t(t,e,r,i){var o=n.call(this)||this;return o._elementRef=t,o._focusTrapFactory=e,o._changeDetectorRef=r,o._document=i,o._elementFocusedBeforeDialogWasOpened=null,o._state="enter",o._animationStateChanged=new l.o,o._ariaLabelledBy=null,o}return Object(i.__extends)(t,n),t.prototype.attachComponentPortal=function(n){return this._portalOutlet.hasAttached()&&sa(),this._savePreviouslyFocusedElement(),this._portalOutlet.attachComponentPortal(n)},t.prototype.attachTemplatePortal=function(n){return this._portalOutlet.hasAttached()&&sa(),this._savePreviouslyFocusedElement(),this._portalOutlet.attachTemplatePortal(n)},t.prototype._trapFocus=function(){this._focusTrap||(this._focusTrap=this._focusTrapFactory.create(this._elementRef.nativeElement)),this._config.autoFocus&&this._focusTrap.focusInitialElementWhenReady()},t.prototype._restoreFocus=function(){var n=this._elementFocusedBeforeDialogWasOpened;n&&"function"==typeof n.focus&&n.focus(),this._focusTrap&&this._focusTrap.destroy()},t.prototype._savePreviouslyFocusedElement=function(){var n=this;this._document&&(this._elementFocusedBeforeDialogWasOpened=this._document.activeElement,Promise.resolve().then(function(){return n._elementRef.nativeElement.focus()}))},t.prototype._onAnimationDone=function(n){"enter"===n.toState?this._trapFocus():"exit"===n.toState&&this._restoreFocus(),this._animationStateChanged.emit(n)},t.prototype._onAnimationStart=function(n){this._animationStateChanged.emit(n)},t.prototype._startExitAnimation=function(){this._state="exit",this._changeDetectorRef.markForCheck()},t}(ri),ua=0,ca=function(){function n(n,t,e){void 0===e&&(e="mat-dialog-"+ua++);var l=this;this._overlayRef=n,this._containerInstance=t,this.id=e,this.disableClose=this._containerInstance._config.disableClose,this._afterOpen=new yl.a,this._afterClosed=new yl.a,this._beforeClose=new yl.a,t._animationStateChanged.pipe(Ge(function(n){return"done"===n.phaseName&&"enter"===n.toState}),Object(_r.a)(1)).subscribe(function(){l._afterOpen.next(),l._afterOpen.complete()}),t._animationStateChanged.pipe(Ge(function(n){return"done"===n.phaseName&&"exit"===n.toState}),Object(_r.a)(1)).subscribe(function(){l._overlayRef.dispose(),l._afterClosed.next(l._result),l._afterClosed.complete(),l.componentInstance=null})}return n.prototype.close=function(n){var t=this;this._result=n,this._containerInstance._animationStateChanged.pipe(Ge(function(n){return"start"===n.phaseName}),Object(_r.a)(1)).subscribe(function(){t._beforeClose.next(n),t._beforeClose.complete(),t._overlayRef.detachBackdrop()}),this._containerInstance._startExitAnimation()},n.prototype.afterOpen=function(){return this._afterOpen.asObservable()},n.prototype.afterClosed=function(){return this._afterClosed.asObservable()},n.prototype.beforeClose=function(){return this._beforeClose.asObservable()},n.prototype.backdropClick=function(){return this._overlayRef.backdropClick()},n.prototype.keydownEvents=function(){return this._overlayRef.keydownEvents()},n.prototype.updatePosition=function(n){var t=this._getPositionStrategy();return n&&(n.left||n.right)?n.left?t.left(n.left):t.right(n.right):t.centerHorizontally(),n&&(n.top||n.bottom)?n.top?t.top(n.top):t.bottom(n.bottom):t.centerVertically(),this._overlayRef.updatePosition(),this},n.prototype.updateSize=function(n,t){return void 0===n&&(n="auto"),void 0===t&&(t="auto"),this._getPositionStrategy().width(n).height(t),this._overlayRef.updatePosition(),this},n.prototype._getPositionStrategy=function(){return this._overlayRef.getConfig().positionStrategy},n}(),da=new l.r("MatDialogData"),ha=new l.r("mat-dialog-scroll-strategy");function pa(n){return function(){return n.scrollStrategies.block()}}var fa=function(){function n(n,t,e,l,r,i){var o=this;this._overlay=n,this._injector=t,this._scrollStrategy=l,this._parentDialog=r,this._overlayContainer=i,this._openDialogsAtThisLevel=[],this._afterAllClosedAtThisLevel=new yl.a,this._afterOpenAtThisLevel=new yl.a,this._ariaHiddenElements=new Map,this.afterAllClosed=ia(function(){return o.openDialogs.length?o._afterAllClosed:o._afterAllClosed.pipe(Ss(void 0))}),!r&&e&&e.subscribe(function(){return o.closeAll()})}return Object.defineProperty(n.prototype,"openDialogs",{get:function(){return this._parentDialog?this._parentDialog.openDialogs:this._openDialogsAtThisLevel},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"afterOpen",{get:function(){return this._parentDialog?this._parentDialog.afterOpen:this._afterOpenAtThisLevel},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_afterAllClosed",{get:function(){var n=this._parentDialog;return n?n._afterAllClosed:this._afterAllClosedAtThisLevel},enumerable:!0,configurable:!0}),n.prototype.open=function(n,t){var e=this;if((t=function(n){return Object(i.__assign)({},new oa,n)}(t)).id&&this.getDialogById(t.id))throw Error('Dialog with id "'+t.id+'" exists already. The dialog id must be unique.');var l=this._createOverlay(t),r=this._attachDialogContainer(l,t),o=this._attachDialogContent(n,r,l,t);return this.openDialogs.length||this._hideNonDialogContentFromAssistiveTechnology(),this.openDialogs.push(o),o.afterClosed().subscribe(function(){return e._removeOpenDialog(o)}),this.afterOpen.next(o),o},n.prototype.closeAll=function(){for(var n=this.openDialogs.length;n--;)this.openDialogs[n].close()},n.prototype.getDialogById=function(n){return this.openDialogs.find(function(t){return t.id===n})},n.prototype._createOverlay=function(n){var t=this._getOverlayConfig(n);return this._overlay.create(t)},n.prototype._getOverlayConfig=function(n){var t=new ci({positionStrategy:this._overlay.position().global(),scrollStrategy:this._scrollStrategy(),panelClass:n.panelClass,hasBackdrop:n.hasBackdrop,direction:n.direction,minWidth:n.minWidth,minHeight:n.minHeight,maxWidth:n.maxWidth,maxHeight:n.maxHeight});return n.backdropClass&&(t.backdropClass=n.backdropClass),t},n.prototype._attachDialogContainer=function(n,t){var e=new ei(aa,t.viewContainerRef),l=n.attach(e);return l.instance._config=t,l.instance},n.prototype._attachDialogContent=function(n,t,e,r){var i=new ca(e,t,r.id);if(r.hasBackdrop&&e.backdropClick().subscribe(function(){i.disableClose||i.close()}),e.keydownEvents().pipe(Ge(function(n){return 27===n.keyCode&&!i.disableClose})).subscribe(function(){return i.close()}),n instanceof l.O)t.attachTemplatePortal(new li(n,null,{$implicit:r.data,dialogRef:i}));else{var o=this._createInjector(r,i,t),s=t.attachComponentPortal(new ei(n,void 0,o));i.componentInstance=s.instance}return i.updateSize(r.width,r.height).updatePosition(r.position),i},n.prototype._createInjector=function(n,t,e){var l=n&&n.viewContainerRef&&n.viewContainerRef.injector,r=new WeakMap;return r.set(ca,t),r.set(aa,e),r.set(da,n.data),r.set(Dl,{value:n.direction,change:Object(Fe.a)()}),new ai(l||this._injector,r)},n.prototype._removeOpenDialog=function(n){var t=this.openDialogs.indexOf(n);t>-1&&(this.openDialogs.splice(t,1),this.openDialogs.length||(this._ariaHiddenElements.forEach(function(n,t){n?t.setAttribute("aria-hidden",n):t.removeAttribute("aria-hidden")}),this._ariaHiddenElements.clear(),this._afterAllClosed.next()))},n.prototype._hideNonDialogContentFromAssistiveTechnology=function(){var n=this._overlayContainer.getContainerElement();if(n.parentElement)for(var t=n.parentElement.children,e=t.length-1;e>-1;e--){var l=t[e];l===n||"SCRIPT"===l.nodeName||"STYLE"===l.nodeName||l.hasAttribute("aria-live")||(this._ariaHiddenElements.set(l,l.getAttribute("aria-hidden")),l.setAttribute("aria-hidden","true"))}},n}(),_a=function(){},ma=function(){},ga=function(){function n(n){this.callback=n}return n.prototype.call=function(n,t){return t.subscribe(new ya(n,this.callback))},n}(),ya=function(n){function t(t,e){n.call(this,t),this.add(new rl.a(e))}return Object(i.__extends)(t,n),t}(Be.a),ba=e("3a3m");function va(n,t){return function(n,t){return Object(nl.a)(n,t,1)}(n,t)(this)}var wa=function(){},xa=function(){},Ma=function(){function n(n){var t=this;this.normalizedNames=new Map,this.lazyUpdate=null,n?this.lazyInit="string"==typeof n?function(){t.headers=new Map,n.split("\n").forEach(function(n){var e=n.indexOf(":");if(e>0){var l=n.slice(0,e),r=l.toLowerCase(),i=n.slice(e+1).trim();t.maybeSetNormalizedName(l,r),t.headers.has(r)?t.headers.get(r).push(i):t.headers.set(r,[i])}})}:function(){t.headers=new Map,Object.keys(n).forEach(function(e){var l=n[e],r=e.toLowerCase();"string"==typeof l&&(l=[l]),l.length>0&&(t.headers.set(r,l),t.maybeSetNormalizedName(e,r))})}:this.headers=new Map}return n.prototype.has=function(n){return this.init(),this.headers.has(n.toLowerCase())},n.prototype.get=function(n){this.init();var t=this.headers.get(n.toLowerCase());return t&&t.length>0?t[0]:null},n.prototype.keys=function(){return this.init(),Array.from(this.normalizedNames.values())},n.prototype.getAll=function(n){return this.init(),this.headers.get(n.toLowerCase())||null},n.prototype.append=function(n,t){return this.clone({name:n,value:t,op:"a"})},n.prototype.set=function(n,t){return this.clone({name:n,value:t,op:"s"})},n.prototype.delete=function(n,t){return this.clone({name:n,value:t,op:"d"})},n.prototype.maybeSetNormalizedName=function(n,t){this.normalizedNames.has(t)||this.normalizedNames.set(t,n)},n.prototype.init=function(){var t=this;this.lazyInit&&(this.lazyInit instanceof n?this.copyFrom(this.lazyInit):this.lazyInit(),this.lazyInit=null,this.lazyUpdate&&(this.lazyUpdate.forEach(function(n){return t.applyUpdate(n)}),this.lazyUpdate=null))},n.prototype.copyFrom=function(n){var t=this;n.init(),Array.from(n.headers.keys()).forEach(function(e){t.headers.set(e,n.headers.get(e)),t.normalizedNames.set(e,n.normalizedNames.get(e))})},n.prototype.clone=function(t){var e=new n;return e.lazyInit=this.lazyInit&&this.lazyInit instanceof n?this.lazyInit:this,e.lazyUpdate=(this.lazyUpdate||[]).concat([t]),e},n.prototype.applyUpdate=function(n){var t=n.name.toLowerCase();switch(n.op){case"a":case"s":var e=n.value;if("string"==typeof e&&(e=[e]),0===e.length)return;this.maybeSetNormalizedName(n.name,t);var l=("a"===n.op?this.headers.get(t):void 0)||[];l.push.apply(l,e),this.headers.set(t,l);break;case"d":var r=n.value;if(r){var i=this.headers.get(t);if(!i)return;0===(i=i.filter(function(n){return-1===r.indexOf(n)})).length?(this.headers.delete(t),this.normalizedNames.delete(t)):this.headers.set(t,i)}else this.headers.delete(t),this.normalizedNames.delete(t)}},n.prototype.forEach=function(n){var t=this;this.init(),Array.from(this.normalizedNames.keys()).forEach(function(e){return n(t.normalizedNames.get(e),t.headers.get(e))})},n}(),ka=function(){function n(){}return n.prototype.encodeKey=function(n){return Ca(n)},n.prototype.encodeValue=function(n){return Ca(n)},n.prototype.decodeKey=function(n){return decodeURIComponent(n)},n.prototype.decodeValue=function(n){return decodeURIComponent(n)},n}();function Ca(n){return encodeURIComponent(n).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/gi,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%2B/gi,"+").replace(/%3D/gi,"=").replace(/%3F/gi,"?").replace(/%2F/gi,"/")}var Sa=function(){function n(n){void 0===n&&(n={});var t,e,l,r=this;if(this.updates=null,this.cloneFrom=null,this.encoder=n.encoder||new ka,n.fromString){if(n.fromObject)throw new Error("Cannot specify both fromString and fromObject.");this.map=(t=n.fromString,e=this.encoder,l=new Map,t.length>0&&t.split("&").forEach(function(n){var t=n.indexOf("="),r=-1==t?[e.decodeKey(n),""]:[e.decodeKey(n.slice(0,t)),e.decodeValue(n.slice(t+1))],i=r[0],o=r[1],s=l.get(i)||[];s.push(o),l.set(i,s)}),l)}else n.fromObject?(this.map=new Map,Object.keys(n.fromObject).forEach(function(t){var e=n.fromObject[t];r.map.set(t,Array.isArray(e)?e:[e])})):this.map=null}return n.prototype.has=function(n){return this.init(),this.map.has(n)},n.prototype.get=function(n){this.init();var t=this.map.get(n);return t?t[0]:null},n.prototype.getAll=function(n){return this.init(),this.map.get(n)||null},n.prototype.keys=function(){return this.init(),Array.from(this.map.keys())},n.prototype.append=function(n,t){return this.clone({param:n,value:t,op:"a"})},n.prototype.set=function(n,t){return this.clone({param:n,value:t,op:"s"})},n.prototype.delete=function(n,t){return this.clone({param:n,value:t,op:"d"})},n.prototype.toString=function(){var n=this;return this.init(),this.keys().map(function(t){var e=n.encoder.encodeKey(t);return n.map.get(t).map(function(t){return e+"="+n.encoder.encodeValue(t)}).join("&")}).join("&")},n.prototype.clone=function(t){var e=new n({encoder:this.encoder});return e.cloneFrom=this.cloneFrom||this,e.updates=(this.updates||[]).concat([t]),e},n.prototype.init=function(){var n=this;null===this.map&&(this.map=new Map),null!==this.cloneFrom&&(this.cloneFrom.init(),this.cloneFrom.keys().forEach(function(t){return n.map.set(t,n.cloneFrom.map.get(t))}),this.updates.forEach(function(t){switch(t.op){case"a":case"s":var e=("a"===t.op?n.map.get(t.param):void 0)||[];e.push(t.value),n.map.set(t.param,e);break;case"d":if(void 0===t.value){n.map.delete(t.param);break}var l=n.map.get(t.param)||[],r=l.indexOf(t.value);-1!==r&&l.splice(r,1),l.length>0?n.map.set(t.param,l):n.map.delete(t.param)}}),this.cloneFrom=null)},n}();function Oa(n){return"undefined"!=typeof ArrayBuffer&&n instanceof ArrayBuffer}function Ta(n){return"undefined"!=typeof Blob&&n instanceof Blob}function La(n){return"undefined"!=typeof FormData&&n instanceof FormData}var Pa=function(){function n(n,t,e,l){var r;if(this.url=t,this.body=null,this.reportProgress=!1,this.withCredentials=!1,this.responseType="json",this.method=n.toUpperCase(),function(n){switch(n){case"DELETE":case"GET":case"HEAD":case"OPTIONS":case"JSONP":return!1;default:return!0}}(this.method)||l?(this.body=void 0!==e?e:null,r=l):r=e,r&&(this.reportProgress=!!r.reportProgress,this.withCredentials=!!r.withCredentials,r.responseType&&(this.responseType=r.responseType),r.headers&&(this.headers=r.headers),r.params&&(this.params=r.params)),this.headers||(this.headers=new Ma),this.params){var i=this.params.toString();if(0===i.length)this.urlWithParams=t;else{var o=t.indexOf("?");this.urlWithParams=t+(-1===o?"?":o=200&&this.status<300}}(),Ea=function(n){function t(t){void 0===t&&(t={});var e=n.call(this,t)||this;return e.type=Da.ResponseHeader,e}return Object(i.__extends)(t,n),t.prototype.clone=function(n){return void 0===n&&(n={}),new t({headers:n.headers||this.headers,status:void 0!==n.status?n.status:this.status,statusText:n.statusText||this.statusText,url:n.url||this.url||void 0})},t}(Aa),Ya=function(n){function t(t){void 0===t&&(t={});var e=n.call(this,t)||this;return e.type=Da.Response,e.body=void 0!==t.body?t.body:null,e}return Object(i.__extends)(t,n),t.prototype.clone=function(n){return void 0===n&&(n={}),new t({body:void 0!==n.body?n.body:this.body,headers:n.headers||this.headers,status:void 0!==n.status?n.status:this.status,statusText:n.statusText||this.statusText,url:n.url||this.url||void 0})},t}(Aa),ja=function(n){function t(t){var e=n.call(this,t,0,"Unknown Error")||this;return e.name="HttpErrorResponse",e.ok=!1,e.message=e.status>=200&&e.status<300?"Http failure during parsing for "+(t.url||"(unknown url)"):"Http failure response for "+(t.url||"(unknown url)")+": "+t.status+" "+t.statusText,e.error=t.error||null,e}return Object(i.__extends)(t,n),t}(Aa);function Ia(n,t){return{body:t,headers:n.headers,observe:n.observe,params:n.params,reportProgress:n.reportProgress,responseType:n.responseType,withCredentials:n.withCredentials}}var Ra=function(){function n(n){this.handler=n}return n.prototype.request=function(n,t,e){var l,r=this;if(void 0===e&&(e={}),n instanceof Pa)l=n;else{var i;i=e.headers instanceof Ma?e.headers:new Ma(e.headers);var o=void 0;e.params&&(o=e.params instanceof Sa?e.params:new Sa({fromObject:e.params})),l=new Pa(n,t,void 0!==e.body?e.body:null,{headers:i,params:o,reportProgress:e.reportProgress,responseType:e.responseType||"json",withCredentials:e.withCredentials})}var s=va.call(Object(Fe.a)(l),function(n){return r.handler.handle(n)});if(n instanceof Pa||"events"===e.observe)return s;var a=Qe.call(s,function(n){return n instanceof Ya});switch(e.observe||"body"){case"body":switch(l.responseType){case"arraybuffer":return Pe.call(a,function(n){if(null!==n.body&&!(n.body instanceof ArrayBuffer))throw new Error("Response is not an ArrayBuffer.");return n.body});case"blob":return Pe.call(a,function(n){if(null!==n.body&&!(n.body instanceof Blob))throw new Error("Response is not a Blob.");return n.body});case"text":return Pe.call(a,function(n){if(null!==n.body&&"string"!=typeof n.body)throw new Error("Response is not a string.");return n.body});case"json":default:return Pe.call(a,function(n){return n.body})}case"response":return a;default:throw new Error("Unreachable: unhandled observe type "+e.observe+"}")}},n.prototype.delete=function(n,t){return void 0===t&&(t={}),this.request("DELETE",n,t)},n.prototype.get=function(n,t){return void 0===t&&(t={}),this.request("GET",n,t)},n.prototype.head=function(n,t){return void 0===t&&(t={}),this.request("HEAD",n,t)},n.prototype.jsonp=function(n,t){return this.request("JSONP",n,{params:(new Sa).append(t,"JSONP_CALLBACK"),observe:"body",responseType:"json"})},n.prototype.options=function(n,t){return void 0===t&&(t={}),this.request("OPTIONS",n,t)},n.prototype.patch=function(n,t,e){return void 0===e&&(e={}),this.request("PATCH",n,Ia(e,t))},n.prototype.post=function(n,t,e){return void 0===e&&(e={}),this.request("POST",n,Ia(e,t))},n.prototype.put=function(n,t,e){return void 0===e&&(e={}),this.request("PUT",n,Ia(e,t))},n}(),Ha=function(){function n(n,t){this.next=n,this.interceptor=t}return n.prototype.handle=function(n){return this.interceptor.intercept(n,this.next)},n}(),Na=new l.r("HTTP_INTERCEPTORS"),Fa=function(){function n(){}return n.prototype.intercept=function(n,t){return t.handle(n)},n}(),Ba=/^\)\]\}',?\n/,Va=function(){},Wa=function(){function n(){}return n.prototype.build=function(){return new XMLHttpRequest},n}(),za=function(){function n(n){this.xhrFactory=n}return n.prototype.handle=function(n){var t=this;if("JSONP"===n.method)throw new Error("Attempted to construct Jsonp request without JsonpClientModule installed.");return new o.a(function(e){var l=t.xhrFactory.build();if(l.open(n.method,n.urlWithParams),n.withCredentials&&(l.withCredentials=!0),n.headers.forEach(function(n,t){return l.setRequestHeader(n,t.join(","))}),n.headers.has("Accept")||l.setRequestHeader("Accept","application/json, text/plain, */*"),!n.headers.has("Content-Type")){var r=n.detectContentTypeHeader();null!==r&&l.setRequestHeader("Content-Type",r)}if(n.responseType){var i=n.responseType.toLowerCase();l.responseType="json"!==i?i:"text"}var o=n.serializeBody(),s=null,a=function(){if(null!==s)return s;var t=1223===l.status?204:l.status,e=l.statusText||"OK",r=new Ma(l.getAllResponseHeaders()),i=function(n){return"responseURL"in n&&n.responseURL?n.responseURL:/^X-Request-URL:/m.test(n.getAllResponseHeaders())?n.getResponseHeader("X-Request-URL"):null}(l)||n.url;return s=new Ea({headers:r,status:t,statusText:e,url:i})},u=function(){var t=a(),r=t.headers,i=t.status,o=t.statusText,s=t.url,u=null;204!==i&&(u="undefined"==typeof l.response?l.responseText:l.response),0===i&&(i=u?200:0);var c=i>=200&&i<300;if("json"===n.responseType&&"string"==typeof u){var d=u;u=u.replace(Ba,"");try{u=""!==u?JSON.parse(u):null}catch(n){u=d,c&&(c=!1,u={error:n,text:u})}}c?(e.next(new Ya({body:u,headers:r,status:i,statusText:o,url:s||void 0})),e.complete()):e.error(new ja({error:u,headers:r,status:i,statusText:o,url:s||void 0}))},c=function(n){var t=new ja({error:n,status:l.status||0,statusText:l.statusText||"Unknown Error"});e.error(t)},d=!1,h=function(t){d||(e.next(a()),d=!0);var r={type:Da.DownloadProgress,loaded:t.loaded};t.lengthComputable&&(r.total=t.total),"text"===n.responseType&&l.responseText&&(r.partialText=l.responseText),e.next(r)},p=function(n){var t={type:Da.UploadProgress,loaded:n.loaded};n.lengthComputable&&(t.total=n.total),e.next(t)};return l.addEventListener("load",u),l.addEventListener("error",c),n.reportProgress&&(l.addEventListener("progress",h),null!==o&&l.upload&&l.upload.addEventListener("progress",p)),l.send(o),e.next({type:Da.Sent}),function(){l.removeEventListener("error",c),l.removeEventListener("load",u),n.reportProgress&&(l.removeEventListener("progress",h),null!==o&&l.upload&&l.upload.removeEventListener("progress",p)),l.abort()}})},n}(),Ua=new l.r("XSRF_COOKIE_NAME"),Ga=new l.r("XSRF_HEADER_NAME"),qa=function(){},Ja=function(){function n(n,t,e){this.doc=n,this.platform=t,this.cookieName=e,this.lastCookieString="",this.lastToken=null,this.parseCount=0}return n.prototype.getToken=function(){if("server"===this.platform)return null;var n=this.doc.cookie||"";return n!==this.lastCookieString&&(this.parseCount++,this.lastToken=S(n,this.cookieName),this.lastCookieString=n),this.lastToken},n}(),Qa=function(){function n(n,t){this.tokenService=n,this.headerName=t}return n.prototype.intercept=function(n,t){var e=n.url.toLowerCase();if("GET"===n.method||"HEAD"===n.method||e.startsWith("http://")||e.startsWith("https://"))return t.handle(n);var l=this.tokenService.getToken();return null===l||n.headers.has(this.headerName)||(n=n.clone({headers:n.headers.set(this.headerName,l)})),t.handle(n)},n}();function Ka(n,t){return void 0===t&&(t=[]),t?t.reduceRight(function(n,t){return new Ha(n,t)},n):n}var Xa=function(){function n(){}return n.disable=function(){return{ngModule:n,providers:[{provide:Qa,useClass:Fa}]}},n.withOptions=function(t){return void 0===t&&(t={}),{ngModule:n,providers:[t.cookieName?{provide:Ua,useValue:t.cookieName}:[],t.headerName?{provide:Ga,useValue:t.headerName}:[]]}},n}(),Za=function(){};function $a(n){return Error('Unable to find icon with the name "'+n+'"')}function nu(n){return Error("The URL provided to MatIconRegistry was not trusted as a resource URL via Angular's DomSanitizer. Attempted URL was \""+n+'".')}var tu=function(n){this.url=n,this.svgElement=null},eu=function(){function n(n,t,e){this._httpClient=n,this._sanitizer=t,this._document=e,this._svgIconConfigs=new Map,this._iconSetConfigs=new Map,this._cachedIconsByUrl=new Map,this._inProgressUrlFetches=new Map,this._fontCssClassesByAlias=new Map,this._defaultFontSetClass="material-icons"}return n.prototype.addSvgIcon=function(n,t){return this.addSvgIconInNamespace("",n,t)},n.prototype.addSvgIconInNamespace=function(n,t,e){var l=iu(n,t);return this._svgIconConfigs.set(l,new tu(e)),this},n.prototype.addSvgIconSet=function(n){return this.addSvgIconSetInNamespace("",n)},n.prototype.addSvgIconSetInNamespace=function(n,t){var e=new tu(t),l=this._iconSetConfigs.get(n);return l?l.push(e):this._iconSetConfigs.set(n,[e]),this},n.prototype.registerFontClassAlias=function(n,t){return void 0===t&&(t=n),this._fontCssClassesByAlias.set(n,t),this},n.prototype.classNameForFontAlias=function(n){return this._fontCssClassesByAlias.get(n)||n},n.prototype.setDefaultFontSetClass=function(n){return this._defaultFontSetClass=n,this},n.prototype.getDefaultFontSetClass=function(){return this._defaultFontSetClass},n.prototype.getSvgIconFromUrl=function(n){var t=this,e=this._sanitizer.sanitize(l.K.RESOURCE_URL,n);if(!e)throw nu(n);var r=this._cachedIconsByUrl.get(e);return r?Object(Fe.a)(ru(r)):this._loadSvgIconFromConfig(new tu(n)).pipe(Ve(function(n){return t._cachedIconsByUrl.set(e,n)}),Object(Le.a)(function(n){return ru(n)}))},n.prototype.getNamedSvgIcon=function(n,t){void 0===t&&(t="");var e=iu(t,n),l=this._svgIconConfigs.get(e);if(l)return this._getSvgFromConfig(l);var r=this._iconSetConfigs.get(t);return r?this._getSvgFromIconSetConfigs(n,r):xe($a(e))},n.prototype._getSvgFromConfig=function(n){return n.svgElement?Object(Fe.a)(ru(n.svgElement)):this._loadSvgIconFromConfig(n).pipe(Ve(function(t){return n.svgElement=t}),Object(Le.a)(function(n){return ru(n)}))},n.prototype._getSvgFromIconSetConfigs=function(n,t){var e=this,r=this._extractIconWithNameFromAnySet(n,t);if(r)return Object(Fe.a)(r);var i=t.filter(function(n){return!n.svgElement}).map(function(n){return e._loadSvgIconSetFromConfig(n).pipe(Ce(function(t){var r=e._sanitizer.sanitize(l.K.RESOURCE_URL,n.url);return console.log("Loading icon set URL: "+r+" failed: "+t),Object(Fe.a)(null)}),Ve(function(t){t&&(n.svgElement=t)}))});return Ne(i).pipe(Object(Le.a)(function(){var l=e._extractIconWithNameFromAnySet(n,t);if(!l)throw $a(n);return l}))},n.prototype._extractIconWithNameFromAnySet=function(n,t){for(var e=t.length-1;e>=0;e--){var l=t[e];if(l.svgElement){var r=this._extractSvgIconFromSet(l.svgElement,n);if(r)return r}}return null},n.prototype._loadSvgIconFromConfig=function(n){var t=this;return this._fetchUrl(n.url).pipe(Object(Le.a)(function(n){return t._createSvgElementForSingleIcon(n)}))},n.prototype._loadSvgIconSetFromConfig=function(n){var t=this;return this._fetchUrl(n.url).pipe(Object(Le.a)(function(n){return t._svgElementFromString(n)}))},n.prototype._createSvgElementForSingleIcon=function(n){var t=this._svgElementFromString(n);return this._setSvgAttributes(t),t},n.prototype._extractSvgIconFromSet=function(n,t){var e=n.querySelector("#"+t);if(!e)return null;var l=e.cloneNode(!0);if(l.id="","svg"===l.nodeName.toLowerCase())return this._setSvgAttributes(l);if("symbol"===l.nodeName.toLowerCase())return this._setSvgAttributes(this._toSvgElement(l));var r=this._svgElementFromString("");return r.appendChild(l),this._setSvgAttributes(r)},n.prototype._svgElementFromString=function(n){if(this._document||"undefined"!=typeof document){var t=(this._document||document).createElement("DIV");t.innerHTML=n;var e=t.querySelector("svg");if(!e)throw Error(" tag not found");return e}throw new Error("MatIconRegistry could not resolve document.")},n.prototype._toSvgElement=function(n){for(var t=this._svgElementFromString(""),e=0;e-1)throw Error('Input type "'+this._type+"\" isn't supported by matInput.")},t.prototype._isNeverEmpty=function(){return this._neverEmptyInputTypes.indexOf(this._type)>-1},t.prototype._isBadInput=function(){var n=this._elementRef.nativeElement.validity;return n&&n.badInput},t.prototype._isTextarea=function(){var n=this._elementRef.nativeElement,t=this._platform.isBrowser?n.nodeName:n.name;return!!t&&"textarea"===t.toLowerCase()},Object.defineProperty(t.prototype,"empty",{get:function(){return!this._isNeverEmpty()&&!this._elementRef.nativeElement.value&&!this._isBadInput()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"shouldLabelFloat",{get:function(){return this.focused||!this.empty},enumerable:!0,configurable:!0}),t.prototype.setDescribedByIds=function(n){this._ariaDescribedby=n.join(" ")},t.prototype.onContainerClick=function(){this.focus()},t}(Ql(function(n,t,e,l){this._defaultErrorStateMatcher=n,this._parentForm=t,this._parentFormGroup=e,this.ngControl=l})),fu=function(){},_u=function(){},mu=function(){},gu=function(){},yu=function(){},bu=function(n){function t(t){var e=n.call(this)||this;return e._elementRef=t,e._hovered=new yl.a,e._highlighted=!1,e._triggersSubmenu=!1,e}return Object(i.__extends)(t,n),t.prototype.focus=function(){this._getHostElement().focus()},t.prototype.ngOnDestroy=function(){this._hovered.complete()},t.prototype._getTabIndex=function(){return this.disabled?"-1":"0"},t.prototype._getHostElement=function(){return this._elementRef.nativeElement},t.prototype._checkDisabled=function(n){this.disabled&&(n.preventDefault(),n.stopPropagation())},t.prototype._emitHoverEvent=function(){this.disabled||this._hovered.next(this)},t.prototype.getLabel=function(){var n=this._elementRef.nativeElement,t="";if(n.childNodes)for(var e=n.childNodes.length,l=0;l')}(),this._xPosition=n,this.setPositionClasses()},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"yPosition",{get:function(){return this._yPosition},set:function(n){"above"!==n&&"below"!==n&&function(){throw Error('y-position value must be either \'above\' or below\'.\n Example: ')}(),this._yPosition=n,this.setPositionClasses()},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"overlapTrigger",{get:function(){return this._overlapTrigger},set:function(n){this._overlapTrigger=El(n)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"panelClass",{set:function(n){n&&n.length&&(this._classList=n.split(" ").reduce(function(n,t){return n[t]=!0,n},{}),this._elementRef.nativeElement.className="",this.setPositionClasses())},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"classList",{get:function(){return this.panelClass},set:function(n){this.panelClass=n},enumerable:!0,configurable:!0}),n.prototype.ngAfterContentInit=function(){var n=this;this._keyManager=new Er(this.items).withWrap().withTypeAhead(),this._tabSubscription=this._keyManager.tabOut.subscribe(function(){return n.close.emit("keydown")})},n.prototype.ngOnDestroy=function(){this._tabSubscription.unsubscribe(),this.closed.complete()},n.prototype._hovered=function(){var n=this;return this.items?this.items.changes.pipe(Ss(this.items),Object(Ri.a)(function(n){return Jr.a.apply(void 0,n.map(function(n){return n._hovered}))})):this._ngZone.onStable.asObservable().pipe(Object(_r.a)(1),Object(Ri.a)(function(){return n._hovered()}))},n.prototype._handleKeydown=function(n){switch(n.keyCode){case 27:this.closed.emit("keydown"),n.stopPropagation();break;case 37:this.parentMenu&&"ltr"===this.direction&&this.closed.emit("keydown");break;case 39:this.parentMenu&&"rtl"===this.direction&&this.closed.emit("keydown");break;default:this._keyManager.onKeydown(n)}},n.prototype.focusFirstItem=function(){this._keyManager.setFirstItemActive()},n.prototype.resetActiveItem=function(){this._keyManager.setActiveItem(-1)},n.prototype.setPositionClasses=function(n,t){void 0===n&&(n=this.xPosition),void 0===t&&(t=this.yPosition),this._classList["mat-menu-before"]="before"===n,this._classList["mat-menu-after"]="after"===n,this._classList["mat-menu-above"]="above"===t,this._classList["mat-menu-below"]="below"===t},n.prototype.setElevation=function(n){var t="mat-elevation-z"+(2+n),e=Object.keys(this._classList).find(function(n){return n.startsWith("mat-elevation-z")});e&&e!==this._previousElevation||(this._previousElevation&&(this._classList[this._previousElevation]=!1),this._classList[t]=!0,this._previousElevation=t)},n.prototype._startAnimation=function(){this._panelAnimationState="enter-start"},n.prototype._resetAnimation=function(){this._panelAnimationState="void"},n.prototype._onAnimationDone=function(n){"enter-start"===n.toState&&(this._panelAnimationState="enter")},n}(),xu=new l.r("mat-menu-scroll-strategy");function Mu(n){return function(){return n.scrollStrategies.reposition()}}var ku=function(){function n(n,t,e,r,i,o,s){this._overlay=n,this._element=t,this._viewContainerRef=e,this._scrollStrategy=r,this._parentMenu=i,this._menuItemInstance=o,this._dir=s,this._overlayRef=null,this._menuOpen=!1,this._closeSubscription=rl.a.EMPTY,this._positionSubscription=rl.a.EMPTY,this._hoverSubscription=rl.a.EMPTY,this._openedByMouse=!1,this.menuOpened=new l.o,this.onMenuOpen=this.menuOpened,this.menuClosed=new l.o,this.onMenuClose=this.menuClosed,o&&(o._triggersSubmenu=this.triggersSubmenu())}return Object.defineProperty(n.prototype,"_deprecatedMatMenuTriggerFor",{get:function(){return this.menu},set:function(n){this.menu=n},enumerable:!0,configurable:!0}),n.prototype.ngAfterContentInit=function(){var n=this;this._checkMenu(),this.menu.close.subscribe(function(t){n._destroyMenu(),"click"===t&&n._parentMenu&&n._parentMenu.closed.emit(t)}),this.triggersSubmenu()&&(this._hoverSubscription=this._parentMenu._hovered().pipe(Ge(function(t){return t===n._menuItemInstance})).subscribe(function(){n._openedByMouse=!0,n.openMenu()}))},n.prototype.ngOnDestroy=function(){this._overlayRef&&(this._overlayRef.dispose(),this._overlayRef=null),this._cleanUpSubscriptions()},Object.defineProperty(n.prototype,"menuOpen",{get:function(){return this._menuOpen},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"dir",{get:function(){return this._dir&&"rtl"===this._dir.value?"rtl":"ltr"},enumerable:!0,configurable:!0}),n.prototype.triggersSubmenu=function(){return!(!this._menuItemInstance||!this._parentMenu)},n.prototype.toggleMenu=function(){return this._menuOpen?this.closeMenu():this.openMenu()},n.prototype.openMenu=function(){var n=this;this._menuOpen||(this._createOverlay().attach(this._portal),this._closeSubscription=this._menuClosingActions().subscribe(function(){return n.closeMenu()}),this._initMenu(),this.menu instanceof wu&&this.menu._startAnimation())},n.prototype.closeMenu=function(){this.menu.close.emit()},n.prototype.focus=function(){this._element.nativeElement.focus()},n.prototype._destroyMenu=function(){this._overlayRef&&this.menuOpen&&(this._resetMenu(),this._closeSubscription.unsubscribe(),this._overlayRef.detach(),this.menu instanceof wu&&this.menu._resetAnimation())},n.prototype._initMenu=function(){if(this.menu.parentMenu=this.triggersSubmenu()?this._parentMenu:void 0,this.menu.direction=this.dir,this._setMenuElevation(),this._setIsMenuOpen(!0),this._openedByMouse){var n=this._overlayRef.overlayElement.firstElementChild;n&&(this.menu.resetActiveItem(),n.focus())}else this.menu.focusFirstItem()},n.prototype._setMenuElevation=function(){if(this.menu.setElevation){for(var n=0,t=this.menu.parentMenu;t;)n++,t=t.parentMenu;this.menu.setElevation(n)}},n.prototype._resetMenu=function(){this._setIsMenuOpen(!1),this._openedByMouse&&this.triggersSubmenu()||this.focus(),this._openedByMouse=!1},n.prototype._setIsMenuOpen=function(n){this._menuOpen=n,this._menuOpen?this.menuOpened.emit():this.menuClosed.emit(),this.triggersSubmenu()&&(this._menuItemInstance._highlighted=n)},n.prototype._checkMenu=function(){this.menu||function(){throw Error('mat-menu-trigger: must pass in an mat-menu instance.\n\n Example:\n \n ')}()},n.prototype._createOverlay=function(){if(!this._overlayRef){this._portal=new li(this.menu.templateRef,this._viewContainerRef);var n=this._getOverlayConfig();this._subscribeToPositions(n.positionStrategy),this._overlayRef=this._overlay.create(n)}return this._overlayRef},n.prototype._getOverlayConfig=function(){return new ci({positionStrategy:this._getPosition(),hasBackdrop:!this.triggersSubmenu(),backdropClass:"cdk-overlay-transparent-backdrop",direction:this.dir,scrollStrategy:this._scrollStrategy()})},n.prototype._subscribeToPositions=function(n){var t=this;this._positionSubscription=n.onPositionChange.subscribe(function(n){t.menu.setPositionClasses("start"===n.connectionPair.overlayX?"after":"before","top"===n.connectionPair.overlayY?"below":"above")})},n.prototype._getPosition=function(){var n="before"===this.menu.xPosition?["end","start"]:["start","end"],t=n[0],e=n[1],l="above"===this.menu.yPosition?["bottom","top"]:["top","bottom"],r=l[0],i=l[1],o=[r,i],s=o[0],a=o[1],u=[t,e],c=u[0],d=u[1],h=0;return this.triggersSubmenu()?(d=t="before"===this.menu.xPosition?"start":"end",e=c="end"===t?"start":"end",h="bottom"===r?8:-8):this.menu.overlapTrigger||(s="top"===r?"bottom":"top",a="top"===i?"bottom":"top"),this._overlay.position().connectedTo(this._element,{originX:t,originY:s},{overlayX:c,overlayY:r}).withDirection(this.dir).withOffsetY(h).withFallbackPosition({originX:e,originY:s},{overlayX:d,overlayY:r}).withFallbackPosition({originX:t,originY:a},{overlayX:c,overlayY:i},void 0,-h).withFallbackPosition({originX:e,originY:a},{overlayX:d,overlayY:i},void 0,-h)},n.prototype._cleanUpSubscriptions=function(){this._closeSubscription.unsubscribe(),this._positionSubscription.unsubscribe(),this._hoverSubscription.unsubscribe()},n.prototype._menuClosingActions=function(){var n=this,t=this._overlayRef.backdropClick(),e=this._overlayRef.detachments(),l=this._parentMenu?this._parentMenu.close:Object(Fe.a)(),r=this._parentMenu?this._parentMenu._hovered().pipe(Ge(function(t){return t!==n._menuItemInstance}),Ge(function(){return n._menuOpen})):Object(Fe.a)();return Object(Jr.a)(t,l,r,e)},n.prototype._handleMousedown=function(n){(function(n){return 0===n.buttons})(n)||(this._openedByMouse=!0,this.triggersSubmenu()&&n.preventDefault())},n.prototype._handleKeydown=function(n){var t=n.keyCode;this.triggersSubmenu()&&(39===t&&"ltr"===this.dir||37===t&&"rtl"===this.dir)&&this.openMenu()},n.prototype._handleClick=function(n){this.triggersSubmenu()?(n.stopPropagation(),this.openMenu()):this.toggleMenu()},n}(),Cu=function(){},Su=0,Ou=new l.r("mat-select-scroll-strategy");function Tu(n){return function(){return n.scrollStrategies.reposition()}}var Lu=function(){},Pu=function(n){function t(t,e,r,i,o,s,a,u,c,d,h,p){var f=n.call(this,o,i,a,u,d)||this;return f._viewportRuler=t,f._changeDetectorRef=e,f._ngZone=r,f._dir=s,f._parentFormField=c,f.ngControl=d,f._scrollStrategyFactory=p,f._panelOpen=!1,f._required=!1,f._scrollTop=0,f._multiple=!1,f._compareWith=function(n,t){return n===t},f._uid="mat-select-"+Su++,f._destroy=new yl.a,f._triggerFontSize=0,f._onChange=function(){},f._onTouched=function(){},f._optionIds="",f._transformOrigin="top",f._panelDoneAnimating=!1,f._scrollStrategy=f._scrollStrategyFactory(),f._offsetY=0,f._positions=[{originX:"start",originY:"top",overlayX:"start",overlayY:"top"},{originX:"start",originY:"bottom",overlayX:"start",overlayY:"bottom"}],f.focused=!1,f.controlType="mat-select",f.ariaLabel="",f.optionSelectionChanges=ia(function(){return f.options?Jr.a.apply(void 0,f.options.map(function(n){return n.onSelectionChange})):f._ngZone.onStable.asObservable().pipe(Object(_r.a)(1),Object(Ri.a)(function(){return f.optionSelectionChanges}))}),f.openedChange=new l.o,f.onOpen=f._openedStream,f.onClose=f._closedStream,f.selectionChange=new l.o,f.change=f.selectionChange,f.valueChange=new l.o,f.ngControl&&(f.ngControl.valueAccessor=f),f.tabIndex=parseInt(h)||0,f.id=f.id,f}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"placeholder",{get:function(){return this._placeholder},set:function(n){this._placeholder=n,this.stateChanges.next()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"required",{get:function(){return this._required},set:function(n){this._required=El(n),this.stateChanges.next()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"multiple",{get:function(){return this._multiple},set:function(n){if(this._selectionModel)throw Error("Cannot change `multiple` mode of select after initialization.");this._multiple=El(n)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"compareWith",{get:function(){return this._compareWith},set:function(n){if("function"!=typeof n)throw Error("`compareWith` must be a function.");this._compareWith=n,this._selectionModel&&this._initializeSelection()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"value",{get:function(){return this._value},set:function(n){n!==this._value&&(this.writeValue(n),this._value=n)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"id",{get:function(){return this._id},set:function(n){this._id=n||this._uid,this.stateChanges.next()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_openedStream",{get:function(){return this.openedChange.pipe(Ge(function(n){return n}),Object(Le.a)(function(){}))},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_closedStream",{get:function(){return this.openedChange.pipe(Ge(function(n){return!n}),Object(Le.a)(function(){}))},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){this._selectionModel=new zs(this.multiple,void 0,!1),this.stateChanges.next()},t.prototype.ngAfterContentInit=function(){var n=this;this._initKeyManager(),this.options.changes.pipe(Ss(null),au(this._destroy)).subscribe(function(){n._resetOptions(),n._initializeSelection()})},t.prototype.ngDoCheck=function(){this.ngControl&&this.updateErrorState()},t.prototype.ngOnChanges=function(n){n.disabled&&this.stateChanges.next()},t.prototype.ngOnDestroy=function(){this._destroy.next(),this._destroy.complete(),this.stateChanges.complete()},t.prototype.toggle=function(){this.panelOpen?this.close():this.open()},t.prototype.open=function(){var n=this;!this.disabled&&this.options&&this.options.length&&(this._triggerRect=this.trigger.nativeElement.getBoundingClientRect(),this._triggerFontSize=parseInt(getComputedStyle(this.trigger.nativeElement)["font-size"]),this._panelOpen=!0,this._calculateOverlayPosition(),this._highlightCorrectOption(),this._changeDetectorRef.markForCheck(),this._ngZone.onStable.asObservable().pipe(Object(_r.a)(1)).subscribe(function(){n._triggerFontSize&&n.overlayDir.overlayRef&&n.overlayDir.overlayRef.overlayElement&&(n.overlayDir.overlayRef.overlayElement.style.fontSize=n._triggerFontSize+"px")}))},t.prototype.close=function(){this._panelOpen&&(this._panelOpen=!1,this._changeDetectorRef.markForCheck(),this._onTouched(),this.focus())},t.prototype.writeValue=function(n){this.options&&this._setSelectionByValue(n)},t.prototype.registerOnChange=function(n){this._onChange=n},t.prototype.registerOnTouched=function(n){this._onTouched=n},t.prototype.setDisabledState=function(n){this.disabled=n,this._changeDetectorRef.markForCheck(),this.stateChanges.next()},Object.defineProperty(t.prototype,"panelOpen",{get:function(){return this._panelOpen},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"selected",{get:function(){return this.multiple?this._selectionModel.selected:this._selectionModel.selected[0]},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"triggerValue",{get:function(){if(this.empty)return"";if(this._multiple){var n=this._selectionModel.selected.map(function(n){return n.viewValue});return this._isRtl()&&n.reverse(),n.join(", ")}return this._selectionModel.selected[0].viewValue},enumerable:!0,configurable:!0}),t.prototype._isRtl=function(){return!!this._dir&&"rtl"===this._dir.value},t.prototype._handleKeydown=function(n){this.disabled||(this.panelOpen?this._handleOpenKeydown(n):this._handleClosedKeydown(n))},t.prototype._handleClosedKeydown=function(n){var t=n.keyCode;13===t||32===t||(this.multiple||n.altKey)&&(40===t||38===t)?(n.preventDefault(),this.open()):this.multiple||this._keyManager.onKeydown(n)},t.prototype._handleOpenKeydown=function(n){var t=n.keyCode;if(36===t||35===t)n.preventDefault(),36===t?this._keyManager.setFirstItemActive():this._keyManager.setLastItemActive();else if(13!==t&&32!==t||!this._keyManager.activeItem){var e=40===t||38===t,l=this._keyManager.activeItemIndex;this._keyManager.onKeydown(n),this._multiple&&e&&n.shiftKey&&this._keyManager.activeItem&&this._keyManager.activeItemIndex!==l&&this._keyManager.activeItem._selectViaInteraction()}else n.preventDefault(),this._keyManager.activeItem._selectViaInteraction()},t.prototype._onPanelDone=function(){this.panelOpen?(this._scrollTop=0,this.openedChange.emit(!0)):(this.openedChange.emit(!1),this._panelDoneAnimating=!1,this.overlayDir.offsetX=0,this._changeDetectorRef.markForCheck())},t.prototype._onFadeInDone=function(){this._panelDoneAnimating=this.panelOpen,this._changeDetectorRef.markForCheck()},t.prototype._onFocus=function(){this.disabled||(this.focused=!0,this.stateChanges.next())},t.prototype._onBlur=function(){this.disabled||this.panelOpen||(this.focused=!1,this._onTouched(),this._changeDetectorRef.markForCheck(),this.stateChanges.next())},t.prototype._onAttached=function(){var n=this;this.overlayDir.positionChange.pipe(Object(_r.a)(1)).subscribe(function(){n._changeDetectorRef.detectChanges(),n._calculateOverlayOffsetX(),n.panel.nativeElement.scrollTop=n._scrollTop})},t.prototype._getPanelTheme=function(){return this._parentFormField?"mat-"+this._parentFormField.color:""},Object.defineProperty(t.prototype,"empty",{get:function(){return!this._selectionModel||this._selectionModel.isEmpty()},enumerable:!0,configurable:!0}),t.prototype._initializeSelection=function(){var n=this;Promise.resolve().then(function(){n._setSelectionByValue(n.ngControl?n.ngControl.value:n._value)})},t.prototype._setSelectionByValue=function(n,t){var e=this;if(void 0===t&&(t=!1),this.multiple&&n){if(!Array.isArray(n))throw Error("Value must be an array in multiple-selection mode.");this._clearSelection(),n.forEach(function(n){return e._selectValue(n,t)}),this._sortValues()}else{this._clearSelection();var l=this._selectValue(n,t);l&&this._keyManager.setActiveItem(this.options.toArray().indexOf(l))}this._changeDetectorRef.markForCheck()},t.prototype._selectValue=function(n,t){var e=this;void 0===t&&(t=!1);var r=this.options.find(function(t){try{return null!=t.value&&e._compareWith(t.value,n)}catch(n){return Object(l.Y)()&&console.warn(n),!1}});return r&&(t?r._selectViaInteraction():r.select(),this._selectionModel.select(r),this.stateChanges.next()),r},t.prototype._clearSelection=function(n){this._selectionModel.clear(),this.options.forEach(function(t){t!==n&&t.deselect()}),this.stateChanges.next()},t.prototype._initKeyManager=function(){var n=this;this._keyManager=new Sr(this.options).withTypeAhead(),this._keyManager.tabOut.pipe(au(this._destroy)).subscribe(function(){return n.close()}),this._keyManager.change.pipe(au(this._destroy)).subscribe(function(){n._panelOpen&&n.panel?n._scrollActiveOptionIntoView():n._panelOpen||n.multiple||!n._keyManager.activeItem||n._keyManager.activeItem._selectViaInteraction()})},t.prototype._resetOptions=function(){var n=this;this.optionSelectionChanges.pipe(au(Object(Jr.a)(this._destroy,this.options.changes)),Ge(function(n){return n.isUserInput})).subscribe(function(t){n._onSelect(t.source),n.multiple||n.close()}),this._setOptionIds()},t.prototype._onSelect=function(n){var t=this._selectionModel.isSelected(n);this.multiple?(this._selectionModel.toggle(n),this.stateChanges.next(),t?n.deselect():n.select(),this._keyManager.setActiveItem(this._getOptionIndex(n)),this._sortValues()):(this._clearSelection(null==n.value?void 0:n),null==n.value?this._propagateChanges(n.value):(this._selectionModel.select(n),this.stateChanges.next())),t!==this._selectionModel.isSelected(n)&&this._propagateChanges()},t.prototype._sortValues=function(){var n=this;this._multiple&&(this._selectionModel.clear(),this.options.forEach(function(t){t.selected&&n._selectionModel.select(t)}),this.stateChanges.next())},t.prototype._propagateChanges=function(n){var t;t=this.multiple?this.selected.map(function(n){return n.value}):this.selected?this.selected.value:n,this._value=t,this.valueChange.emit(t),this._onChange(t),this.selectionChange.emit(new function(n,t){this.source=n,this.value=t}(this,t)),this._changeDetectorRef.markForCheck()},t.prototype._setOptionIds=function(){this._optionIds=this.options.map(function(n){return n.id}).join(" ")},t.prototype._highlightCorrectOption=function(){this._keyManager&&(this.empty?this._keyManager.setFirstItemActive():this._keyManager.setActiveItem(this._getOptionIndex(this._selectionModel.selected[0])))},t.prototype._scrollActiveOptionIntoView=function(){var n=this._getItemHeight(),t=this._keyManager.activeItemIndex||0,e=(t+pr.countGroupLabelsBeforeOption(t,this.options,this.optionGroups))*n,l=this.panel.nativeElement.scrollTop;el+256&&(this.panel.nativeElement.scrollTop=Math.max(0,e-256+n))},t.prototype.focus=function(){this._elementRef.nativeElement.focus()},t.prototype._getOptionIndex=function(n){return this.options.reduce(function(t,e,l){return void 0===t?n===e?l:void 0:t},void 0)},t.prototype._calculateOverlayPosition=function(){var n=this._getItemHeight(),t=this._getItemCount(),e=Math.min(t*n,256),l=t*n-e,r=this.empty?0:this._getOptionIndex(this._selectionModel.selected[0]);r+=pr.countGroupLabelsBeforeOption(r,this.options,this.optionGroups);var i=e/2;this._scrollTop=this._calculateOverlayScroll(r,i,l),this._offsetY=this._calculateOverlayOffsetY(r,i,l),this._checkOverlayWithinViewport(l)},t.prototype._calculateOverlayScroll=function(n,t,e){var l=this._getItemHeight();return Math.min(Math.max(0,l*n-t+l/2),e)},Object.defineProperty(t.prototype,"_ariaLabel",{get:function(){return this.ariaLabelledby?null:this.ariaLabel||this.placeholder},enumerable:!0,configurable:!0}),t.prototype._getAriaActiveDescendant=function(){return this.panelOpen&&this._keyManager&&this._keyManager.activeItem?this._keyManager.activeItem.id:null},t.prototype._calculateOverlayOffsetX=function(){var n,t=this.overlayDir.overlayRef.overlayElement.getBoundingClientRect(),e=this._viewportRuler.getViewportSize(),l=this._isRtl(),r=this.multiple?60:32;if(this.multiple)n=44;else{var i=this._selectionModel.selected[0]||this.options.first;n=i&&i.group?32:16}l||(n*=-1);var o=0-(t.left+n-(l?r:0)),s=t.right+n-e.width+(l?0:r);o>0?n+=o+8:s>0&&(n-=s+8),this.overlayDir.offsetX=n,this.overlayDir.overlayRef.updatePosition()},t.prototype._calculateOverlayOffsetY=function(n,t,e){var l=this._getItemHeight(),r=(l-this._triggerRect.height)/2,i=Math.floor(256/l);return-1*(0===this._scrollTop?n*l:this._scrollTop===e?(n-(this._getItemCount()-i))*l+(l-(this._getItemCount()*l-256)%l):t-l/2)-r},t.prototype._checkOverlayWithinViewport=function(n){var t=this._getItemHeight(),e=this._viewportRuler.getViewportSize(),l=this._triggerRect.top-8,r=e.height-this._triggerRect.bottom-8,i=Math.abs(this._offsetY),o=Math.min(this._getItemCount()*t,256)-i-this._triggerRect.height;o>r?this._adjustPanelUp(o,r):i>l?this._adjustPanelDown(i,l,n):this._transformOrigin=this._getOriginBasedOnOption()},t.prototype._adjustPanelUp=function(n,t){var e=Math.round(n-t);this._scrollTop-=e,this._offsetY-=e,this._transformOrigin=this._getOriginBasedOnOption(),this._scrollTop<=0&&(this._scrollTop=0,this._offsetY=0,this._transformOrigin="50% bottom 0px")},t.prototype._adjustPanelDown=function(n,t,e){var l=Math.round(n-t);if(this._scrollTop+=l,this._offsetY+=l,this._transformOrigin=this._getOriginBasedOnOption(),this._scrollTop>=e)return this._scrollTop=e,this._offsetY=0,void(this._transformOrigin="50% top 0px")},t.prototype._getOriginBasedOnOption=function(){var n=this._getItemHeight(),t=(n-this._triggerRect.height)/2;return"50% "+(Math.abs(this._offsetY)-t+n/2)+"px 0px"},t.prototype._getItemCount=function(){return this.options.length+this.optionGroups.length},t.prototype._getItemHeight=function(){return 3*this._triggerFontSize},t.prototype.setDescribedByIds=function(n){this._ariaDescribedby=n.join(" ")},t.prototype.onContainerClick=function(){this.focus(),this.open()},Object.defineProperty(t.prototype,"shouldLabelFloat",{get:function(){return this._panelOpen||!this.empty},enumerable:!0,configurable:!0}),t}(ql(Jl(Ul(Ql(function(n,t,e,l,r){this._elementRef=n,this._defaultErrorStateMatcher=t,this._parentForm=e,this._parentFormGroup=l,this.ngControl=r}))))),Du=function(){},Au=20;function Eu(n){return Error('Tooltip position "'+n+'" is invalid.')}var Yu=new l.r("mat-tooltip-scroll-strategy");function ju(n){return function(){return n.scrollStrategies.reposition({scrollThrottle:Au})}}var Iu=function(){function n(n,t,e,l,r,i,o,s,a,u){var c=this;this._overlay=n,this._elementRef=t,this._scrollDispatcher=e,this._viewContainerRef=l,this._ngZone=r,this._platform=i,this._ariaDescriber=o,this._focusMonitor=s,this._scrollStrategy=a,this._dir=u,this._position="below",this._disabled=!1,this.showDelay=0,this.hideDelay=0,this._message="",this._manualListeners=new Map;var d=t.nativeElement;i.IOS?"INPUT"!==d.nodeName&&"TEXTAREA"!==d.nodeName||(d.style.webkitUserSelect=d.style.userSelect=""):(this._manualListeners.set("mouseenter",function(){return c.show()}),this._manualListeners.set("mouseleave",function(){return c.hide()}),this._manualListeners.forEach(function(n,e){return t.nativeElement.addEventListener(e,n)})),s.monitor(d,!1).subscribe(function(n){n?"program"!==n&&r.run(function(){return c.show()}):r.run(function(){return c.hide(0)})})}return Object.defineProperty(n.prototype,"position",{get:function(){return this._position},set:function(n){n!==this._position&&(this._position=n,this._tooltipInstance&&this._disposeTooltip())},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"disabled",{get:function(){return this._disabled},set:function(n){this._disabled=El(n),this._disabled&&this.hide(0)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_positionDeprecated",{get:function(){return this._position},set:function(n){this._position=n},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"message",{get:function(){return this._message},set:function(n){this._ariaDescriber.removeDescription(this._elementRef.nativeElement,this._message),this._message=null!=n?(""+n).trim():"",!this._message&&this._isTooltipVisible()?this.hide(0):(this._updateTooltipMessage(),this._ariaDescriber.describe(this._elementRef.nativeElement,this.message))},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"tooltipClass",{get:function(){return this._tooltipClass},set:function(n){this._tooltipClass=n,this._tooltipInstance&&this._setTooltipClass(this._tooltipClass)},enumerable:!0,configurable:!0}),n.prototype.ngOnDestroy=function(){var n=this;this._tooltipInstance&&this._disposeTooltip(),this._platform.IOS||(this._manualListeners.forEach(function(t,e){n._elementRef.nativeElement.removeEventListener(e,t)}),this._manualListeners.clear()),this._ariaDescriber.removeDescription(this._elementRef.nativeElement,this.message),this._focusMonitor.stopMonitoring(this._elementRef.nativeElement)},n.prototype.show=function(n){void 0===n&&(n=this.showDelay),!this.disabled&&this.message&&(this._tooltipInstance||this._createTooltip(),this._setTooltipClass(this._tooltipClass),this._updateTooltipMessage(),this._tooltipInstance.show(this._position,n))},n.prototype.hide=function(n){void 0===n&&(n=this.hideDelay),this._tooltipInstance&&this._tooltipInstance.hide(n)},n.prototype.toggle=function(){this._isTooltipVisible()?this.hide():this.show()},n.prototype._isTooltipVisible=function(){return!!this._tooltipInstance&&this._tooltipInstance.isVisible()},n.prototype._handleKeydown=function(n){this._isTooltipVisible()&&27===n.keyCode&&(n.stopPropagation(),this.hide(0))},n.prototype._createTooltip=function(){var n=this,t=this._createOverlay(),e=new ei(Ru,this._viewContainerRef);this._tooltipInstance=t.attach(e).instance,Object(Jr.a)(this._tooltipInstance.afterHidden(),t.detachments()).subscribe(function(){n._tooltipInstance&&n._disposeTooltip()})},n.prototype._createOverlay=function(){var n=this,t=this._getOrigin(),e=this._getOverlayPosition(),l=this._overlay.position().connectedTo(this._elementRef,t.main,e.main).withFallbackPosition(t.fallback,e.fallback),r=this._scrollDispatcher.getAncestorScrollContainers(this._elementRef);l.withScrollableContainers(r),l.onPositionChange.subscribe(function(t){n._tooltipInstance&&(t.scrollableViewProperties.isOverlayClipped&&n._tooltipInstance.isVisible()?n._ngZone.run(function(){return n.hide(0)}):n._tooltipInstance._setTransformOrigin(t.connectionPair))});var i=new ci({direction:this._dir?this._dir.value:"ltr",positionStrategy:l,panelClass:"mat-tooltip-panel",scrollStrategy:this._scrollStrategy()});return this._overlayRef=this._overlay.create(i),this._overlayRef},n.prototype._disposeTooltip=function(){this._overlayRef&&(this._overlayRef.dispose(),this._overlayRef=null),this._tooltipInstance=null},n.prototype._getOrigin=function(){var n,t=!this._dir||"ltr"==this._dir.value;if("above"==this.position||"below"==this.position)n={originX:"center",originY:"above"==this.position?"top":"bottom"};else if("left"==this.position||"before"==this.position&&t||"after"==this.position&&!t)n={originX:"start",originY:"center"};else{if(!("right"==this.position||"after"==this.position&&t||"before"==this.position&&!t))throw Eu(this.position);n={originX:"end",originY:"center"}}var e=this._invertPosition(n.originX,n.originY);return{main:n,fallback:{originX:e.x,originY:e.y}}},n.prototype._getOverlayPosition=function(){var n,t=!this._dir||"ltr"==this._dir.value;if("above"==this.position)n={overlayX:"center",overlayY:"bottom"};else if("below"==this.position)n={overlayX:"center",overlayY:"top"};else if("left"==this.position||"before"==this.position&&t||"after"==this.position&&!t)n={overlayX:"end",overlayY:"center"};else{if(!("right"==this.position||"after"==this.position&&t||"before"==this.position&&!t))throw Eu(this.position);n={overlayX:"start",overlayY:"center"}}var e=this._invertPosition(n.overlayX,n.overlayY);return{main:n,fallback:{overlayX:e.x,overlayY:e.y}}},n.prototype._updateTooltipMessage=function(){var n=this;this._tooltipInstance&&(this._tooltipInstance.message=this.message,this._tooltipInstance._markForCheck(),this._ngZone.onMicrotaskEmpty.asObservable().pipe(Object(_r.a)(1)).subscribe(function(){n._tooltipInstance&&n._overlayRef.updatePosition()}))},n.prototype._setTooltipClass=function(n){this._tooltipInstance&&(this._tooltipInstance.tooltipClass=n,this._tooltipInstance._markForCheck())},n.prototype._invertPosition=function(n,t){return"above"===this.position||"below"===this.position?"top"===t?t="bottom":"bottom"===t&&(t="top"):"end"===n?n="start":"start"===n&&(n="end"),{x:n,y:t}},n}(),Ru=function(){function n(n){this._changeDetectorRef=n,this._visibility="initial",this._closeOnInteraction=!1,this._transformOrigin="bottom",this._onHide=new yl.a}return n.prototype.show=function(n,t){var e=this;this._hideTimeoutId&&clearTimeout(this._hideTimeoutId),this._closeOnInteraction=!0,this._position=n,this._showTimeoutId=setTimeout(function(){e._visibility="visible",e._markForCheck()},t)},n.prototype.hide=function(n){var t=this;this._showTimeoutId&&clearTimeout(this._showTimeoutId),this._hideTimeoutId=setTimeout(function(){t._visibility="hidden",t._markForCheck()},n)},n.prototype.afterHidden=function(){return this._onHide.asObservable()},n.prototype.isVisible=function(){return"visible"===this._visibility},n.prototype._setTransformOrigin=function(n){var t="X"==("above"===this._position||"below"===this._position?"Y":"X")?n.overlayX:n.overlayY;if("top"===t||"bottom"===t)this._transformOrigin=t;else if("start"===t)this._transformOrigin="left";else{if("end"!==t)throw Eu(this._position);this._transformOrigin="right"}},n.prototype._animationStart=function(){this._closeOnInteraction=!1},n.prototype._animationDone=function(n){var t=this,e=n.toState;"hidden"!==e||this.isVisible()||this._onHide.next(),"visible"!==e&&"hidden"!==e||Promise.resolve().then(function(){return t._closeOnInteraction=!0})},n.prototype._handleBodyInteraction=function(){this._closeOnInteraction&&this.hide(0)},n.prototype._markForCheck=function(){this._changeDetectorRef.markForCheck()},n}(),Hu=function(){},Nu=function(){function n(){this.color="primary",this._value=0,this._bufferValue=0,this.mode="determinate"}return Object.defineProperty(n.prototype,"value",{get:function(){return this._value},set:function(n){this._value=Fu(n||0)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"bufferValue",{get:function(){return this._bufferValue},set:function(n){this._bufferValue=Fu(n||0)},enumerable:!0,configurable:!0}),n.prototype._primaryTransform=function(){return{transform:"scaleX("+this.value/100+")"}},n.prototype._bufferTransform=function(){if("buffer"==this.mode)return{transform:"scaleX("+this.bufferValue/100+")"}},n}();function Fu(n,t,e){return void 0===t&&(t=0),void 0===e&&(e=100),Math.max(t,Math.min(e,n))}var Bu=function(){},Vu=100,Wu=function(n){function t(t,e,l){var r=n.call(this,t,e,l)||this;return r.mode="indeterminate",r}return Object(i.__extends)(t,n),t}(function(n){function t(t,e,l){var r=n.call(this,t)||this;return r._elementRef=t,r._document=l,r._value=0,r._fallbackAnimation=!1,r._elementSize=Vu,r._diameter=Vu,r.mode="determinate",r._fallbackAnimation=e.EDGE||e.TRIDENT,t.nativeElement.classList.add("mat-progress-spinner-indeterminate"+(r._fallbackAnimation?"-fallback":"")+"-animation"),r}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"diameter",{get:function(){return this._diameter},set:function(n){this._diameter=Yl(n),this._fallbackAnimation||t.diameters.has(this._diameter)||this._attachStyleNode()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"strokeWidth",{get:function(){return this._strokeWidth||this.diameter/10},set:function(n){this._strokeWidth=Yl(n)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"value",{get:function(){return"determinate"===this.mode?this._value:0},set:function(n){this._value=Math.max(0,Math.min(100,Yl(n)))},enumerable:!0,configurable:!0}),t.prototype.ngOnChanges=function(n){(n.strokeWidth||n.diameter)&&(this._elementSize=this._diameter+Math.max(this.strokeWidth-10,0))},Object.defineProperty(t.prototype,"_circleRadius",{get:function(){return(this.diameter-10)/2},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_viewBox",{get:function(){var n=2*this._circleRadius+this.strokeWidth;return"0 0 "+n+" "+n},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_strokeCircumference",{get:function(){return 2*Math.PI*this._circleRadius},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_strokeDashOffset",{get:function(){return"determinate"===this.mode?this._strokeCircumference*(100-this._value)/100:this._fallbackAnimation&&"indeterminate"===this.mode?.2*this._strokeCircumference:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_circleStrokeWidth",{get:function(){return this.strokeWidth/this._elementSize*100},enumerable:!0,configurable:!0}),t.prototype._attachStyleNode=function(){var n=t.styleTag;n||(n=this._document.createElement("style"),this._document.head.appendChild(n),t.styleTag=n),n&&n.sheet&&n.sheet.insertRule(this._getAnimationText(),0),t.diameters.add(this.diameter)},t.prototype._getAnimationText=function(){return"\n @keyframes mat-progress-spinner-stroke-rotate-DIAMETER {\n 0% { stroke-dashoffset: START_VALUE; transform: rotate(0); }\n 12.5% { stroke-dashoffset: END_VALUE; transform: rotate(0); }\n 12.51% { stroke-dashoffset: END_VALUE; transform: rotateX(180deg) rotate(72.5deg); }\n 25% { stroke-dashoffset: START_VALUE; transform: rotateX(180deg) rotate(72.5deg); }\n\n 25.1% { stroke-dashoffset: START_VALUE; transform: rotate(270deg); }\n 37.5% { stroke-dashoffset: END_VALUE; transform: rotate(270deg); }\n 37.51% { stroke-dashoffset: END_VALUE; transform: rotateX(180deg) rotate(161.5deg); }\n 50% { stroke-dashoffset: START_VALUE; transform: rotateX(180deg) rotate(161.5deg); }\n\n 50.01% { stroke-dashoffset: START_VALUE; transform: rotate(180deg); }\n 62.5% { stroke-dashoffset: END_VALUE; transform: rotate(180deg); }\n 62.51% { stroke-dashoffset: END_VALUE; transform: rotateX(180deg) rotate(251.5deg); }\n 75% { stroke-dashoffset: START_VALUE; transform: rotateX(180deg) rotate(251.5deg); }\n\n 75.01% { stroke-dashoffset: START_VALUE; transform: rotate(90deg); }\n 87.5% { stroke-dashoffset: END_VALUE; transform: rotate(90deg); }\n 87.51% { stroke-dashoffset: END_VALUE; transform: rotateX(180deg) rotate(341.5deg); }\n 100% { stroke-dashoffset: START_VALUE; transform: rotateX(180deg) rotate(341.5deg); }\n }\n".replace(/START_VALUE/g,""+.95*this._strokeCircumference).replace(/END_VALUE/g,""+.2*this._strokeCircumference).replace(/DIAMETER/g,""+this.diameter)},t.diameters=new Set([Vu]),t.styleTag=null,t}(Gl(function(n){this._elementRef=n},"primary"))),zu=function(){},Uu=function(n){function t(t,e,r,i,o){var s=n.call(this,t)||this;return s._focusMonitor=e,s._changeDetectorRef=r,s._dir=i,s._invert=!1,s._max=100,s._min=0,s._step=1,s._thumbLabel=!1,s._tickInterval=0,s._value=null,s._vertical=!1,s.change=new l.o,s.input=new l.o,s.onTouched=function(){},s._percent=0,s._isSliding=!1,s._isActive=!1,s._tickIntervalPercent=0,s._sliderDimensions=null,s._controlValueAccessorChangeFn=function(){},s._dirChangeSubscription=rl.a.EMPTY,s.tabIndex=parseInt(o)||0,s}return Object(i.__extends)(t,n),Object.defineProperty(t.prototype,"invert",{get:function(){return this._invert},set:function(n){this._invert=El(n)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"max",{get:function(){return this._max},set:function(n){this._max=Yl(n,this._max),this._percent=this._calculatePercentage(this._value),this._changeDetectorRef.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"min",{get:function(){return this._min},set:function(n){this._min=Yl(n,this._min),null===this._value&&(this.value=this._min),this._percent=this._calculatePercentage(this._value),this._changeDetectorRef.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"step",{get:function(){return this._step},set:function(n){this._step=Yl(n,this._step),this._step%1!=0&&(this._roundLabelTo=this._step.toString().split(".").pop().length),this._changeDetectorRef.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"thumbLabel",{get:function(){return this._thumbLabel},set:function(n){this._thumbLabel=El(n)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_thumbLabelDeprecated",{get:function(){return this._thumbLabel},set:function(n){this._thumbLabel=n},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"tickInterval",{get:function(){return this._tickInterval},set:function(n){this._tickInterval="auto"===n?"auto":"number"==typeof n||"string"==typeof n?Yl(n,this._tickInterval):0},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_tickIntervalDeprecated",{get:function(){return this.tickInterval},set:function(n){this.tickInterval=n},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"value",{get:function(){return null===this._value&&(this.value=this._min),this._value},set:function(n){n!==this._value&&(this._value=Yl(n,this._value||0),this._percent=this._calculatePercentage(this._value),this._changeDetectorRef.markForCheck())},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"vertical",{get:function(){return this._vertical},set:function(n){this._vertical=El(n)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"displayValue",{get:function(){return this._roundLabelTo&&this.value&&this.value%1!=0?this.value.toFixed(this._roundLabelTo):this.value||0},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"percent",{get:function(){return this._clamp(this._percent)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_invertAxis",{get:function(){return this.vertical?!this.invert:this.invert},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_isMinValue",{get:function(){return 0===this.percent},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_thumbGap",{get:function(){return this.disabled?7:this._isMinValue&&!this.thumbLabel?this._isActive?10:7:0},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_trackBackgroundStyles",{get:function(){var n=this.vertical?"Y":"X";return{transform:"translate"+n+"("+(this._invertMouseCoords?"-":"")+this._thumbGap+"px) scale"+n+"("+(1-this.percent)+")"}},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_trackFillStyles",{get:function(){var n=this.vertical?"Y":"X";return{transform:"translate"+n+"("+(this._invertMouseCoords?"":"-")+this._thumbGap+"px) scale"+n+"("+this.percent+")"}},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_ticksContainerStyles",{get:function(){return{transform:"translate"+(this.vertical?"Y":"X")+"("+(this.vertical||"rtl"!=this._direction?"-":"")+this._tickIntervalPercent/2*100+"%)"}},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_ticksStyles",{get:function(){var n=100*this._tickIntervalPercent,t={backgroundSize:this.vertical?"2px "+n+"%":n+"% 2px",transform:"translateZ(0) translate"+(this.vertical?"Y":"X")+"("+(this.vertical||"rtl"!=this._direction?"":"-")+n/2+"%)"+(this.vertical||"rtl"!=this._direction?"":" rotate(180deg)")};return this._isMinValue&&this._thumbGap&&(t["padding"+(this.vertical?this._invertAxis?"Bottom":"Top":this._invertAxis?"Right":"Left")]=this._thumbGap+"px"),t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_thumbContainerStyles",{get:function(){return{transform:"translate"+(this.vertical?"Y":"X")+"(-"+100*(("rtl"!=this._direction||this.vertical?this._invertAxis:!this._invertAxis)?this.percent:1-this.percent)+"%)"}},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_invertMouseCoords",{get:function(){return"rtl"!=this._direction||this.vertical?this._invertAxis:!this._invertAxis},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_direction",{get:function(){return this._dir&&"rtl"==this._dir.value?"rtl":"ltr"},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){var n=this;this._focusMonitor.monitor(this._elementRef.nativeElement,!0).subscribe(function(t){n._isActive=!!t&&"keyboard"!==t,n._changeDetectorRef.detectChanges()}),this._dir&&(this._dirChangeSubscription=this._dir.change.subscribe(function(){n._changeDetectorRef.markForCheck()}))},t.prototype.ngOnDestroy=function(){this._focusMonitor.stopMonitoring(this._elementRef.nativeElement),this._dirChangeSubscription.unsubscribe()},t.prototype._onMouseenter=function(){this.disabled||(this._sliderDimensions=this._getSliderDimensions(),this._updateTickIntervalPercent())},t.prototype._onClick=function(n){if(!this.disabled){var t=this.value;this._isSliding=!1,this._focusHostElement(),this._updateValueFromPosition({x:n.clientX,y:n.clientY}),t!=this.value&&(this._emitInputEvent(),this._emitChangeEvent())}},t.prototype._onSlide=function(n){if(!this.disabled){this._isSliding||this._onSlideStart(null),n.preventDefault();var t=this.value;this._updateValueFromPosition({x:n.center.x,y:n.center.y}),t!=this.value&&this._emitInputEvent()}},t.prototype._onSlideStart=function(n){this.disabled||this._isSliding||(this._onMouseenter(),this._isSliding=!0,this._focusHostElement(),this._valueOnSlideStart=this.value,n&&(this._updateValueFromPosition({x:n.center.x,y:n.center.y}),n.preventDefault()))},t.prototype._onSlideEnd=function(){this._isSliding=!1,this._valueOnSlideStart!=this.value&&this._emitChangeEvent(),this._valueOnSlideStart=null},t.prototype._onFocus=function(){this._sliderDimensions=this._getSliderDimensions(),this._updateTickIntervalPercent()},t.prototype._onBlur=function(){this.onTouched()},t.prototype._onKeydown=function(n){if(!this.disabled){var t=this.value;switch(n.keyCode){case 33:this._increment(10);break;case 34:this._increment(-10);break;case 35:this.value=this.max;break;case 36:this.value=this.min;break;case 37:this._increment("rtl"==this._direction?1:-1);break;case 38:this._increment(1);break;case 39:this._increment("rtl"==this._direction?-1:1);break;case 40:this._increment(-1);break;default:return}t!=this.value&&(this._emitInputEvent(),this._emitChangeEvent()),this._isSliding=!0,n.preventDefault()}},t.prototype._onKeyup=function(){this._isSliding=!1},t.prototype._increment=function(n){this.value=this._clamp((this.value||0)+this.step*n,this.min,this.max)},t.prototype._updateValueFromPosition=function(n){if(this._sliderDimensions){var t=this._clamp(((this.vertical?n.y:n.x)-(this.vertical?this._sliderDimensions.top:this._sliderDimensions.left))/(this.vertical?this._sliderDimensions.height:this._sliderDimensions.width));this._invertMouseCoords&&(t=1-t);var e=this._calculateValue(t),l=Math.round((e-this.min)/this.step)*this.step+this.min;this.value=this._clamp(l,this.min,this.max)}},t.prototype._emitChangeEvent=function(){this._controlValueAccessorChangeFn(this.value),this.change.emit(this._createChangeEvent())},t.prototype._emitInputEvent=function(){this.input.emit(this._createChangeEvent())},t.prototype._updateTickIntervalPercent=function(){if(this.tickInterval&&this._sliderDimensions)if("auto"==this.tickInterval){var n=this.vertical?this._sliderDimensions.height:this._sliderDimensions.width,t=Math.ceil(30/(n*this.step/(this.max-this.min)));this._tickIntervalPercent=t*this.step/n}else this._tickIntervalPercent=this.tickInterval*this.step/(this.max-this.min)},t.prototype._createChangeEvent=function(n){void 0===n&&(n=this.value);var t=new function(){};return t.source=this,t.value=n,t},t.prototype._calculatePercentage=function(n){return((n||0)-this.min)/(this.max-this.min)},t.prototype._calculateValue=function(n){return this.min+n*(this.max-this.min)},t.prototype._clamp=function(n,t,e){return void 0===t&&(t=0),void 0===e&&(e=1),Math.max(t,Math.min(n,e))},t.prototype._getSliderDimensions=function(){return this._sliderWrapper?this._sliderWrapper.nativeElement.getBoundingClientRect():null},t.prototype._focusHostElement=function(){this._elementRef.nativeElement.focus()},t.prototype.writeValue=function(n){this.value=n},t.prototype.registerOnChange=function(n){this._controlValueAccessorChangeFn=n},t.prototype.registerOnTouched=function(n){this.onTouched=n},t.prototype.setDisabledState=function(n){this.disabled=n},t}(Jl(Gl(Ul(function(n){this._elementRef=n}),"accent"))),Gu=function(){},qu=function(){},Ju=function(n){function t(t,e){var l=n.call(this,t)||this;return l._platform=e,l}return Object(i.__extends)(t,n),t.prototype.ngAfterViewInit=function(){var n=this;Object(l.Y)()&&this._platform.isBrowser&&(this._checkToolbarMixedModes(),this._toolbarRows.changes.subscribe(function(){return n._checkToolbarMixedModes()}))},t.prototype._checkToolbarMixedModes=function(){this._toolbarRows.length&&[].slice.call(this._elementRef.nativeElement.childNodes).filter(function(n){return!(n.classList&&n.classList.contains("mat-toolbar-row"))}).filter(function(n){return n.nodeType!==Node.COMMENT_NODE}).some(function(n){return n.textContent.trim()})&&function(){throw Error("MatToolbar: Attempting to combine different toolbar modes. Either specify multiple `` elements explicitly or just place content inside of a `` for a single row.")}()},t}(Gl(function(n){this._elementRef=n})),Qu=function(){},Ku=function(n){return n[n.RequestingCurrentPin=0]="RequestingCurrentPin",n[n.RequestingNewPin=1]="RequestingNewPin",n[n.ConfirmingNewPin=2]="ConfirmingNewPin",n}({}),Xu=function(){function n(n){this.dialog=n}return Object.defineProperty(n.prototype,"requestPinComponent",{set:function(n){this.requestPinComponentInternal=n},enumerable:!0,configurable:!0}),n.prototype.resetValues=function(){this.changingPin=!1,this.signingTx=!1},n.prototype.requestPin=function(){var n=this;return this.dialog.open(this.requestPinComponentInternal,{width:"350px",autoFocus:!1,data:{changingPin:this.changingPin,changePinState:this.changePinState,signingTx:this.signingTx}}).afterClosed().map(function(t){return n.changingPin&&(n.changePinState===Ku.RequestingCurrentPin?n.changePinState=Ku.RequestingNewPin:n.changePinState===Ku.RequestingNewPin&&(n.changePinState=Ku.ConfirmingNewPin)),t})},n}(),Zu=function(){function n(n){this.dialog=n}return Object.defineProperty(n.prototype,"requestWordComponent",{set:function(n){this.requestWordComponentInternal=n},enumerable:!0,configurable:!0}),n.prototype.requestWord=function(){return this.dialog.open(this.requestWordComponentInternal,{width:"350px",data:{isForHwWallet:!0,wordNumber:0,restoringSoftwareWallet:!1}}).afterClosed().map(function(n){return n})},n}(),$u=function(n){function t(){var t=n.call(this,"Timeout has occurred");this.name=t.name="TimeoutError",this.stack=t.stack,this.message=t.message}return Object(i.__extends)(t,n),t}(Error),nc=function(){function n(n,t,e,l){this.waitFor=n,this.absoluteTimeout=t,this.scheduler=e,this.errorInstance=l}return n.prototype.call=function(n,t){return t.subscribe(new tc(n,this.absoluteTimeout,this.waitFor,this.scheduler,this.errorInstance))},n}(),tc=function(n){function t(t,e,l,r,i){n.call(this,t),this.absoluteTimeout=e,this.waitFor=l,this.scheduler=r,this.errorInstance=i,this.action=null,this.scheduleTimeout()}return Object(i.__extends)(t,n),t.dispatchTimeout=function(n){n.error(n.errorInstance)},t.prototype.scheduleTimeout=function(){var n=this.action;n?this.action=n.schedule(this,this.waitFor):this.add(this.action=this.scheduler.schedule(t.dispatchTimeout,this.waitFor,this))},t.prototype._next=function(t){this.absoluteTimeout||this.scheduleTimeout(),n.prototype._next.call(this,t)},t.prototype._unsubscribe=function(){this.action=null,this.scheduler=null,this.errorInstance=null},t}(Be.a);o.a.prototype.timeout=function(n,t){return void 0===t&&(t=sl),function(n,t){void 0===t&&(t=sl);var e=ul(n),l=e?+n-t.now():Math.abs(n);return function(n){return n.lift(new nc(l,e,t,new $u))}}(n,t)(this)};var ec,lc=function(){function n(n,t,e,l,r){this.http=n,this.apiService=t,this.hwWalletPinService=e,this.hwWalletSeedWordService=l,this.ngZone=r,this.url="http://127.0.0.1:9510/api/v1",this.hwConnected=!1,this.connectionEventSubject=new Tl(!1),this.disconnectedChecks=0,this.maxFastDisconnectedChecks=32}return Object.defineProperty(n.prototype,"connectionEvent",{get:function(){return this.connectionEventSubject.asObservable()},enumerable:!0,configurable:!0}),n.prototype.get=function(n){return this.checkResponse(this.http.get(this.url+n,this.returnRequestOptions()),n.includes("/available"))},n.prototype.post=function(n,t){return void 0===t&&(t={}),this.checkResponse(this.http.post(this.url+n,JSON.stringify(t),this.returnRequestOptions()))},n.prototype.put=function(n,t,e,l){return void 0===t&&(t=null),void 0===e&&(e=!1),void 0===l&&(l=!1),this.checkResponse(this.http.put(this.url+n,t,this.returnRequestOptions(e)),!1,l)},n.prototype.delete=function(n){return this.checkResponse(this.http.delete(this.url+n,this.returnRequestOptions()))},n.prototype.checkResponse=function(t,e,l){var r=this;return void 0===e&&(e=!1),void 0===l&&(l=!1),t.timeout(l?3e4:55e3).flatMap(function(t){var l=t.json();return l.data&&l.data.length&&(l.data=1===l.data.length?l.data[0]:l.data),e?r.ngZone.run(function(){return r.updateHwConnected(!!l.data)}):r.updateHwConnected(!0),"string"==typeof l.data&&-1!==l.data.indexOf("PinMatrixRequest")?r.hwWalletPinService.requestPin().flatMap(function(t){return t?r.post("/intermediate/pin_matrix",{pin:t}):r.put("/cancel").map(function(){return n.errorCancelled})}):"string"==typeof l.data&&-1!==l.data.indexOf("WordRequest")?r.hwWalletSeedWordService.requestWord().flatMap(function(t){return t?r.post("/intermediate/word",{word:t}):r.put("/cancel").map(function(){return n.errorCancelled})}):"string"==typeof l.data&&-1!==l.data.indexOf("ButtonRequest")?r.post("/intermediate/button"):o.a.of(l)}).catch(function(t){if(t&&t.name&&"TimeoutError"===t.name)return r.put("/cancel").subscribe(),o.a.throw({_body:n.errorTimeout});if(t&&t._body){var e=void 0;if("string"==typeof t._body)e=t._body;else if(t._body.error)e=t._body.error;else try{e=JSON.parse(t._body).error}catch(n){}if(e)return r.apiService.processConnectionError({_body:e},!0)}return o.a.throw({_body:n.errorConnectingWithTheDaemon})})},n.prototype.returnRequestOptions=function(n){void 0===n&&(n=!1);var t=new ae;return t.headers=new qt,n||t.headers.append("Content-Type","application/json"),t},n.prototype.checkHw=function(n){var t=this;this.checkHwSubscription&&this.checkHwSubscription.unsubscribe(),this.ngZone.runOutsideAngular(function(){t.checkHwSubscription=o.a.of(1).delay(n?t.hwConnected||t.disconnectedChecksthis.total&&this.destination.next(n)},t}(Be.a);e("lAP5"),e("T1Dh");var vc=function(){function n(n){this.predicate=n}return n.prototype.call=function(n,t){return t.subscribe(new wc(n,this.predicate))},n}(),wc=function(n){function t(t,e){n.call(this,t),this.predicate=e,this.index=0}return Object(i.__extends)(t,n),t.prototype._next=function(n){var t,e=this.destination;try{t=this.predicate(n,this.index++)}catch(n){return void e.error(n)}this.nextOrComplete(n,t)},t.prototype.nextOrComplete=function(n,t){var e=this.destination;Boolean(t)?e.next(n):e.complete()},t}(Be.a);e("DDro");var xc=e("Uter"),Mc=function(){function n(){}return n.encode=function(n,t,e,l,r){var i=this;if(void 0===r&&(r=0),n.length!==e.length)throw new Error("Invalid number of signatures.");var o=this.encodeSizeTransaction(n,t,e).toNumber(),s=new ArrayBuffer(o),a=new DataView(s),u=0;if(a.setUint32(u,o,!0),a.setUint8(u+=4,r),u+=1,this.convertToBytes(l).forEach(function(n){a.setUint8(u,n),u+=1}),e.length>65535)throw new Error("Too many signatures.");if(a.setUint32(u,e.length,!0),u+=4,e.forEach(function(n){i.convertToBytes(n).forEach(function(n){a.setUint8(u,n),u+=1})}),n.length>65535)throw new Error("Too many inputs.");if(a.setUint32(u,n.length,!0),u+=4,n.forEach(function(n){i.convertToBytes(n.hashIn).forEach(function(n){a.setUint8(u,n),u+=1})}),t.length>65535)throw new Error("Too many outputs.");a.setUint32(u,t.length,!0),u+=4;var c=xc("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");return t.forEach(function(n){var t=c.decode(n.address);a.setUint8(u,t[20]),u+=1;for(var e=0;e<20;e++)a.setUint8(u,t[e]),u+=1;u=i.setUint64(a,u,new Ee.a(n.coin)),u=i.setUint64(a,u,new Ee.a(n.hour))}),this.convertToHex(s)},n.encodeSizeTransaction=function(n,t,e){var l=new Ee.a(0);return(l=(l=(l=(l=(l=(l=(l=(l=l.plus(4)).plus(1)).plus(32)).plus(4)).plus(new Ee.a(65).multipliedBy(e.length))).plus(4)).plus(new Ee.a(32).multipliedBy(n.length))).plus(4)).plus(new Ee.a(37).multipliedBy(t.length))},n.setUint64=function(n,t,e){var l=e.toString(16);l.length%2!=0&&(l="0"+l);for(var r=this.convertToBytes(l),i=r.length-1;i>=0;i--)n.setUint8(t,r[i]),t+=1;for(i=0;i<8-r.length;i++)n.setUint8(t,0),t+=1;return t},n.convertToBytes=function(n){if(n.length%2!=0)throw new Error("Invalid hex string.");for(var t=[],e=0;es[0]?i=!0:a===s[0]&&(u>s[1]?i=!0:u===s[1]&&(Ll.useHwWalletDaemon?l.rawResponse.fw_patch:l.rawResponse.patchVersion)>=s[2]&&(i=!0))}}var c=[],d=!1;Ll.useHwWalletDaemon?(l.rawResponse.needs_backup&&(c.push(Cc.NeedsBackup),d=!0),l.rawResponse.pin_protection||(c.push(Cc.NeedsPin),d=!0)):(l.rawResponse.needsBackup&&(c.push(Cc.NeedsBackup),d=!0),l.rawResponse.pinProtection||(c.push(Cc.NeedsPin),d=!0)),r?i||(c.push(Cc.OutdatedFirmware),d=!0):c.push(Cc.FirmwareVersionNotVerified);var h=!1;if(n){var p=l.rawResponse.label?l.rawResponse.label:l.rawResponse.deviceId?l.rawResponse.deviceId:l.rawResponse.device_id;n.label!==p&&(n.label=p,h=!0),n.hasHwSecurityWarnings=d,e.saveHardwareWallets()}return{features:l.rawResponse,securityWarnings:c,walletNameUpdated:h}}):null},n.prototype.deleteHardwareWallet=function(n){var t=this;return n.isHardware?this.wallets.first().map(function(e){var l=e.indexOf(n);return-1!==l&&(e.splice(l,1),t.saveHardwareWallets(),t.refreshBalances(),!0)}):null},n.prototype.folder=function(){return this.apiService.get("wallets/folderName").map(function(n){return n.address})},n.prototype.outputs=function(){var n=this;return this.addressesAsString().first().filter(function(n){return!!n}).flatMap(function(t){return n.apiService.post("outputs",{addrs:t})})},n.prototype.outputsWithWallets=function(){return o.a.zip(this.all(),this.outputs(),function(n,t){return n.map(function(n){return n.addresses=n.addresses.map(function(n){return n.outputs=t.head_outputs.filter(function(t){return t.address===n.address}),n}),n})})},n.prototype.pendingTransactions=function(){return this.pendingTxs.asObservable()},n.prototype.refreshBalances=function(){var n=this;this.wallets.first().subscribe(function(t){o.a.forkJoin(t.map(function(t){return n.retrieveWalletBalance(t).map(function(n){return t.coins=n.coins,t.hours=n.hours,t.addresses.map(function(t){var e=n.addresses.find(function(n){return n.address===t.address});t.coins=e.coins,t.hours=e.hours}),t})})).subscribe(function(t){return n.wallets.next(t)})})},n.prototype.renameWallet=function(n,t){var e=this;return this.apiService.post("wallet/update",{id:n.filename,label:t}).do(function(){n.label=t,e.updateWallet(n)})},n.prototype.toggleEncryption=function(n,t){var e=this;return this.apiService.postWalletToggleEncryption(n,t).do(function(t){n.encrypted=t.meta.encrypted,e.updateWallet(t)})},n.prototype.resetPassword=function(n,t,e){var l=this,r=new Object;return r.id=n.filename,r.seed=t,e&&(r.password=e),this.apiService.post("wallet/recover",r,{},!0).do(function(t){n.encrypted=t.data.meta.encrypted,l.updateWallet(t.data)})},n.prototype.getWalletSeed=function(n,t){return this.apiService.getWalletSeed(n,t)},n.prototype.createTransaction=function(n,t,e,l,r,i,o,s){var a=this;e&&(t=null),n.isHardware&&!i&&(i=n.addresses[0].address);var u=!!n.isHardware,c={hours_selection:r,wallet_id:n?n.filename:null,password:o,addresses:t,unspents:e,to:l,change_address:i};u||(c.unsigned=s);var d,h=this.apiService.post(u?"transaction":"wallet/transaction",c,{json:!0},u).map(function(t){var e=u?t.data:t;if(n.isHardware){if(e.transaction.inputs.length>8)throw new Error(a.translate.instant("hardware-wallet.errors.too-many-inputs-outputs"));if(e.transaction.outputs.length>8)throw new Error(a.translate.instant("hardware-wallet.errors.too-many-inputs-outputs"))}return kc({},e.transaction,{hoursBurned:new Ae.BigNumber(e.transaction.fee),encoded:e.encoded_transaction,innerHash:e.transaction.inner_hash})});return n.isHardware&&!s&&(h=h.flatMap(function(t){return d=t,a.signTransaction(n,null,t)}).map(function(n){return d.encoded=n.encoded,d})),h},n.prototype.signTransaction=function(n,t,e){if(n.isHardware){var l=[],r=[],i=[],s=[];if(e.outputs.forEach(function(n){l.push({address:n.address,coins:parseInt(new Ae.BigNumber(n.coins).multipliedBy(1e6).toFixed(0),10),hours:parseInt(n.hours,10)}),i.push({address:n.address,coin:parseInt(new Ae.BigNumber(n.coins).multipliedBy(1e6).toFixed(0),10),hour:parseInt(n.hours,10)})}),i.length>1)for(var a=l.length-1;a>=0;a--)if(i[a].address===n.addresses[0].address){i[a].address_index=0;break}var u=new Map;return n.addresses.forEach(function(n,t){return u.set(n.address,t)}),e.inputs.forEach(function(n){r.push({hash:n.uxid,secret:"",address:n.address,address_index:u.get(n.address),calculated_hours:parseInt(n.calculated_hours,10),coins:parseInt(n.coins,10)}),s.push({hashIn:n.uxid,index:u.get(n.address)})}),this.hwWalletService.signTransaction(s,i).flatMap(function(n){var t=Mc.encode(s,i,n.rawResponse,e.innerHash);return o.a.of(kc({},e,{encoded:t}))})}return this.apiService.post("wallet/transaction/sign",{wallet_id:n?n.filename:null,password:t,encoded_transaction:e.encoded},{json:!0},!0).map(function(n){return kc({},n.data.transaction,{hoursBurned:new Ae.BigNumber(n.data.transaction.fee),encoded:n.data.encoded_transaction})})},n.prototype.injectTransaction=function(n,t){var e=this;return this.apiService.post("injectTransaction",{rawtx:n},{json:!0}).flatMap(function(n){return setTimeout(function(){return e.startDataRefreshSubscription()},32),t?e.storageService.store(ec.NOTES,n,t).retryWhen(function(n){return n.delay(1e3).take(3).concat(o.a.throw(-1))}).catch(function(n){return-1===n?o.a.of(-1):n}).map(function(n){return-1!==n}):o.a.of(!1)})},n.prototype.transaction=function(n){var t=this;return this.apiService.get("transaction",{txid:n}).flatMap(function(n){return n.txn.inputs&&!n.txn.inputs.length?o.a.of(n):o.a.forkJoin(n.txn.inputs.map(function(n){return t.retrieveInputAddress(n).map(function(n){return n.owner_address})})).map(function(t){return n.txn.inputs=t,n})})},n.prototype.transactions=function(){var n,t,e=this,l=new Map;return this.wallets.first().flatMap(function(t){return n=t,e.allAddresses().first()}).flatMap(function(n){return e.addresses=n,n.map(function(n){return l.set(n.address,!0)}),e.apiService.getTransactions(n)}).flatMap(function(n){return t=n,e.storageService.get(ec.NOTES,null)}).map(function(e){var r=new Map;return Object.keys(e.data).forEach(function(n){r.set(n,e.data[n])}),t.sort(function(n,t){return t.timestamp-n.timestamp}).map(function(t){var e=t.inputs.some(function(n){return l.has(n.owner)}),i=new Map;if(t.balance=new Ae.BigNumber("0"),t.hoursSent=new Ae.BigNumber("0"),e){var o=new Map;if(t.inputs.map(function(t){l.has(t.owner)&&(i.set(t.owner,!0),n.map(function(n){n.addresses.some(function(n){return n.address===t.owner})&&n.addresses.map(function(n){return o.set(n.address,!0)})}))}),t.outputs.map(function(n){o.has(n.dst)||(t.balance=t.balance.minus(n.coins),t.hoursSent=t.hoursSent.plus(n.hours))}),t.balance.isEqualTo(0)){t.coinsMovedInternally=!0;var s=new Map;t.inputs.map(function(n){s.set(n.owner,!0)}),t.outputs.map(function(n){s.has(n.dst)||(i.set(n.dst,!0),t.balance=t.balance.plus(n.coins),t.hoursSent=t.hoursSent.plus(n.hours))})}}else t.outputs.map(function(n){l.has(n.dst)&&(i.set(n.dst,!0),t.balance=t.balance.plus(n.coins),t.hoursSent=t.hoursSent.plus(n.hours))});i.forEach(function(n,e){t.addresses.push(e)});var a=new Ae.BigNumber("0");t.inputs.map(function(n){return a=a.plus(new Ae.BigNumber(n.calculated_hours))});var u=new Ae.BigNumber("0");t.outputs.map(function(n){return u=u.plus(new Ae.BigNumber(n.hours))}),t.hoursBurned=a.minus(u);var c=r.get(t.txid);return c&&(t.note=c),t})})},n.prototype.startDataRefreshSubscription=function(){var n=this;this.dataRefreshSubscription&&this.dataRefreshSubscription.unsubscribe(),this.ngZone.runOutsideAngular(function(){n.dataRefreshSubscription=o.a.timer(0,1e4).subscribe(function(){return n.ngZone.run(function(){n.refreshBalances(),n.refreshPendingTransactions()})})})},n.prototype.saveHardwareWallets=function(){var n=this;this.wallets.first().subscribe(function(t){var e=[];t.map(function(t){t.isHardware&&e.push(n.createHardwareWalletData(t.label,t.addresses.map(function(n){return{address:n.address,confirmed:n.confirmed}}),t.hasHwSecurityWarnings,t.stopShowingHwSecurityPopup))}),n.hwWalletService.saveWalletsData(JSON.stringify(e)),n.wallets.next(t)})},n.prototype.verifyAddress=function(n){return this.apiService.post("address/verify",{address:n},{},!0).pipe(Object(Le.a)(function(){return!0}),Ce(function(){return o.a.of(!1)}))},n.prototype.getWalletUnspentOutputs=function(n){var t=n.addresses.map(function(n){return n.address}).join(",");return this.getOutputs(t)},n.prototype.createHardwareWalletData=function(n,t,e,l){return{label:n,filename:"",hasHwSecurityWarnings:e,stopShowingHwSecurityPopup:l,coins:null,hours:null,addresses:t.map(function(n){return{address:n.address,coins:null,hours:null,confirmed:n.confirmed}}),encrypted:!1,isHardware:!0}},n.prototype.loadData=function(){var n=this,t=[],e=[];this.apiService.getWallets().first().flatMap(function(l){return e=l,n.hwWalletService.hwWalletCompatibilityActivated?n.loadHardwareWallets(t):o.a.of(null)}).subscribe(function(){t=t.concat(e),n.wallets.next(t)},function(){return n.initialLoadFailed.next(!0)})},n.prototype.loadHardwareWallets=function(n){return this.hwWalletService.getSavedWalletsData().map(function(t){return t&&JSON.parse(t).map(function(t){return n.push(t)}),null})},n.prototype.retrieveInputAddress=function(n){return this.apiService.get("uxout",{uxid:n})},n.prototype.retrieveWalletBalance=function(n){var t;if(n.isHardware){var e=n.addresses.map(function(n){return n.address}).join(",");t=this.apiService.post("balance",{addrs:e})}else t=this.apiService.get("wallet/balance",{id:n.filename});return t.map(function(n){return{coins:new Ae.BigNumber(n.confirmed.coins).dividedBy(1e6),hours:new Ae.BigNumber(n.confirmed.hours),addresses:Object.keys(n.addresses).map(function(t){return{address:t,coins:new Ae.BigNumber(n.addresses[t].confirmed.coins).dividedBy(1e6),hours:new Ae.BigNumber(n.addresses[t].confirmed.hours)}})}})},n.prototype.updateWallet=function(n){var t=this;this.wallets.first().subscribe(function(e){e[e.findIndex(function(t){return t.filename===n.filename})]=n,t.wallets.next(e)})},n.prototype.refreshPendingTransactions=function(){var n=this;this.apiService.get("pendingTxs",{verbose:!0}).flatMap(function(t){return 0===t.length?o.a.of({user:[],all:[]}):n.wallets.first().map(function(n){var e=new Set;return n.forEach(function(n){n.addresses.forEach(function(n){return e.add(n.address)})}),{user:t.filter(function(n){return n.transaction.inputs.some(function(n){return e.has(n.owner)})||n.transaction.outputs.some(function(n){return e.has(n.dst)})}),all:t}})}).subscribe(function(t){return n.pendingTxs.next(t)})},n.prototype.getOutputs=function(n){return n?this.apiService.post("outputs",{addrs:n}).map(function(n){var t=[];return n.head_outputs.forEach(function(n){return t.push({address:n.address,coins:new Ae.BigNumber(n.coins),hash:n.hash,calculated_hours:new Ae.BigNumber(n.calculated_hours)})}),t}):o.a.of([])},n.prototype.sortOutputs=function(n,t){n.sort(function(n,e){return e.coins.isGreaterThan(n.coins)?t?1:-1:e.coins.isLessThan(n.coins)?t?-1:1:e.calculated_hours.isGreaterThan(n.calculated_hours)?-1:e.calculated_hours.isLessThan(n.calculated_hours)?1:0})},n.prototype.getMinRequiredOutputs=function(n,t){var e=[],l=[];if(t.forEach(function(n){n.calculated_hours.isGreaterThan(0)?e.push(n):l.push(n)}),0===e.length)return[];this.sortOutputs(e,!0);var r=[e[0]],i=new Ae.BigNumber(e[0].coins);return i.isGreaterThanOrEqualTo(n)?r:(this.sortOutputs(l,!1),l.forEach(function(t){i.isLessThan(n)&&(r.push(t),i=i.plus(t.coins))}),i.isGreaterThanOrEqualTo(n)?r:(e.splice(0,1),this.sortOutputs(e,!1),e.forEach(function(t){i.isLessThan(n)&&(r.push(t),i=i.plus(t.coins))}),r))},n}();function Oc(n){if("object"==typeof n&&(n._body?n=n._body:n+=""),-1!==n.indexOf('"error":')&&(n=JSON.parse(n).error.message),n.startsWith("400")||n.startsWith("403")){var t=n.split(" - ",2);return 2===t.length?t[1].charAt(0).toUpperCase()+t[1].slice(1):n}return n}function Tc(n,t,e){return void 0===e&&(e=null),Ll.useHwWalletDaemon||window.ipcRenderer.sendSync("hwGetDeviceConnectedSync")?(l=t.result?t.result===rc.FailedOrRefused?"hardware-wallet.general.refused":t.result===rc.WrongPin?"hardware-wallet.general.error-incorrect-pin":t.result===rc.IncorrectHardwareWallet?"hardware-wallet.general.error-incorrect-wallet":t.result===rc.DaemonError?"hardware-wallet.errors.daemon-connection":t.result===rc.InvalidAddress?"hardware-wallet.errors.invalid-address":t.result===rc.Timeout?"hardware-wallet.errors.timeout":t.result===rc.Disconnected?"hardware-wallet.general.error-disconnected":t.result===rc.NotInBootloaderMode?"hardware-wallet.errors.not-in-bootloader-mode":t.result===rc.PinMismatch?"hardware-wallet.change-pin.pin-mismatch":t.result===rc.WrongWord?"hardware-wallet.restore-seed.error-wrong-word":t.result===rc.InvalidSeed?"hardware-wallet.restore-seed.error-invalid-seed":t.result===rc.WrongSeed?"hardware-wallet.restore-seed.error-wrong-seed":e||"hardware-wallet.general.generic-error":e||"hardware-wallet.general.generic-error",n?n.instant(l):l):n?n.instant("hardware-wallet.general.error-disconnected"):"hardware-wallet.general.error-disconnected";var l}var Lc=function(){function n(){this.forceEmitEvents=!1,this.action=new l.o,this.mouseOver=!1}return n.prototype.onClick=function(){this.disabled&&!this.forceEmitEvents||(this.error="",this.action.emit())},n.prototype.focus=function(){this.button.focus()},n.prototype.setLoading=function(){this.state=0},n.prototype.setSuccess=function(){var n=this;this.state=1,setTimeout(function(){return n.state=null},3e3)},n.prototype.setError=function(n){var t=this;this.error="string"==typeof n?n:Oc(n._body),this.state=2,this.mouseOver&&setTimeout(function(){return t.tooltip.show()},50)},n.prototype.setDisabled=function(){this.disabled=!0},n.prototype.setEnabled=function(){this.disabled=!1},n.prototype.isLoading=function(){return 0===this.state},n.prototype.resetState=function(){return this.state=null,this.error="",this},n}();o.a.prototype.switchMap=function(n,t){return Object(Ri.a)(n,t)(this)},o.a.prototype.debounceTime=function(n,t){return void 0===t&&(t=sl),mr(n,t)(this)};var Pc,Dc,Ac=function(){function n(){var n=this;this.lastSearchTerm="",this.searchResultsSubject=new yl.a,this.wordList=[],this.wordMap=new Map,e.e(6).then(e.bind(null,"flj1")).then(function(t){n.wordList=t.list,n.wordList.forEach(function(t){n.wordMap.set(t,!0)}),n.searchResultsSubject.next(n.lastSearchTerm)})}return Object.defineProperty(n.prototype,"searchResults",{get:function(){var n=this;return this.searchResultsSubject.asObservable().debounceTime(100).map(function(t){return t.length>1?n.wordList.filter(function(n){return n.startsWith(t)}):[]})},enumerable:!0,configurable:!0}),n.prototype.setSearchTerm=function(n){this.lastSearchTerm=n,this.searchResultsSubject.next(n)},n.prototype.validateWord=function(n){return this.wordList.length>0?!!this.wordMap.has(n):null},n}();!function(n){n.Error="error",n.Done="done",n.Warning="warning"}(Pc||(Pc={})),function(n){n.Red="red-background",n.Green="green-background",n.Yellow="yellow-background"}(Dc||(Dc={}));var Ec=function(){},Yc=function(){function n(){this.config=new Ec,this.visible=!1}return n.prototype.show=function(){var n=this;this.visible?(this.visible=!1,setTimeout(function(){return n.visible=!0},32)):this.visible=!0},n.prototype.hide=function(){this.visible=!1},n}(),jc=function(){function n(){}return Object.defineProperty(n.prototype,"msgBarComponent",{set:function(n){this.msgBarComponentInternal=n},enumerable:!0,configurable:!0}),n.prototype.show=function(n){this.msgBarComponentInternal&&(this.msgBarComponentInternal.config=n,this.msgBarComponentInternal.show())},n.prototype.hide=function(){this.msgBarComponentInternal&&this.msgBarComponentInternal.hide()},n.prototype.showError=function(n,t){void 0===t&&(t=2e4);var e=new Ec;e.text=Oc(n),e.title="errors.error",e.icon=Pc.Error,e.color=Dc.Red,this.show(e),this.setTimer(t)},n.prototype.showWarning=function(n,t){void 0===t&&(t=2e4);var e=new Ec;e.text=Oc(n),e.title="common.warning",e.icon=Pc.Warning,e.color=Dc.Yellow,this.show(e),this.setTimer(t)},n.prototype.showDone=function(n,t){void 0===t&&(t=1e4);var e=new Ec;e.text=n,e.title="common.success",e.icon=Pc.Done,e.color=Dc.Green,this.show(e),this.setTimer(t)},n.prototype.setTimer=function(n){var t=this;void 0===n&&(n=1e4),this.timeSubscription&&this.timeSubscription.unsubscribe(),this.timeSubscription=o.a.of(1).delay(n).subscribe(function(){return t.hide()})},n}(),Ic=function(n){return n[n.None=0]="None",n[n.Spinner=1]="Spinner",n[n.Success=2]="Success",n[n.Error=3]="Error",n[n.Usb=4]="Usb",n[n.HardwareWallet=5]="HardwareWallet",n[n.Warning=6]="Warning",n[n.Confirm=7]="Confirm",n}({}),Rc=function(){function n(){this.icon=Ic.HardwareWallet,this.linkClicked=new l.o,this.icons=Ic}return n.prototype.activateLink=function(){this.linkClicked.emit()},n}(),Hc=function(){function n(n,t,e,l,r,i,o){var s=this;this.data=n,this.dialogRef=t,this.formBuilder=e,this.bip38WordList=l,this.msgBarService=r,this.translateService=i,this.msgIcons=Ic,this.sendingWord=!1,n.isForHwWallet&&(this.hwConnectionSubscription=o.walletConnectedAsyncEvent.subscribe(function(n){n||s.dialogRef.close()}))}return n.prototype.ngOnInit=function(){var n=this;this.form=this.formBuilder.group({word:["",Xi.required]}),this.valueChangeSubscription=this.form.controls.word.valueChanges.subscribe(function(t){n.bip38WordList.setSearchTerm(t.trim().toLowerCase())}),this.filteredOptions=this.bip38WordList.searchResults.map(function(n){return n})},n.prototype.ngOnDestroy=function(){this.msgBarService.hide(),this.valueChangeSubscription.unsubscribe(),this.hwConnectionSubscription&&this.hwConnectionSubscription.unsubscribe()},n.prototype.sendWord=function(){var n=this;this.sendingWord||(this.sendingWord=!0,this.msgBarService.hide(),setTimeout(function(){if(n.form.valid){var t=n.bip38WordList.validateWord(n.form.value.word.trim().toLowerCase());t?n.dialogRef.close(n.form.value.word.trim().toLowerCase()):n.msgBarService.showError(n.translateService.instant(null===t?"hardware-wallet.seed-word.error-loading-words":"hardware-wallet.seed-word.error-invalid-word"))}n.sendingWord=!1},32))},n}(),Nc=function(){function n(n,t){this.dialogRef=n,this.data=t,this.accepted=!1,this.disableDismiss=!1,this.disableDismiss=!!t.disableDismiss}return n.prototype.closeModal=function(n){this.dialogRef.close(n)},n.prototype.setAccept=function(n){this.accepted=!!n.checked},n}(),Fc=function(){return function(n){Object.assign(this,n)}}(),Bc=function(){function n(n,t){this.translate=n,this.storageService=t,this.currentLanguage=new Sl(1),this.selectedLanguageLoaded=new Sl(1),this.storageKey="lang",this.languagesInternal=[]}return Object.defineProperty(n.prototype,"languages",{get:function(){return this.languagesInternal},enumerable:!0,configurable:!0}),n.prototype.loadLanguageSettings=function(){var n=this,t=[];Ll.languages.forEach(function(e){var l=new Fc(e);n.languagesInternal.push(l),t.push(l.code)}),this.translate.addLangs(t),this.translate.setDefaultLang(Ll.defaultLanguage),this.translate.onLangChange.subscribe(function(t){return n.onLanguageChanged(t)}),this.loadCurrentLanguage()},n.prototype.changeLanguage=function(n){this.translate.use(n)},n.prototype.onLanguageChanged=function(n){this.currentLanguage.next(this.languages.find(function(t){return t.code===n.lang})),this.subscription&&this.subscription.unsubscribe(),this.subscription=this.storageService.store(ec.CLIENT,this.storageKey,n.lang).subscribe()},n.prototype.loadCurrentLanguage=function(){var n=this;this.storageService.get(ec.CLIENT,this.storageKey).subscribe(function(t){t.data&&-1!==n.translate.getLangs().indexOf(t.data)?(setTimeout(function(){n.translate.use(t.data)},16),n.selectedLanguageLoaded.next(!0)):n.selectedLanguageLoaded.next(!1)},function(){n.selectedLanguageLoaded.next(!1)})},n}(),Vc=function(){function n(n,t){this.dialogRef=n,this.languageService=t}return n.prototype.ngOnInit=function(){this.disableDismiss=this.dialogRef.disableClose,this.languages=this.languageService.languages},n.prototype.closePopup=function(n){void 0===n&&(n=null),this.dialogRef.close(n?n.code:void 0)},n}();function Wc(n,t){return n.open(Nc,{width:"450px",data:t,autoFocus:!1})}function zc(n,t){void 0===t&&(t=!1);var e=new oa;return e.width="600px",e.disableClose=t,e.autoFocus=!1,n.open(Vc,e).afterClosed()}function Uc(n){var t=document.createElement("textarea");t.style.position="fixed",t.style.left="0",t.style.top="0",t.style.opacity="0",t.value=n,document.body.appendChild(t),t.focus(),t.select(),document.execCommand("copy"),document.body.removeChild(t)}var Gc=function(){function n(n,t,e){this.apiService=n,this.dialog=t,this.msgBarService=e,this.customSeedIsNormal=!0,this.customSeedAccepted=!1,this.encrypt=!0,this.enterSeedWithAssistance=!0,this.assistedSeedConfirmed=!1,this.lastAssistedSeed="",this.numberOfAutogeneratedWords=0,this.seed=new yl.a}return n.prototype.ngOnInit=function(){this.onboarding?this.initForm(!1,null):this.initForm()},n.prototype.ngOnDestroy=function(){this.msgBarService.hide(),this.statusSubscription.unsubscribe(),this.seedValiditySubscription.unsubscribe()},Object.defineProperty(n.prototype,"isValid",{get:function(){return this.form.valid&&(!this.enterSeedWithAssistance&&(this.customSeedIsNormal||this.customSeedAccepted)||this.create&&this.enterSeedWithAssistance&&this.assistedSeedConfirmed||!this.create&&this.enterSeedWithAssistance&&this.lastAssistedSeed.length>2)},enumerable:!0,configurable:!0}),n.prototype.onCustomSeedAcceptance=function(n){this.customSeedAccepted=n.checked},n.prototype.setEncrypt=function(n){this.encrypt=n.checked,this.form.updateValueAndValidity()},n.prototype.getData=function(){return{creatingNewWallet:this.create,label:this.form.value.label,seed:this.enterSeedWithAssistance?this.lastAssistedSeed:this.form.value.seed,password:!this.onboarding&&this.encrypt?this.form.value.password:null,enterSeedWithAssistance:this.enterSeedWithAssistance,lastAssistedSeed:this.lastAssistedSeed,lastCustomSeed:this.form.value.seed,numberOfWords:this.create?this.numberOfAutogeneratedWords:this.form.value.number_of_words}},n.prototype.changeSeedType=function(){var n=this;this.msgBarService.hide(),this.enterSeedWithAssistance?Wc(this.dialog,{text:this.create?"wallet.new.seed.custom-seed-warning-text":"wallet.new.seed.custom-seed-warning-text-recovering",headerText:"wallet.new.seed.custom-seed-warning-title",checkboxText:this.create?"wallet.new.seed.custom-seed-warning-check":null,confirmButtonText:"wallet.new.seed.custom-seed-warning-continue",cancelButtonText:"wallet.new.seed.custom-seed-warning-cancel"}).afterClosed().subscribe(function(t){t&&(n.enterSeedWithAssistance=!1,n.removeConfirmations())}):(this.enterSeedWithAssistance=!0,this.removeConfirmations())},n.prototype.enterSeed=function(){this.create||(this.partialSeed=[],this.askForWord(0),this.msgBarService.hide())},n.prototype.confirmNormalSeed=function(){this.assistedSeedConfirmed||(this.partialSeed=[],this.askForWord(0),this.msgBarService.hide())},n.prototype.askForWord=function(n){var t=this;this.dialog.open(Hc,{width:"350px",data:{isForHwWallet:!1,wordNumber:n+1,restoringSoftwareWallet:!this.create}}).afterClosed().subscribe(function(e){if(e){if(t.create&&e!==t.lastAssistedSeed.split(" ")[n])return void t.msgBarService.showError("wallet.new.seed.incorrect-word");if(t.partialSeed[n]=e,n+=1,t.create&&nn.length)return null;if("full"===e.pathMatch&&(t.hasChildren()||l.length0?n[n.length-1]:null}function Bd(n,t){for(var e in n)n.hasOwnProperty(e)&&t(n[e],e)}function Vd(n){var t=pd.call(n);return dd.call(t,function(n){return!0===n})}function Wd(n){return Object(l._14)(n)?n:Object(l._15)(n)?Ui(Promise.resolve(n)):Object(Fe.a)(n)}function zd(n,t,e){return e?function(n,t){return Hd(n,t)}(n.queryParams,t.queryParams)&&function n(t,e){if(!Jd(t.segments,e.segments))return!1;if(t.numberOfChildren!==e.numberOfChildren)return!1;for(var l in e.children){if(!t.children[l])return!1;if(!n(t.children[l],e.children[l]))return!1}return!0}(n.root,t.root):function(n,t){return Object.keys(t).length<=Object.keys(n).length&&Object.keys(t).every(function(e){return t[e]===n[e]})}(n.queryParams,t.queryParams)&&function n(t,e){return function t(e,l,r){if(e.segments.length>r.length)return!!Jd(o=e.segments.slice(0,r.length),r)&&!l.hasChildren();if(e.segments.length===r.length){if(!Jd(e.segments,r))return!1;for(var i in l.children){if(!e.children[i])return!1;if(!n(e.children[i],l.children[i]))return!1}return!0}var o=r.slice(0,e.segments.length),s=r.slice(e.segments.length);return!!Jd(e.segments,o)&&!!e.children[Pd]&&t(e.children[Pd],l,s)}(t,e,e.segments)}(n.root,t.root)}var Ud=function(){function n(n,t,e){this.root=n,this.queryParams=t,this.fragment=e}return Object.defineProperty(n.prototype,"queryParamMap",{get:function(){return this._queryParamMap||(this._queryParamMap=Ad(this.queryParams)),this._queryParamMap},enumerable:!0,configurable:!0}),n.prototype.toString=function(){return Zd.serialize(this)},n}(),Gd=function(){function n(n,t){var e=this;this.segments=n,this.children=t,this.parent=null,Bd(t,function(n,t){return n.parent=e})}return n.prototype.hasChildren=function(){return this.numberOfChildren>0},Object.defineProperty(n.prototype,"numberOfChildren",{get:function(){return Object.keys(this.children).length},enumerable:!0,configurable:!0}),n.prototype.toString=function(){return $d(this)},n}(),qd=function(){function n(n,t){this.path=n,this.parameters=t}return Object.defineProperty(n.prototype,"parameterMap",{get:function(){return this._parameterMap||(this._parameterMap=Ad(this.parameters)),this._parameterMap},enumerable:!0,configurable:!0}),n.prototype.toString=function(){return eh(this)},n}();function Jd(n,t){return n.length===t.length&&n.every(function(n,e){return n.path===t[e].path})}function Qd(n,t){var e=[];return Bd(n.children,function(n,l){l===Pd&&(e=e.concat(t(n,l)))}),Bd(n.children,function(n,l){l!==Pd&&(e=e.concat(t(n,l)))}),e}var Kd=function(){},Xd=function(){function n(){}return n.prototype.parse=function(n){var t=new sh(n);return new Ud(t.parseRootSegment(),t.parseQueryParams(),t.parseFragment())},n.prototype.serialize=function(n){var t,e;return"/"+function n(t,e){if(!t.hasChildren())return $d(t);if(e){var l=t.children[Pd]?n(t.children[Pd],!1):"",r=[];return Bd(t.children,function(t,e){e!==Pd&&r.push(e+":"+n(t,!1))}),r.length>0?l+"("+r.join("//")+")":l}var i=Qd(t,function(e,l){return l===Pd?[n(t.children[Pd],!1)]:[l+":"+n(e,!1)]});return $d(t)+"/("+i.join("//")+")"}(n.root,!0)+(t=n.queryParams,(e=Object.keys(t).map(function(n){var e=t[n];return Array.isArray(e)?e.map(function(t){return nh(n)+"="+nh(t)}).join("&"):nh(n)+"="+nh(e)})).length?"?"+e.join("&"):"")+("string"==typeof n.fragment?"#"+encodeURI(n.fragment):"")},n}(),Zd=new Xd;function $d(n){return n.segments.map(function(n){return eh(n)}).join("/")}function nh(n){return encodeURIComponent(n).replace(/%40/g,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";")}function th(n){return decodeURIComponent(n)}function eh(n){return""+nh(n.path)+(t=n.parameters,Object.keys(t).map(function(n){return";"+nh(n)+"="+nh(t[n])}).join(""));var t}var lh=/^[^\/()?;=&#]+/;function rh(n){var t=n.match(lh);return t?t[0]:""}var ih=/^[^=?&#]+/,oh=/^[^?&#]+/,sh=function(){function n(n){this.url=n,this.remaining=n}return n.prototype.parseRootSegment=function(){return this.consumeOptional("/"),""===this.remaining||this.peekStartsWith("?")||this.peekStartsWith("#")?new Gd([],{}):new Gd([],this.parseChildren())},n.prototype.parseQueryParams=function(){var n={};if(this.consumeOptional("?"))do{this.parseQueryParam(n)}while(this.consumeOptional("&"));return n},n.prototype.parseFragment=function(){return this.consumeOptional("#")?decodeURI(this.remaining):null},n.prototype.parseChildren=function(){if(""===this.remaining)return{};this.consumeOptional("/");var n=[];for(this.peekStartsWith("(")||n.push(this.parseSegment());this.peekStartsWith("/")&&!this.peekStartsWith("//")&&!this.peekStartsWith("/(");)this.capture("/"),n.push(this.parseSegment());var t={};this.peekStartsWith("/(")&&(this.capture("/"),t=this.parseParens(!0));var e={};return this.peekStartsWith("(")&&(e=this.parseParens(!1)),(n.length>0||Object.keys(t).length>0)&&(e[Pd]=new Gd(n,t)),e},n.prototype.parseSegment=function(){var n=rh(this.remaining);if(""===n&&this.peekStartsWith(";"))throw new Error("Empty path url segment cannot have parameters: '"+this.remaining+"'.");return this.capture(n),new qd(th(n),this.parseMatrixParams())},n.prototype.parseMatrixParams=function(){for(var n={};this.consumeOptional(";");)this.parseParam(n);return n},n.prototype.parseParam=function(n){var t=rh(this.remaining);if(t){this.capture(t);var e="";if(this.consumeOptional("=")){var l=rh(this.remaining);l&&this.capture(e=l)}n[th(t)]=th(e)}},n.prototype.parseQueryParam=function(n){var t,e=(t=this.remaining.match(ih))?t[0]:"";if(e){this.capture(e);var l="";if(this.consumeOptional("=")){var r=function(n){var t=n.match(oh);return t?t[0]:""}(this.remaining);r&&this.capture(l=r)}var i=th(e),o=th(l);if(n.hasOwnProperty(i)){var s=n[i];Array.isArray(s)||(n[i]=s=[s]),s.push(o)}else n[i]=o}},n.prototype.parseParens=function(n){var t={};for(this.capture("(");!this.consumeOptional(")")&&this.remaining.length>0;){var e=rh(this.remaining),l=this.remaining[e.length];if("/"!==l&&")"!==l&&";"!==l)throw new Error("Cannot parse url '"+this.url+"'");var r=void 0;e.indexOf(":")>-1?(r=e.substr(0,e.indexOf(":")),this.capture(r),this.capture(":")):n&&(r=Pd);var i=this.parseChildren();t[r]=1===Object.keys(i).length?i[Pd]:new Gd([],i),this.consumeOptional("//")}return t},n.prototype.peekStartsWith=function(n){return this.remaining.startsWith(n)},n.prototype.consumeOptional=function(n){return!!this.peekStartsWith(n)&&(this.remaining=this.remaining.substring(n.length),!0)},n.prototype.capture=function(n){if(!this.consumeOptional(n))throw new Error('Expected "'+n+'".')},n}(),ah=function(n){this.segmentGroup=n||null},uh=function(n){this.urlTree=n};function ch(n){return new o.a(function(t){return t.error(new ah(n))})}function dh(n){return new o.a(function(t){return t.error(new uh(n))})}function hh(n){return new o.a(function(t){return t.error(new Error("Only absolute redirects can have named outlets. redirectTo: '"+n+"'"))})}var ph=function(){function n(n,t,e,r,i){this.configLoader=t,this.urlSerializer=e,this.urlTree=r,this.config=i,this.allowRedirects=!0,this.ngModule=n.get(l.z)}return n.prototype.apply=function(){var n=this,t=this.expandSegmentGroup(this.ngModule,this.config,this.urlTree.root,Pd),e=Pe.call(t,function(t){return n.createUrlTree(t,n.urlTree.queryParams,n.urlTree.fragment)});return Te.call(e,function(t){if(t instanceof uh)return n.allowRedirects=!1,n.match(t.urlTree);if(t instanceof ah)throw n.noMatchError(t);throw t})},n.prototype.match=function(n){var t=this,e=this.expandSegmentGroup(this.ngModule,this.config,n.root,Pd),l=Pe.call(e,function(e){return t.createUrlTree(e,n.queryParams,n.fragment)});return Te.call(l,function(n){if(n instanceof ah)throw t.noMatchError(n);throw n})},n.prototype.noMatchError=function(n){return new Error("Cannot match any routes. URL Segment: '"+n.segmentGroup+"'")},n.prototype.createUrlTree=function(n,t,e){var l,r=n.segments.length>0?new Gd([],((l={})[Pd]=n,l)):n;return new Ud(r,t,e)},n.prototype.expandSegmentGroup=function(n,t,e,l){return 0===e.segments.length&&e.hasChildren()?Pe.call(this.expandChildren(n,t,e),function(n){return new Gd([],n)}):this.expandSegment(n,e,t,e.segments,l,!0)},n.prototype.expandChildren=function(n,t,e){var l=this;return function(e,r){if(0===Object.keys(e).length)return Object(Fe.a)({});var i=[],o=[],s={};Bd(e,function(e,r){var a=Pe.call(l.expandSegmentGroup(n,t,e,r),function(n){return s[r]=n});r===Pd?i.push(a):o.push(a)});var a=cd.call(Fe.a.apply(void 0,i.concat(o))),u=hd.call(a);return Pe.call(u,function(){return s})}(e.children)},n.prototype.expandSegment=function(n,t,e,l,r,i){var o=this,s=Fe.a.apply(void 0,e),a=Pe.call(s,function(s){var a=o.expandSegmentAgainstRoute(n,t,e,s,l,r,i);return Te.call(a,function(n){if(n instanceof ah)return Object(Fe.a)(null);throw n})}),u=cd.call(a),c=$e.call(u,function(n){return!!n});return Te.call(c,function(n,e){if(n instanceof Ke||"EmptyError"===n.name){if(o.noLeftoversInUrl(t,l,r))return Object(Fe.a)(new Gd([],{}));throw new ah(t)}throw n})},n.prototype.noLeftoversInUrl=function(n,t,e){return 0===t.length&&!n.children[e]},n.prototype.expandSegmentAgainstRoute=function(n,t,e,l,r,i,o){return gh(l)!==i?ch(t):void 0===l.redirectTo?this.matchSegmentAgainstRoute(n,t,l,r):o&&this.allowRedirects?this.expandSegmentAgainstRouteUsingRedirect(n,t,e,l,r,i):ch(t)},n.prototype.expandSegmentAgainstRouteUsingRedirect=function(n,t,e,l,r,i){return"**"===l.path?this.expandWildCardWithParamsAgainstRouteUsingRedirect(n,e,l,i):this.expandRegularSegmentAgainstRouteUsingRedirect(n,t,e,l,r,i)},n.prototype.expandWildCardWithParamsAgainstRouteUsingRedirect=function(n,t,e,l){var r=this,i=this.applyRedirectCommands([],e.redirectTo,{});return e.redirectTo.startsWith("/")?dh(i):tl.call(this.lineralizeSegments(e,i),function(e){var i=new Gd(e,{});return r.expandSegment(n,i,t,e,l,!1)})},n.prototype.expandRegularSegmentAgainstRouteUsingRedirect=function(n,t,e,l,r,i){var o=this,s=fh(t,l,r),a=s.consumedSegments,u=s.lastChild,c=s.positionalParamSegments;if(!s.matched)return ch(t);var d=this.applyRedirectCommands(a,l.redirectTo,c);return l.redirectTo.startsWith("/")?dh(d):tl.call(this.lineralizeSegments(l,d),function(l){return o.expandSegment(n,t,e,l.concat(r.slice(u)),i,!1)})},n.prototype.matchSegmentAgainstRoute=function(n,t,e,l){var r=this;if("**"===e.path)return e.loadChildren?Pe.call(this.configLoader.load(n.injector,e),function(n){return e._loadedConfig=n,new Gd(l,{})}):Object(Fe.a)(new Gd(l,{}));var o=fh(t,e,l),s=o.consumedSegments,a=o.lastChild;if(!o.matched)return ch(t);var u=l.slice(a),c=this.getChildConfig(n,e);return tl.call(c,function(n){var e=n.module,l=n.routes,o=function(n,t,e,l){return e.length>0&&function(n,t,e){return l.some(function(e){return mh(n,t,e)&&gh(e)!==Pd})}(n,e)?{segmentGroup:_h(new Gd(t,function(n,t){var e={};e[Pd]=t;for(var l=0,r=n;l1||!l.children[Pd])return hh(n.redirectTo);l=l.children[Pd]}},n.prototype.applyRedirectCommands=function(n,t,e){return this.applyRedirectCreatreUrlTree(t,this.urlSerializer.parse(t),n,e)},n.prototype.applyRedirectCreatreUrlTree=function(n,t,e,l){var r=this.createSegmentGroup(n,t.root,e,l);return new Ud(r,this.createQueryParams(t.queryParams,this.urlTree.queryParams),t.fragment)},n.prototype.createQueryParams=function(n,t){var e={};return Bd(n,function(n,l){if("string"==typeof n&&n.startsWith(":")){var r=n.substring(1);e[l]=t[r]}else e[l]=n}),e},n.prototype.createSegmentGroup=function(n,t,e,l){var r=this,i=this.createSegments(n,t.segments,e,l),o={};return Bd(t.children,function(t,i){o[i]=r.createSegmentGroup(n,t,e,l)}),new Gd(i,o)},n.prototype.createSegments=function(n,t,e,l){var r=this;return t.map(function(t){return t.path.startsWith(":")?r.findPosParam(n,t,l):r.findOrReturn(t,e)})},n.prototype.findPosParam=function(n,t,e){var l=e[t.path.substring(1)];if(!l)throw new Error("Cannot redirect to '"+n+"'. Cannot find '"+t.path+"'.");return l},n.prototype.findOrReturn=function(n,t){for(var e=0,l=0,r=t;l0)?{matched:!1,consumedSegments:[],lastChild:0,positionalParamSegments:{}}:{matched:!0,consumedSegments:[],lastChild:0,positionalParamSegments:{}};var l=(t.matcher||Ed)(e,n,t);return l?{matched:!0,consumedSegments:l.consumed,lastChild:l.consumed.length,positionalParamSegments:l.posParams}:{matched:!1,consumedSegments:[],lastChild:0,positionalParamSegments:{}}}function _h(n){if(1===n.numberOfChildren&&n.children[Pd]){var t=n.children[Pd];return new Gd(n.segments.concat(t.segments),t.children)}return n}function mh(n,t,e){return(!(n.hasChildren()||t.length>0)||"full"!==e.pathMatch)&&""===e.path&&void 0!==e.redirectTo}function gh(n){return n.outlet||Pd}var yh=function(){function n(n){this._root=n}return Object.defineProperty(n.prototype,"root",{get:function(){return this._root.value},enumerable:!0,configurable:!0}),n.prototype.parent=function(n){var t=this.pathFromRoot(n);return t.length>1?t[t.length-2]:null},n.prototype.children=function(n){var t=bh(n,this._root);return t?t.children.map(function(n){return n.value}):[]},n.prototype.firstChild=function(n){var t=bh(n,this._root);return t&&t.children.length>0?t.children[0].value:null},n.prototype.siblings=function(n){var t=vh(n,this._root);return t.length<2?[]:t[t.length-2].children.map(function(n){return n.value}).filter(function(t){return t!==n})},n.prototype.pathFromRoot=function(n){return vh(n,this._root).map(function(n){return n.value})},n}();function bh(n,t){if(n===t.value)return t;for(var e=0,l=t.children;e=1;){var r=e[l],o=e[l-1];if(r.routeConfig&&""===r.routeConfig.path)l--;else{if(o.component)break;l--}}return function(n){return n.reduce(function(n,t){return{params:Object(i.__assign)({},n.params,t.params),data:Object(i.__assign)({},n.data,t.data),resolve:Object(i.__assign)({},n.resolve,t._resolvedData)}},{params:{},data:{},resolve:{}})}(e.slice(l))}var Oh=function(){function n(n,t,e,l,r,i,o,s,a,u,c){this.url=n,this.params=t,this.queryParams=e,this.fragment=l,this.data=r,this.outlet=i,this.component=o,this.routeConfig=s,this._urlSegment=a,this._lastPathIndex=u,this._resolve=c}return Object.defineProperty(n.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"paramMap",{get:function(){return this._paramMap||(this._paramMap=Ad(this.params)),this._paramMap},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"queryParamMap",{get:function(){return this._queryParamMap||(this._queryParamMap=Ad(this.queryParams)),this._queryParamMap},enumerable:!0,configurable:!0}),n.prototype.toString=function(){return"Route(url:'"+this.url.map(function(n){return n.toString()}).join("/")+"', path:'"+(this.routeConfig?this.routeConfig.path:"")+"')"},n}(),Th=function(n){function t(t,e){var l=n.call(this,e)||this;return l.url=t,Lh(l,e),l}return Object(i.__extends)(t,n),t.prototype.toString=function(){return Ph(this._root)},t}(yh);function Lh(n,t){t.value._routerState=n,t.children.forEach(function(t){return Lh(n,t)})}function Ph(n){var t=n.children.length>0?" { "+n.children.map(Ph).join(", ")+" } ":"";return""+n.value+t}function Dh(n){if(n.snapshot){var t=n.snapshot,e=n._futureSnapshot;n.snapshot=e,Hd(t.queryParams,e.queryParams)||n.queryParams.next(e.queryParams),t.fragment!==e.fragment&&n.fragment.next(e.fragment),Hd(t.params,e.params)||n.params.next(e.params),function(n,t){if(n.length!==t.length)return!1;for(var e=0;e0&&Eh(e[0]))throw new Error("Root segment cannot have matrix parameters");var l=e.find(function(n){return"object"==typeof n&&null!=n&&n.outlets});if(l&&l!==Fd(e))throw new Error("{outlets:{}} has to be the last command")}return n.prototype.toRoot=function(){return this.isAbsolute&&1===this.commands.length&&"/"==this.commands[0]},n}(),Ih=function(n,t,e){this.segmentGroup=n,this.processChildren=t,this.index=e};function Rh(n){return"object"==typeof n&&null!=n&&n.outlets?n.outlets[Pd]:""+n}function Hh(n,t,e){if(n||(n=new Gd([],{})),0===n.segments.length&&n.hasChildren())return Nh(n,t,e);var l=function(n,t,e){for(var l=0,r=t,i={match:!1,pathIndex:0,commandIndex:0};r=e.length)return i;var o=n.segments[r],s=Rh(e[l]),a=l0&&void 0===s)break;if(s&&a&&"object"==typeof a&&void 0===a.outlets){if(!Wh(s,a,o))return i;l+=2}else{if(!Wh(s,{},o))return i;l++}r++}return{match:!0,pathIndex:r,commandIndex:l}}(n,t,e),r=e.slice(l.commandIndex);if(l.match&&l.pathIndex=2?Object(pc.a)(n,t)(this):Object(pc.a)(n)(this)}).call(l,function(n,t){return n})},n.prototype.isDeactivating=function(){return 0!==this.canDeactivateChecks.length},n.prototype.isActivating=function(){return 0!==this.canActivateChecks.length},n.prototype.setupChildRouteGuards=function(n,t,e,l){var r=this,i=xh(t);n.children.forEach(function(n){r.setupRouteGuards(n,i[n.value.outlet],e,l.concat([n.value])),delete i[n.value.outlet]}),Bd(i,function(n,t){return r.deactivateRouteAndItsChildren(n,e.getContext(t))})},n.prototype.setupRouteGuards=function(n,t,e,l){var r=n.value,i=t?t.value:null,o=e?e.getContext(n.value.outlet):null;if(i&&r.routeConfig===i.routeConfig){var s=this.shouldRunGuardsAndResolvers(i,r,r.routeConfig.runGuardsAndResolvers);s?this.canActivateChecks.push(new zh(l)):(r.data=i.data,r._resolvedData=i._resolvedData),this.setupChildRouteGuards(n,t,r.component?o?o.children:null:e,l),s&&this.canDeactivateChecks.push(new Uh(o.outlet.component,i))}else i&&this.deactivateRouteAndItsChildren(t,o),this.canActivateChecks.push(new zh(l)),this.setupChildRouteGuards(n,null,r.component?o?o.children:null:e,l)},n.prototype.shouldRunGuardsAndResolvers=function(n,t,e){switch(e){case"always":return!0;case"paramsOrQueryParamsChange":return!Ah(n,t)||!Hd(n.queryParams,t.queryParams);case"paramsChange":default:return!Ah(n,t)}},n.prototype.deactivateRouteAndItsChildren=function(n,t){var e=this,l=xh(n),r=n.value;Bd(l,function(n,l){e.deactivateRouteAndItsChildren(n,r.component?t?t.children.getContext(l):null:t)}),this.canDeactivateChecks.push(new Uh(r.component&&t&&t.outlet&&t.outlet.isActivated?t.outlet.component:null,r))},n.prototype.runCanDeactivateChecks=function(){var n=this,t=xs(this.canDeactivateChecks),e=tl.call(t,function(t){return n.runCanDeactivate(t.component,t.route)});return dd.call(e,function(n){return!0===n})},n.prototype.runCanActivateChecks=function(){var n=this,t=xs(this.canActivateChecks),e=va.call(t,function(t){return Vd(xs([n.fireChildActivationStart(t.route.parent),n.fireActivationStart(t.route),n.runCanActivateChild(t.path),n.runCanActivate(t.route)]))});return dd.call(e,function(n){return!0===n})},n.prototype.fireActivationStart=function(n){return null!==n&&this.forwardEvent&&this.forwardEvent(new Td(n)),Object(Fe.a)(!0)},n.prototype.fireChildActivationStart=function(n){return null!==n&&this.forwardEvent&&this.forwardEvent(new Sd(n)),Object(Fe.a)(!0)},n.prototype.runCanActivate=function(n){var t=this,e=n.routeConfig?n.routeConfig.canActivate:null;return e&&0!==e.length?Vd(Pe.call(xs(e),function(e){var l,r=t.getToken(e,n);return l=Wd(r.canActivate?r.canActivate(n,t.future):r(n,t.future)),$e.call(l)})):Object(Fe.a)(!0)},n.prototype.runCanActivateChild=function(n){var t=this,e=n[n.length-1],l=n.slice(0,n.length-1).reverse().map(function(n){return t.extractCanActivateChild(n)}).filter(function(n){return null!==n});return Vd(Pe.call(xs(l),function(n){return Vd(Pe.call(xs(n.guards),function(l){var r,i=t.getToken(l,n.node);return r=Wd(i.canActivateChild?i.canActivateChild(e,t.future):i(e,t.future)),$e.call(r)}))}))},n.prototype.extractCanActivateChild=function(n){var t=n.routeConfig?n.routeConfig.canActivateChild:null;return t&&0!==t.length?{node:n,guards:t}:null},n.prototype.runCanDeactivate=function(n,t){var e=this,l=t&&t.routeConfig?t.routeConfig.canDeactivate:null;if(!l||0===l.length)return Object(Fe.a)(!0);var r=tl.call(xs(l),function(l){var r,i=e.getToken(l,t);return r=Wd(i.canDeactivate?i.canDeactivate(n,t,e.curr,e.future):i(n,t,e.curr,e.future)),$e.call(r)});return dd.call(r,function(n){return!0===n})},n.prototype.runResolve=function(n,t){return Pe.call(this.resolveNode(n._resolve,n),function(e){return n._resolvedData=e,n.data=Object(i.__assign)({},n.data,Sh(n,t).resolve),null})},n.prototype.resolveNode=function(n,t){var e=this,l=Object.keys(n);if(0===l.length)return Object(Fe.a)({});if(1===l.length){var r=l[0];return Pe.call(this.getResolver(n[r],t),function(n){return(t={})[r]=n,t;var t})}var i={},o=tl.call(xs(l),function(l){return Pe.call(e.getResolver(n[l],t),function(n){return i[l]=n,n})});return Pe.call(hd.call(o),function(){return i})},n.prototype.getResolver=function(n,t){var e=this.getToken(n,t);return Wd(e.resolve?e.resolve(t,this.future):e(t,this.future))},n.prototype.getToken=function(n,t){var e=function(n){if(!n)return null;for(var t=n.parent;t;t=t.parent){var e=t.routeConfig;if(e&&e._loadedConfig)return e._loadedConfig}return null}(t);return(e?e.module.injector:this.moduleInjector).get(n)},n}(),qh=function(){},Jh=function(){function n(n,t,e,l,r){this.rootComponentType=n,this.config=t,this.urlTree=e,this.url=l,this.paramsInheritanceStrategy=r}return n.prototype.recognize=function(){try{var n=Xh(this.urlTree.root,[],[],this.config).segmentGroup,t=this.processSegmentGroup(this.config,n,Pd),e=new Oh([],Object.freeze({}),Object.freeze(this.urlTree.queryParams),this.urlTree.fragment,{},Pd,this.rootComponentType,null,this.urlTree.root,-1,{}),l=new wh(e,t),r=new Th(this.url,l);return this.inheritParamsAndData(r._root),Object(Fe.a)(r)}catch(n){return new o.a(function(t){return t.error(n)})}},n.prototype.inheritParamsAndData=function(n){var t=this,e=n.value,l=Sh(e,this.paramsInheritanceStrategy);e.params=Object.freeze(l.params),e.data=Object.freeze(l.data),n.children.forEach(function(n){return t.inheritParamsAndData(n)})},n.prototype.processSegmentGroup=function(n,t,e){return 0===t.segments.length&&t.hasChildren()?this.processChildren(n,t):this.processSegment(n,t,t.segments,e)},n.prototype.processChildren=function(n,t){var e,l=this,r=Qd(t,function(t,e){return l.processSegmentGroup(n,t,e)});return e={},r.forEach(function(n){var t=e[n.value.outlet];if(t){var l=t.url.map(function(n){return n.toString()}).join("/"),r=n.value.url.map(function(n){return n.toString()}).join("/");throw new Error("Two segments cannot have the same outlet name: '"+l+"' and '"+r+"'.")}e[n.value.outlet]=n.value}),r.sort(function(n,t){return n.value.outlet===Pd?-1:t.value.outlet===Pd?1:n.value.outlet.localeCompare(t.value.outlet)}),r},n.prototype.processSegment=function(n,t,e,l){for(var r=0,i=n;r0?Fd(e).parameters:{};r=new Oh(e,a,Object.freeze(this.urlTree.queryParams),this.urlTree.fragment,np(n),l,n.component,n,Qh(t),Kh(t)+e.length,tp(n))}else{var u=function(n,t,e){if(""===t.path){if("full"===t.pathMatch&&(n.hasChildren()||e.length>0))throw new qh;return{consumedSegments:[],lastChild:0,parameters:{}}}var l=(t.matcher||Ed)(e,n,t);if(!l)throw new qh;var r={};Bd(l.posParams,function(n,t){r[t]=n.path});var o=l.consumed.length>0?Object(i.__assign)({},r,l.consumed[l.consumed.length-1].parameters):r;return{consumedSegments:l.consumed,lastChild:l.consumed.length,parameters:o}}(t,n,e);o=u.consumedSegments,s=e.slice(u.lastChild),r=new Oh(o,u.parameters,Object.freeze(this.urlTree.queryParams),this.urlTree.fragment,np(n),l,n.component,n,Qh(t),Kh(t)+o.length,tp(n))}var c=function(n){return n.children?n.children:n.loadChildren?n._loadedConfig.routes:[]}(n),d=Xh(t,o,s,c),h=d.segmentGroup,p=d.slicedSegments;if(0===p.length&&h.hasChildren()){var f=this.processChildren(c,h);return[new wh(r,f)]}if(0===c.length&&0===p.length)return[new wh(r,[])];var _=this.processSegment(c,h,p,Pd);return[new wh(r,_)]},n}();function Qh(n){for(var t=n;t._sourceSegment;)t=t._sourceSegment;return t}function Kh(n){for(var t=n,e=t._segmentIndexShift?t._segmentIndexShift:0;t._sourceSegment;)e+=(t=t._sourceSegment)._segmentIndexShift?t._segmentIndexShift:0;return e-1}function Xh(n,t,e,l){if(e.length>0&&function(n,t,e){return l.some(function(e){return Zh(n,t,e)&&$h(e)!==Pd})}(n,e)){var r=new Gd(t,function(n,t,e,l){var r={};r[Pd]=l,l._sourceSegment=n,l._segmentIndexShift=t.length;for(var i=0,o=e;i0)||"full"!==e.pathMatch)&&""===e.path&&void 0===e.redirectTo}function $h(n){return n.outlet||Pd}function np(n){return n.data||{}}function tp(n){return n.resolve||{}}var ep=function(){},lp=function(){function n(){}return n.prototype.shouldDetach=function(n){return!1},n.prototype.store=function(n,t){},n.prototype.shouldAttach=function(n){return!1},n.prototype.retrieve=function(n){return null},n.prototype.shouldReuseRoute=function(n,t){return n.routeConfig===t.routeConfig},n}(),rp=new l.r("ROUTES"),ip=function(){function n(n,t,e,l){this.loader=n,this.compiler=t,this.onLoadStartListener=e,this.onLoadEndListener=l}return n.prototype.load=function(n,t){var e=this;this.onLoadStartListener&&this.onLoadStartListener(t);var l=this.loadModuleFactory(t.loadChildren);return Pe.call(l,function(l){e.onLoadEndListener&&e.onLoadEndListener(t);var r=l.create(n);return new Yd(Nd(r.injector.get(rp)),r)})},n.prototype.loadModuleFactory=function(n){var t=this;return"string"==typeof n?Ui(this.loader.load(n)):tl.call(Wd(n()),function(n){return n instanceof l.x?Object(Fe.a)(n):Ui(t.compiler.compileModuleAsync(n))})},n}(),op=function(){},sp=function(){function n(){}return n.prototype.shouldProcessUrl=function(n){return!0},n.prototype.extract=function(n){return n},n.prototype.merge=function(n,t){return n},n}();function ap(n){throw n}function up(n){return Object(Fe.a)(null)}var cp=function(){function n(n,t,e,r,i,o,s,a){var u=this;this.rootComponentType=n,this.urlSerializer=t,this.rootContexts=e,this.location=r,this.config=a,this.navigations=new Tl(null),this.navigationId=0,this.events=new yl.a,this.errorHandler=ap,this.navigated=!1,this.hooks={beforePreactivation:up,afterPreactivation:up},this.urlHandlingStrategy=new sp,this.routeReuseStrategy=new lp,this.onSameUrlNavigation="ignore",this.paramsInheritanceStrategy="emptyOnly",this.ngModule=i.get(l.z),this.resetConfig(a),this.currentUrlTree=new Ud(new Gd([],{}),{},null),this.rawUrlTree=this.currentUrlTree,this.configLoader=new ip(o,s,function(n){return u.triggerEvent(new kd(n))},function(n){return u.triggerEvent(new Cd(n))}),this.routerState=kh(this.currentUrlTree,this.rootComponentType),this.processNavigations()}return n.prototype.resetRootComponentType=function(n){this.rootComponentType=n,this.routerState.root.component=this.rootComponentType},n.prototype.initialNavigation=function(){this.setUpLocationChangeListener(),0===this.navigationId&&this.navigateByUrl(this.location.path(!0),{replaceUrl:!0})},n.prototype.setUpLocationChangeListener=function(){var n=this;this.locationSubscription||(this.locationSubscription=this.location.subscribe(Zone.current.wrap(function(t){var e=n.urlSerializer.parse(t.url),l="popstate"===t.type?"popstate":"hashchange";setTimeout(function(){n.scheduleNavigation(e,l,{replaceUrl:!0})},0)})))},Object.defineProperty(n.prototype,"url",{get:function(){return this.serializeUrl(this.currentUrlTree)},enumerable:!0,configurable:!0}),n.prototype.triggerEvent=function(n){this.events.next(n)},n.prototype.resetConfig=function(n){jd(n),this.config=n,this.navigated=!1},n.prototype.ngOnDestroy=function(){this.dispose()},n.prototype.dispose=function(){this.locationSubscription&&(this.locationSubscription.unsubscribe(),this.locationSubscription=null)},n.prototype.createUrlTree=function(n,t){void 0===t&&(t={});var e=t.relativeTo,r=t.queryParams,o=t.fragment,s=t.preserveQueryParams,a=t.queryParamsHandling,u=t.preserveFragment;Object(l.Y)()&&s&&console&&console.warn&&console.warn("preserveQueryParams is deprecated, use queryParamsHandling instead.");var c=e||this.routerState.root,d=u?this.currentUrlTree.fragment:o,h=null;if(a)switch(a){case"merge":h=Object(i.__assign)({},this.currentUrlTree.queryParams,r);break;case"preserve":h=this.currentUrlTree.queryParams;break;default:h=r||null}else h=s?this.currentUrlTree.queryParams:r||null;return null!==h&&(h=this.removeEmptyProps(h)),function(n,t,e,l,r){if(0===e.length)return Yh(t.root,t.root,t,l,r);var i=function(n){if("string"==typeof n[0]&&1===n.length&&"/"===n[0])return new jh(!0,0,n);var t=0,e=!1,l=n.reduce(function(n,l,r){if("object"==typeof l&&null!=l){if(l.outlets){var i={};return Bd(l.outlets,function(n,t){i[t]="string"==typeof n?n.split("/"):n}),n.concat([{outlets:i}])}if(l.segmentPath)return n.concat([l.segmentPath])}return"string"!=typeof l?n.concat([l]):0===r?(l.split("/").forEach(function(l,r){0==r&&"."===l||(0==r&&""===l?e=!0:".."===l?t++:""!=l&&n.push(l))}),n):n.concat([l])},[]);return new jh(e,t,l)}(e);if(i.toRoot())return Yh(t.root,new Gd([],{}),t,l,r);var o=function(n,e,l){if(n.isAbsolute)return new Ih(t.root,!0,0);if(-1===l.snapshot._lastPathIndex)return new Ih(l.snapshot._urlSegment,!0,0);var r=Eh(n.commands[0])?0:1;return function(t,e,i){for(var o=l.snapshot._urlSegment,s=l.snapshot._lastPathIndex+r,a=n.numberOfDoubleDots;a>s;){if(a-=s,!(o=o.parent))throw new Error("Invalid number of '../'");s=o.segments.length}return new Ih(o,!1,s-a)}()}(i,0,n),s=o.processChildren?Nh(o.segmentGroup,o.index,i.commands):Hh(o.segmentGroup,o.index,i.commands);return Yh(o.segmentGroup,s,t,l,r)}(c,this.currentUrlTree,n,h,d)},n.prototype.navigateByUrl=function(n,t){void 0===t&&(t={skipLocationChange:!1});var e=n instanceof Ud?n:this.parseUrl(n),l=this.urlHandlingStrategy.merge(e,this.rawUrlTree);return this.scheduleNavigation(l,"imperative",t)},n.prototype.navigate=function(n,t){return void 0===t&&(t={skipLocationChange:!1}),function(n){for(var t=0;t0?(this.currentQrContent+=n+"amount="+this.form.get("coins").value,n="&"):this.invalidCoins=!0);var e=this.form.get("hours").value;e&&(Number.parseInt(e).toString()===e&&Number.parseInt(e)>0?(this.currentQrContent+=n+"hours="+this.form.get("hours").value,n="&"):this.invalidHours=!0);var l=this.form.get("note").value;l&&(this.currentQrContent+=n+"message="+encodeURIComponent(l)),this.updateQrCode()},n.prototype.updateQrCode=function(){this.qr.nativeElement.innerHTML="",new QRCode(this.qr.nativeElement,{text:this.currentQrContent,width:this.defaultQrConfig.size,height:this.defaultQrConfig.size,colorDark:this.defaultQrConfig.colordark,colorLight:this.defaultQrConfig.colorlight,useSVG:this.defaultQrConfig.usesvg,correctLevel:QRCode.CorrectLevel[this.defaultQrConfig.level]})},n}(),Jp=function(){function n(n,t,e){var l=this;this.walletService=n,this.route=t,this.dialog=e,t.queryParams.subscribe(function(n){l.wallets=null,l.lastRouteParams=n,l.walletService.startDataRefreshSubscription()}),n.all().subscribe(function(){return l.loadData()})}return n.prototype.ngOnDestroy=function(){this.outputsSubscription.unsubscribe()},n.prototype.loadData=function(){var n=this,t=this.lastRouteParams.addr;this.outputsSubscription=this.walletService.outputsWithWallets().subscribe(function(e){n.wallets=e.map(function(n){return Object.assign({},n)}).map(function(n){return n.addresses=n.addresses.filter(function(n){if(n.outputs.length>0)return!t||n.address===t}),n}).filter(function(n){return n.addresses.length>0})})},n.prototype.showQrCode=function(n,t){n.stopPropagation(),qp.openDialog(this.dialog,{address:t})},n}(),Qp=function(n){function t(t,e){void 0===t&&(t=0),void 0===e&&(e=sl),n.call(this),this.period=t,this.scheduler=e,(!el(t)||t<0)&&(this.period=0),e&&"function"==typeof e.schedule||(this.scheduler=sl)}return Object(i.__extends)(t,n),t.create=function(n,e){return void 0===n&&(n=0),void 0===e&&(e=sl),new t(n,e)},t.dispatch=function(n){var t=n.subscriber,e=n.period;t.next(n.index),t.closed||(n.index+=1,this.schedule(n,e))},t.prototype._subscribe=function(n){var e=this.period;n.add(this.scheduler.schedule(t.dispatch,e,{index:0,subscriber:n,period:e}))},t}(o.a),Kp=function(){function n(n){this.blockchainService=n,this.subscriptionsGroup=[]}return n.prototype.ngOnInit=function(){var n=this;this.subscriptionsGroup.push(Qp.create(5e3).switchMap(function(){return n.blockchainService.lastBlock()}).subscribe(function(t){return n.block=t})),this.subscriptionsGroup.push(Qp.create(5e3).switchMap(function(){return n.blockchainService.coinSupply()}).subscribe(function(t){return n.coinSupply=t}))},n.prototype.ngOnDestroy=function(){this.subscriptionsGroup.forEach(function(n){return n.unsubscribe()})},n}(),Xp=function(){function n(n,t){this.data=n,this.dialogRef=t}return n.prototype.ngOnDestroy=function(){this.data.seed=null},n}(),Zp=function(){function n(n,t,e,l){var r=this;this.data=n,this.dialogRef=t,this.msgBarService=e,this.translateService=l,this.passwordSubmit=new yl.a,this.working=!1,this.subscriptions=[],this.data=Object.assign({confirm:!1,description:null,warning:!1,title:null,wallet:null},n||{}),this.translateService.get(["errors.incorrect-password","errors.api-disabled","errors.no-wallet"]).subscribe(function(n){r.errors=n})}return n.prototype.ngOnInit=function(){var n=this;this.form=new Fo({},this.validateForm.bind(this)),this.form.addControl("password",new No("")),this.form.addControl("confirm_password",new No("")),["password","confirm_password"].forEach(function(t){n.subscriptions.push(n.form.get(t).valueChanges.subscribe(function(){2===n.button.state&&n.button.resetState()}))}),this.data.confirm?this.form.get("confirm_password").enable():this.form.get("confirm_password").disable(),this.data.description&&this.dialogRef.updateSize("400px")},n.prototype.ngOnDestroy=function(){this.msgBarService.hide(),this.form.get("password").setValue(""),this.form.get("confirm_password").setValue(""),this.passwordSubmit.complete(),this.subscriptions.forEach(function(n){return n.unsubscribe()})},n.prototype.proceed=function(){this.form.valid&&!this.button.isLoading()&&(this.msgBarService.hide(),this.button.setLoading(),this.working=!0,this.passwordSubmit.next({password:this.form.get("password").value,close:this.close.bind(this),error:this.error.bind(this)}))},n.prototype.validateForm=function(){if(this.form&&this.form.get("password")&&this.form.get("confirm_password")){if(0===this.form.get("password").value.length)return{Required:!0};if(this.data.confirm&&this.form.get("password").value!==this.form.get("confirm_password").value)return{NotEqual:!0}}return null},n.prototype.close=function(){this.dialogRef.close()},n.prototype.error=function(n){if("object"==typeof n)if(n.status)switch(n.status){case 400:n=Oc(n._body);break;case 401:n=this.errors["errors.incorrect-password"];break;case 403:n=this.errors["errors.api-disabled"];break;case 404:n=this.errors["errors.no-wallet"];break;default:n=this.errors["errors.error-decrypting"]}else n=this.errors["errors.error-decrypting"];this.msgBarService.showError(n=n||this.errors["errors.error-decrypting"]),this.button.resetState(),this.working=!1},n}(),$p=function(){function n(n,t){this.walletService=n,this.dialog=t,this.wallets=[]}return n.prototype.ngOnInit=function(){var n=this;this.walletService.folder().subscribe(function(t){return n.folder=t}),this.walletSubscription=this.walletService.all().subscribe(function(t){n.wallets=t})},n.prototype.ngOnDestroy=function(){this.walletSubscription.unsubscribe()},Object.defineProperty(n.prototype,"onlyEncrypted",{get:function(){return this.wallets.filter(function(n){return n.encrypted})},enumerable:!0,configurable:!0}),n.prototype.showSeed=function(n){var t=this,e=new oa;e.data={wallet:n},this.dialog.open(Zp,e).componentInstance.passwordSubmit.subscribe(function(e){t.walletService.getWalletSeed(n,e.password).subscribe(function(n){e.close();var l=new oa;l.width="566px",l.data={seed:n},t.dialog.open(Xp,l)},function(n){return e.error(n)})})},n}(),nf=function(){function n(n,t){this.apiService=n,this.ngZone=t,this.noConnections=!1,this.automaticPeers=new Tl([]),this.loadData()}return n.prototype.automatic=function(){return this.automaticPeers.asObservable()},n.prototype.retrieveDefaultConnections=function(){return this.apiService.get("network/defaultConnections").map(function(n){return n.map(function(n,t){return{id:t+1,address:n,listen_port:6e3}})})},n.prototype.loadData=function(){var n=this;this.retrieveConnections().subscribe(function(t){return n.automaticPeers.next(t)}),this.ngZone.runOutsideAngular(function(){Qp.create(5e3).flatMap(function(){return n.retrieveConnections()}).subscribe(function(t){return n.ngZone.run(function(){n.automaticPeers.next(t)})})})},n.prototype.retrieveConnections=function(){var n=this;return this.apiService.get("network/connections").map(function(t){return null===t.connections||0===t.connections.length?(n.noConnections=!0,[]):(n.noConnections=!1,t.connections.sort(function(n,t){return n.id-t.id}))})},n}(),tf=function(){function n(n){this.networkService=n}return n.prototype.ngOnInit=function(){var n=this;this.subscription=this.networkService.retrieveDefaultConnections().subscribe(function(t){n.subscription=n.networkService.automatic().subscribe(function(e){n.peers=e.map(function(n){return n.source=t.find(function(t){return t.address===n.address})?"default":"exchange",n}).sort(function(n,t){return n.address.localeCompare(t.address)})})})},n.prototype.ngOnDestroy=function(){this.subscription.unsubscribe()},n}(),ef=function(){function n(n,t){this.httpClient=n,this.walletService=t,this.configSubject=new Tl(null),this.purchaseOrders=new Tl([]),this.purchaseUrl=r.tellerUrl,this.getConfig()}return n.prototype.all=function(){return this.purchaseOrders.asObservable()},n.prototype.config=function(){return this.configSubject.asObservable()},n.prototype.getConfig=function(){var n=this;return this.get("config").map(function(n){return{enabled:!0,sky_btc_exchange_rate:parseFloat(n.sky_btc_exchange_rate)}}).subscribe(function(t){return n.configSubject.next(t)})},n.prototype.generate=function(n){var t=this;return this.walletService.addAddress(n,1).flatMap(function(e){return t.post("bind",{skyaddr:e[0].address,coin_type:"BTC"}).map(function(t){return{coin_type:t.coin_type,deposit_address:t.deposit_address,filename:n.filename,recipient_address:e[0].address,status:"waiting_deposit"}})})},n.prototype.scan=function(n){return this.get("status?skyaddr="+n).map(function(n){if(!n.statuses||n.statuses.length>1)throw new Error("too many purchase orders found");return n.statuses[0]})},n.prototype.get=function(n){return this.httpClient.get(this.purchaseUrl+n)},n.prototype.post=function(n,t){return void 0===t&&(t={}),this.httpClient.post(this.purchaseUrl+n,t)},n}(),lf=function(){function n(n,t,e,l){this.formBuilder=n,this.purchaseService=t,this.msgBarService=e,this.walletService=l,this.subscriptionsGroup=[]}return n.prototype.ngOnInit=function(){this.initForm(),this.loadData()},n.prototype.ngOnDestroy=function(){this.subscriptionsGroup.forEach(function(n){return n.unsubscribe()})},n.prototype.checkStatus=function(){var n=this;this.button.setLoading(),this.purchaseService.scan(this.order.recipient_address).subscribe(function(t){n.button.setSuccess(),n.order.status=t.status},function(t){return n.button.setError(t)})},n.prototype.removeOrder=function(){window.localStorage.removeItem("purchaseOrder"),this.order=null},n.prototype.initForm=function(){var n=this;this.form=this.formBuilder.group({wallet:["",Xi.required]}),this.subscriptionsGroup.push(this.form.get("wallet").valueChanges.subscribe(function(t){var e=n.wallets.find(function(n){return n.filename===t});console.log("changing wallet value",t),n.purchaseService.generate(e).subscribe(function(t){return n.saveData(t)},function(t){return n.msgBarService.showError(t.toString())})}))},n.prototype.loadConfig=function(){var n=this;this.purchaseService.config().filter(function(n){return!!n&&!!n.sky_btc_exchange_rate}).first().subscribe(function(t){return n.config=t})},n.prototype.loadData=function(){var n=this;this.loadConfig(),this.loadOrder(),this.subscriptionsGroup.push(this.walletService.all().subscribe(function(t){n.wallets=t,n.order&&n.form.get("wallet").setValue(n.order.filename,{emitEvent:!1})}))},n.prototype.loadOrder=function(){var n=JSON.parse(window.localStorage.getItem("purchaseOrder"));n&&(this.order=n,this.updateOrder())},n.prototype.saveData=function(n){this.order=n,window.localStorage.setItem("purchaseOrder",JSON.stringify(n))},n.prototype.updateOrder=function(){var n=this;this.purchaseService.scan(this.order.recipient_address).first().subscribe(function(t){return n.order.status=t.status},function(n){return console.log(n)})},n}(),rf=function(){function n(n,t){this.http=n,this.ngZone=t,this.PRICE_API_ID="sky-skycoin",this.price=new Tl(null),this.updatePeriod=6e5,this.startTimer()}return n.prototype.startTimer=function(n){var t=this;void 0===n&&(n=0),this.timerSubscriptions&&this.timerSubscriptions.forEach(function(n){return n.unsubscribe()}),this.timerSubscriptions=[],this.ngZone.runOutsideAngular(function(){t.timerSubscriptions.push(o.a.timer(t.updatePeriod,t.updatePeriod).subscribe(function(){t.ngZone.run(function(){return t.lastPriceSubscription?null:t.loadPrice()})}))}),this.timerSubscriptions.push(o.a.of(1).delay(n).subscribe(function(){t.ngZone.run(function(){return t.loadPrice()})}))},n.prototype.loadPrice=function(){var n=this;this.PRICE_API_ID&&(this.lastPriceSubscription&&this.lastPriceSubscription.unsubscribe(),this.lastPriceSubscription=this.http.get("https://api.coinpaprika.com/v1/tickers/"+this.PRICE_API_ID+"?quotes=USD").subscribe(function(t){n.lastPriceSubscription=null,n.price.next(t.quotes.USD.price)},function(){return n.startTimer(3e4)}))},n}(),of=function(){function n(n,t){this.transaction=n,this.dialogRef=t}return n.prototype.closePopup=function(){this.dialogRef.close()},n}(),sf=function(){function n(n,t,e,l,r){var i=this;this.dialog=n,this.priceService=t,this.walletService=e,this.formBuilder=l,this.transactionsLoaded=!1,this.form=this.formBuilder.group({filter:[[]]}),this.routeSubscription=r.queryParams.subscribe(function(n){i.requestedAddress=n.addr?n.addr:"",i.showRequestedAddress()}),this.walletsSubscription=e.all().delay(1).flatMap(function(n){if(i.wallets)return i.walletService.transactions().first();i.wallets=[];var t=!1;return n.forEach(function(n){n.coins&&n.hours&&!t?(i.wallets.push({label:n.label,coins:n.coins.decimalPlaces(6).toString(),hours:n.hours.decimalPlaces(0).toString(),addresses:[],allAddressesSelected:!1}),n.addresses.forEach(function(n){n.coins&&n.hours&&!t?i.wallets[i.wallets.length-1].addresses.push({address:n.address,coins:n.coins.decimalPlaces(6).toString(),hours:n.hours.decimalPlaces(0).toString(),showingWholeWallet:!1}):t=!0})):t=!0}),t?(i.wallets=null,o.a.of(null)):i.walletService.transactions().first()}).subscribe(function(n){n&&(i.allTransactions=n,i.transactionsLoaded=!0,i.showRequestedAddress(),i.filterTransactions())})}return n.prototype.ngOnInit=function(){var n=this;this.priceSubscription=this.priceService.price.subscribe(function(t){return n.price=t}),this.filterSubscription=this.form.get("filter").valueChanges.subscribe(function(){return n.filterTransactions()})},n.prototype.ngOnDestroy=function(){this.priceSubscription.unsubscribe(),this.filterSubscription.unsubscribe(),this.walletsSubscription.unsubscribe(),this.routeSubscription.unsubscribe()},n.prototype.showTransaction=function(n){var t=new oa;t.width="800px",t.data=n,this.dialog.open(of,t)},n.prototype.showQrCode=function(n,t){n.stopPropagation(),qp.openDialog(this.dialog,{address:t})},n.prototype.removeFilters=function(){this.form.get("filter").setValue([])},n.prototype.filterTransactions=function(){var n=this.form.get("filter").value;if(this.wallets.forEach(function(n){n.allAddressesSelected=!1,n.addresses.forEach(function(n){return n.showingWholeWallet=!1})}),0===n.length)this.transactions=this.allTransactions;else{var t=new Map;n.forEach(function(n){n.addresses?(n.addresses.forEach(function(n){return t.set(n.address,!0)}),n.allAddressesSelected=!0,n.addresses.forEach(function(n){return n.showingWholeWallet=!0})):t.set(n.address,!0)}),this.transactions=this.allTransactions.filter(function(n){return n.inputs.some(function(n){return t.has(n.owner)})||n.outputs.some(function(n){return t.has(n.dst)})})}},n.prototype.showRequestedAddress=function(){var n,t=this;this.transactionsLoaded&&this.wallets&&0!==this.wallets.length&&null!==this.requestedAddress&&void 0!==this.requestedAddress&&(""!==this.requestedAddress?(this.wallets.forEach(function(e){var l=e.addresses.find(function(n){return n.address===t.requestedAddress});l&&(n=l)}),n&&this.form.get("filter").setValue([n])):this.form.get("filter").setValue([]),this.requestedAddress=null)},n}(),af=function(){function n(n,t){this.walletService=n,this.router=t}return n.prototype.canActivate=function(n,t){var e=this;return new Promise(function(n){e.walletService.all().first().subscribe(function(t){return 0===t.length?(e.router.navigate(["/wizard"]),n(!1)):n(!0)})})},n}(),uf=function(){function n(n){this.formBuilder=n,this.onPasswordCreated=new l.o,this.onBack=new l.o}return n.prototype.ngOnInit=function(){this.initEncryptForm()},n.prototype.initEncryptForm=function(){this.form=this.formBuilder.group({password:new No("",Xi.compose([Xi.required,Xi.minLength(2)])),confirm:new No("",Xi.compose([Xi.required,Xi.minLength(2)]))},{validator:this.passwordMatchValidator.bind(this)})},n.prototype.setEncrypt=function(n){n.checked?this.form.enable():this.form.disable()},n.prototype.emitCreatedPassword=function(){this.form.enabled&&!this.form.valid||this.button.isLoading()||(this.button.setLoading(),this.onPasswordCreated.emit(this.form.enabled?this.form.get("password").value:null))},n.prototype.emitBack=function(){this.onBack.emit()},n.prototype.resetButton=function(){this.button.resetState()},Object.defineProperty(n.prototype,"isWorking",{get:function(){return this.button.isLoading()},enumerable:!0,configurable:!0}),n.prototype.passwordMatchValidator=function(n){return n.get("password").value===n.get("confirm").value?null:{mismatch:!0}},n}(),cf=function(){function n(n,t,e,l,r){this.router=n,this.walletService=t,this.languageService=e,this.dialog=l,this.msgBarService=r,this.step=1}return n.prototype.ngOnInit=function(){var n=this;this.subscription=this.languageService.currentLanguage.subscribe(function(t){return n.language=t})},n.prototype.ngOnDestroy=function(){this.subscription.unsubscribe()},n.prototype.onLabelAndSeedCreated=function(n){this.formData=n,this.step=2},n.prototype.onPasswordCreated=function(n){this.password=n,this.createWallet()},n.prototype.onBack=function(){this.step=1},n.prototype.changelanguage=function(){var n=this;zc(this.dialog).subscribe(function(t){t&&n.languageService.changeLanguage(t)})},Object.defineProperty(n.prototype,"fill",{get:function(){return this.formData},enumerable:!0,configurable:!0}),n.prototype.createWallet=function(){var n=this;this.walletService.create(this.formData.label,this.formData.seed,100,this.password).subscribe(function(){n.router.navigate(["/wallets"])},function(t){n.msgBarService.showError(t),n.encryptForm.resetButton()})},n}(),df=function(){function n(n,t,e,l,r){var i=this;this.formBuilder=n,this.route=t,this.router=e,this.walletService=l,this.msgBarService=r,this.done=!1,this.hideBarWhenClosing=!0,this.initForm(""),this.subscription=o.a.zip(this.route.params,this.walletService.all(),function(n,t){var e=t.find(function(t){return t.filename===n.id});e?(i.wallet=e,i.initForm(e.label)):setTimeout(function(){return i.router.navigate([""],{skipLocationChange:!0})})}).subscribe()}return n.prototype.ngOnDestroy=function(){this.subscription.unsubscribe(),this.hideBarWhenClosing&&this.msgBarService.hide()},n.prototype.initForm=function(n){var t=[];t.push(this.passwordMatchValidator.bind(this)),this.form=new Fo({},t),this.form.addControl("wallet",new No(n)),this.form.addControl("seed",new No("",[Xi.required])),this.form.addControl("password",new No),this.form.addControl("confirm",new No)},n.prototype.reset=function(){var n=this;!this.form.valid||this.resetButton.isLoading()||this.done||(this.msgBarService.hide(),this.resetButton.setLoading(),this.walletService.resetPassword(this.wallet,this.form.value.seed,""!==this.form.value.password?this.form.value.password:null).subscribe(function(){n.resetButton.setSuccess(),n.resetButton.setDisabled(),n.done=!0,n.hideBarWhenClosing=!1,n.msgBarService.showDone("reset.done"),setTimeout(function(){n.router.navigate([""])},2e3)},function(t){n.resetButton.resetState(),n.msgBarService.showError(t)}))},n.prototype.passwordMatchValidator=function(){return this.form&&this.form.get("password")&&this.form.get("confirm")&&this.form.get("password").value===this.form.get("confirm").value?null:{NotEqual:!0}},n}();o.a.prototype.repeatWhen=function(n){return function(n){return function(t){return t.lift(new fc(n))}}(n)(this)};var hf=this&&this.__assign||Object.assign||function(n){for(var t,e=1,l=arguments.length;e-1},n.prototype.post=function(n,t,e){var l=this;return this.http.post(this.buildUrl(n),t,{responseType:"json",headers:new Ma(hf({"api-key":this.API_KEY,Accept:"application/json"},e))}).catch(function(n){return l.apiService.processConnectionError(n)})},n.prototype.buildUrl=function(n){return this.TEST_MODE&&"trading_pairs"!==n?this.API_ENDPOINT+"sandbox/"+n:this.API_ENDPOINT+"/"+n},n.prototype.storeOrder=function(n,t){var e=this;return this.history().catch(function(n){try{if(n._body){var t=JSON.parse(n._body);if(t&&t.error&&404===t.error.code)return o.a.of([])}}catch(n){}return o.a.throw(n)}).flatMap(function(l){return e.storeOrderEntry(l,n,t)})},n.prototype.storeOrderEntry=function(n,t,e){var l={id:t.id,pair:t.pair,fromAmount:t.fromAmount,toAmount:t.toAmount,address:t.toAddress,timestamp:zp().unix(),price:e};n.push(l);var r=JSON.stringify(n);return n.pop(),this.storageService.store(ec.CLIENT,this.STORAGE_KEY,r).do(function(){return n.push(l)})},n}(),ff=function(){function n(n,t,e){this.dialogRef=n,this.blockchainService=t,this.exchangeService=e}return n.prototype.ngOnInit=function(){var n=this;this.exchangeService.history().subscribe(function(t){return n.orders=t.reverse()},function(){return n.orders=[]})},n.prototype.closePopup=function(){this.dialogRef.close()},n.prototype.select=function(n){this.dialogRef.close(n)},n.prototype.getFromCoin=function(n){return n.split("/")[0].toUpperCase()},n.prototype.getToCoin=function(n){return n.split("/")[1].toUpperCase()},n}(),_f=function(){function n(n,t){this.exchangeService=n,this.dialog=t,this.hasHistory=!1,this.loading=!0}return n.prototype.ngOnInit=function(){var n=this;this.lastViewedSubscription=this.exchangeService.lastViewedOrderLoaded.subscribe(function(t){if(t){var e=n.exchangeService.lastViewedOrder;e&&(n.currentOrderDetails=e),setTimeout(function(){return n.lastViewedSubscription.unsubscribe()}),n.loading=!1}}),this.historySubscription=this.exchangeService.history().subscribe(function(){return n.hasHistory=!0})},n.prototype.ngOnDestroy=function(){this.lastViewedSubscription.unsubscribe(),this.historySubscription.unsubscribe()},n.prototype.showStatus=function(n){this.currentOrderDetails=n,this.hasHistory=!0},n.prototype.showHistory=function(n){var t=this;n.preventDefault();var e=new oa;e.width="566px",e.autoFocus=!1,this.dialog.open(ff,e).afterClosed().subscribe(function(n){n&&(t.currentOrderDetails=n)})},n.prototype.goBack=function(){this.currentOrderDetails=null,this.exchangeService.lastViewedOrder=null},n}(),mf=function(){};o.a.prototype.takeWhile=function(n){return function(n){return function(t){return t.lift(new vc(n))}}(n)(this)};var gf=function(){function n(n,t){this.apiService=n,this.http=t,this.fullCoinName=" ",this.coinName=" ",this.hoursName=" ",this.hoursNameSingular=" ",this.explorerUrl=" ",this.burnRateInternal=new Ee.a(.5),this.updateAvailableInternal=!1,this.lastestVersionInternal=""}return Object.defineProperty(n.prototype,"burnRate",{get:function(){return this.burnRateInternal},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"updateAvailable",{get:function(){return this.updateAvailableInternal},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"lastestVersion",{get:function(){return this.lastestVersionInternal},enumerable:!0,configurable:!0}),n.prototype.testBackend=function(){var n=this;this.apiService.get("health").subscribe(function(t){n.version=t.version,n.detectUpdateAvailable(),n.burnRateInternal=new Ee.a(t.user_verify_transaction.burn_factor),n.fullCoinName=t.fiber.display_name,n.coinName=t.fiber.ticker,n.hoursName=t.fiber.coin_hours_display_name,n.hoursNameSingular=t.fiber.coin_hours_display_name_singular,n.explorerUrl=t.fiber.explorer_url,n.explorerUrl.endsWith("/")&&(n.explorerUrl=n.explorerUrl.substr(0,n.explorerUrl.length-1)),t.csrf_enabled||(n.error=3)},function(){return n.error=2})},n.prototype.detectUpdateAvailable=function(){var n=this;Ll.urlForVersionChecking&&this.http.get(Ll.urlForVersionChecking).retryWhen(function(n){return n.delay(3e4)}).subscribe(function(t){n.lastestVersionInternal=t.text().trim(),n.lastestVersionInternal.startsWith("v")&&(n.lastestVersionInternal=n.lastestVersionInternal.substr(1)),n.updateAvailableInternal=function(t,e){for(var l=n.lastestVersionInternal.split("."),r=t.split("-"),i=r[0].split("."),o=0;o<3;o++){var s=Number(l[o]),a=Number(i[o]);if(s>a)return!0;if(s0&&t<10?this.addNumber(t.toString()):8===n.keyCode?this.removeNumber():13===n.keyCode&&this.sendPin()},t.prototype.addNumber=function(n){var t=this.form.value.pin;t.length<8&&this.form.get("pin").setValue(t+n)},t.prototype.removeNumber=function(){var n=this.form.value.pin;this.form.get("pin").setValue(n.substring(0,n.length-1))},t.prototype.sendPin=function(){this.form.valid&&this.dialogRef.close(this.form.value.pin)},t}(Kc),vf=function(n){function t(t,e,l){var r=n.call(this,l,e)||this;return r.data=t,r.dialogRef=e,r}return Object(i.__extends)(t,n),t}(Kc),wf=function(){function n(n,t,e,l,r,i,o,s,a){this.appService=n,this.languageService=t,this.bip38WordList=o,this.dialog=s,this.msgBarService=a,r.requestPinComponent=bf,i.requestWordComponent=Hc,l.signTransactionConfirmationComponent=vf,e.initialLoadFailed.subscribe(function(n){n&&window.location.assign("assets/error-alert/index.html?2")})}return n.prototype.ngOnInit=function(){var n=this;this.appService.testBackend(),this.languageService.loadLanguageSettings();var t=this.languageService.selectedLanguageLoaded.subscribe(function(e){e||zc(n.dialog,!0).subscribe(function(t){t&&n.languageService.changeLanguage(t)}),t.unsubscribe(),n.msgBarService.msgBarComponent=n.msgBar})},n}(),xf=l._7({encapsulation:2,styles:[".mat-dialog-container{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);display:block;padding:24px;border-radius:2px;box-sizing:border-box;overflow:auto;outline:0;width:100%;height:100%}@media screen and (-ms-high-contrast:active){.mat-dialog-container{outline:solid 1px}}.mat-dialog-content{display:block;margin:0 -24px;padding:0 24px;max-height:65vh;overflow:auto;-webkit-overflow-scrolling:touch;-webkit-backface-visibility:hidden;backface-visibility:hidden}.mat-dialog-title{margin:0 0 20px;display:block}.mat-dialog-actions{padding:12px 0;display:flex;flex-wrap:wrap}.mat-dialog-actions:last-child{margin-bottom:-24px}.mat-dialog-actions[align=end]{justify-content:flex-end}.mat-dialog-actions[align=center]{justify-content:center}.mat-dialog-actions .mat-button+.mat-button,.mat-dialog-actions .mat-button+.mat-raised-button,.mat-dialog-actions .mat-raised-button+.mat-button,.mat-dialog-actions .mat-raised-button+.mat-raised-button{margin-left:8px}[dir=rtl] .mat-dialog-actions .mat-button+.mat-button,[dir=rtl] .mat-dialog-actions .mat-button+.mat-raised-button,[dir=rtl] .mat-dialog-actions .mat-raised-button+.mat-button,[dir=rtl] .mat-dialog-actions .mat-raised-button+.mat-raised-button{margin-left:0;margin-right:8px}"],data:{animation:[{type:7,name:"slideDialog",definitions:[{type:0,name:"enter",styles:{type:6,styles:{transform:"none",opacity:1},offset:null},options:void 0},{type:0,name:"void",styles:{type:6,styles:{transform:"translate3d(0, 25%, 0) scale(0.9)",opacity:0},offset:null},options:void 0},{type:0,name:"exit",styles:{type:6,styles:{transform:"translate3d(0, 25%, 0)",opacity:0},offset:null},options:void 0},{type:1,expr:"* => *",animation:{type:4,styles:null,timings:"400ms cubic-bezier(0.25, 0.8, 0.25, 1)"},options:null}],options:{}}]}});function Mf(n){return l._33(0,[(n()(),l._4(0,null,null,0))],null,null)}function kf(n){return l._33(0,[l._29(402653184,1,{_portalOutlet:0}),(n()(),l._4(16777216,null,null,1,null,Mf)),l._8(2,212992,[[1,4]],0,oi,[l.j,l.R],{portal:[0,"portal"]},null)],function(n,t){n(t,2,0,"")},null)}var Cf=l._5("mat-dialog-container",aa,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-dialog-container",[["class","mat-dialog-container"],["tabindex","-1"]],[[1,"role",0],[1,"aria-labelledby",0],[1,"aria-label",0],[1,"aria-describedby",0],[40,"@slideDialog",0]],[["component","@slideDialog.start"],["component","@slideDialog.done"]],function(n,t,e){var r=!0;return"component:@slideDialog.start"===t&&(r=!1!==l._22(n,1)._onAnimationStart(e)&&r),"component:@slideDialog.done"===t&&(r=!1!==l._22(n,1)._onAnimationDone(e)&&r),r},kf,xf)),l._8(1,49152,null,0,aa,[l.l,kr,l.h,[2,sn]],null,null)],null,function(n,t){n(t,0,0,null==l._22(t,1)._config?null:l._22(t,1)._config.role,null!=l._22(t,1)._config&&l._22(t,1)._config.ariaLabel?null:l._22(t,1)._ariaLabelledBy,null==l._22(t,1)._config?null:l._22(t,1)._config.ariaLabel,(null==l._22(t,1)._config?null:l._22(t,1)._config.ariaDescribedBy)||null,l._22(t,1)._state)})},{},{},[]),Sf=l._7({encapsulation:2,styles:[".mat-tooltip-panel{pointer-events:none!important}.mat-tooltip{color:#fff;border-radius:2px;margin:14px;max-width:250px;padding-left:8px;padding-right:8px}@media screen and (-ms-high-contrast:active){.mat-tooltip{outline:solid 1px}}"],data:{animation:[{type:7,name:"state",definitions:[{type:0,name:"initial, void, hidden",styles:{type:6,styles:{transform:"scale(0)"},offset:null},options:void 0},{type:0,name:"visible",styles:{type:6,styles:{transform:"scale(1)"},offset:null},options:void 0},{type:1,expr:"* => visible",animation:{type:4,styles:null,timings:"150ms cubic-bezier(0.0, 0.0, 0.2, 1)"},options:null},{type:1,expr:"* => hidden",animation:{type:4,styles:null,timings:"150ms cubic-bezier(0.4, 0.0, 1, 1)"},options:null}],options:{}}]}});function Of(n){return l._33(2,[(n()(),l._9(0,0,null,null,2,"div",[["class","mat-tooltip"]],[[4,"transform-origin",null],[24,"@state",0]],[[null,"@state.start"],[null,"@state.done"]],function(n,t,e){var l=!0,r=n.component;return"@state.start"===t&&(l=!1!==r._animationStart()&&l),"@state.done"===t&&(l=!1!==r._animationDone(e)&&l),l},null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(n()(),l._31(2,null,["",""]))],function(n,t){n(t,1,0,"mat-tooltip",t.component.tooltipClass)},function(n,t){var e=t.component;n(t,0,0,e._transformOrigin,e._visibility),n(t,2,0,e.message)})}var Tf=l._5("mat-tooltip-component",Ru,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-tooltip-component",[["aria-hidden","true"]],[[4,"zoom",null]],[["body","click"]],function(n,t,e){var r=!0;return"body:click"===t&&(r=!1!==l._22(n,1)._handleBodyInteraction()&&r),r},Of,Sf)),l._8(1,49152,null,0,Ru,[l.h],null,null)],null,function(n,t){n(t,0,0,"visible"===l._22(t,1)._visibility?1:null)})},{},{},[]),Lf=l._7({encapsulation:2,styles:[".mat-progress-spinner{display:block;position:relative}.mat-progress-spinner svg{position:absolute;transform:rotate(-90deg);top:0;left:0;transform-origin:center;overflow:visible}.mat-progress-spinner circle{fill:transparent;transform-origin:center;transition:stroke-dashoffset 225ms linear}.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate]{animation:mat-progress-spinner-linear-rotate 2s linear infinite}.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate] circle{transition-property:stroke;animation-duration:4s;animation-timing-function:cubic-bezier(.35,0,.25,1);animation-iteration-count:infinite}.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate]{animation:mat-progress-spinner-stroke-rotate-fallback 10s cubic-bezier(.87,.03,.33,1) infinite}.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate] circle{transition-property:stroke}@keyframes mat-progress-spinner-linear-rotate{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes mat-progress-spinner-stroke-rotate-100{0%{stroke-dashoffset:268.60617px;transform:rotate(0)}12.5%{stroke-dashoffset:56.54867px;transform:rotate(0)}12.51%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(72.5deg)}25%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(72.5deg)}25.1%{stroke-dashoffset:268.60617px;transform:rotate(270deg)}37.5%{stroke-dashoffset:56.54867px;transform:rotate(270deg)}37.51%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(161.5deg)}50%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(161.5deg)}50.01%{stroke-dashoffset:268.60617px;transform:rotate(180deg)}62.5%{stroke-dashoffset:56.54867px;transform:rotate(180deg)}62.51%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(251.5deg)}75%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(251.5deg)}75.01%{stroke-dashoffset:268.60617px;transform:rotate(90deg)}87.5%{stroke-dashoffset:56.54867px;transform:rotate(90deg)}87.51%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(341.5deg)}100%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(341.5deg)}}@keyframes mat-progress-spinner-stroke-rotate-fallback{0%{transform:rotate(0)}25%{transform:rotate(1170deg)}50%{transform:rotate(2340deg)}75%{transform:rotate(3510deg)}100%{transform:rotate(4680deg)}}"],data:{}});function Pf(n){return l._33(2,[(n()(),l._9(0,0,null,null,1,":svg:svg",[["focusable","false"],["preserveAspectRatio","xMidYMid meet"]],[[4,"width","px"],[4,"height","px"],[1,"viewBox",0]],null,null,null,null)),(n()(),l._9(1,0,null,null,0,":svg:circle",[["cx","50%"],["cy","50%"]],[[1,"r",0],[4,"animation-name",null],[4,"stroke-dashoffset","px"],[4,"stroke-dasharray","px"],[4,"stroke-width","%"]],null,null,null,null))],null,function(n,t){var e=t.component;n(t,0,0,e._elementSize,e._elementSize,e._viewBox),n(t,1,0,e._circleRadius,"mat-progress-spinner-stroke-rotate-"+e.diameter,e._strokeDashOffset,e._strokeCircumference,e._circleStrokeWidth)})}var Df=l._7({encapsulation:2,styles:[".mat-menu-panel{min-width:112px;max-width:280px;overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 48px);border-radius:2px;outline:0}.mat-menu-panel:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-menu-panel.mat-menu-after.mat-menu-below{transform-origin:left top}.mat-menu-panel.mat-menu-after.mat-menu-above{transform-origin:left bottom}.mat-menu-panel.mat-menu-before.mat-menu-below{transform-origin:right top}.mat-menu-panel.mat-menu-before.mat-menu-above{transform-origin:right bottom}[dir=rtl] .mat-menu-panel.mat-menu-after.mat-menu-below{transform-origin:right top}[dir=rtl] .mat-menu-panel.mat-menu-after.mat-menu-above{transform-origin:right bottom}[dir=rtl] .mat-menu-panel.mat-menu-before.mat-menu-below{transform-origin:left top}[dir=rtl] .mat-menu-panel.mat-menu-before.mat-menu-above{transform-origin:left bottom}.mat-menu-panel.ng-animating{pointer-events:none}@media screen and (-ms-high-contrast:active){.mat-menu-panel{outline:solid 1px}}.mat-menu-content{padding-top:8px;padding-bottom:8px}.mat-menu-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;position:relative}.mat-menu-item[disabled]{cursor:default}[dir=rtl] .mat-menu-item{text-align:right}.mat-menu-item .mat-icon{margin-right:16px}[dir=rtl] .mat-menu-item .mat-icon{margin-left:16px;margin-right:0}.mat-menu-item .mat-icon{vertical-align:middle}.mat-menu-item-submenu-trigger{padding-right:32px}.mat-menu-item-submenu-trigger::after{width:0;height:0;border-style:solid;border-width:5px 0 5px 5px;border-color:transparent transparent transparent currentColor;content:'';display:inline-block;position:absolute;top:50%;right:16px;transform:translateY(-50%)}[dir=rtl] .mat-menu-item-submenu-trigger{padding-right:8px;padding-left:32px}[dir=rtl] .mat-menu-item-submenu-trigger::after{right:auto;left:16px;transform:rotateY(180deg) translateY(-50%)}button.mat-menu-item{width:100%}.mat-menu-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}"],data:{animation:[{type:7,name:"transformMenu",definitions:[{type:0,name:"void",styles:{type:6,styles:{opacity:0,transform:"scale(0.01, 0.01)"},offset:null},options:void 0},{type:0,name:"enter-start",styles:{type:6,styles:{opacity:1,transform:"scale(1, 0.5)"},offset:null},options:void 0},{type:0,name:"enter",styles:{type:6,styles:{transform:"scale(1, 1)"},offset:null},options:void 0},{type:1,expr:"void => enter-start",animation:{type:4,styles:null,timings:"100ms linear"},options:null},{type:1,expr:"enter-start => enter",animation:{type:4,styles:null,timings:"300ms cubic-bezier(0.25, 0.8, 0.25, 1)"},options:null},{type:1,expr:"* => void",animation:{type:4,styles:{type:6,styles:{opacity:0},offset:null},timings:"150ms 50ms linear"},options:null}],options:{}},{type:7,name:"fadeInItems",definitions:[{type:0,name:"showing",styles:{type:6,styles:{opacity:1},offset:null},options:void 0},{type:1,expr:"void => *",animation:[{type:6,styles:{opacity:0},offset:null},{type:4,styles:null,timings:"400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)"}],options:null}],options:{}}]}});function Af(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"div",[["class","mat-menu-panel"],["role","menu"],["tabindex","-1"]],[[24,"@transformMenu",0]],[[null,"keydown"],[null,"click"],[null,"@transformMenu.done"]],function(n,t,e){var l=!0,r=n.component;return"keydown"===t&&(l=!1!==r._handleKeydown(e)&&l),"click"===t&&(l=!1!==r.closed.emit("click")&&l),"@transformMenu.done"===t&&(l=!1!==r._onAnimationDone(e)&&l),l},null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(n()(),l._9(2,0,null,null,1,"div",[["class","mat-menu-content"]],[[24,"@fadeInItems",0]],null,null,null,null)),l._21(null,0)],function(n,t){n(t,1,0,"mat-menu-panel",t.component._classList)},function(n,t){n(t,0,0,t.component._panelAnimationState),n(t,2,0,"showing")})}function Ef(n){return l._33(2,[l._29(402653184,1,{templateRef:0}),(n()(),l._4(0,[[1,2]],null,0,null,Af))],null,null)}var Yf=l._7({encapsulation:2,styles:[],data:{}});function jf(n){return l._33(2,[l._21(null,0),(n()(),l._9(1,0,null,null,1,"div",[["class","mat-menu-ripple mat-ripple"],["matRipple",""]],[[2,"mat-ripple-unbounded",null]],null,null,null,null)),l._8(2,212992,null,0,ir,[l.l,l.B,Hl,[2,rr]],{disabled:[0,"disabled"],trigger:[1,"trigger"]},null)],function(n,t){var e=t.component;n(t,2,0,e.disableRipple||e.disabled,e._getHostElement())},function(n,t){n(t,1,0,l._22(t,2).unbounded)})}var If=function(){function n(n,t,e){this.decimalPipe=n,this.blockchainService=t,this.appService=e}return n.prototype.transform=function(n,t,e){void 0===t&&(t=!0),void 0===e&&(e="");var l="";return"last"!==e&&(l=this.decimalPipe.transform(n,t?"1.0-"+this.blockchainService.currentMaxDecimals:"1.0-0"),"first"!==e&&(l+=" ")),"first"!==e&&(l+=t?this.appService.coinName:1===Number(n)||-1===Number(n)?this.appService.hoursNameSingular:this.appService.hoursName),l},n}(),Rf=l._7({encapsulation:2,styles:[".mat-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px}"],data:{}});function Hf(n){return l._33(2,[l._21(null,0)],null,null)}var Nf=function(){function n(n,t,e){this.data=n,this.dialogRef=t,this.msgBarService=e}return n.prototype.ngOnInit=function(){this.form=new Fo({}),this.form.addControl("quantity",new No(1,[this.validateQuantity]))},n.prototype.ngOnDestroy=function(){this.msgBarService.hide()},n.prototype.closePopup=function(){this.dialogRef.close()},n.prototype.continue=function(){var n=this;this.button.isLoading()||(this.msgBarService.hide(),this.button.setLoading(),this.data(this.form.value.quantity,function(t,e){void 0===e&&(e=!1),n.button.resetState(),e?n.msgBarService.showError("wallet.add-addresses.error"):t&&n.closePopup()}))},n.prototype.validateQuantity=function(n){return n.value<1||n.value>100||Number(n.value)!==Math.round(Number(n.value))?{invalid:!0}:null},n}(),Ff=function(n){function t(t,e,l,r){var i=n.call(this,l,e)||this;return i.data=t,i.dialogRef=e,i.hwWalletService=l,i.walletService=r,i.operationSubscription=i.hwWalletService.confirmAddress(t.addressIndex).subscribe(function(){i.showResult({text:t.showCompleteConfirmation?"hardware-wallet.confirm-address.confirmation":"hardware-wallet.confirm-address.short-confirmation",icon:i.msgIcons.Success}),i.data.address.confirmed=!0,i.walletService.saveHardwareWallets()},function(n){return i.processResult(n.result)}),i}return Object(i.__extends)(t,n),t}(Kc),Bf=function(){function n(n,t,e,l,r,i,o){this.dialog=n,this.walletService=t,this.msgBarService=e,this.hwWalletService=l,this.translateService=r,this.router=i,this.apiService=o,this.confirmingIndex=null,this.creatingAddress=!1,this.preparingToEdit=!1}return n.prototype.ngOnDestroy=function(){this.msgBarService.hide(),this.editSubscription&&this.editSubscription.unsubscribe(),this.confirmSubscription&&this.confirmSubscription.unsubscribe(),this.txHistorySubscription&&this.txHistorySubscription.unsubscribe()},n.prototype.editWallet=function(){var n=this;if(this.msgBarService.hide(),this.wallet.isHardware){if(this.preparingToEdit)return;this.preparingToEdit=!0,this.editSubscription=this.hwWalletService.checkIfCorrectHwConnected(this.wallet.addresses[0].address).flatMap(function(){return n.walletService.getHwFeaturesAndUpdateData(n.wallet)}).subscribe(function(t){n.continueEditWallet(),n.preparingToEdit=!1,t.walletNameUpdated&&n.msgBarService.showWarning("hardware-wallet.general.name-updated")},function(t){n.msgBarService.showError(Tc(n.translateService,t)),n.preparingToEdit=!1})}else this.continueEditWallet()},n.prototype.newAddress=function(){var n=this;if(!this.creatingAddress)if(this.wallet.isHardware&&this.wallet.addresses.length>=Ll.maxHardwareWalletAddresses)Wc(this.dialog,{text:"wallet.max-hardware-wallets-error",headerText:"errors.error",confirmButtonText:"confirmation.close"});else if(this.msgBarService.hide(),this.wallet.isHardware)this.howManyAddresses=1,this.continueNewAddress();else{var t=new oa;t.width="566px",t.data=function(t,e){n.howManyAddresses=t;var l=0;n.wallet.addresses.forEach(function(n,t){n.coins.isGreaterThan(0)&&(l=t)}),n.wallet.addresses.length-(l+1)+t<20?(e(!0),n.continueNewAddress()):n.txHistorySubscription=n.apiService.getTransactions(n.wallet.addresses).first().subscribe(function(l){var r=new Map;l.forEach(function(n){n.outputs.forEach(function(n){r.has(n.dst)||r.set(n.dst,!0)})});var i=0;n.wallet.addresses.forEach(function(n,t){r.has(n.address)&&(i=t)}),n.wallet.addresses.length-(i+1)+t<20?(e(!0),n.continueNewAddress()):Wc(n.dialog,{text:"wallet.add-many-confirmation",headerText:"confirmation.header-text",confirmButtonText:"confirmation.confirm-button",cancelButtonText:"confirmation.cancel-button"}).afterClosed().subscribe(function(t){t?(e(!0),n.continueNewAddress()):e(!1)})},function(){return e(!1,!0)})},this.dialog.open(Nf,t)}},n.prototype.toggleEmpty=function(){this.wallet.hideEmpty=!this.wallet.hideEmpty},n.prototype.deleteWallet=function(){var n=this;this.msgBarService.hide();var t={text:this.translateService.instant("wallet.delete-confirmation",{name:this.wallet.label}),headerText:"confirmation.header-text",checkboxText:"wallet.delete-confirmation-check",confirmButtonText:"confirmation.confirm-button",cancelButtonText:"confirmation.cancel-button"};Wc(this.dialog,t).afterClosed().subscribe(function(t){t&&n.walletService.deleteHardwareWallet(n.wallet).subscribe(function(t){t&&n.walletService.all().first().subscribe(function(t){0===t.length&&setTimeout(function(){return n.router.navigate(["/wizard"])},500)})})})},n.prototype.toggleEncryption=function(){var n=this,t=new oa;t.data={confirm:!this.wallet.encrypted,title:this.wallet.encrypted?"wallet.decrypt":"wallet.encrypt"},this.wallet.encrypted?(t.data.description="wallet.decrypt-warning",t.data.warning=!0,t.data.wallet=this.wallet):t.data.description="wallet.new.encrypt-warning",this.dialog.open(Zp,t).componentInstance.passwordSubmit.subscribe(function(t){n.walletService.toggleEncryption(n.wallet,t.password).subscribe(function(){t.close(),setTimeout(function(){return n.msgBarService.showDone("common.changes-made")})},function(n){return t.error(n)})})},n.prototype.confirmAddress=function(n,t,e){var l=this;null===this.confirmingIndex&&(this.confirmingIndex=t,this.msgBarService.hide(),this.confirmSubscription&&this.confirmSubscription.unsubscribe(),this.confirmSubscription=this.hwWalletService.checkIfCorrectHwConnected(this.wallet.addresses[0].address).subscribe(function(r){var i=new function(){};i.address=n,i.addressIndex=t,i.showCompleteConfirmation=e;var o=new oa;o.width="566px",o.autoFocus=!1,o.data=i,l.dialog.open(Ff,o),l.confirmingIndex=null},function(n){l.msgBarService.showError(Tc(l.translateService,n)),l.confirmingIndex=null}))},n.prototype.copyAddress=function(n,t,e){void 0===e&&(e=500),n.stopPropagation(),t.copying||(Uc(t.address),t.copying=!0,setTimeout(function(){t.copying=!1},e))},n.prototype.showQrCode=function(n,t){n.stopPropagation(),qp.openDialog(this.dialog,{address:t})},n.prototype.continueNewAddress=function(){var n=this;if(this.creatingAddress=!0,!this.wallet.isHardware&&this.wallet.encrypted){var t=new oa;t.data={wallet:this.wallet};var e=this.dialog.open(Zp,t);e.afterClosed().subscribe(function(){return n.creatingAddress=!1}),e.componentInstance.passwordSubmit.subscribe(function(t){n.walletService.addAddress(n.wallet,n.howManyAddresses,t.password).subscribe(function(){return t.close()},function(n){return t.error(n)})})}else(this.wallet.isHardware?this.hwWalletService.checkIfCorrectHwConnected(this.wallet.addresses[0].address).flatMap(function(){return n.walletService.addAddress(n.wallet,n.howManyAddresses)}):this.walletService.addAddress(this.wallet,this.howManyAddresses)).subscribe(function(){return n.creatingAddress=!1},function(t){n.msgBarService.showError(n.wallet.isHardware?Tc(n.translateService,t):t),n.creatingAddress=!1})},n.prototype.continueEditWallet=function(){var n=new oa;n.width="566px",n.data=new $c,n.data.wallet=this.wallet,this.dialog.open(nd,n)},n}(),Vf=l._7({encapsulation:0,styles:[[".-record[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:13px;padding:21px 20px 16px;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.-record[_ngcontent-%COMP%]:not(:last-of-type){border-bottom:1px solid rgba(30,34,39,.05)}.-record[_ngcontent-%COMP%] .id-column[_ngcontent-%COMP%]{width:50px;color:rgba(30,34,39,.5);-ms-flex-negative:0;flex-shrink:0}.-record[_ngcontent-%COMP%] .address-column[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.-record[_ngcontent-%COMP%] .address-column[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{display:inline-block;height:17px;vertical-align:middle;width:17px;margin-right:10px;-ms-flex-negative:0;flex-shrink:0}.-record[_ngcontent-%COMP%] .address-column[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{display:inline-block;margin:0;vertical-align:middle;word-break:break-all}.-record[_ngcontent-%COMP%] .address-column[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:hover .copy-label[_ngcontent-%COMP%]{opacity:.999!important}.-record[_ngcontent-%COMP%] .truncated-address[_ngcontent-%COMP%]{max-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;vertical-align:middle}.-record[_ngcontent-%COMP%] .hours-column[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);width:130px;text-align:right;-ms-flex-negative:0;flex-shrink:0}.-record[_ngcontent-%COMP%] .coins-column[_ngcontent-%COMP%]{color:#1e2227;width:130px;text-align:right;-ms-flex-negative:0;flex-shrink:0}.-record[_ngcontent-%COMP%] .options-column[_ngcontent-%COMP%]{width:80px;text-align:right;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-ms-flex-negative:0;flex-shrink:0}.-record[_ngcontent-%COMP%] .options-column[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{cursor:pointer;color:rgba(97,109,125,.5)}.-record[_ngcontent-%COMP%] .options-column[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]:hover{color:#0072ff}.-record[_ngcontent-%COMP%] > img[_ngcontent-%COMP%]{display:inline-block;margin-left:0;height:32px;width:32px}.click-to-copy[_ngcontent-%COMP%]{cursor:pointer}.-actions[_ngcontent-%COMP%]{background-color:#fefefe;border-bottom:1px solid #eff0f0;display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;-webkit-box-shadow:0 4px 10px rgba(0,0,0,.03)!important;box-shadow:0 4px 10px rgba(0,0,0,.03)!important;border-top-left-radius:0!important;border-top-right-radius:0!important;z-index:100;position:relative;padding:0!important}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%]{padding-right:20px;padding-left:0}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%]:first-child{padding-left:5px}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] .-enabled-span[_ngcontent-%COMP%]{cursor:pointer}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] .-enabled-span[_ngcontent-%COMP%]:hover{color:rgba(30,34,39,.5)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:#cecfd0;font-size:12px;height:60px;margin:0 5px;cursor:pointer;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span.-img[_ngcontent-%COMP%]::before{content:'';display:inline-block;height:32px;width:32px;margin-right:5px;background-repeat:no-repeat;background-size:32px 32px}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span.-new-address[_ngcontent-%COMP%]::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAANpSURBVHgB7ZndcdswDIBBOQO4G6gTxOzfa9IJmk6QdoK6E8TeIJkg6QRtJqj72l4qZ4JyBA8QiwUk2qVoWbJFyNdc8N3pbFIS+AcCIAQgCIIgCIIgCIIgCMJTQ8GByLJsiD9n2OSJBRjh/xSvobu9wMtgZ+Z4fwaQ32qtF3AAep8AHHia5zBWiTqHfwNuBTt2A2CnOBEGeqS3CShXPLmwYMcQgQJ1iRox7UsjepkAWnUL6juUas4Bbg/7tg9tSICZn1k2ahj8AjViusTB4ICev9AjRRf+f0Z1NrdX+Iypea+YUJINzLBqQMPKGxzgx9daz3aU8wHlXNTJ4dYEtgmgPY+dziDoNK74FarZZN89TPLQeE7QeH4KbtEkaC6bcARsJLhiNvVrSN1faj2BDrgBju+ybKFKbViRlm3BZ2CARQOc6v/x62jlcfDj7e/cn+MzaOGBBogacvxl27N3d9llqAlkQzi2AosRtBYmQZUhtW98Byzdp7ggdROxlSQpZBm/jmILYCB6Agp/r4ogZ025oq17NPX+NwZIJIuMaKUNDKxcdBkFhwacBWXTpM5dcR7En9ThcrnR9t5ETwCq/2mlnNtb6AkXJ6wZDNQJRBKvAUod+8U8gW/QEyh75pfdoSoKDjeYBgLnftmz9o379Xc2t0GVCb0Dyja2oe0ucNiAysBC4+dZ+33Z8A41bu+/MIJtxHSy95wAxwRUOklBkV/OwVLEZqCDXHx3GsgeNrXdBQ4bYMAzRg/lvjSr8iutb6BIblQJ9zydCqGdUU3bUcRrgLX3FYF51S1ygtFfxe+rwOB2IXoC8DA/q5Q3T29soOx3Qc0MIuGwAeT3KxHaryw7BWYoRwAbbi+PDrqiJ4DcHkZoldB3AOp6hzjdnzTT9KDLNfhH4iJpypETYHGDeFoLT3OpO7NvxfMOG9a+poWa7FDbO7vBlhGqP7MXkVxURzGSvHDB1Jq2XMM+9J4S65rWbkirs6bEDpYUbcv6BHJOUc41PKak6ApKXR+B+gr1BxVDx+WkPDHOV6vooke8khO34nUG1DyAff9G62jf7yMfRqAHqKO0T8MERhfI4Lk9b6AHDvJxtEiaBnnDForYgtzro/04GrL6PF6k0MosUgo1n8cx+fljgNHloT6PC4IgCIIgCIIgCILw9PgL6Ap8qFzYW2UAAAAASUVORK5CYII=)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span.-hide-empty[_ngcontent-%COMP%]::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAANISURBVHgB7ZndcdswDIBBOQO4G6gTxOzfa9IJmk6QdIKmE8TewJkg6QStJ6j72p6PzgTlBvUAsVhAohqK1jm2CPkuF3x3uphyDJIgCIAggCAIgiAIgiAIgiAIzw0FB8IYM8Q/Z9jliQMY4eccn6H/eoWPxcEs8fs5QDHTWq/gAPSuAJx4XhRwqTJ1Dg8TfhQc2C2Am6AiLPRIbwqoVjy7cuAuIQEFaooWMenLInpRAK26A/UDKjPnALeHe9+HNWTAzC9jRlsmv0KLmKxxMjihl6/0SNGDn1/QO1e4a/wf2/K7UqEkG5hhtYAtK29xgp/eaj3fUc4Fyrlqk8NtCWwKoD2PgzYQDRpX/BrNbLzvHiZ56DzH6Dw/R1+REjSXTzgCNjJcMZeHb8jcX2s9hg74CV4ujFmpyhpq8qov+AIMsFiAN/0/4TtaeZx8UgSoWSzMNLYE8iEcW4HFCToH4+iVJbMHJrKslGXDd5RbAAPJFuD3/t+mUHWh9fFXYOS3MaeDysHWrLwVJPkCDgs4i9qWe/KEjyDhZIfr9Ubfe5OsADT/00a7cDPoCZ8n/GcwUCeQSLoFKHUcNosMvkNPoOx52PaHqiQ4wmAeCVyGbWPuzjEiYD6/+0HIg/FejcPthLKt29J3Fzh8QGNisVPCyY9h/8kTuVdcKNvClr67wH4WaCFlkL3XBDgU0BgkJUVhuwBHGZuFDnLxt5NI9nBb313g8AEWAmd0X+1LW7ffaH0LZXGDhVFL30mkW4Bzdw2BRTMscoLZXyPuq8jhdiFZAXiYnzfam6c3NlD2h+jNHBLh8AEU9xsZGqWtwAzVCGAj7BXJSVeyAijsYYbWSH0xZ79pcVid8eeN8EhcFk05agIsYRBPa9PoVe7P7ExkLdWhZoToLBkYoAQlztOpGoxZYLISSEZcWaZaA1dZrPeSWNey9payOmtJ7GBF0Tivf0TOKcq5gadUFK2h0vURqG/QflChrTLLqhPjsl5Fnz3ik534FW9zoPYe3Md3WifH/hC5GIEeoIHSPo0dYxfI4fk9b6EHDnI5WhZNVXk5uitlbkHh9clejsbU1+NlCa2qIuXQcj2ON0g/B5hdHup6XBAEQRAEQRAEQRCE58c/90hmWzuzaIoAAAAASUVORK5CYII=)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span.-show-empty[_ngcontent-%COMP%]::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAANpSURBVHgB7ZndcdswDIBBOQO4G6gTxOzfa9IJmk6QdoK6E8TeIJkg6QRtJqj72l4qZ4JyBA8QiwUk2qVoWbJFyNdc8N3pbFIS+AcCIAQgCIIgCIIgCIIgCMJTQ8GByLJsiD9n2OSJBRjh/xSvobu9wMtgZ+Z4fwaQ32qtF3AAep8AHHia5zBWiTqHfwNuBTt2A2CnOBEGeqS3CShXPLmwYMcQgQJ1iRox7UsjepkAWnUL6juUas4Bbg/7tg9tSICZn1k2ahj8AjViusTB4ICev9AjRRf+f0Z1NrdX+Iypea+YUJINzLBqQMPKGxzgx9daz3aU8wHlXNTJ4dYEtgmgPY+dziDoNK74FarZZN89TPLQeE7QeH4KbtEkaC6bcARsJLhiNvVrSN1faj2BDrgBju+ybKFKbViRlm3BZ2CARQOc6v/x62jlcfDj7e/cn+MzaOGBBogacvxl27N3d9llqAlkQzi2AosRtBYmQZUhtW98Byzdp7ggdROxlSQpZBm/jmILYCB6Agp/r4ogZ025oq17NPX+NwZIJIuMaKUNDKxcdBkFhwacBWXTpM5dcR7En9ThcrnR9t5ETwCq/2mlnNtb6AkXJ6wZDNQJRBKvAUod+8U8gW/QEyh75pfdoSoKDjeYBgLnftmz9o379Xc2t0GVCb0Dyja2oe0ucNiAysBC4+dZ+33Z8A41bu+/MIJtxHSy95wAxwRUOklBkV/OwVLEZqCDXHx3GsgeNrXdBQ4bYMAzRg/lvjSr8iutb6BIblQJ9zydCqGdUU3bUcRrgLX3FYF51S1ygtFfxe+rwOB2IXoC8DA/q5Q3T29soOx3Qc0MIuGwAeT3KxHaryw7BWYoRwAbbi+PDrqiJ4DcHkZoldB3AOp6hzjdnzTT9KDLNfhH4iJpypETYHGDeFoLT3OpO7NvxfMOG9a+poWa7FDbO7vBlhGqP7MXkVxURzGSvHDB1Jq2XMM+9J4S65rWbkirs6bEDpYUbcv6BHJOUc41PKak6ApKXR+B+gr1BxVDx+WkPDHOV6vooke8khO34nUG1DyAff9G62jf7yMfRqAHqKO0T8MERhfI4Lk9b6AHDvJxtEiaBnnDForYgtzro/04GrL6PF6k0MosUgo1n8cx+fljgNHloT6PC4IgCIIgCIIgCILw9PgL6Ap8qFzYW2UAAAAASUVORK5CYII=)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span.-enable-encryption[_ngcontent-%COMP%]::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAKbSURBVHgB7ZnRbdswEIZ/MhkgI7gTxKzdhz41mSAdIZ2gyQS1J0g8QdIJ6kzQvMcu1QmiEfzYAonYO1stZNaIDfdOcOH7AMMSIRK644n87wgYhmEYhmEYhmEY+4dDi8QYj6oK5967d3TbTUCnfomC/sqqSne9XrhFi7TmgEmM7z3cDV0erXm0TFUatuUIjxaI8fsVGf8F641nOs67G+rzCS2gHgFsSEIaYAsc3HUIx5dQRDUCpjGerzB+Rm3DZ6TT16Hr+PeEFID0Oe9Pz13wpwNFVCPgWyweUS90NeVPMvxtCOWq52mR7CS4r1mfmUN6FUKYQQG1CODZx7IheMl4howsydhTumwaO985oISaA7xzZ817CrXbl4z/DTuBdoHRUl+HEyihtwYkdLOGETak8rhfanDuGEqoOSBl4U8zW2za900I91lTB0q0ogN2mb13wCFagrbEhB1EXAdwwkOBxervAoKwKqTlcSitB0QdwMbXQqYLHQrWCZJOEF4DPCcwWsZjMbYXTZLEIqCWsY9Zc0ma/wMtNMU2s1an0FfItkHOI1ZslVshFwHO5TPDsjbwi24bsv0Qxm6eKKFstvsKYgmSmANSpvyq53Qp8a3yGBxFzTaqF5xBCMk1YMkB/X4YQ4jDRcmsSQdC/BdCSCsVZkwKY88xB2DPMQdAiUVStPuIOcBlau1JMCeYTP4qjW9cXVqHmAP4XK95fwA+3fn3KOAx/ME8H/iD20kHeOTKj5OjuGL2NoINf3iIJzwGMuX3gw5WIIRoPWA6jdek0z9CESq0jHohiBVbRBdB7zGAYHiuoKAXHkAQUQewZueKTX6wIQHPvHQ1iFE7G1wUSHi25oca2+4IJRl+VwFjqQKIYRiGYRiGYRiGYRjGL/wq6dJf5iBxAAAAAElFTkSuQmCC)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span.-disable-encryption[_ngcontent-%COMP%]::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAN+SURBVHgB7dlvT9pAGADw566tgAhUFJ0ijgSXidnM5t5s2YtlcS/2BfyUfoglvt5csmwMXFjYhij/W0H+lPZurQmmEKeId2SG+727o1T79Gm55zkAQRAEQRAEYTohmKS9PWn54HBhJoACQBUfAuq5+Cew3CK0Y5C2rB0fp6swQRMLQDz+TO3BeVyyXXccoWDQLhQmFQgJJiC6sbGGEIlh203HIgQSlkFVgxHQ9UoTOOMegIfJ5Aqy8ArcFoaA3xeSG436GXDENQDR6OaCfUdj7jmLEBMpUGxjODn5kcnp9crJrFfRFezFFMOs+1isSP750Fpb0047wAnXAIQiixtOSvfHFFA36JUy2XRaa1WrRn++2Wz2NK2iRVeWql0LVPvFJPc/Q3I3pO3uliGVosDBjc/kuJy7jxHMuOcCHnSUSqWMf33H+cw5xrL15wiRpMTh4QJwwi0A2CerA2MLqtddfJ9zjOyTi+45A9k/m5xwCwAl5sDzbJrN4qjfPSekOXgueRY44ZcBQ+mfz+fbI34VKplM47pzscQtAPeFDP+p39n0J5iAqc8AEQCYclMfAG7l8Hpi8wXckdMn6PbM9uksLsAIi6hxsK8F7KZH1DCiGPAc3BUlimQXSCGLLl9Uhu/fnbOuCdgGwL749c/fHmOKVGDMqQzVYi2o776pswwC0wBc3HkOF3/Jzgj/z2PMskfA7h2wtTWz3iVP3VNO+duWya+329ut/f19C25JjcfVgORb6/cO+1o6PapUBpfL42KWAQ/8CzHJ1dBwLv7lzpPvHw8OOqkxU7ajaZ2zeqUaDEfm3T0C7POYjVqRSRYw+xlE1PK5xw2rnR/nrl/BcrJo4G8RYx4YYRYARZYGSlYtl9OAEbs6bLnHLKvD+7IQYpFJVxJLYZhyIgAw5UQAgBe7LoB7gFkAnF1d93jxwxdmrWxnSewe90yrBYwwCwDFZt099gZRnEkW2OeYw96B/UUPkkZusd+EWZp6IhGqEHS5heXsCQYKpXA4tGaMtblpX/hiyZoL10qPhld+fh/OlstlJosjph2h1UQiJoOyBByZIJcK2a9/gBGmL8FCNltg+XwOc1pkr3eSBWCI9ZuaNvVa3R8OYQySHxhy7vyr58kcowrzErem6JbdIGm1yGrXLpOHK8VROT2FGZB0Xe5pw/uFgiAIgiAIgiAIgiAI4/oLaQBI2smc1O8AAAAASUVORK5CYII=)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span.-edit-wallet[_ngcontent-%COMP%]::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMiSURBVHgB7ZnbcdNAFIbPSvYzpgJEBfaSgdeYDkwFhA5CBXFKoIIkHdABziszILkCnArwc8bSco4jT1aypGgvkjzD+R680lq3/9fZsxcBMAzDMAzDMAzzPyLghIjjeILFAh/rXAFEVIflNgDxHSC7l1JuwDMnYwCKXygQN7g5qTtGgFhKOb0Gj5yEAXG8vlKglm2OxYi4PZOzL+CJwQ0wEX/ApwmDGlAjfot131BkQu1/BMEU9y8hzwkHfJkwmAF14negPn6QMikeG0eYH35AByYMYoCJ+OdzujEhgJ6pa/OY4S/rxBPUBQo0CDc3xfPg4lec3IAlvUbACwmvMQKer1EdCSme+17KFRjSWwQ0hL3EQL7D7ckIhf2M41nTdeoiIQRxBRb0EgFt2vzvOL7Fx/kMZpHwR69DY96ajhY7j4C2Ce+dlBemkYDFSq8Lw3AKhnRqgGm2NzUBlHrQdx8f09dgSGcG2HR1hJEJQrzRd1VYzAtt6MQAW/EH2phAOQCLuV43ghMwwFX8gSYTtK5QZ2UzXfbaC1RlZrAQr1PuHcb7ucLxOIC6U5t7eI0ApWBZqnIST5QjoXo4rK5t7+G3CYj9m9LZ0hsDR3QToEL8mZRLsMSbARj+84rqfVvNE5bLtSNaJivXu4onvBmQZVDM1Erd4y+FpZMJ9bNAd/GEzyYQ6TuYD1b5mN3ahK7FE94MEIEoDEPH4zDGbmlra0If4gmfEVBoAmmarqm0MaEv8YQXA/JBir6cvdUHJSYm9Cme8GJAkBYfFp6EFmhjQt/iCS8GCFEMf5WpddVxTSYMIZ7wkwNKCRAT4nn+meuIGhPmQ4gn/EQAHDWBWS6syYRP8DR7i4YSTzhPhkgkCvhb83eSv21ijn7j/F2hOftpbFR3zb7EEyNwp2nVZlY0R8FL9CmecG4CR0Nge+iT2Nc+xRPOEVDuAQzZ0DfAAMQKrbzDWZ/zzNEUZwOUEK9aJBIShuv5lPlFsoNsjTdO5ACCy7gbgPN0/Ky10KowlHG5OlMPKoAktFyq6gsvS2I0iNlhVj+Vt8owDMMwDMMwDMMwDNPEPw5aH3llqGexAAAAAElFTkSuQmCC)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span.-btn-delete[_ngcontent-%COMP%]::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkZGMEIyRDk3NzBFMDExRTg4QjAwOEEwQTk4MTI2NjcwIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkZGMEIyRDk4NzBFMDExRTg4QjAwOEEwQTk4MTI2NjcwIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RkYwQjJEOTU3MEUwMTFFODhCMDA4QTBBOTgxMjY2NzAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RkYwQjJEOTY3MEUwMTFFODhCMDA4QTBBOTgxMjY2NzAiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5XdpwRAAACxElEQVR42uyZPWsUURSGd9dYCakisdDKQomI2dJOSCoVQRSsFBE7Y6siSCJYqE1A4gcG0ySiBkVtBFHjxw/QjabQTlGI4AeYIFGIOz4Hz8IwbMaZ2ZnJneRceLhk5nLnvO+euXPPTdnzvNJybpXSMm9mgBlgBpgBZoAZYAaYAWaAGWAGmAFmgBlgBpgBqbVXtcn10JHCPJ3at2cRZzmLIzGCPUDXBdvhEtyodm/5kVD8BNyFaea46LwBBL2H7jZ8gdXwEw4R/HhC8V16aQ5uwUnmmnbSAE3597DKd7kOkzAADwh+PoF4f9sP15nHc3ENWBcQ33hGFe7D4RbFi5lbXV4Ev8KbkPt9COxNKL4R70Rav34WBsh7PxhyfxOMIrQvuKpHEC/tPOLvOJsBBPeL7ibsgxo0+6XWwCnYFlP8OeY/XojPoIraRXcNmu0F5KFTIgoeRxR/omg7wWfQD5+aGQ+bYWwxxWeaAb5M6KG78B+RiyI+l1oAAU/UAOfE51kMDcMOeBRx/EAe4nN5BQKvw9EI2fAN8R15xVTJUbx86o5FGDrL2L15xZVLBkT8zjfavNYO/Vo7eIU2IKb4YDsCl7M0oeKA+FpY7QC9hcyAqNtbeAcjIWM+6rhRMmGmEBkQY28vn7pxrfFfh5TYp6GnEBkQU3ywdrgKnQvUDrIwnpVzBS263MsARKzUGiDJ3v4pnIHPC9QO3VppHuQ5ZVdfAan3NybZ3nJ9Fob0dZgKmWODGuKkAXJw+baVvT1jpDweChnykjF1Vw34AA99f9cTFjZyjrBbxMIf3/UXpX8nzqm1tpQN+A1XYAXsBFkTxuIWNnpyfE/XlEEVvlZM4d5cUfYBchJcJeCRFuZo10x4DjPM9b3Q1WALRrRF+X/CkjVgSZTDZoAZYAaYAWaAGWAGmAFmgBlgBpgBZoAZYAaYAa60vwIMACj3FKsCfgkuAAAAAElFTkSuQmCC)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:hover{color:rgba(30,34,39,.5)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:hover.-new-address::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAM+SURBVHgB7ZnRbdswEIZ/OxnAnSAyMkDTCZpM0HSCJBMkncAU0AGSCepO0HSCJhMkfW4LMS999msBV+5RlGuLlGTJPBoBch9Aw6JESjwe745HQBAEQRAEQRAEQRCEl8YAuyJTI/zFKfbwlq6OqCRURuXdGRVN5ZGeuadnbjFWM+yA+ALIVEK/l1TOsRpwF6ZUUhKERkTiCcDMODChcoUwrkkIHxCJOAKws/4NVs050FROYmjDENxkyqzvpsGbdZ3CDAYY04AGRQFeFXU5bmAH65IUfdq+WeHVgOaZ11QuaLB36EKmzmGXT1LTD6sm8GmAXfP+4O2svuk8eMNYTYs2tu06Cawm9DGmreyDD3/GclL3Q6WwDdYNXtFgZ2XfS5LymsUw8iwBq/pZpc7M3qFq9gBP6RnyxTWMXRgOFA4mnxuf/aWuSVcvndoxx1LgWgIT51pTz6q1Rb4w940qJ6UgmrF96Wr7YPdadh2KXY/nTm3aIZJL1v63r2nb10WlbogzDlsQLgAT3lbRpRHjxRrRdaGOat7dm3AB2Nh+RY6viMdN67u3gMMGHDk93iIed2h79xZwuMHEuX6sXK2sfft6zdTCqdE13kFveHdvODSgOjDX+K2sfV987+C7vWdgBDcT8pHRcwIcAqh+5O+PB859E7FpbNdvWqnx3V6wgDhsgMa6MfozH9Pv0/9r6xKnXit3zdtd4SaOat4dRLgGLPC9cp3jGLHIPb//iEDCBZA7rsmP2fkY4p1Tc49AOAIh4/erEVqmjsHNzyJHkDi1wTFHuACM28vh7uQ+dYjT14WmW580fe15G64pR+aYxw0O4e7mEvg7RJeld/CtvU9ddmhTm07wpcRq9+wUyY0nYR/6lE7KYGrFplxDD/gEYFX+Af5MGe1Ie6trc1pdw6bYWIIkvkjQfpDJ9mrnjhnAQ2nEuvGjMKIPqB/8CeepEf+5gE1df0H9RkXDWO45bZn3yYcvB2JSanN6fn9A29uFGfSooe17ahPs+9eRgxHEwH5oXVq7P6u0ukYEdnM4uqCk5oByeN2xscWwOBfUiEh8ASyxVv2UhHFMb32NpuNxG97u7HhcEARBEARBEARBEISXxz+STv7SiHuLFAAAAABJRU5ErkJggg==)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:hover.-hide-empty::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkI5QTAxQTVDNzBERTExRTg4MkJCOEU1MUQyMjM4MDJGIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkI5QTAxQTVENzBERTExRTg4MkJCOEU1MUQyMjM4MDJGIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjlBMDFBNUE3MERFMTFFODgyQkI4RTUxRDIyMzgwMkYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjlBMDFBNUI3MERFMTFFODgyQkI4RTUxRDIyMzgwMkYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5A1duRAAACq0lEQVR42uyb3W3CMBCATdUBzAZhAmACYIKm75WgE0AHqAjqAJQJmkp9L0xQOgF0ArJBPUAlakuHhKwzzo+tGOVOugcMcXyfz5e7i2gdj0fWZLlhDRcCQAAIAAEgAASAABAAAkAACAABIABNlNuqE/w9f+T9KZcaSx1I7UmNYEyJkJpJ3UvdSt3AmN2Al4d6AeQQZehM6vjMYAxOD3QCY6nUBYC5yiOgjFpKPUidXjDeJBO4dlni2toBqF3fwc5XlRnMFV0LAOXGX4YFC3DrkdSO1BZoG8ZWBpePYM5e6ADUQj8R4zMwUBmaQKDLNDBb2G0F5hEBYZo7GADcsPNqV/tgYF5J4ZqVwRN4iADmiPEL2FVRYj4B1y4QCPPQAERIwFuBu1eVBPGEmauj4ApAgpz5xKF3JUhMmIUCgEOSoy9YOAQgIDCey9hFLHABIEZ2/93D43WrQeXIvWsBMNQ+bzxml3osGIQAoKt9XnsEsEWSrtoB6NF4j5zVX6nHgnpAYktmuXdtQVAPWHpA5CXBvloABBEEiwIqGv29igsAwuKWTyVreoFkgdw1IBcAbOcy1Sq/vNqGay8FvSwEAD+Wx6JLiS0BtxYA+qNp6hHAneXetQBYIxmaDy+YIMdrEwIAgaS+b8xtH48jJXAaShBkyPPaac1+odcQTDmcGWr2uSPjsV5DFhIAU82uxsq2tU9tda+9BpcA1HkcGRoXOySvt1WYWFs9g3uIEAGcFnhvSI5SKHBewUCufT8Ed1eFE9ZcNc1dSXy8GtvDLmFGRJAnTEuAHTEPr8l8FUNqoVhbu2wTpM88vSP0WQ2e2todVrxFJsDwDivfVq/tCGDeMAFDYjjrXWZ+Pf6NZJfepEX/F2i4EAACQAAIAAEgAASAABAAAkAACAABaKL8CzAAuPuelr6IAx8AAAAASUVORK5CYII=)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:hover.-show-empty::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAM+SURBVHgB7ZnRbdswEIZ/OxnAnSAyMkDTCZpM0HSCJBMkncAU0AGSCepO0HSCJhMkfW4LMS999msBV+5RlGuLlGTJPBoBch9Aw6JESjwe745HQBAEQRAEQRAEQRCEl8YAuyJTI/zFKfbwlq6OqCRURuXdGRVN5ZGeuadnbjFWM+yA+ALIVEK/l1TOsRpwF6ZUUhKERkTiCcDMODChcoUwrkkIHxCJOAKws/4NVs050FROYmjDENxkyqzvpsGbdZ3CDAYY04AGRQFeFXU5bmAH65IUfdq+WeHVgOaZ11QuaLB36EKmzmGXT1LTD6sm8GmAXfP+4O2svuk8eMNYTYs2tu06Cawm9DGmreyDD3/GclL3Q6WwDdYNXtFgZ2XfS5LymsUw8iwBq/pZpc7M3qFq9gBP6RnyxTWMXRgOFA4mnxuf/aWuSVcvndoxx1LgWgIT51pTz6q1Rb4w940qJ6UgmrF96Wr7YPdadh2KXY/nTm3aIZJL1v63r2nb10WlbogzDlsQLgAT3lbRpRHjxRrRdaGOat7dm3AB2Nh+RY6viMdN67u3gMMGHDk93iIed2h79xZwuMHEuX6sXK2sfft6zdTCqdE13kFveHdvODSgOjDX+K2sfV987+C7vWdgBDcT8pHRcwIcAqh+5O+PB859E7FpbNdvWqnx3V6wgDhsgMa6MfozH9Pv0/9r6xKnXit3zdtd4SaOat4dRLgGLPC9cp3jGLHIPb//iEDCBZA7rsmP2fkY4p1Tc49AOAIh4/erEVqmjsHNzyJHkDi1wTFHuACM28vh7uQ+dYjT14WmW580fe15G64pR+aYxw0O4e7mEvg7RJeld/CtvU9ddmhTm07wpcRq9+wUyY0nYR/6lE7KYGrFplxDD/gEYFX+Af5MGe1Ie6trc1pdw6bYWIIkvkjQfpDJ9mrnjhnAQ2nEuvGjMKIPqB/8CeepEf+5gE1df0H9RkXDWO45bZn3yYcvB2JSanN6fn9A29uFGfSooe17ahPs+9eRgxHEwH5oXVq7P6u0ukYEdnM4uqCk5oByeN2xscWwOBfUiEh8ASyxVv2UhHFMb32NpuNxG97u7HhcEARBEARBEARBEISXxz+STv7SiHuLFAAAAABJRU5ErkJggg==)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:hover.-enable-encryption::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAKESURBVHgB7ZnRbdswEIb/o+33jKAiddG3Ogsk1gTpBk0nqDtBnQkaT5B0groTKG0HqB6LukE0Qt6d6ELSChIqhm0IR8GB7wMEmLR00h2P1P0UoCiKoiiKoiiKouwehBbhLNmD6X0A0RDMA9uVVH/ltq8AY0pH/76hRVoLAGf772HMuf25t+bUwj7WuK1AGLQA/+p/tc5/x3rnHYm94oJ/v/mCFoieAd6RksdoAuGMDmefEZGoGcBZ/2SJ8ze279QeKR3NyB0ocWCP5ynPGPmpE5GoGcA/+9d4XOgcBcp5SmlRLD0/e5vA3GW1a2zA5q/sNTeIQLQM8KMfOoJVzjso/WsD1EnhnH7ErhvdE0Qi3hTo8HHQZlyscv6BRRB4EvaaISIRLwBMg7CNCTbnMmgZfodIxFwEk6cNSmc5NoTS/5erbEnSSh2wzex8ALpoCftKZGwh4hngBI8vfaXtWpteTAkjWghVas8VMgPEIa9qCbGiSDYDOj0nYGI5D297cQ8xxDKgKmOva92uqPkI3OZNRq2S0G46JcEfTkc8f1U2Qi4DzN241uPq/gP3oE1TltKrqbPhbQWwmEASnAK1ao3KkcRc9TZ8Fj3BmGMIIRiAsPSlw6sfEOO2XkUmEOJFFEKxpLBDS2HsOBoA7DgaAEQihnCJgWQAirDZFdMES7bGN95dWodcAMoyLHwMnUtkwUJhmlBe8zYGADStdVhx1PvT9MOG31fIXg+dDdQrP56fQgjh/YD9MztanxCTspxYkTSCEMKLoFeEYum5hLy6hxiiAVgot3nqRgnSOJvCu0GOaN8G/QaJGy2yMpmo2RuB7ZuF3eJKU6kNEEVRFEVRFEVRFEVRlHvYheXBAEeGBAAAAABJRU5ErkJggg==)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:hover.-disable-encryption::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAKZSURBVHgB7ZlRbtpAEIb/NfCeI1ClVH0ruUATnyA9QnqCNidIOEHCCUhP0OQETtsDlMdKtApHyDuxpzNrV8EGAXJnLSLPJ1liF1h7/p3dnRkDhmEYhmEYRjtxaBBK+gdA9wyd6BhEQ+7qF19N4dwcKd25eHaDBmlMAEoOPyCKJvzxYMtP58gwakqICA1A3wdXbPxXbDde6PNTTejHmws0QHAP8IZkdIk6OFy797NzBCSoB1AyOFtj/CP3jfiK3fHMycUuf8TXl9UB8NkvnYAE9QD6NnjA80Yn8PpexC6ez9f+PnnL7p8mlf+wYItX/J9HBCCYB/jZLxuCTcYLLv7FAnViiNHP5CdHIMItgQ6dltqEm03G/yMXgcbl3ugEgQgnALlhuY0xdue+1IroHQIRchPsLzf4XJ9iR1z8+37TWJo0EgfsM13sKf54bIDWe4AJgJbTegGCbTQcBhP+H64T8JUuRrsEUXVQF8AXPTq9C0lkoAlnhoUQqjmBqgDe+KgnycwQYZgW+YSaCLp7gMx8OOPhx87voYaaBxSp7EOlWxKbj8DTtM6sFWW0K6xklVxLWA2Xa6HnAZ20OjOS+x/Jg9Z1WRf/uZUx/FglSK1IoicAVVw/y8411qofw3vRElF0CiU094CSAH721HiqZpJ9KPEiAqFQ5TDBQmG0HBMALccEQCDyN8H7j6YA83Kzq5YTrHk9tnOFeRt6AmTZXXlkN9HwgjzD9PnAUuc+CgBXjfw4Oer9rPtyUwyn5PWJjIFq5EeLEZRQrgccXvNsfUJIsmzMYbZasUV5E0wvobg+1zAt7qGGqgB55raIZZagjYypXA0SwhVFpUAis+X4xaZz9U4E4pOFZHN1t1oFEMMwDMMwDMMwDMMwjL+78e87Hb4jwAAAAABJRU5ErkJggg==)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:hover.-edit-wallet::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMSSURBVHgB7ZrRcdpAEIb/w/BOB1EHIY8Z4gQ6oIM4FWRSgU0HSQXGJaQCMCTPIRUEVxA9Z4DLrrBmJCFpdNLqxIz3mzE6nWWs/7+93TsBoCiKoiiKoijKS8TgkljaIa4wQw8fYBE894bU/o4DVpiaHYS5HAPWdkZ3c0+tYclVd7g2cwhyGQZs7C1YXBUMFnhnPkGI7g1wER8jaEK3BuSJtzTnDb7RcUtHnv8j6v1M7SB1nZAJ3RlQJP6AKSW7bap/aQNKjss2TOjGABfxMS2Z0INviuf8l0LxDJdANshil+q3uMEPe4+a+I2A8oQX0nBMMS4xgSmKBLKISuQKjviLgKKw3+MNHR/A9f9Iwn7aUen7FEUCcIsa+ImAKnN+bRd0Nx/hEgl9/En19SgqxuYJDrQfAVUT3ntz4xwJoOVxkgNFkyPtGuCa7V1NsMiO9hCOtGdAnVLHuJhg8CpzvoMj7RhQV3xMFRM4BwCTVN/+EgxoKj6mzAQWP6C+NLW2y7JVIC8z1xGfJFsd/tGRxdvMOqBHCXDs/j/6kGRAtdgmzpuKZzgS1haRCRwJg2iDFGSumtcRz8hOAV6Wpt89BKKfZiSnQ574a3OHmsgZsLGTsz6+WQ7XU8KqD/89PyY7p5F4Rs6A7MhYPNLrtrEJccITHvkYSQNGmfMVlaUpmpjQsnhGzoAeXqfODQmfmrC2CR7EM5JJMB0BB5yych0TPIlnZAxYRouU5Do8TC1KXEzwKJ6RMeDq7GbPa3IVEzyLZ2QMyCbAI37nXldmQgfiGRkDsgmQazZ/zJVHngm8huhAPCOzF9jYX8gmQRa4j5bB+SvB4hGPaV0809wAHuk+/hb8dvs82pwnJvQaRNFypLYpFM54Ec803wz1UfbUZnRmDm+Wym33Jp5pbgAnQImJZKPt7pw+5PgKjzQ3gEPaoh78aNtEyfCRFk4L2vU13zk6IhEBwwrXhNHzOhbLJdJEuWFbmCA9ImHAAwmaJc5Z7IpaT9EnvANqv5X/ZocUMmXw9CgsuJRRVRRFURRFURRFURRFKeM/oxaTpik5gaYAAAAASUVORK5CYII=)}.-actions[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:hover.-btn-delete::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkYwRTIyQTZCNzBFMDExRTg4ODM5RUYyOTE4Q0I1M0FGIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkYwRTIyQTZDNzBFMDExRTg4ODM5RUYyOTE4Q0I1M0FGIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RjBFMjJBNjk3MEUwMTFFODg4MzlFRjI5MThDQjUzQUYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RjBFMjJBNkE3MEUwMTFFODg4MzlFRjI5MThDQjUzQUYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4w5yWGAAACxElEQVR42uyZTUgVURiG773ZSmxl2CJXLQzbZLtaBboqCcTATUVEu2zbH0QKLcqNEP5R6MYikyLdBFHZz6KlWEnUrmihYAkpYYLd6fnwXBiG2zQzd2Y8o9+Bh8G5h7nnfe6ZmfMd847j5LZyK+S2eFMBKkAFqAAVoAJUgApQASpABagAFaACVIAKiK0tHzi0B2pjuE6dOe5IYpz5JLbEGOwpDo1wBAbgfs30258Rw0/BY5jjGv3WC2DQ7RwewgLshF9whsGPRwzfaE6twAO4wrXmrBRgpvwXqHadLsI76IInDH4tQnh3Own3uI5j4zOg3hO+9B1NMAlnKwwvMg/a/BD8Dh98Pu8kYEvE8KXxTsX16ychQO77Xp/P98EoQTu9T/UA4aX1EP6RtTOAwf3mMAYdMAPlfqldcBUOhwx/k+tfzMRr0IQ6xmEYyq0F5EtnJRQ8Dxj+UmbWAa6Fywm4DLt9un7cqPCJCnCJaOZw6z8hNyR8KrUAAV4YAdaFT7MYugNH4VnA/l1phE/lFvDcDucDzIYfhK9Na0yFFMPLq+5CkK70PZ7WuFKZAQHf86W2ZmqHa6Z2cDItIGR4bzsHg0lKKFgQfsavdoCWTM6AoMtb+AwjPn2+mX6jzISlTMyAEGt7edWNmxr/vU+J3Q3NmZgBIcN7a4fbUPeP2kEejDdkX8EUXfbNAEJs5/Aq4tr+JVyH+XI/FOw3leZpvidv6y0g9f7eKMtbzi9Dn7kdZn2u0WCEWClANi4/VbK2p4+Ux30+XabpU7RVwFd46vq7GLGwkX2ENgkLf1zn3+TWd5xja1UxC1iFIdgGrSDPhLthCxuzczxhnim9JrjsKbTx2UpW1gGyE9zEgEcq3FSRmfAalrjWYqarwQpEVAX5f8KmFbApymEVoAJUgApQASpABagAFaACVIAKUAEqQAWoAFvaXwEGAEeBGUrXm8wHAAAAAElFTkSuQmCC)}@-webkit-keyframes floatup{50%{opacity:1}100%{-webkit-transform:translateY(-20px);transform:translateY(-20px);opacity:0}}@keyframes floatup{50%{opacity:1}100%{-webkit-transform:translateY(-20px);transform:translateY(-20px);opacity:0}}.copy-label[_ngcontent-%COMP%]{color:#0072ff;opacity:0;font-size:12px;position:relative;padding-left:10px}.copy-label[_ngcontent-%COMP%]::after{content:attr(data-label);position:absolute;white-space:nowrap;top:0;left:4px;opacity:0;line-height:1}.unconfirmed-label[_ngcontent-%COMP%]{opacity:.5!important}.copying[_ngcontent-%COMP%] .copy-label[_ngcontent-%COMP%]::after{-webkit-animation:.5s ease-in-out floatup;animation:.5s ease-in-out floatup}mat-spinner[_ngcontent-%COMP%]{margin-left:7px;margin-right:12px}mat-spinner[_ngcontent-%COMP%] circle{stroke:rgba(30,34,39,.2)}"]],data:{}});function Wf(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-spinner",[["class","in-button small mat-spinner mat-progress-spinner"],["mode","indeterminate"],["role","progressbar"]],[[4,"width","px"],[4,"height","px"]],null,null,Pf,Lf)),l._8(1,573440,null,0,Wu,[l.l,Hl,[2,sn]],null,null)],null,function(n,t){n(t,0,0,l._22(t,1)._elementSize,l._22(t,1)._elementSize)})}function zf(n){return l._33(0,[(n()(),l._9(0,0,null,null,24,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,12,"div",[["class","-button"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.newAddress()&&l),l},null,null)),l._8(3,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(4,{"mouse-disabled":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,7,"span",[],null,null,null,null,null)),l._8(7,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(8,{"-img -new-address":0,"-disabled-span":1,"-enabled-span":2}),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Wf)),l._8(11,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(12,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,7,"div",[["class","-button"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.toggleEmpty()&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,4,"span",[],null,null,null,null,null)),l._8(19,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(20,{"-img":0,"-show-empty":1,"-hide-empty":2}),(n()(),l._31(21,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,"-button",n(t,4,0,e.creatingAddress)),n(t,7,0,n(t,8,0,!e.creatingAddress,e.creatingAddress,!e.creatingAddress)),n(t,11,0,e.creatingAddress),n(t,19,0,n(t,20,0,!0,e.wallet.hideEmpty,!e.wallet.hideEmpty))},function(n,t){var e=t.component;n(t,12,0,l._32(t,12,0,l._22(t,13).transform(e.wallet.isHardware?"wallet.new-address":"wallet.new-addresses"))),n(t,21,0,l._32(t,21,0,l._22(t,22).transform("wallet."+(e.wallet.hideEmpty?"show":"hide")+"-empty")))})}function Uf(n){return l._33(0,[(n()(),l._9(0,0,null,null,5,"div",[["class","-button btn-delete-wallet"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.deleteWallet()&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"span",[["class","-img -btn-delete -enabled-span"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("wallet.delete")))})}function Gf(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[["class","-button"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.toggleEncryption()&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,4,"span",[],null,null,null,null,null)),l._8(3,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(4,{"-img":0,"-enable-encryption":1,"-disable-encryption":2}),(n()(),l._31(5,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,n(t,4,0,!0,!e.wallet.encrypted,e.wallet.encrypted))},function(n,t){var e=t.component;n(t,5,0,l._32(t,5,0,l._22(t,6).transform("wallet."+(e.wallet.encrypted?"decrypt":"encrypt"))))})}function qf(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-spinner",[["class","in-button small mat-spinner mat-progress-spinner"],["mode","indeterminate"],["role","progressbar"]],[[4,"width","px"],[4,"height","px"]],null,null,Pf,Lf)),l._8(1,573440,null,0,Wu,[l.l,Hl,[2,sn]],null,null)],null,function(n,t){n(t,0,0,l._22(t,1)._elementSize,l._22(t,1)._elementSize)})}function Jf(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-spinner",[["class","in-text small mat-spinner mat-progress-spinner"],["mode","indeterminate"],["role","progressbar"]],[[4,"width","px"],[4,"height","px"]],null,null,Pf,Lf)),l._8(1,573440,null,0,Wu,[l.l,Hl,[2,sn]],null,null)],null,function(n,t){n(t,0,0,l._22(t,1)._elementSize,l._22(t,1)._elementSize)})}function Qf(n){return l._33(0,[(n()(),l._9(0,0,null,null,16,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,0,"img",[["class","qr-code-button"],["src","../../../../../assets/img/qr-code-black.png"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.showQrCode(e,n.parent.parent.context.$implicit.address)&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,11,"p",[["class","click-to-copy"]],null,[[null,"click"],[null,"mouseleave"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.copyAddress(e,n.parent.parent.context.$implicit)&&l),"mouseleave"===t&&(l=0!=(n.parent.parent.context.$implicit.copying=!1)&&l),l},null,null)),l._8(5,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(6,{copying:0}),(n()(),l._31(7,null,["\n ","\n "])),(n()(),l._4(16777216,null,null,1,null,Jf)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,3,"span",[["class","copy-label"]],[[1,"data-label",0]],null,null,null,null)),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(13,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,5,0,"click-to-copy",n(t,6,0,t.parent.parent.context.$implicit.copying)),n(t,9,0,e.confirmingIndex===t.parent.parent.context.index)},function(n,t){n(t,7,0,t.parent.parent.context.$implicit.address),n(t,11,0,l._32(t,11,0,l._22(t,12).transform("wallet.address.copied"))),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("wallet.address.copy")))})}function Kf(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-spinner",[["class","in-text small mat-spinner mat-progress-spinner"],["mode","indeterminate"],["role","progressbar"]],[[4,"width","px"],[4,"height","px"]],null,null,Pf,Lf)),l._8(1,573440,null,0,Wu,[l.l,Hl,[2,sn]],null,null)],null,function(n,t){n(t,0,0,l._22(t,1)._elementSize,l._22(t,1)._elementSize)})}function Xf(n){return l._33(0,[(n()(),l._9(0,0,null,null,14,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,11,"p",[["class","click-to-copy"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.confirmAddress(n.parent.parent.context.$implicit,n.parent.parent.context.index,!0)&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,1,"span",[["class","truncated-address"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,5,"span",[["class","copy-label unconfirmed-label"]],null,null,null,null,null)),(n()(),l._31(8,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._4(16777216,null,null,1,null,Kf)),l._8(11,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,11,0,t.component.confirmingIndex===t.parent.parent.context.index)},function(n,t){n(t,5,0,t.parent.parent.context.$implicit.address),n(t,8,0,l._32(t,8,0,l._22(t,9).transform("wallet.address.show")))})}function Zf(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0,i=n.component;return"click"===t&&(r=!1!==l._22(n,1)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,1)._emitHoverEvent()&&r),"click"===t&&(r=!1!==i.copyAddress(e,n.parent.parent.context.$implicit,1e3)&&r),r},jf,Yf)),l._8(1,180224,[[1,4]],0,bu,[l.l],null,null),(n()(),l._31(2,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,0,0,l._22(t,1)._highlighted,l._22(t,1)._triggersSubmenu,l._22(t,1)._getTabIndex(),l._22(t,1).disabled.toString(),l._22(t,1).disabled||null),n(t,2,0,l._32(t,2,0,l._22(t,3).transform("wallet.address."+(t.parent.parent.context.$implicit.copying?"copied":"copy-address"))))})}function $f(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0,i=n.component;return"click"===t&&(r=!1!==l._22(n,1)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,1)._emitHoverEvent()&&r),"click"===t&&(r=!1!==i.confirmAddress(n.parent.parent.context.$implicit,n.parent.parent.context.index,!n.parent.parent.context.$implicit.confirmed)&&r),r},jf,Yf)),l._8(1,180224,[[1,4]],0,bu,[l.l],null,null),(n()(),l._31(2,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,0,0,l._22(t,1)._highlighted,l._22(t,1)._triggersSubmenu,l._22(t,1)._getTabIndex(),l._22(t,1).disabled.toString(),l._22(t,1).disabled||null),n(t,2,0,l._32(t,2,0,l._22(t,3).transform("wallet.address.confirm")))})}function n_(n){return l._33(0,[(n()(),l._9(0,0,null,null,54,"div",[["class","-record"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"div",[["class","id-column"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,7,"div",[["class","address-column"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Qf)),l._8(8,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Xf)),l._8(11,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"div",[["class","coins-column"]],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,2,"div",[["class","hours-column"]],null,null,null,null,null)),(n()(),l._31(19,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,31,"div",[["class","options-column"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,16777216,null,null,3,"mat-icon",[["aria-haspopup","true"],["class","mat-icon"],["role","img"]],null,[[null,"mousedown"],[null,"keydown"],[null,"click"]],function(n,t,e){var r=!0;return"mousedown"===t&&(r=!1!==l._22(n,26)._handleMousedown(e)&&r),"keydown"===t&&(r=!1!==l._22(n,26)._handleKeydown(e)&&r),"click"===t&&(r=!1!==l._22(n,26)._handleClick(e)&&r),r},Hf,Rf)),l._8(25,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(26,1196032,null,0,ku,[Pi,l.l,l.R,xu,[2,wu],[8,null],[2,Dl]],{menu:[0,"menu"]},null),(n()(),l._31(-1,0,["more_vert"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(29,0,null,null,23,"mat-menu",[["class","compact"]],null,null,null,Ef,Df)),l._8(30,1228800,[["optionsMenu",4]],1,wu,[l.l,l.B,vu],{overlapTrigger:[0,"overlapTrigger"],panelClass:[1,"panelClass"]},null),l._29(603979776,1,{items:1}),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,Zf)),l._8(34,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,$f)),l._8(37,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(39,0,null,0,5,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"],["routerLink","/settings/outputs"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,40)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,40)._emitHoverEvent()&&r),"click"===t&&(r=!1!==l._22(n,41).onClick()&&r),r},jf,Yf)),l._8(40,180224,[[1,4]],0,bu,[l.l],null,null),l._8(41,16384,null,0,pp,[cp,Ch,[8,null],l.G,l.l],{queryParams:[0,"queryParams"],routerLink:[1,"routerLink"]},null),l._26(42,{addr:0}),(n()(),l._31(43,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(46,0,null,0,5,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"],["routerLink","/transactions"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,47)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,47)._emitHoverEvent()&&r),"click"===t&&(r=!1!==l._22(n,48).onClick()&&r),r},jf,Yf)),l._8(47,180224,[[1,4]],0,bu,[l.l],null,null),l._8(48,16384,null,0,pp,[cp,Ch,[8,null],l.G,l.l],{queryParams:[0,"queryParams"],routerLink:[1,"routerLink"]},null),l._26(49,{addr:0}),(n()(),l._31(50,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,8,0,!e.wallet.isHardware||t.parent.context.$implicit.confirmed),n(t,11,0,e.wallet.isHardware&&!t.parent.context.$implicit.confirmed),n(t,25,0),n(t,26,0,l._22(t,30)),n(t,30,0,!1,"compact"),n(t,34,0,!e.wallet.isHardware||t.parent.context.$implicit.confirmed),n(t,37,0,e.wallet.isHardware),n(t,41,0,n(t,42,0,t.parent.context.$implicit.address),"/settings/outputs"),n(t,48,0,n(t,49,0,t.parent.context.$implicit.address),"/transactions")},function(n,t){n(t,3,0,t.parent.context.index+1),n(t,15,0,l._32(t,15,0,l._22(t,16).transform(t.parent.context.$implicit.coins?t.parent.context.$implicit.coins.toString():0,!0,"first"))),n(t,19,0,l._32(t,19,0,l._22(t,20).transform(t.parent.context.$implicit.hours?t.parent.context.$implicit.hours.toString():0,!1,"first"))),n(t,39,0,l._22(t,40)._highlighted,l._22(t,40)._triggersSubmenu,l._22(t,40)._getTabIndex(),l._22(t,40).disabled.toString(),l._22(t,40).disabled||null),n(t,43,0,l._32(t,43,0,l._22(t,44).transform("wallet.address.outputs"))),n(t,46,0,l._22(t,47)._highlighted,l._22(t,47)._triggersSubmenu,l._22(t,47)._getTabIndex(),l._22(t,47).disabled.toString(),l._22(t,47).disabled||null),n(t,50,0,l._32(t,50,0,l._22(t,51).transform("wallet.address.history")))})}function t_(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,n_)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,!t.component.wallet.hideEmpty||t.context.$implicit.coins.isGreaterThan(0))},null)}function e_(n){return l._33(0,[(n()(),l._9(0,0,null,null,24,"div",[["class","-row -actions"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,zf)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Uf)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,0,"div",[["class","flex-fill"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Gf)),l._8(11,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,10,"div",[["class","-button"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.editWallet()&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,7,"span",[],null,null,null,null,null)),l._8(16,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(17,{"-img -edit-wallet":0,"-disabled-span":1,"-enabled-span":2}),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,qf)),l._8(20,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(21,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n\n"])),(n()(),l._9(26,0,null,null,4,"div",[["class","-records"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,t_)),l._8(29,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,!e.wallet.isHardware),n(t,6,0,e.wallet.isHardware),n(t,11,0,!e.wallet.isHardware),n(t,16,0,n(t,17,0,!e.preparingToEdit,e.preparingToEdit,!e.preparingToEdit)),n(t,20,0,e.preparingToEdit),n(t,29,0,e.wallet?e.wallet.addresses:l._3)},function(n,t){n(t,21,0,l._32(t,21,0,l._22(t,22).transform("wallet.edit")))})}var l_=function(){function n(n){this.appService=n}return n.prototype.transform=function(n){return"hours"===n?this.appService.hoursName:"coin"===n?this.appService.coinName:"coinFull"===n?this.appService.fullCoinName:""},n}(),r_=l._7({encapsulation:2,styles:[".mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:88px;line-height:36px;padding:0 16px;border-radius:2px}[disabled].mat-button,[disabled].mat-fab,[disabled].mat-icon-button,[disabled].mat-mini-fab,[disabled].mat-raised-button{cursor:default}.cdk-keyboard-focused.mat-button .mat-button-focus-overlay,.cdk-keyboard-focused.mat-fab .mat-button-focus-overlay,.cdk-keyboard-focused.mat-icon-button .mat-button-focus-overlay,.cdk-keyboard-focused.mat-mini-fab .mat-button-focus-overlay,.cdk-keyboard-focused.mat-raised-button .mat-button-focus-overlay,.cdk-program-focused.mat-button .mat-button-focus-overlay,.cdk-program-focused.mat-fab .mat-button-focus-overlay,.cdk-program-focused.mat-icon-button .mat-button-focus-overlay,.cdk-program-focused.mat-mini-fab .mat-button-focus-overlay,.cdk-program-focused.mat-raised-button .mat-button-focus-overlay{opacity:1}.mat-button::-moz-focus-inner,.mat-fab::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-mini-fab::-moz-focus-inner,.mat-raised-button::-moz-focus-inner{border:0}.mat-fab,.mat-mini-fab,.mat-raised-button{transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1)}.mat-fab:not([class*=mat-elevation-z]),.mat-mini-fab:not([class*=mat-elevation-z]),.mat-raised-button:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-raised-button:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}[disabled].mat-fab,[disabled].mat-mini-fab,[disabled].mat-raised-button{box-shadow:none}.mat-button .mat-button-focus-overlay,.mat-icon-button .mat-button-focus-overlay{transition:none;opacity:0}.mat-button:hover .mat-button-focus-overlay{opacity:1}.mat-fab{min-width:0;border-radius:50%;width:56px;height:56px;padding:0;flex-shrink:0}.mat-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-fab .mat-button-wrapper{padding:16px 0;display:inline-block;line-height:24px}.mat-mini-fab{min-width:0;border-radius:50%;width:40px;height:40px;padding:0;flex-shrink:0}.mat-mini-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-mini-fab .mat-button-wrapper{padding:8px 0;display:inline-block;line-height:24px}.mat-icon-button{padding:0;min-width:0;width:40px;height:40px;flex-shrink:0;line-height:40px;border-radius:50%}.mat-icon-button .mat-icon,.mat-icon-button i{line-height:24px}.mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{color:currentColor}.mat-button .mat-button-wrapper>*,.mat-fab .mat-button-wrapper>*,.mat-icon-button .mat-button-wrapper>*,.mat-mini-fab .mat-button-wrapper>*,.mat-raised-button .mat-button-wrapper>*{vertical-align:middle}.mat-button-focus-overlay,.mat-button-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-button-focus-overlay{background-color:rgba(0,0,0,.12);border-radius:inherit;opacity:0;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1)}@media screen and (-ms-high-contrast:active){.mat-button-focus-overlay{background-color:rgba(255,255,255,.5)}}.mat-button-ripple-round{border-radius:50%;z-index:1}@media screen and (-ms-high-contrast:active){.mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{outline:solid 1px}}"],data:{}});function i_(n){return l._33(2,[(n()(),l._9(0,0,null,null,1,"span",[["class","mat-button-wrapper"]],null,null,null,null,null)),l._21(null,0),(n()(),l._9(2,0,null,null,1,"div",[["class","mat-button-ripple mat-ripple"],["matRipple",""]],[[2,"mat-button-ripple-round",null],[2,"mat-ripple-unbounded",null]],null,null,null,null)),l._8(3,212992,null,0,ir,[l.l,l.B,Hl,[2,rr]],{centered:[0,"centered"],disabled:[1,"disabled"],trigger:[2,"trigger"]},null),(n()(),l._9(4,0,null,null,0,"div",[["class","mat-button-focus-overlay"]],null,null,null,null,null))],function(n,t){var e=t.component;n(t,3,0,e._isIconButton,e._isRippleDisabled(),e._getHostElement())},function(n,t){var e=t.component;n(t,2,0,e._isRoundButton||e._isIconButton,l._22(t,3).unbounded)})}var o_=l._7({encapsulation:2,styles:[".mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:88px;line-height:36px;padding:0 16px;border-radius:2px}[disabled].mat-button,[disabled].mat-fab,[disabled].mat-icon-button,[disabled].mat-mini-fab,[disabled].mat-raised-button{cursor:default}.cdk-keyboard-focused.mat-button .mat-button-focus-overlay,.cdk-keyboard-focused.mat-fab .mat-button-focus-overlay,.cdk-keyboard-focused.mat-icon-button .mat-button-focus-overlay,.cdk-keyboard-focused.mat-mini-fab .mat-button-focus-overlay,.cdk-keyboard-focused.mat-raised-button .mat-button-focus-overlay,.cdk-program-focused.mat-button .mat-button-focus-overlay,.cdk-program-focused.mat-fab .mat-button-focus-overlay,.cdk-program-focused.mat-icon-button .mat-button-focus-overlay,.cdk-program-focused.mat-mini-fab .mat-button-focus-overlay,.cdk-program-focused.mat-raised-button .mat-button-focus-overlay{opacity:1}.mat-button::-moz-focus-inner,.mat-fab::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-mini-fab::-moz-focus-inner,.mat-raised-button::-moz-focus-inner{border:0}.mat-fab,.mat-mini-fab,.mat-raised-button{transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1)}.mat-fab:not([class*=mat-elevation-z]),.mat-mini-fab:not([class*=mat-elevation-z]),.mat-raised-button:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-raised-button:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}[disabled].mat-fab,[disabled].mat-mini-fab,[disabled].mat-raised-button{box-shadow:none}.mat-button .mat-button-focus-overlay,.mat-icon-button .mat-button-focus-overlay{transition:none;opacity:0}.mat-button:hover .mat-button-focus-overlay{opacity:1}.mat-fab{min-width:0;border-radius:50%;width:56px;height:56px;padding:0;flex-shrink:0}.mat-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-fab .mat-button-wrapper{padding:16px 0;display:inline-block;line-height:24px}.mat-mini-fab{min-width:0;border-radius:50%;width:40px;height:40px;padding:0;flex-shrink:0}.mat-mini-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-mini-fab .mat-button-wrapper{padding:8px 0;display:inline-block;line-height:24px}.mat-icon-button{padding:0;min-width:0;width:40px;height:40px;flex-shrink:0;line-height:40px;border-radius:50%}.mat-icon-button .mat-icon,.mat-icon-button i{line-height:24px}.mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{color:currentColor}.mat-button .mat-button-wrapper>*,.mat-fab .mat-button-wrapper>*,.mat-icon-button .mat-button-wrapper>*,.mat-mini-fab .mat-button-wrapper>*,.mat-raised-button .mat-button-wrapper>*{vertical-align:middle}.mat-button-focus-overlay,.mat-button-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-button-focus-overlay{background-color:rgba(0,0,0,.12);border-radius:inherit;opacity:0;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1)}@media screen and (-ms-high-contrast:active){.mat-button-focus-overlay{background-color:rgba(255,255,255,.5)}}.mat-button-ripple-round{border-radius:50%;z-index:1}@media screen and (-ms-high-contrast:active){.mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{outline:solid 1px}}"],data:{}});function s_(n){return l._33(2,[(n()(),l._9(0,0,null,null,1,"span",[["class","mat-button-wrapper"]],null,null,null,null,null)),l._21(null,0),(n()(),l._9(2,0,null,null,1,"div",[["class","mat-button-ripple mat-ripple"],["matRipple",""]],[[2,"mat-button-ripple-round",null],[2,"mat-ripple-unbounded",null]],null,null,null,null)),l._8(3,212992,null,0,ir,[l.l,l.B,Hl,[2,rr]],{centered:[0,"centered"],disabled:[1,"disabled"],trigger:[2,"trigger"]},null),(n()(),l._9(4,0,null,null,0,"div",[["class","mat-button-focus-overlay"]],null,null,null,null,null))],function(n,t){var e=t.component;n(t,3,0,e._isIconButton,e._isRippleDisabled(),e._getHostElement())},function(n,t){var e=t.component;n(t,2,0,e._isRoundButton||e._isIconButton,l._22(t,3).unbounded)})}var a_=l._7({encapsulation:2,styles:[".mat-progress-bar{display:block;height:5px;overflow:hidden;position:relative;transition:opacity 250ms linear;width:100%}.mat-progress-bar .mat-progress-bar-element,.mat-progress-bar .mat-progress-bar-fill::after{height:100%;position:absolute;width:100%}.mat-progress-bar .mat-progress-bar-background{background-repeat:repeat-x;background-size:10px 4px;display:none}.mat-progress-bar .mat-progress-bar-buffer{transform-origin:top left;transition:transform 250ms ease}.mat-progress-bar .mat-progress-bar-secondary{display:none}.mat-progress-bar .mat-progress-bar-fill{animation:none;transform-origin:top left;transition:transform 250ms ease}.mat-progress-bar .mat-progress-bar-fill::after{animation:none;content:'';display:inline-block;left:0}.mat-progress-bar[dir=rtl],[dir=rtl] .mat-progress-bar{transform:rotateY(180deg)}.mat-progress-bar[mode=query]{transform:rotateZ(180deg)}.mat-progress-bar[mode=query][dir=rtl],[dir=rtl] .mat-progress-bar[mode=query]{transform:rotateZ(180deg) rotateY(180deg)}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-fill,.mat-progress-bar[mode=query] .mat-progress-bar-fill{transition:none}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-primary,.mat-progress-bar[mode=query] .mat-progress-bar-primary{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-primary-indeterminate-translate 2s infinite linear;left:-145.166611%}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-primary.mat-progress-bar-fill::after,.mat-progress-bar[mode=query] .mat-progress-bar-primary.mat-progress-bar-fill::after{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-primary-indeterminate-scale 2s infinite linear}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-secondary,.mat-progress-bar[mode=query] .mat-progress-bar-secondary{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-secondary-indeterminate-translate 2s infinite linear;left:-54.888891%;display:block}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-secondary.mat-progress-bar-fill::after,.mat-progress-bar[mode=query] .mat-progress-bar-secondary.mat-progress-bar-fill::after{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-secondary-indeterminate-scale 2s infinite linear}.mat-progress-bar[mode=buffer] .mat-progress-bar-background{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-background-scroll 250ms infinite linear;display:block}@keyframes mat-progress-bar-primary-indeterminate-translate{0%{transform:translateX(0)}20%{animation-timing-function:cubic-bezier(.5,0,.70173,.49582);transform:translateX(0)}59.15%{animation-timing-function:cubic-bezier(.30244,.38135,.55,.95635);transform:translateX(83.67142%)}100%{transform:translateX(200.61106%)}}@keyframes mat-progress-bar-primary-indeterminate-scale{0%{transform:scaleX(.08)}36.65%{animation-timing-function:cubic-bezier(.33473,.12482,.78584,1);transform:scaleX(.08)}69.15%{animation-timing-function:cubic-bezier(.06,.11,.6,1);transform:scaleX(.66148)}100%{transform:scaleX(.08)}}@keyframes mat-progress-bar-secondary-indeterminate-translate{0%{animation-timing-function:cubic-bezier(.15,0,.51506,.40969);transform:translateX(0)}25%{animation-timing-function:cubic-bezier(.31033,.28406,.8,.73371);transform:translateX(37.65191%)}48.35%{animation-timing-function:cubic-bezier(.4,.62704,.6,.90203);transform:translateX(84.38617%)}100%{transform:translateX(160.27778%)}}@keyframes mat-progress-bar-secondary-indeterminate-scale{0%{animation-timing-function:cubic-bezier(.15,0,.51506,.40969);transform:scaleX(.08)}19.15%{animation-timing-function:cubic-bezier(.31033,.28406,.8,.73371);transform:scaleX(.4571)}44.15%{animation-timing-function:cubic-bezier(.4,.62704,.6,.90203);transform:scaleX(.72796)}100%{transform:scaleX(.08)}}@keyframes mat-progress-bar-background-scroll{to{transform:translateX(-10px)}}"],data:{}});function u_(n){return l._33(2,[(n()(),l._9(0,0,null,null,0,"div",[["class","mat-progress-bar-background mat-progress-bar-element"]],null,null,null,null,null)),(n()(),l._9(1,0,null,null,1,"div",[["class","mat-progress-bar-buffer mat-progress-bar-element"]],null,null,null,null,null)),l._8(2,278528,null,0,R,[l.v,l.l,l.G],{ngStyle:[0,"ngStyle"]},null),(n()(),l._9(3,0,null,null,1,"div",[["class","mat-progress-bar-primary mat-progress-bar-fill mat-progress-bar-element"]],null,null,null,null,null)),l._8(4,278528,null,0,R,[l.v,l.l,l.G],{ngStyle:[0,"ngStyle"]},null),(n()(),l._9(5,0,null,null,0,"div",[["class","mat-progress-bar-secondary mat-progress-bar-fill mat-progress-bar-element"]],null,null,null,null,null))],function(n,t){var e=t.component;n(t,2,0,e._bufferTransform()),n(t,4,0,e._primaryTransform())},null)}var c_=l._7({encapsulation:2,styles:[".mat-toolbar-row,.mat-toolbar-single-row{display:flex;box-sizing:border-box;padding:0 16px;width:100%;flex-direction:row;align-items:center;white-space:nowrap}.mat-toolbar-multiple-rows{display:flex;box-sizing:border-box;flex-direction:column;width:100%}.mat-toolbar-multiple-rows{min-height:64px}.mat-toolbar-row,.mat-toolbar-single-row{height:64px}@media (max-width:600px){.mat-toolbar-multiple-rows{min-height:56px}.mat-toolbar-row,.mat-toolbar-single-row{height:56px}}"],data:{}});function d_(n){return l._33(2,[l._21(null,0),l._21(null,1)],null,null)}var h_=function(){function n(n,t,e){this.appService=n,this.languageService=t,this.dialog=e}return n.prototype.ngOnInit=function(){var n=this;this.subscription=this.languageService.currentLanguage.subscribe(function(t){return n.language=t})},n.prototype.ngOnDestroy=function(){this.subscription.unsubscribe()},n.prototype.changelanguage=function(){var n=this;zc(this.dialog).subscribe(function(t){t&&n.languageService.changeLanguage(t)})},n}(),p_=l._7({encapsulation:0,styles:[["[_nghost-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;color:#fafafa;width:100%}.buttons-left[_ngcontent-%COMP%]{display:inline-block;padding:0 10px;width:120px}.title[_ngcontent-%COMP%]{font-size:13px;font-weight:700;display:inline;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;letter-spacing:1px;line-height:50px;text-align:center}.buttons-right[_ngcontent-%COMP%]{display:inline-block;text-align:right;width:120px}.buttons-right[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{display:inline-block}button[_ngcontent-%COMP%]{height:50px;width:50px}.color-primary[_ngcontent-%COMP%]{color:#0072ff}.separator[_ngcontent-%COMP%]{width:100%;height:2px;background-color:rgba(30,34,39,.05);margin:8px 0}.flag[_ngcontent-%COMP%]{width:16px;height:16px;position:relative;top:3px}"]],data:{}});function f_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,1)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,1)._emitHoverEvent()&&r),r},jf,Yf)),l._8(1,180224,[[1,4]],0,bu,[l.l],{disabled:[0,"disabled"]},null),(n()(),l._31(2,0,[" v"," "]))],function(n,t){n(t,1,0,!0)},function(n,t){var e=t.component;n(t,0,0,l._22(t,1)._highlighted,l._22(t,1)._triggersSubmenu,l._22(t,1)._getTabIndex(),l._22(t,1).disabled.toString(),l._22(t,1).disabled||null),n(t,2,0,e.appService.version.version)})}function __(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0,i=n.component;return"click"===t&&(r=!1!==l._22(n,1)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,1)._emitHoverEvent()&&r),"click"===t&&(r=!1!==i.changelanguage()&&r),r},jf,Yf)),l._8(1,180224,[[2,4]],0,bu,[l.l],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(3,0,null,0,0,"img",[["class","flag"]],[[8,"src",4]],null,null,null,null)),(n()(),l._31(4,0,["\n ","\n "]))],null,function(n,t){var e=t.component;n(t,0,0,l._22(t,1)._highlighted,l._22(t,1)._triggersSubmenu,l._22(t,1)._getTabIndex(),l._22(t,1).disabled.toString(),l._22(t,1).disabled||null),n(t,3,0,"assets/img/lang/"+e.language.iconName),n(t,4,0,e.language.name)})}function m_(n){return l._33(0,[(n()(),l._9(0,0,null,null,0,"div",[["class","buttons-left"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(2,0,null,null,1,"div",[["class","title"]],null,null,null,null,null)),(n()(),l._31(3,null,["\n ","\n"])),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(5,0,null,null,79,"div",[["class","buttons-right"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,34,"mat-menu",[],null,null,null,Ef,Df)),l._8(8,1228800,[["settingsMenu",4]],1,wu,[l.l,l.B,vu],{overlapTrigger:[0,"overlapTrigger"]},null),l._29(603979776,1,{items:1}),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(11,0,null,0,5,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,12)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,12)._emitHoverEvent()&&r),"click"===t&&(r=!1!==l._22(n,13).onClick()&&r),r},jf,Yf)),l._8(12,180224,[[1,4]],0,bu,[l.l],null,null),l._8(13,16384,null,0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._24(14,1),(n()(),l._31(15,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(18,0,null,0,5,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,19)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,19)._emitHoverEvent()&&r),"click"===t&&(r=!1!==l._22(n,20).onClick()&&r),r},jf,Yf)),l._8(19,180224,[[1,4]],0,bu,[l.l],null,null),l._8(20,16384,null,0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._24(21,1),(n()(),l._31(22,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(25,0,null,0,5,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,26)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,26)._emitHoverEvent()&&r),"click"===t&&(r=!1!==l._22(n,27).onClick()&&r),r},jf,Yf)),l._8(26,180224,[[1,4]],0,bu,[l.l],null,null),l._8(27,16384,null,0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._24(28,1),(n()(),l._31(29,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(32,0,null,0,5,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,33)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,33)._emitHoverEvent()&&r),"click"===t&&(r=!1!==l._22(n,34).onClick()&&r),r},jf,Yf)),l._8(33,180224,[[1,4]],0,bu,[l.l],null,null),l._8(34,16384,null,0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._24(35,1),(n()(),l._31(36,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,f_)),l._8(40,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(43,0,null,null,20,"mat-menu",[],null,null,null,Ef,Df)),l._8(44,1228800,[["menuMenu",4]],1,wu,[l.l,l.B,vu],{overlapTrigger:[0,"overlapTrigger"]},null),l._29(603979776,2,{items:1}),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(47,0,null,0,5,"button",[["class","mat-menu-item"],["mat-menu-item",""],["role","menuitem"]],[[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,48)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,48)._emitHoverEvent()&&r),"click"===t&&(r=!1!==l._22(n,49).onClick()&&r),r},jf,Yf)),l._8(48,180224,[[2,4]],0,bu,[l.l],null,null),l._8(49,16384,null,0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._24(50,1),(n()(),l._31(51,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(54,0,null,0,3,"a",[["class","color-primary mat-menu-item"],["mat-menu-item",""],["rel","noreferrer nofollow"],["role","menuitem"],["target","_blank"]],[[8,"href",4],[2,"mat-menu-item-highlighted",null],[2,"mat-menu-item-submenu-trigger",null],[1,"tabindex",0],[1,"aria-disabled",0],[1,"disabled",0]],[[null,"click"],[null,"mouseenter"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,55)._checkDisabled(e)&&r),"mouseenter"===t&&(r=!1!==l._22(n,55)._emitHoverEvent()&&r),r},jf,Yf)),l._8(55,180224,[[2,4]],0,bu,[l.l],null,null),(n()(),l._31(56,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(59,0,null,0,0,"div",[["class","separator"]],null,null,null,null,null)),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,__)),l._8(62,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(65,16777216,null,null,8,"button",[["aria-haspopup","true"],["class","mat-icon-button"],["mat-icon-button",""]],[[8,"disabled",0]],[[null,"mousedown"],[null,"keydown"],[null,"click"]],function(n,t,e){var r=!0;return"mousedown"===t&&(r=!1!==l._22(n,68)._handleMousedown(e)&&r),"keydown"===t&&(r=!1!==l._22(n,68)._handleKeydown(e)&&r),"click"===t&&(r=!1!==l._22(n,68)._handleClick(e)&&r),r},i_,r_)),l._8(66,180224,null,0,Bs,[l.l,Hl,Rr],null,null),l._8(67,16384,null,0,Fs,[],null,null),l._8(68,1196032,null,0,ku,[Pi,l.l,l.R,xu,[2,wu],[8,null],[2,Dl]],{menu:[0,"menu"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(70,0,null,0,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(71,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["settings"])),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(75,16777216,null,null,8,"button",[["aria-haspopup","true"],["class","mat-icon-button"],["mat-icon-button",""]],[[8,"disabled",0]],[[null,"mousedown"],[null,"keydown"],[null,"click"]],function(n,t,e){var r=!0;return"mousedown"===t&&(r=!1!==l._22(n,78)._handleMousedown(e)&&r),"keydown"===t&&(r=!1!==l._22(n,78)._handleKeydown(e)&&r),"click"===t&&(r=!1!==l._22(n,78)._handleClick(e)&&r),r},i_,r_)),l._8(76,180224,null,0,Bs,[l.l,Hl,Rr],null,null),l._8(77,16384,null,0,Fs,[],null,null),l._8(78,1196032,null,0,ku,[Pi,l.l,l.R,xu,[2,wu],[8,null],[2,Dl]],{menu:[0,"menu"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(80,0,null,0,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(81,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["menu"])),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,8,0,!1),n(t,13,0,n(t,14,0,"/settings/network")),n(t,20,0,n(t,21,0,"/settings/blockchain")),n(t,27,0,n(t,28,0,"/settings/outputs")),n(t,34,0,n(t,35,0,"/settings/pending-transactions")),n(t,40,0,e.appService.version),n(t,44,0,!1),n(t,49,0,n(t,50,0,"/settings/backup")),n(t,62,0,e.language),n(t,68,0,l._22(t,8)),n(t,71,0),n(t,78,0,l._22(t,44)),n(t,81,0)},function(n,t){var e=t.component;n(t,3,0,e.headline),n(t,11,0,l._22(t,12)._highlighted,l._22(t,12)._triggersSubmenu,l._22(t,12)._getTabIndex(),l._22(t,12).disabled.toString(),l._22(t,12).disabled||null),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("title.network"))),n(t,18,0,l._22(t,19)._highlighted,l._22(t,19)._triggersSubmenu,l._22(t,19)._getTabIndex(),l._22(t,19).disabled.toString(),l._22(t,19).disabled||null),n(t,22,0,l._32(t,22,0,l._22(t,23).transform("title.blockchain"))),n(t,25,0,l._22(t,26)._highlighted,l._22(t,26)._triggersSubmenu,l._22(t,26)._getTabIndex(),l._22(t,26).disabled.toString(),l._22(t,26).disabled||null),n(t,29,0,l._32(t,29,0,l._22(t,30).transform("title.outputs"))),n(t,32,0,l._22(t,33)._highlighted,l._22(t,33)._triggersSubmenu,l._22(t,33)._getTabIndex(),l._22(t,33).disabled.toString(),l._22(t,33).disabled||null),n(t,36,0,l._32(t,36,0,l._22(t,37).transform("title.pending-txs"))),n(t,47,0,l._22(t,48)._highlighted,l._22(t,48)._triggersSubmenu,l._22(t,48)._getTabIndex(),l._22(t,48).disabled.toString(),l._22(t,48).disabled||null),n(t,51,0,l._32(t,51,0,l._22(t,52).transform("title.backup"))),n(t,54,0,e.appService.explorerUrl,l._22(t,55)._highlighted,l._22(t,55)._triggersSubmenu,l._22(t,55)._getTabIndex(),l._22(t,55).disabled.toString(),l._22(t,55).disabled||null),n(t,56,0,l._32(t,56,0,l._22(t,57).transform("title.explorer"))),n(t,65,0,l._22(t,66).disabled||null),n(t,75,0,l._22(t,76).disabled||null)})}var g_=l._7({encapsulation:0,styles:[[".button-container[_ngcontent-%COMP%]{display:inline-block}button[_ngcontent-%COMP%]{border-radius:25px;height:50px;margin:20px 10px 0;width:160px;overflow:hidden}button.enabled[_ngcontent-%COMP%]{background-color:rgba(30,34,39,.05);-webkit-box-shadow:none;box-shadow:none;color:#1e2227}mat-icon[_ngcontent-%COMP%]{margin-left:10px;opacity:.3;line-height:20px}mat-spinner[_ngcontent-%COMP%]{display:inline-block;height:24px!important;width:24px!important;margin-left:10px;position:relative;top:-2px}"]],data:{}});function y_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(1,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["done"]))],function(n,t){n(t,1,0)},null)}function b_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(1,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["error"]))],function(n,t){n(t,1,0)},null)}function v_(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-spinner",[["class","in-button mat-spinner mat-progress-spinner"],["mode","indeterminate"],["role","progressbar"]],[[4,"width","px"],[4,"height","px"]],null,null,Pf,Lf)),l._8(1,573440,null,0,Wu,[l.l,Hl,[2,sn]],null,null)],null,function(n,t){n(t,0,0,l._22(t,1)._elementSize,l._22(t,1)._elementSize)})}function w_(n){return l._33(0,[l._29(402653184,1,{tooltip:0}),l._29(402653184,2,{button:0}),(n()(),l._9(2,0,null,null,21,"div",[["class","button-container"]],null,[[null,"mouseenter"],[null,"mouseleave"]],function(n,t,e){var l=!0,r=n.component;return"mouseenter"===t&&(l=0!=(r.mouseOver=!0)&&l),"mouseleave"===t&&(l=0!=(r.mouseOver=!1)&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,16777216,null,null,18,"button",[["class","mat-button mat-raised-button"],["color","primary"],["mat-button",""],["mat-raised-button",""],["type","submit"]],[[8,"disabled",0]],[[null,"click"],[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0,i=n.component;return"longpress"===t&&(r=!1!==l._22(n,10).show()&&r),"keydown"===t&&(r=!1!==l._22(n,10)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,10).hide(1500)&&r),"click"===t&&(r=!1!==(0!==i.state?i.onClick():null)&&r),r},i_,r_)),l._8(5,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(6,{enabled:0}),l._8(7,180224,[[2,4],["button",4]],0,Bs,[l.l,Hl,Rr],{disabled:[0,"disabled"],color:[1,"color"]},null),l._8(8,16384,null,0,Hs,[],null,null),l._8(9,16384,null,0,Ns,[],null,null),l._8(10,147456,[[1,4],["tooltip",4]],0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),(n()(),l._31(-1,0,["\n "])),l._21(0,0),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,y_)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,b_)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,v_)),l._8(21,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,5,0,n(t,6,0,!e.disabled)),n(t,7,0,e.disabled&&!e.forceEmitEvents,"primary"),n(t,10,0,e.error?e.error:null),n(t,15,0,1===e.state),n(t,18,0,2===e.state),n(t,21,0,0===e.state)},function(n,t){n(t,4,0,l._22(t,7).disabled||null)})}var x_=l._7({encapsulation:0,styles:[[".-small-button[_ngcontent-%COMP%] button{width:unset;height:unset;padding:0 10px;min-width:100px;margin:unset;font-size:13px}.-toggle[_ngcontent-%COMP%] button{-webkit-box-shadow:unset;box-shadow:unset;background-color:rgba(0,0,0,0)!important;line-height:unset!important;min-height:26px}.-toggle[_ngcontent-%COMP%] button span{color:#171a1d;line-height:unset!important}.-toggle[_ngcontent-%COMP%] button.enabled{background-color:#171a1d!important}.-toggle[_ngcontent-%COMP%] button.enabled span{color:#fafafa}.-buttons-container[_ngcontent-%COMP%]{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:5px;background:rgba(255,255,255,.1);border-radius:100px;margin:0 auto;text-align:center}.light.-buttons-container[_ngcontent-%COMP%]{background:#f1f1f1}.light[_ngcontent-%COMP%] .-toggle[_ngcontent-%COMP%] button.enabled{background-color:#fff!important}.light[_ngcontent-%COMP%] .-toggle[_ngcontent-%COMP%] button.enabled span{color:#1e2227}@media (min-width:768px) and (max-width:991px){.-buttons-container.navbar.light[_ngcontent-%COMP%]{border-radius:20px}.-buttons-container.navbar.light[_ngcontent-%COMP%] app-button[_ngcontent-%COMP%] .button-container{display:block}}.small.-buttons-container[_ngcontent-%COMP%]{padding:2px;line-height:0}.small[_ngcontent-%COMP%] .-small-button[_ngcontent-%COMP%] button{padding:0 10px;min-width:70px;font-size:9px;min-height:16px}"]],data:{}});function M_(n){return l._33(0,[(n()(),l._9(0,0,null,null,9,"div",[],[[8,"className",0]],null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-button",[["class","-toggle dark -small-button"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.onLeftClick()&&l),l},w_,g_)),l._8(3,49152,null,0,Lc,[],{disabled:[0,"disabled"],forceEmitEvents:[1,"forceEmitEvents"]},{action:"action"}),(n()(),l._31(4,0,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,2,"app-button",[["class","-toggle dark -small-button"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.onRightClick()&&l),l},w_,g_)),l._8(7,49152,null,0,Lc,[],{disabled:[0,"disabled"],forceEmitEvents:[1,"forceEmitEvents"]},{action:"action"}),(n()(),l._31(8,0,["",""])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,e.activeButton!==e.ButtonState.LeftButton,!0),n(t,7,0,e.activeButton!==e.ButtonState.RightButton,!0)},function(n,t){var e=t.component;n(t,0,0,l._12(1,"-buttons-container ",e.className,"")),n(t,4,0,e.leftButtonText),n(t,8,0,e.rightButtonText)})}var k_=function(){function n(n){this.navbarService=n,this.otcEnabled=Ll.otcEnabled,this.exchangeEnabled=!!r.swaplab.apiKey}return n.prototype.changeActiveComponent=function(n){this.navbarService.setActiveComponent(n)},n}(),C_=l._7({encapsulation:0,styles:[["[_nghost-%COMP%]{background-color:#fbfbfb;min-height:66px}.-buttons[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%}.-buttons[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%]{cursor:pointer;padding:0 20px}.-buttons[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{display:inline-block;float:left;height:66px;padding:17px 0;width:32px}.-buttons[_ngcontent-%COMP%] .-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{display:inline-block;font-size:14px;height:66px;line-height:66px;margin:0 5px}.-buttons[_ngcontent-%COMP%] .-low-opacity[_ngcontent-%COMP%]{opacity:.2}.-buttons[_ngcontent-%COMP%] .-switch[_ngcontent-%COMP%]{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;padding:0 20px}"]],data:{}});function S_(n){return l._33(0,[(n()(),l._9(0,0,null,null,11,"div",[["class","-button -low-opacity"],["routerLink","/exchange"],["routerLinkActive","no-opacity"]],null,[[null,"click"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,1).onClick()&&r),r},null,null)),l._8(1,16384,[[7,4]],0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._8(2,1720320,null,2,mp,[cp,l.l,l.G,l.h],{routerLinkActive:[0,"routerLinkActive"]},null),l._29(603979776,7,{links:1}),l._29(603979776,8,{linksWithHrefs:1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,0,"img",[["src","../../../../../assets/img/money-gold.png"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,1,0,"/exchange"),n(t,2,0,"no-opacity")},function(n,t){n(t,9,0,l._32(t,9,0,l._22(t,10).transform("title.buy-coin")))})}function O_(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[["class","-button"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,0,"img",[["src","../../../../../assets/img/money-gold.png"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"span",[["class","secondary-color"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,5,0,l._32(t,5,0,l._22(t,6).transform("title.buy-coin")))})}function T_(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"app-double-button",[["class","-switch"],["className","light navbar"]],null,[[null,"onStateChange"]],function(n,t,e){var l=!0;return"onStateChange"===t&&(l=!1!==n.component.changeActiveComponent(e)&&l),l},M_,x_)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(2,{"-switch":0,"element-disabled":1}),l._8(3,49152,null,0,Bp,[],{rightButtonText:[0,"rightButtonText"],leftButtonText:[1,"leftButtonText"],activeButton:[2,"activeButton"],className:[3,"className"]},{onStateChange:"onStateChange"}),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h]),l._25(131072,nn,[l.h])],function(n,t){var e=t.component;n(t,1,0,"-switch",n(t,2,0,!0,e.navbarService.switchDiabled)),n(t,3,0,l._32(t,3,0,l._22(t,4).transform(e.navbarService.rightText)),l._32(t,3,1,l._22(t,5).transform(e.navbarService.leftText)),l._32(t,3,2,l._22(t,6).transform(e.navbarService.activeComponent)),"light navbar")},null)}function L_(n){return l._33(0,[(n()(),l._9(0,0,null,null,54,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,51,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,11,"div",[["class","-button -low-opacity"],["routerLink","/wallets"],["routerLinkActive","no-opacity"]],null,[[null,"click"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,5).onClick()&&r),r},null,null)),l._8(5,16384,[[1,4]],0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._8(6,1720320,null,2,mp,[cp,l.l,l.G,l.h],{routerLinkActive:[0,"routerLinkActive"]},null),l._29(603979776,1,{links:1}),l._29(603979776,2,{linksWithHrefs:1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,0,"img",[["src","../../../../../assets/img/wallet-black.png"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,null,null,11,"div",[["class","-button -low-opacity"],["routerLink","/send"],["routerLinkActive","no-opacity"]],null,[[null,"click"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,18).onClick()&&r),r},null,null)),l._8(18,16384,[[3,4]],0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._8(19,1720320,null,2,mp,[cp,l.l,l.G,l.h],{routerLinkActive:[0,"routerLinkActive"]},null),l._29(603979776,3,{links:1}),l._29(603979776,4,{linksWithHrefs:1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(23,0,null,null,0,"img",[["src","../../../../../assets/img/send-black.png"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(26,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(30,0,null,null,11,"div",[["class","-button -low-opacity"],["routerLink","/transactions"],["routerLinkActive","no-opacity"]],null,[[null,"click"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,31).onClick()&&r),r},null,null)),l._8(31,16384,[[5,4]],0,pp,[cp,Ch,[8,null],l.G,l.l],{routerLink:[0,"routerLink"]},null),l._8(32,1720320,null,2,mp,[cp,l.l,l.G,l.h],{routerLinkActive:[0,"routerLinkActive"]},null),l._29(603979776,5,{links:1}),l._29(603979776,6,{linksWithHrefs:1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(36,0,null,null,0,"img",[["src","../../../../../assets/img/transactions-black.png"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(38,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(39,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(43,0,null,null,0,"div",[["class","flex-fill"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,S_)),l._8(46,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,O_)),l._8(49,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,T_)),l._8(52,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,5,0,"/wallets"),n(t,6,0,"no-opacity"),n(t,18,0,"/send"),n(t,19,0,"no-opacity"),n(t,31,0,"/transactions"),n(t,32,0,"no-opacity"),n(t,46,0,e.exchangeEnabled),n(t,49,0,e.otcEnabled),n(t,52,0,e.navbarService.switchVisible)},function(n,t){n(t,13,0,l._32(t,13,0,l._22(t,14).transform("title.wallets"))),n(t,26,0,l._32(t,26,0,l._22(t,27).transform("title.send"))),n(t,39,0,l._32(t,39,0,l._22(t,40).transform("title.history")))})}o.a.prototype.skip=function(n){return function(n){return function(t){return t.lift(new yc(n))}}(n)(this)},o.a.prototype.take=function(n){return Object(_r.a)(n)(this)};var P_=function(){function n(n,t,e,l,r){this.appService=n,this.networkService=t,this.blockchainService=e,this.priceService=l,this.walletService=r,this.addresses=[],this.querying=!0,this.synchronized=!0,this.walletDownloadUrl=Ll.walletDownloadUrl,this.subscriptionsGroup=[]}return Object.defineProperty(n.prototype,"loading",{get:function(){return!(this.current&&this.highest&&this.current===this.highest&&this.coins&&"NaN"!==this.coins&&this.hours&&"NaN"!==this.hours)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"coins",{get:function(){var n=new Ae.BigNumber("0");return this.addresses.map(function(t){return n=n.plus(t.coins)}),n.decimalPlaces(6).toString()},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"hours",{get:function(){var n=new Ae.BigNumber("0");return this.addresses.map(function(t){return n=n.plus(t.hours)}),n.decimalPlaces(0).toString()},enumerable:!0,configurable:!0}),n.prototype.ngOnInit=function(){var n=this;this.subscriptionsGroup.push(this.blockchainService.progress.filter(function(n){return!!n}).subscribe(function(t){n.querying=!1,n.highest=t.highest,n.current=t.current,n.percentage=n.current&&n.highest?n.current/n.highest:0,n.synchronizedSubscription||(n.synchronizedSubscription=n.blockchainService.synchronized.subscribe(function(t){return n.synchronized=t}))})),this.subscriptionsGroup.push(this.priceService.price.subscribe(function(t){return n.price=t})),this.subscriptionsGroup.push(this.walletService.allAddresses().subscribe(function(t){n.addresses=t.reduce(function(n,t){return n.find(function(n){return n.address===t.address})||n.push(t),n},[])})),this.subscriptionsGroup.push(this.walletService.pendingTransactions().subscribe(function(t){n.hasPendingTxs=t.user.length>0}))},n.prototype.ngOnDestroy=function(){this.subscriptionsGroup.forEach(function(n){return n.unsubscribe()}),this.synchronizedSubscription&&this.synchronizedSubscription.unsubscribe()},n}(),D_=l._7({encapsulation:0,styles:[[".-container[_ngcontent-%COMP%]{background-color:#fbfbfb;border-bottom:2px solid rgba(30,34,39,.05)}.large-header[_ngcontent-%COMP%]{background:#0072ff;background:-webkit-gradient(linear,left top,right bottom,from(rgba(0,114,255,.7)),to(rgba(0,195,255,.7))),url(header.03fb33b04c982a1a804d.png) center center no-repeat;background:linear-gradient(to bottom right,rgba(0,114,255,.7),rgba(0,195,255,.7)),url(header.03fb33b04c982a1a804d.png) center center no-repeat;background-size:100% auto;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-flow:column;flex-flow:column;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;min-height:190px}.balance-container[_ngcontent-%COMP%]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#fafafa;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;font-size:12px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.balance-container[_ngcontent-%COMP%] .balance[_ngcontent-%COMP%] .coins[_ngcontent-%COMP%]{line-height:1;margin:0 0 .5em}.balance-container[_ngcontent-%COMP%] .balance[_ngcontent-%COMP%] .coins[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{font-size:4em}.balance-container[_ngcontent-%COMP%] .dollars[_ngcontent-%COMP%]{margin:0}.hour-balance[_ngcontent-%COMP%]{text-align:center}.hour-balance[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{background-color:rgba(255,255,255,.3);border-radius:15px;color:#171a1d;display:inline-block;font-size:12px;line-height:22px;margin:1em 0 2em;padding:0 30px}.notification-bar[_ngcontent-%COMP%]{background-color:#f44a4d;color:#fbfbfb}.notification-bar[_ngcontent-%COMP%] div[_ngcontent-%COMP%]{margin:auto}.notification-bar[_ngcontent-%COMP%] div[_ngcontent-%COMP%] a[_ngcontent-%COMP%]{text-decoration:none;color:#ffebee}"]],data:{}});function A_(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"p",[["class","coins"]],null,null,null,null,null)),(n()(),l._9(1,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(2,null,["",""])),l._27(3,2)],null,function(n,t){var e=t.component;n(t,2,0,l._32(t,2,0,n(t,3,0,l._22(t.parent,0),e.percentage,"1.2-2")))})}function E_(n){return l._33(0,[(n()(),l._9(0,0,null,null,5,"p",[["class","coins"]],null,null,null,null,null)),(n()(),l._9(1,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(2,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(4,null,[" ",""])),l._25(0,If,[tn,qc,gf])],null,function(n,t){var e=t.component;n(t,2,0,l._32(t,2,0,l._22(t,3).transform(e.coins,!0,"first"))),n(t,4,0,l._32(t,4,0,l._22(t,5).transform(e.coins,!0,"last")))})}function Y_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"p",[["class","coins"]],null,null,null,null,null)),(n()(),l._9(1,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\xa0"]))],null,null)}function j_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._27(2,4)],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,n(t,2,0,l._22(t.parent.parent,1),e.coins*e.price,"USD","symbol","1.2-2")))})}function I_(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(-1,null,["-"]))],null,null)}function R_(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,"span",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,j_)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,I_)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(7,null,["\n (",")\n "])),l._27(8,4)],function(n,t){var e=t.component;n(t,3,0,!e.loading),n(t,6,0,e.loading)},function(n,t){var e=t.component;n(t,7,0,l._32(t,7,0,n(t,8,0,l._22(t.parent,1),e.price,"USD","symbol","1.2-2")))})}function H_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("common.loading")))})}function N_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform("header.syncing-blocks")),e.current&&e.highest?"("+e.current+"/"+e.highest+")":"...")})}function F_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(0,If,[tn,qc,gf])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform(e.hours,!1)))})}function B_(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-progress-bar",[["aria-valuemax","100"],["aria-valuemin","0"],["class","example-margin mat-progress-bar"],["color","primary"],["role","progressbar"]],[[1,"aria-valuenow",0],[1,"mode",0],[2,"mat-primary",null],[2,"mat-accent",null],[2,"mat-warn",null]],null,null,u_,a_)),l._8(1,49152,null,0,Nu,[],{color:[0,"color"],value:[1,"value"],mode:[2,"mode"]},null)],function(n,t){var e=t.component;n(t,1,0,"primary",100*e.percentage,e.querying?"query":"determinate")},function(n,t){n(t,0,0,l._22(t,1).value,l._22(t,1).mode,"primary"==l._22(t,1).color,"accent"==l._22(t,1).color,"warn"==l._22(t,1).color)})}function V_(n){return l._33(0,[(n()(),l._9(0,0,null,null,11,"mat-toolbar",[["class","notification-bar mat-toolbar"]],[[2,"mat-toolbar-multiple-rows",null],[2,"mat-toolbar-single-row",null]],null,null,d_,c_)),l._8(1,4243456,null,1,Ju,[l.l,Hl],null,null),l._29(603979776,1,{_toolbarRows:1}),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,6,"div",[],null,null,null,null,null)),(n()(),l._31(5,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(7,0,null,null,1,"a",[["rel","noreferrer nofollow"],["target","_blank"]],[[8,"href",4]],null,null,null,null)),(n()(),l._31(8,null,["v",""])),(n()(),l._31(9,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "]))],null,function(n,t){var e=t.component;n(t,0,0,l._22(t,1)._toolbarRows.length,!l._22(t,1)._toolbarRows.length),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("header.update1"))),n(t,7,0,e.walletDownloadUrl),n(t,8,0,e.appService.lastestVersion),n(t,9,0,l._32(t,9,0,l._22(t,10).transform("header.update2")))})}function W_(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(3,0,null,null,2,"a",[["href","https://web.telegram.org/#/im?p=@skycoinsupport"],["rel","noreferrer nofollow"],["target","_blank"]],null,null,null,null,null)),(n()(),l._31(4,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(6,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("header.errors.no-backend1"))),n(t,4,0,l._32(t,4,0,l._22(t,5).transform("header.errors.no-backend2"))),n(t,6,0,l._32(t,6,0,l._22(t,7).transform("header.errors.no-backend3")))})}function z_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"div",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("header.errors.csrf")))})}function U_(n){return l._33(0,[(n()(),l._9(0,0,null,null,9,"mat-toolbar",[["class","notification-bar mat-toolbar"]],[[2,"mat-toolbar-multiple-rows",null],[2,"mat-toolbar-single-row",null]],null,null,d_,c_)),l._8(1,4243456,null,1,Ju,[l.l,Hl],null,null),l._29(603979776,2,{_toolbarRows:1}),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,W_)),l._8(5,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,z_)),l._8(8,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "]))],function(n,t){var e=t.component;n(t,5,0,2===e.appService.error),n(t,8,0,3===e.appService.error)},function(n,t){n(t,0,0,l._22(t,1)._toolbarRows.length,!l._22(t,1)._toolbarRows.length)})}function G_(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"mat-toolbar",[["class","notification-bar mat-toolbar"]],[[2,"mat-toolbar-multiple-rows",null],[2,"mat-toolbar-single-row",null]],null,null,d_,c_)),l._8(1,4243456,null,1,Ju,[l.l,Hl],null,null),l._29(603979776,3,{_toolbarRows:1}),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,2,"div",[],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "]))],null,function(n,t){n(t,0,0,l._22(t,1)._toolbarRows.length,!l._22(t,1)._toolbarRows.length),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("header.errors.no-connections")))})}function q_(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,"div",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(3,0,null,null,3,"a",[["routerLink","/settings/pending-transactions"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,4).onClick(e.button,e.ctrlKey,e.metaKey,e.shiftKey)&&r),r},null,null)),l._8(4,671744,null,0,fp,[cp,Ch,u],{routerLink:[0,"routerLink"]},null),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(7,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,4,0,"/settings/pending-transactions")},function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("header.pending-txs1"))),n(t,3,0,l._22(t,4).target,l._22(t,4).href),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("header.pending-txs2"))),n(t,7,0,l._32(t,7,0,l._22(t,8).transform("header.pending-txs3")))})}function J_(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"div",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("header.synchronizing")))})}function Q_(n){return l._33(0,[(n()(),l._9(0,0,null,null,9,"mat-toolbar",[["class","notification-bar mat-toolbar"]],[[2,"mat-toolbar-multiple-rows",null],[2,"mat-toolbar-single-row",null]],null,null,d_,c_)),l._8(1,4243456,null,1,Ju,[l.l,Hl],null,null),l._29(603979776,4,{_toolbarRows:1}),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,q_)),l._8(5,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,J_)),l._8(8,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "]))],function(n,t){var e=t.component;n(t,5,0,e.hasPendingTxs),n(t,8,0,!e.synchronized&&!e.hasPendingTxs)},function(n,t){n(t,0,0,l._22(t,1)._toolbarRows.length,!l._22(t,1)._toolbarRows.length)})}function K_(n){return l._33(0,[l._25(0,en,[l.w]),l._25(0,ln,[l.w]),(n()(),l._9(2,0,null,null,58,"div",[["class","-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,37,"div",[["class","large-header"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,1,"app-top-bar",[],null,null,null,m_,p_)),l._8(7,245760,null,0,h_,[gf,Bc,fa],{headline:[0,"headline"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,22,"div",[["class","balance-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,19,"div",[["class","balance"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,A_)),l._8(14,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,E_)),l._8(17,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Y_)),l._8(20,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,7,"p",[["class","dollars"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,R_)),l._8(25,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,H_)),l._8(28,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(33,0,null,null,7,"div",[["class","hour-balance"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,N_)),l._8(36,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,F_)),l._8(39,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(43,0,null,null,1,"app-nav-bar",[],null,null,null,L_,C_)),l._8(44,49152,null,0,k_,[Vp],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,B_)),l._8(47,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,V_)),l._8(50,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,U_)),l._8(53,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,G_)),l._8(56,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Q_)),l._8(59,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,7,0,e.headline),n(t,14,0,e.highest&&e.loading),n(t,17,0,!e.loading),n(t,20,0,!e.highest&&e.loading),n(t,25,0,e.price),n(t,28,0,!e.price),n(t,36,0,e.loading),n(t,39,0,!e.loading),n(t,47,0,e.loading),n(t,50,0,e.appService.updateAvailable),n(t,53,0,e.appService.error),n(t,56,0,!e.appService.error&&e.networkService.noConnections),n(t,59,0,e.hasPendingTxs||!e.synchronized)},null)}var X_=l._7({encapsulation:0,styles:[[".-width-130[_ngcontent-%COMP%]{width:130px;-ms-flex-negative:0;flex-shrink:0}.-width-250[_ngcontent-%COMP%]{width:250px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;padding-right:20px}.-headers[_ngcontent-%COMP%]{color:rgba(30,34,39,.2);display:-webkit-box;display:-ms-flexbox;display:flex;font-size:12px;font-weight:700;height:50px;line-height:50px;padding:0 130px 0 50px}.-wallets[_ngcontent-%COMP%]{margin:0 30px}.-body[_ngcontent-%COMP%]{border-radius:15px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);margin:0 0 10px}.-wallet[_ngcontent-%COMP%]{background-color:#fafafa;border-bottom:1px solid rgba(30,34,39,.05);display:-webkit-box;display:-ms-flexbox;display:flex;font-size:13px;line-height:60px;height:60px;padding-left:20px;cursor:pointer}.-wallet[_ngcontent-%COMP%]:first-child{border-top-left-radius:10px;border-top-right-radius:10px}.-wallet[_ngcontent-%COMP%]:last-child{border-bottom-left-radius:10px;border-bottom-right-radius:10px}.-wallet[_ngcontent-%COMP%] .-label[_ngcontent-%COMP%]{color:#1e2227}.-wallet[_ngcontent-%COMP%] .-hours[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);text-align:right}.-wallet[_ngcontent-%COMP%] .-coins[_ngcontent-%COMP%]{color:#1e2227;text-align:right}.-wallet[_ngcontent-%COMP%] .-encryption[_ngcontent-%COMP%]{padding-left:20px}.-wallet[_ngcontent-%COMP%] .-encryption[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{border-radius:50%;background-color:#f7f7f7;display:inline-block;height:38px;margin:11px 0;padding:3px;width:38px;cursor:pointer}.-wallet[_ngcontent-%COMP%] .-expand[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:85px;margin-right:15px;-ms-flex-negative:0;flex-shrink:0}.-wallet[_ngcontent-%COMP%] .-expand[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{width:32px;height:32px}.-text-right[_ngcontent-%COMP%]{text-align:right}.action-buttons[_ngcontent-%COMP%]{margin-bottom:74px;padding:40px 0;text-align:center}.action-buttons[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{background-color:#f7f7f7;border:none;-webkit-box-shadow:none;box-shadow:none;color:rgba(30,34,39,.5);font-size:13px;margin:0 5px;min-width:140px}.action-buttons[_ngcontent-%COMP%] button[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{height:28px;margin-left:-4px;width:28px}"]],data:{}});function Z_(n){return l._33(0,[(n()(),l._9(0,16777216,null,null,2,"img",[["src","../../../../assets/img/lock-gold.png"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,1).show()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,1).hide(1500)&&r),r},null,null)),l._8(1,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._4(0,null,null,0))],function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("wallet.encryption-enabled")))},null)}function $_(n){return l._33(0,[(n()(),l._9(0,16777216,null,null,2,"img",[["src","../../../../assets/img/unlock-grey.png"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,1).show()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,1).hide(1500)&&r),r},null,null)),l._8(1,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._4(0,null,null,0))],function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("wallet.encryption-disabled")))},null)}function nm(n){return l._33(0,[(n()(),l._9(0,16777216,null,null,2,"img",[["src","../../../../assets/img/alert-red.png"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,1).show()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,1).hide(1500)&&r),r},null,null)),l._8(1,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._4(0,null,null,0))],function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("wallet.hw-security-warning")))},null)}function tm(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-wallet-detail",[],null,null,null,e_,Vf)),l._8(1,180224,null,0,Bf,[fa,Sc,jc,oc,De.j,cp,Ye],{wallet:[0,"wallet"]},null)],function(n,t){n(t,1,0,t.parent.context.$implicit)},null)}function em(n){return l._33(0,[(n()(),l._9(0,0,null,null,40,"div",[["class","-wallets"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,37,"div",[["class","-body"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,31,"div",[["class","-wallet"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.toggleWallet(n.context.$implicit)&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,1,"div",[["class","-width-250 -label"]],[[1,"title",0]],null,null,null,null)),(n()(),l._31(7,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,10,"div",[["class","-flex-fill -encryption"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Z_)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,$_)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,nm)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(21,0,null,null,2,"div",[["class","-width-130 -coins"]],null,null,null,null,null)),(n()(),l._31(22,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,2,"div",[["class","-width-130 -hours"]],null,null,null,null,null)),(n()(),l._31(26,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(29,0,null,null,5,"div",[["class","-expand"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(31,0,null,null,2,"img",[["src","../../../../assets/img/chevron-right-grey.png"]],null,null,null,null,null)),l._8(32,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(33,{"rotate-270":0,"rotate-90":1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,tm)),l._8(38,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,12,0,t.context.$implicit.encrypted&&!t.context.$implicit.isHardware),n(t,15,0,!t.context.$implicit.encrypted&&!t.context.$implicit.isHardware),n(t,18,0,t.context.$implicit.hasHwSecurityWarnings&&t.context.$implicit.isHardware),n(t,32,0,n(t,33,0,t.context.$implicit.opened,!t.context.$implicit.opened)),n(t,38,0,t.context.$implicit.opened)},function(n,t){n(t,6,0,t.context.$implicit.label),n(t,7,0,t.context.$implicit.label),n(t,22,0,l._32(t,22,0,l._22(t,23).transform(t.context.$implicit.coins?t.context.$implicit.coins.toString():0,!0,"first"))),n(t,26,0,l._32(t,26,0,l._22(t,27).transform(t.context.$implicit.hours?t.context.$implicit.hours.toString():0,!1,"first")))})}function lm(n){return l._33(0,[(n()(),l._9(0,0,null,null,21,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,15,"div",[["class","-headers"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"div",[["class","-width-250"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,0,"div",[["class","-flex-fill"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"div",[["class","-width-130 -text-right"]],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"div",[["class","-width-130 -text-right"]],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,em)),l._8(20,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,20,0,0===t.parent.context.$implicit?e.hardwareWallets:e.wallets)},function(n,t){n(t,5,0,l._32(t,5,0,l._22(t,6).transform(0===t.parent.context.$implicit?"wallet.hardware-wallet":"wallet.wallet"))),n(t,11,0,l._32(t,11,0,l._22(t,12).transform("coin"))),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("hours")))})}function rm(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,lm)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,0===t.context.$implicit&&e.hardwareWallets.length>0||1===t.context.$implicit&&e.wallets.length>0)},null)}function im(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"button",[["class","mat-button"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.adminHwWallet()&&l),l},i_,r_)),l._8(1,180224,null,0,Bs,[l.l,Hl,Rr],null,null),l._8(2,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,0,"img",[["src","../../../../assets/img/hw-gold.png"]],null,null,null,null,null)),(n()(),l._31(5,0,[" ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,0,0,l._22(t,1).disabled||null),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("wallet.hardware-wallet")))})}function om(n){return l._33(0,[(n()(),l._9(0,0,null,null,34,"div",[["class","sky-container sky-container-grey"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(3,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(6,0,null,null,27,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,2,null,rm)),l._8(9,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),l._24(10,2),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(12,0,null,null,20,"div",[["class","action-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,6,"button",[["class","mat-button"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addWallet(!0)&&l),l},i_,r_)),l._8(15,180224,null,0,Bs,[l.l,Hl,Rr],null,null),l._8(16,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(18,0,null,0,0,"img",[["src","../../../../assets/img/plus-gold.png"]],null,null,null,null,null)),(n()(),l._31(19,0,[" ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,6,"button",[["class","mat-button"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addWallet(!1)&&l),l},i_,r_)),l._8(23,180224,null,0,Bs,[l.l,Hl,Rr],null,null),l._8(24,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(26,0,null,0,0,"img",[["src","../../../../assets/img/load-gold.png"]],null,null,null,null,null)),(n()(),l._31(27,0,[" ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,im)),l._8(31,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,l._22(t,4).transform("title.wallets"))),n(t,9,0,n(t,10,0,0,1)),n(t,31,0,e.hwCompatibilityActivated)},function(n,t){n(t,14,0,l._22(t,15).disabled||null),n(t,19,0,l._32(t,19,0,l._22(t,20).transform("wallet.add"))),n(t,22,0,l._22(t,23).disabled||null),n(t,27,0,l._32(t,27,0,l._22(t,28).transform("wallet.load")))})}var sm=l._5("app-wallets",Np,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-wallets",[],null,null,null,om,X_)),l._8(1,245760,null,0,Np,[Sc,oc,fa,cp],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]);o.a.prototype.delay=function(n,t){return void 0===t&&(t=sl),Hi(n,t)(this)};var am=function(){function n(t,e,l,r,i){this.dialogRef=t,this.data=e,this.formBuilder=l,this.msgBarService=r,this.storageService=i,this.maxNoteChars=n.MAX_NOTE_CHARS}return n.prototype.ngOnInit=function(){this.originalNote=this.data.note?this.data.note:"",this.form=this.formBuilder.group({note:[this.data.note]})},n.prototype.ngOnDestroy=function(){this.msgBarService.hide(),this.OperationSubscription&&this.OperationSubscription.unsubscribe()},n.prototype.closePopup=function(){this.dialogRef.close()},n.prototype.changeNote=function(){var n=this;if(!this.button.isLoading()){var t=this.form.value.note?this.form.value.note.trim():"";this.originalNote!==t?(this.msgBarService.hide(),this.button.setLoading(),this.OperationSubscription=this.storageService.store(ec.NOTES,this.data.txid,t).subscribe(function(){n.dialogRef.close(t)},function(t){n.msgBarService.showError(t),n.button.resetState().setEnabled()})):this.closePopup()}},n.MAX_NOTE_CHARS=64,n}(),um=function(){function n(n,t,e,r,i,o,s,a,u,c,d){var h=this;this.formBuilder=n,this.blockchainService=t,this.walletService=e,this.dialog=r,this.msgBarService=i,this.navbarService=o,this.hwWalletService=s,this.translate=a,this.changeDetector=u,this.appService=c,this.onFormSubmitted=new l.o,this.maxNoteChars=am.MAX_NOTE_CHARS,this.transactions=[],this.busy=!1,this.doubleButtonActive=Fp,this.selectedCurrency=Fp.LeftButton,this.valueGreaterThanBalance=!1,this.subscriptionsGroup=[],this.subscriptionsGroup.push(d.price.subscribe(function(n){h.price=n,h.updateValue()}))}return n.prototype.ngOnInit=function(){var n=this;this.navbarService.showSwitch("send.simple","send.advanced"),this.initForm(),this.subscriptionsGroup.push(this.walletService.all().first().subscribe(function(t){n.wallets=t,1===t.length&&n.form.get("wallet").setValue(t[0])}))},n.prototype.ngOnDestroy=function(){this.processingSubscription&&!this.processingSubscription.closed&&this.processingSubscription.unsubscribe(),this.subscriptionsGroup.forEach(function(n){return n.unsubscribe()}),this.closeSyncCheckSubscription(),this.navbarService.hideSwitch(),this.msgBarService.hide()},n.prototype.preview=function(){this.previewTx=!0,this.checkBeforeSending(),this.changeDetector.detectChanges()},n.prototype.send=function(){this.previewTx=!1,this.checkBeforeSending()},n.prototype.changeActiveCurrency=function(n){n!==this.selectedCurrency&&(this.selectedCurrency=n,this.askIfConvertAmount(),this.updateValue(),this.form.get("amount").updateValueAndValidity())},n.prototype.askIfConvertAmount=function(){var n=this;if(this.form.get("amount").value){var t=this.form.get("amount").value.trim(),e=new Ae.BigNumber(this.form.get("amount").value.trim());if(t&&!e.isNaN()){var l,r,i=this.translate.instant("common.usd"),o=this.appService.coinName;this.selectedCurrency===Fp.LeftButton?(l=i,r=o):(l=o,r=i);var s={text:this.translate.instant("send.convert-confirmation",{from:l,to:r}),headerText:"confirmation.header-text",confirmButtonText:"confirmation.confirm-button",cancelButtonText:"confirmation.cancel-button"};Wc(this.dialog,s).afterClosed().subscribe(function(t){t&&n.convertAmount()})}}},n.prototype.convertAmount=function(){if(this.msgBarService.hide(),this.form.get("amount").value){var t,e=this.form.get("amount").value.trim(),l=new Ae.BigNumber(e);if(!e||l.isNaN())return void this.msgBarService.showWarning(this.translate.instant("send.invaid-amount-warning"));this.selectedCurrency===Fp.LeftButton?((t=l.dividedBy(this.price).decimalPlaces(this.blockchainService.currentMaxDecimals)).multipliedBy(this.price).decimalPlaces(n.MaxUsdDecimals,Ae.BigNumber.ROUND_FLOOR).isEqualTo(l)||this.msgBarService.showWarning(this.translate.instant("send.precision-error-warning")),this.form.get("amount").setValue(t.toString())):((t=l.multipliedBy(this.price).decimalPlaces(n.MaxUsdDecimals,Ae.BigNumber.ROUND_FLOOR)).dividedBy(this.price).decimalPlaces(this.blockchainService.currentMaxDecimals).isEqualTo(l)||this.msgBarService.showWarning(this.translate.instant("send.precision-error-warning")),this.form.get("amount").setValue(t.toString()))}},n.prototype.assignAll=function(){this.msgBarService.hide();var t=this.form.get("wallet").value&&this.form.get("wallet").value.coins?this.form.get("wallet").value.coins:new Ae.BigNumber(-1);t.isEqualTo(-1)?this.msgBarService.showError(this.translate.instant("send.no-wallet-selected")):(this.selectedCurrency===Fp.RightButton&&(t=t.multipliedBy(this.price).decimalPlaces(n.MaxUsdDecimals,Ae.BigNumber.ROUND_FLOOR)),this.form.get("amount").setValue(t.toString()))},n.prototype.updateValue=function(){if(this.price)if(this.form&&null===this.validateAmount(this.form.get("amount"))){var n=this.form.get("wallet").value&&this.form.get("wallet").value.coins?this.form.get("wallet").value.coins:-1;this.valueGreaterThanBalance=!1,this.selectedCurrency===Fp.LeftButton?(this.value=new Ae.BigNumber(this.form.get("amount").value).multipliedBy(this.price).decimalPlaces(2).toNumber(),n>0&&parseFloat(this.form.get("amount").value)>n&&(this.valueGreaterThanBalance=!0)):(this.value=new Ae.BigNumber(this.form.get("amount").value).dividedBy(this.price).decimalPlaces(this.blockchainService.currentMaxDecimals).toNumber(),n>0&&this.value>n&&(this.valueGreaterThanBalance=!0))}else this.value=-1;else this.value=null},n.prototype.checkBeforeSending=function(){var n=this;!this.form.valid||this.previewButton.isLoading()||this.sendButton.isLoading()||(this.closeSyncCheckSubscription(),this.syncCheckSubscription=this.blockchainService.synchronized.first().subscribe(function(t){t?n.prepareTransaction():n.showSynchronizingWarning()}))},n.prototype.showSynchronizingWarning=function(){var n=this;Wc(this.dialog,{text:"send.synchronizing-warning",headerText:"confirmation.header-text",confirmButtonText:"confirmation.confirm-button",cancelButtonText:"confirmation.cancel-button"}).afterClosed().subscribe(function(t){t&&n.prepareTransaction()})},n.prototype.prepareTransaction=function(){var n=this;if(this.msgBarService.hide(),this.previewButton.resetState(),this.sendButton.resetState(),!this.form.value.wallet.encrypted||this.form.value.wallet.isHardware||this.previewTx)!this.form.value.wallet.isHardware||this.previewTx?this.createTransaction():(this.showBusy(),this.processingSubscription=this.hwWalletService.checkIfCorrectHwConnected(this.form.value.wallet.addresses[0].address).subscribe(function(){return n.createTransaction()},function(t){return n.showError(Tc(n.translate,t))}));else{var t=new oa;t.data={wallet:this.form.value.wallet},this.dialog.open(Zp,t).componentInstance.passwordSubmit.subscribe(function(t){n.createTransaction(t)})}},n.prototype.showBusy=function(){this.previewTx?(this.previewButton.setLoading(),this.sendButton.setDisabled()):(this.sendButton.setLoading(),this.previewButton.setDisabled()),this.busy=!0,this.navbarService.disableSwitch()},n.prototype.createTransaction=function(n){var t=this;this.showBusy(),this.processingSubscription=this.walletService.createTransaction(this.form.value.wallet,this.form.value.wallet.addresses.map(function(n){return n.address}),null,[{address:this.form.value.address.trim(),coins:(this.selectedCurrency===Fp.LeftButton?this.form.value.amount:this.value.toString()).trim()}],{type:"auto",mode:"share",share_factor:"0.5"},null,n?n.password:null,this.previewTx).subscribe(function(e){n&&n.close();var l=t.form.value.note.trim();t.previewTx?(t.onFormSubmitted.emit({form:{wallet:t.form.value.wallet,address:t.form.value.address.trim(),amount:t.form.value.amount,currency:t.selectedCurrency,note:l},amount:new Ae.BigNumber(t.form.value.amount),to:[t.form.value.address.trim()],transaction:e}),t.busy=!1,t.navbarService.enableSwitch()):t.processingSubscription=t.walletService.injectTransaction(e.encoded,l).subscribe(function(n){var e=!0;l&&!n&&(t.msgBarService.showWarning(t.translate.instant("send.error-saving-note")),e=!1),t.showSuccess(e)},function(n){return t.showError(n)})},function(e){n&&n.error(e),t.showError(e&&e.result?Tc(t.translate,e):e)})},n.prototype.showSuccess=function(n){var t=this;this.busy=!1,this.navbarService.enableSwitch(),this.resetForm(),n?(this.msgBarService.showDone("send.sent"),this.sendButton.resetState()):(this.sendButton.setSuccess(),setTimeout(function(){t.sendButton.resetState()},3e3))},n.prototype.showError=function(n){this.busy=!1,this.msgBarService.showError(n),this.navbarService.enableSwitch(),this.previewButton.resetState().setEnabled(),this.sendButton.resetState().setEnabled()},n.prototype.initForm=function(){var n=this;this.form=this.formBuilder.group({wallet:["",Xi.required],address:[""],amount:["",Xi.required],note:[""]}),this.form.get("address").setValidators([this.validateAddress.bind(this)]),this.subscriptionsGroup.push(this.form.get("wallet").valueChanges.subscribe(function(t){n.form.get("amount").setValidators([Xi.required,n.validateAmountWithValue.bind(n)]),n.form.get("amount").updateValueAndValidity()})),this.subscriptionsGroup.push(this.form.get("amount").valueChanges.subscribe(function(t){n.updateValue()})),this.formData&&Object.keys(this.form.controls).forEach(function(t){n.form.get(t)&&n.form.get(t).setValue(n.formData.form[t]),n.selectedCurrency=n.formData.form.currency})},n.prototype.validateAddress=function(n){if(!n.value||0===n.value.trim().length)return{Required:!0}},n.prototype.validateAmount=function(t){var e=t.value;e=e?e.trim():e;var l=new Ae.BigNumber(e);if(!e||l.isNaN()||l.isLessThanOrEqualTo(0))return{Invalid:!0};var r=e.split(".");if(this.selectedCurrency===Fp.LeftButton){if(2===r.length&&r[1].length>this.blockchainService.currentMaxDecimals)return{Invalid:!0}}else if(2===r.length&&r[1].length>n.MaxUsdDecimals)return{Invalid:!0};return null},n.prototype.validateAmountWithValue=function(n){var t=this.validateAmount(n);if(t)return t;var e=this.form.get("wallet").value&&this.form.get("wallet").value.coins?this.form.get("wallet").value.coins:0;if(this.selectedCurrency===Fp.LeftButton){if(parseFloat(n.value)>e)return{Invalid:!0}}else if(this.updateValue(),this.value>e)return{Invalid:!0};return null},n.prototype.resetForm=function(){this.form.get("wallet").setValue(""),this.form.get("address").setValue(""),this.form.get("amount").setValue(""),this.form.get("note").setValue(""),this.selectedCurrency=Fp.LeftButton},n.prototype.closeSyncCheckSubscription=function(){this.syncCheckSubscription&&this.syncCheckSubscription.unsubscribe()},n.MaxUsdDecimals=6,n}(),cm=l._7({encapsulation:0,styles:[[".-buttons[_ngcontent-%COMP%]{text-align:center}.amount-label[_ngcontent-%COMP%]{display:inline-block}label[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{display:inline;font-size:14px;color:rgba(121,135,152,.5);vertical-align:text-bottom;padding-left:5px}"]],data:{}});function dm(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n (",")\n "])),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform(t.parent.context.$implicit.coins?t.parent.context.$implicit.coins.toString():0)),l._32(t,1,1,l._22(t,3).transform(t.parent.context.$implicit.hours.toString(),!1)))})}function hm(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"option",[],[[8,"disabled",0]],null,null,null,null)),l._8(1,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(2,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(3,null,["\n "," -\n "])),(n()(),l._4(16777216,null,null,1,null,dm)),l._8(5,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,1,0,t.context.$implicit),n(t,2,0,t.context.$implicit),n(t,5,0,t.context.$implicit.coins&&t.context.$implicit.hours)},function(n,t){n(t,0,0,!t.context.$implicit.coins||t.context.$implicit.coins.isLessThanOrEqualTo(0)),n(t,3,0,t.context.$implicit.label)})}function pm(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,hm)),l._8(3,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.component.wallets)},null)}function fm(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,"div",[["class","coin-selector-container"]],null,null,null,null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(2,{"element-disabled":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,3,"app-double-button",[["className","light small"]],null,[[null,"onStateChange"]],function(n,t,e){var l=!0;return"onStateChange"===t&&(l=!1!==n.component.changeActiveCurrency(e)&&l),l},M_,x_)),l._8(5,49152,null,0,Bp,[],{rightButtonText:[0,"rightButtonText"],leftButtonText:[1,"leftButtonText"],activeButton:[2,"activeButton"],className:[3,"className"]},{onStateChange:"onStateChange"}),l._25(131072,De.i,[De.j,l.h]),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,1,0,"coin-selector-container",n(t,2,0,e.busy)),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("common.usd")),l._32(t,5,1,l._22(t,7).transform("coin")),e.selectedCurrency,"light small")},null)}function _m(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("send.invalid-amount")))})}function mm(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ~ "," ","\n "])),l._27(2,2),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,n(t,2,0,l._22(t.parent,0),e.value,"1.0-2")),l._32(t,1,1,l._22(t,3).transform("common.usd")))})}function gm(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ~ ","\n "])),l._25(0,If,[tn,qc,gf])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform(e.value)))})}function ym(n){return l._33(0,[l._25(0,tn,[l.w]),l._29(402653184,1,{previewButton:0}),l._29(402653184,2,{sendButton:0}),(n()(),l._9(3,0,null,null,127,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,4).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,4).onReset()&&r),r},null,null)),l._8(4,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(6,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,27,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"label",[["for","wallet"]],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,20,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,17,"select",[["formControlName","wallet"],["id","wallet"]],[[1,"disabled",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(n,t,e){var r=!0;return"change"===t&&(r=!1!==l._22(n,19).onChange(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,19).onTouched()&&r),r},null,null)),l._8(17,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(18,{"element-disabled":0}),l._8(19,16384,null,0,_o,[l.G,l.l],null,null),l._28(1024,null,to,function(n){return[n]},[_o]),l._8(21,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(23,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,4,"option",[["disabled",""],["hidden",""]],null,null,null,null,null)),l._8(26,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(27,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(28,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,pm)),l._8(32,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(37,0,null,null,12,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(39,0,null,null,2,"label",[["for","address"]],null,null,null,null,null)),(n()(),l._31(40,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(43,0,null,null,5,"input",[["formControlName","address"],["id","address"]],[[1,"disabled",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,44)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,44).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,44)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,44)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(44,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(46,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(48,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(51,0,null,null,43,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(53,0,null,null,2,"label",[["class","amount-label"],["for","amount"]],null,null,null,null,null)),(n()(),l._31(54,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,fm)),l._8(58,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(60,0,null,null,13,"div",[["class","-input-addon"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(62,0,null,null,5,"input",[["formControlName","amount"],["id","amount"]],[[1,"disabled",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,63)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,63).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,63)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,63)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(63,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(65,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(67,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(69,0,null,null,3,"span",[],null,null,null,null,null)),(n()(),l._31(70,null,["",""])),l._25(0,l_,[gf]),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(75,0,null,null,18,"div",[["class","coins-value-label"]],null,null,null,null,null)),l._8(76,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(77,{red:0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,_m)),l._8(80,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,mm)),l._8(83,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,gm)),l._8(86,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(88,0,null,null,4,"div",[["class","link"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.assignAll()&&l),l},null,null)),l._8(89,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(90,{"centerd-link":0}),(n()(),l._31(91,null,["(",")"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(96,0,null,null,20,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(98,0,null,null,8,"label",[["for","note"]],null,null,null,null,null)),(n()(),l._31(99,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(101,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,103).show()&&r),"keydown"===t&&(r=!1!==l._22(n,103)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,103).hide(1500)&&r),r},Hf,Rf)),l._8(102,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(103,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(108,0,null,null,7,"input",[["formControlName","note"],["id","note"]],[[1,"disabled",0],[1,"maxlength",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,109)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,109).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,109)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,109)._compositionEnd(e.target.value)&&r),"keydown.enter"===t&&(r=!1!==i.preview()&&r),r},null,null)),l._8(109,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(110,540672,null,0,$o,[],{maxlength:[0,"maxlength"]},null),l._28(1024,null,Qi,function(n){return[n]},[$o]),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(113,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(115,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(118,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(120,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.preview()&&l),l},w_,g_)),l._8(121,49152,[[1,4],["previewButton",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(122,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(125,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.send()&&l),l},w_,g_)),l._8(126,49152,[[2,4],["sendButton",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(127,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,4,0,e.form),n(t,17,0,n(t,18,0,e.busy)),n(t,21,0,"wallet"),n(t,26,0,""),n(t,27,0,""),n(t,32,0,e.wallets),n(t,46,0,"address"),n(t,58,0,e.price),n(t,65,0,"amount"),n(t,76,0,"coins-value-label",n(t,77,0,e.value>=0&&e.valueGreaterThanBalance)),n(t,80,0,e.price&&e.value<0),n(t,83,0,e.price&&e.value>=0&&e.selectedCurrency===e.doubleButtonActive.LeftButton),n(t,86,0,e.price&&e.value>=0&&e.selectedCurrency===e.doubleButtonActive.RightButton),n(t,89,0,"link",n(t,90,0,!e.price)),n(t,102,0),n(t,103,0,l._32(t,103,0,l._22(t,104).transform("send.personal-note-help"))),n(t,110,0,e.maxNoteChars),n(t,113,0,"note"),n(t,121,0,!e.form.valid),n(t,126,0,!e.form.valid)},function(n,t){var e=t.component;n(t,3,0,l._22(t,6).ngClassUntouched,l._22(t,6).ngClassTouched,l._22(t,6).ngClassPristine,l._22(t,6).ngClassDirty,l._22(t,6).ngClassValid,l._22(t,6).ngClassInvalid,l._22(t,6).ngClassPending),n(t,11,0,l._32(t,11,0,l._22(t,12).transform("send.from-label"))),n(t,16,0,e.busy?"true":null,l._22(t,23).ngClassUntouched,l._22(t,23).ngClassTouched,l._22(t,23).ngClassPristine,l._22(t,23).ngClassDirty,l._22(t,23).ngClassValid,l._22(t,23).ngClassInvalid,l._22(t,23).ngClassPending),n(t,28,0,l._32(t,28,0,l._22(t,29).transform("send.select-wallet"))),n(t,40,0,l._32(t,40,0,l._22(t,41).transform("send.to-label"))),n(t,43,0,e.busy?"true":null,l._22(t,48).ngClassUntouched,l._22(t,48).ngClassTouched,l._22(t,48).ngClassPristine,l._22(t,48).ngClassDirty,l._22(t,48).ngClassValid,l._22(t,48).ngClassInvalid,l._22(t,48).ngClassPending),n(t,54,0,l._32(t,54,0,l._22(t,55).transform("send.amount-label"))),n(t,62,0,e.busy?"true":null,l._22(t,67).ngClassUntouched,l._22(t,67).ngClassTouched,l._22(t,67).ngClassPristine,l._22(t,67).ngClassDirty,l._22(t,67).ngClassValid,l._22(t,67).ngClassInvalid,l._22(t,67).ngClassPending),n(t,70,0,l._32(t,70,0,e.selectedCurrency===e.doubleButtonActive.LeftButton?l._22(t,71).transform("coin"):l._22(t,72).transform("common.usd"))),n(t,91,0,l._32(t,91,0,l._22(t,92).transform("send.send-all-available-coins"))),n(t,99,0,l._32(t,99,0,l._22(t,100).transform("send.personal-note-label"))),n(t,108,0,e.busy?"true":null,l._22(t,110).maxlength?l._22(t,110).maxlength:null,l._22(t,115).ngClassUntouched,l._22(t,115).ngClassTouched,l._22(t,115).ngClassPristine,l._22(t,115).ngClassDirty,l._22(t,115).ngClassValid,l._22(t,115).ngClassInvalid,l._22(t,115).ngClassPending),n(t,122,0,l._32(t,122,0,l._22(t,123).transform("send.preview-button"))),n(t,127,0,l._32(t,127,0,l._22(t,128).transform("send.send-button")))})}var bm=l._7({encapsulation:2,styles:[],data:{}});function vm(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-pseudo-checkbox",[["class","mat-option-pseudo-checkbox mat-pseudo-checkbox"]],[[2,"mat-pseudo-checkbox-indeterminate",null],[2,"mat-pseudo-checkbox-checked",null],[2,"mat-pseudo-checkbox-disabled",null]],null,null,Cm,km)),l._8(1,49152,null,0,sr,[],{state:[0,"state"],disabled:[1,"disabled"]},null)],function(n,t){var e=t.component;n(t,1,0,e.selected?"checked":"",e.disabled)},function(n,t){n(t,0,0,"indeterminate"===l._22(t,1).state,"checked"===l._22(t,1).state,l._22(t,1).disabled)})}function wm(n){return l._33(2,[(n()(),l._4(16777216,null,null,1,null,vm)),l._8(1,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._9(2,0,null,null,1,"span",[["class","mat-option-text"]],null,null,null,null,null)),l._21(null,0),(n()(),l._9(4,0,null,null,1,"div",[["class","mat-option-ripple mat-ripple"],["mat-ripple",""]],[[2,"mat-ripple-unbounded",null]],null,null,null,null)),l._8(5,212992,null,0,ir,[l.l,l.B,Hl,[2,rr]],{disabled:[0,"disabled"],trigger:[1,"trigger"]},null)],function(n,t){var e=t.component;n(t,1,0,e.multiple),n(t,5,0,e.disabled||e.disableRipple,e._getHostElement())},function(n,t){n(t,4,0,l._22(t,5).unbounded)})}var xm=l._7({encapsulation:2,styles:[],data:{}});function Mm(n){return l._33(2,[(n()(),l._9(0,0,null,null,1,"label",[["class","mat-optgroup-label"]],[[8,"id",0]],null,null,null,null)),(n()(),l._31(1,null,["",""])),l._21(null,0)],null,function(n,t){var e=t.component;n(t,0,0,e._labelId),n(t,1,0,e.label)})}var km=l._7({encapsulation:2,styles:[".mat-pseudo-checkbox{width:20px;height:20px;border:2px solid;border-radius:2px;cursor:pointer;display:inline-block;vertical-align:middle;box-sizing:border-box;position:relative;flex-shrink:0;transition:border-color 90ms cubic-bezier(0,0,.2,.1),background-color 90ms cubic-bezier(0,0,.2,.1)}.mat-pseudo-checkbox::after{position:absolute;opacity:0;content:'';border-bottom:2px solid currentColor;transition:opacity 90ms cubic-bezier(0,0,.2,.1)}.mat-pseudo-checkbox.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox.mat-pseudo-checkbox-indeterminate{border:none}.mat-pseudo-checkbox-disabled{cursor:default}.mat-pseudo-checkbox-indeterminate::after{top:9px;left:2px;width:16px;opacity:1}.mat-pseudo-checkbox-checked::after{top:5px;left:3px;width:12px;height:5px;border-left:2px solid currentColor;transform:rotate(-45deg);opacity:1}"],data:{}});function Cm(n){return l._33(2,[],null,null)}var Sm=l._7({encapsulation:2,styles:[".mat-select{display:inline-block;width:100%;outline:0}.mat-select-trigger{display:inline-table;cursor:pointer;position:relative;box-sizing:border-box}.mat-select-disabled .mat-select-trigger{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.mat-select-value{display:table-cell;max-width:0;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mat-select-value-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mat-select-arrow-wrapper{display:table-cell;vertical-align:middle}.mat-select-arrow{width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid;margin:0 4px}.mat-select-panel{min-width:112px;max-width:280px;overflow:auto;-webkit-overflow-scrolling:touch;padding-top:0;padding-bottom:0;max-height:256px;min-width:100%}.mat-select-panel:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}@media screen and (-ms-high-contrast:active){.mat-select-panel{outline:solid 1px}}.mat-select-panel .mat-optgroup-label,.mat-select-panel .mat-option{font-size:inherit;line-height:3em;height:3em}.mat-form-field-type-mat-select:not(.mat-form-field-disabled) .mat-form-field-flex{cursor:pointer}.mat-form-field-type-mat-select .mat-form-field-label{width:calc(100% - 18px)}.mat-select-placeholder{transition:color .4s .133s cubic-bezier(.25,.8,.25,1)}.mat-form-field-hide-placeholder .mat-select-placeholder{color:transparent;transition:none}"],data:{animation:[{type:7,name:"transformPanel",definitions:[{type:0,name:"showing",styles:{type:6,styles:{opacity:1,minWidth:"calc(100% + 32px)",transform:"scaleY(1)"},offset:null},options:void 0},{type:0,name:"showing-multiple",styles:{type:6,styles:{opacity:1,minWidth:"calc(100% + 64px)",transform:"scaleY(1)"},offset:null},options:void 0},{type:1,expr:"void => *",animation:[{type:6,styles:{opacity:0,minWidth:"100%",transform:"scaleY(0)"},offset:null},{type:4,styles:null,timings:"150ms cubic-bezier(0.25, 0.8, 0.25, 1)"}],options:null},{type:1,expr:"* => void",animation:[{type:4,styles:{type:6,styles:{opacity:0},offset:null},timings:"250ms 100ms linear"}],options:null}],options:{}},{type:7,name:"fadeInContent",definitions:[{type:0,name:"showing",styles:{type:6,styles:{opacity:1},offset:null},options:void 0},{type:1,expr:"void => showing",animation:[{type:6,styles:{opacity:0},offset:null},{type:4,styles:null,timings:"150ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)"}],options:null}],options:{}}]}});function Om(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[["class","mat-select-placeholder"]],null,null,null,null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.component.placeholder||"\xa0")})}function Tm(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.component.triggerValue)})}function Lm(n){return l._33(0,[l._21(null,0),(n()(),l._4(0,null,null,0))],null,null)}function Pm(n){return l._33(0,[(n()(),l._9(0,0,null,null,5,"span",[["class","mat-select-value-text"]],null,null,null,null,null)),l._8(1,16384,null,0,Y,[],{ngSwitch:[0,"ngSwitch"]},null),(n()(),l._4(16777216,null,null,1,null,Tm)),l._8(3,16384,null,0,I,[l.R,l.O,Y],null,null),(n()(),l._4(16777216,null,null,1,null,Lm)),l._8(5,278528,null,0,j,[l.R,l.O,Y],{ngSwitchCase:[0,"ngSwitchCase"]},null)],function(n,t){n(t,1,0,!!t.component.customTrigger),n(t,5,0,!0)},null)}function Dm(n){return l._33(0,[(n()(),l._9(0,0,[[2,0],["panel",1]],null,3,"div",[],[[24,"@transformPanel",0],[4,"transformOrigin",null],[2,"mat-select-panel-done-animating",null],[4,"font-size","px"]],[[null,"@transformPanel.done"]],function(n,t,e){var l=!0;return"@transformPanel.done"===t&&(l=!1!==n.component._onPanelDone()&&l),l},null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(n()(),l._9(2,0,null,null,1,"div",[["class","mat-select-content"]],[[24,"@fadeInContent",0]],[[null,"@fadeInContent.done"]],function(n,t,e){var l=!0;return"@fadeInContent.done"===t&&(l=!1!==n.component._onFadeInDone()&&l),l},null,null)),l._21(null,1)],function(n,t){var e=t.component;n(t,1,0,l._12(1,"mat-select-panel ",e._getPanelTheme(),""),e.panelClass)},function(n,t){var e=t.component;n(t,0,0,e.multiple?"showing-multiple":"showing",e._transformOrigin,e._panelDoneAnimating,e._triggerFontSize),n(t,2,0,"showing")})}function Am(n){return l._33(2,[l._29(402653184,1,{trigger:0}),l._29(671088640,2,{panel:0}),l._29(402653184,3,{overlayDir:0}),(n()(),l._9(3,0,[[1,0],["trigger",1]],null,9,"div",[["aria-hidden","true"],["cdk-overlay-origin",""],["class","mat-select-trigger"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.toggle()&&l),l},null,null)),l._8(4,16384,[["origin",4]],0,Yi,[l.l],null,null),(n()(),l._9(5,0,null,null,5,"div",[["class","mat-select-value"]],null,null,null,null,null)),l._8(6,16384,null,0,Y,[],{ngSwitch:[0,"ngSwitch"]},null),(n()(),l._4(16777216,null,null,1,null,Om)),l._8(8,278528,null,0,j,[l.R,l.O,Y],{ngSwitchCase:[0,"ngSwitchCase"]},null),(n()(),l._4(16777216,null,null,1,null,Pm)),l._8(10,278528,null,0,j,[l.R,l.O,Y],{ngSwitchCase:[0,"ngSwitchCase"]},null),(n()(),l._9(11,0,null,null,1,"div",[["class","mat-select-arrow-wrapper"]],null,null,null,null,null)),(n()(),l._9(12,0,null,null,0,"div",[["class","mat-select-arrow"]],null,null,null,null,null)),(n()(),l._4(16777216,null,null,1,function(n,t,e){var l=!0,r=n.component;return"backdropClick"===t&&(l=!1!==r.close()&&l),"attach"===t&&(l=!1!==r._onAttached()&&l),"detach"===t&&(l=!1!==r.close()&&l),l},Dm)),l._8(14,671744,[[3,4]],0,ji,[Pi,l.O,l.R,Ai,[2,Dl]],{_deprecatedOrigin:[0,"_deprecatedOrigin"],_deprecatedPositions:[1,"_deprecatedPositions"],_deprecatedOffsetY:[2,"_deprecatedOffsetY"],_deprecatedMinWidth:[3,"_deprecatedMinWidth"],_deprecatedBackdropClass:[4,"_deprecatedBackdropClass"],_deprecatedScrollStrategy:[5,"_deprecatedScrollStrategy"],_deprecatedOpen:[6,"_deprecatedOpen"],_deprecatedHasBackdrop:[7,"_deprecatedHasBackdrop"]},{backdropClick:"backdropClick",attach:"attach",detach:"detach"})],function(n,t){var e=t.component;n(t,6,0,e.empty),n(t,8,0,!0),n(t,10,0,!1),n(t,14,0,l._22(t,4),e._positions,e._offsetY,null==e._triggerRect?null:e._triggerRect.width,"cdk-overlay-transparent-backdrop",e._scrollStrategy,e.panelOpen,"")},null)}var Em=l._7({encapsulation:2,styles:["@keyframes mat-checkbox-fade-in-background{0%{opacity:0}50%{opacity:1}}@keyframes mat-checkbox-fade-out-background{0%,50%{opacity:1}100%{opacity:0}}@keyframes mat-checkbox-unchecked-checked-checkmark-path{0%,50%{stroke-dashoffset:22.91026}50%{animation-timing-function:cubic-bezier(0,0,.2,.1)}100%{stroke-dashoffset:0}}@keyframes mat-checkbox-unchecked-indeterminate-mixedmark{0%,68.2%{transform:scaleX(0)}68.2%{animation-timing-function:cubic-bezier(0,0,0,1)}100%{transform:scaleX(1)}}@keyframes mat-checkbox-checked-unchecked-checkmark-path{from{animation-timing-function:cubic-bezier(.4,0,1,1);stroke-dashoffset:0}to{stroke-dashoffset:-22.91026}}@keyframes mat-checkbox-checked-indeterminate-checkmark{from{animation-timing-function:cubic-bezier(0,0,.2,.1);opacity:1;transform:rotate(0)}to{opacity:0;transform:rotate(45deg)}}@keyframes mat-checkbox-indeterminate-checked-checkmark{from{animation-timing-function:cubic-bezier(.14,0,0,1);opacity:0;transform:rotate(45deg)}to{opacity:1;transform:rotate(360deg)}}@keyframes mat-checkbox-checked-indeterminate-mixedmark{from{animation-timing-function:cubic-bezier(0,0,.2,.1);opacity:0;transform:rotate(-45deg)}to{opacity:1;transform:rotate(0)}}@keyframes mat-checkbox-indeterminate-checked-mixedmark{from{animation-timing-function:cubic-bezier(.14,0,0,1);opacity:1;transform:rotate(0)}to{opacity:0;transform:rotate(315deg)}}@keyframes mat-checkbox-indeterminate-unchecked-mixedmark{0%{animation-timing-function:linear;opacity:1;transform:scaleX(1)}100%,32.8%{opacity:0;transform:scaleX(0)}}.mat-checkbox-checkmark,.mat-checkbox-mixedmark{width:calc(100% - 4px)}.mat-checkbox-background,.mat-checkbox-frame{top:0;left:0;right:0;bottom:0;position:absolute;border-radius:2px;box-sizing:border-box;pointer-events:none}.mat-checkbox{transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);cursor:pointer}.mat-checkbox-layout{cursor:inherit;align-items:baseline;vertical-align:middle;display:inline-flex;white-space:nowrap}.mat-checkbox-inner-container{display:inline-block;height:20px;line-height:0;margin:auto;margin-right:8px;order:0;position:relative;vertical-align:middle;white-space:nowrap;width:20px;flex-shrink:0}[dir=rtl] .mat-checkbox-inner-container{margin-left:8px;margin-right:auto}.mat-checkbox-inner-container-no-side-margin{margin-left:0;margin-right:0}.mat-checkbox-frame{background-color:transparent;transition:border-color 90ms cubic-bezier(0,0,.2,.1);border-width:2px;border-style:solid}.mat-checkbox-background{align-items:center;display:inline-flex;justify-content:center;transition:background-color 90ms cubic-bezier(0,0,.2,.1),opacity 90ms cubic-bezier(0,0,.2,.1)}.mat-checkbox-checkmark{top:0;left:0;right:0;bottom:0;position:absolute;width:100%}.mat-checkbox-checkmark-path{stroke-dashoffset:22.91026;stroke-dasharray:22.91026;stroke-width:2.66667px}.mat-checkbox-mixedmark{height:2px;opacity:0;transform:scaleX(0) rotate(0)}.mat-checkbox-label-before .mat-checkbox-inner-container{order:1;margin-left:8px;margin-right:auto}[dir=rtl] .mat-checkbox-label-before .mat-checkbox-inner-container{margin-left:auto;margin-right:8px}.mat-checkbox-checked .mat-checkbox-checkmark{opacity:1}.mat-checkbox-checked .mat-checkbox-checkmark-path{stroke-dashoffset:0}.mat-checkbox-checked .mat-checkbox-mixedmark{transform:scaleX(1) rotate(-45deg)}.mat-checkbox-indeterminate .mat-checkbox-checkmark{opacity:0;transform:rotate(45deg)}.mat-checkbox-indeterminate .mat-checkbox-checkmark-path{stroke-dashoffset:0}.mat-checkbox-indeterminate .mat-checkbox-mixedmark{opacity:1;transform:scaleX(1) rotate(0)}.mat-checkbox-unchecked .mat-checkbox-background{background-color:transparent}.mat-checkbox-disabled{cursor:default}.mat-checkbox-anim-unchecked-checked .mat-checkbox-background{animation:180ms linear 0s mat-checkbox-fade-in-background}.mat-checkbox-anim-unchecked-checked .mat-checkbox-checkmark-path{animation:180ms linear 0s mat-checkbox-unchecked-checked-checkmark-path}.mat-checkbox-anim-unchecked-indeterminate .mat-checkbox-background{animation:180ms linear 0s mat-checkbox-fade-in-background}.mat-checkbox-anim-unchecked-indeterminate .mat-checkbox-mixedmark{animation:90ms linear 0s mat-checkbox-unchecked-indeterminate-mixedmark}.mat-checkbox-anim-checked-unchecked .mat-checkbox-background{animation:180ms linear 0s mat-checkbox-fade-out-background}.mat-checkbox-anim-checked-unchecked .mat-checkbox-checkmark-path{animation:90ms linear 0s mat-checkbox-checked-unchecked-checkmark-path}.mat-checkbox-anim-checked-indeterminate .mat-checkbox-checkmark{animation:90ms linear 0s mat-checkbox-checked-indeterminate-checkmark}.mat-checkbox-anim-checked-indeterminate .mat-checkbox-mixedmark{animation:90ms linear 0s mat-checkbox-checked-indeterminate-mixedmark}.mat-checkbox-anim-indeterminate-checked .mat-checkbox-checkmark{animation:.5s linear 0s mat-checkbox-indeterminate-checked-checkmark}.mat-checkbox-anim-indeterminate-checked .mat-checkbox-mixedmark{animation:.5s linear 0s mat-checkbox-indeterminate-checked-mixedmark}.mat-checkbox-anim-indeterminate-unchecked .mat-checkbox-background{animation:180ms linear 0s mat-checkbox-fade-out-background}.mat-checkbox-anim-indeterminate-unchecked .mat-checkbox-mixedmark{animation:.3s linear 0s mat-checkbox-indeterminate-unchecked-mixedmark}.mat-checkbox-input{bottom:0;left:50%}.mat-checkbox-ripple{position:absolute;left:-15px;top:-15px;height:50px;width:50px;z-index:1;pointer-events:none}"],data:{}});function Ym(n){return l._33(2,[l._29(402653184,1,{_inputElement:0}),l._29(402653184,2,{_ripple:0}),(n()(),l._9(2,0,[["label",1]],null,14,"label",[["class","mat-checkbox-layout"]],[[1,"for",0]],null,null,null,null)),(n()(),l._9(3,0,null,null,8,"div",[["class","mat-checkbox-inner-container"]],[[2,"mat-checkbox-inner-container-no-side-margin",null]],null,null,null,null)),(n()(),l._9(4,0,[[1,0],["input",1]],null,0,"input",[["class","mat-checkbox-input cdk-visually-hidden"],["type","checkbox"]],[[8,"id",0],[8,"required",0],[8,"checked",0],[1,"value",0],[8,"disabled",0],[1,"name",0],[8,"tabIndex",0],[8,"indeterminate",0],[1,"aria-label",0],[1,"aria-labelledby",0],[1,"aria-checked",0]],[[null,"change"],[null,"click"]],function(n,t,e){var l=!0,r=n.component;return"change"===t&&(l=!1!==r._onInteractionEvent(e)&&l),"click"===t&&(l=!1!==r._onInputClick(e)&&l),l},null,null)),(n()(),l._9(5,0,null,null,1,"div",[["class","mat-checkbox-ripple mat-ripple"],["matRipple",""]],[[2,"mat-ripple-unbounded",null]],null,null,null,null)),l._8(6,212992,[[2,4]],0,ir,[l.l,l.B,Hl,[2,rr]],{centered:[0,"centered"],radius:[1,"radius"],speedFactor:[2,"speedFactor"],disabled:[3,"disabled"],trigger:[4,"trigger"]},null),(n()(),l._9(7,0,null,null,0,"div",[["class","mat-checkbox-frame"]],null,null,null,null,null)),(n()(),l._9(8,0,null,null,3,"div",[["class","mat-checkbox-background"]],null,null,null,null,null)),(n()(),l._9(9,0,null,null,1,":svg:svg",[[":xml:space","preserve"],["class","mat-checkbox-checkmark"],["focusable","false"],["version","1.1"],["viewBox","0 0 24 24"]],null,null,null,null,null)),(n()(),l._9(10,0,null,null,0,":svg:path",[["class","mat-checkbox-checkmark-path"],["d","M4.1,12.7 9,17.6 20.3,6.3"],["fill","none"],["stroke","white"]],null,null,null,null,null)),(n()(),l._9(11,0,null,null,0,"div",[["class","mat-checkbox-mixedmark"]],null,null,null,null,null)),(n()(),l._9(12,0,[["checkboxLabel",1]],null,4,"span",[["class","mat-checkbox-label"]],null,[[null,"cdkObserveContent"]],function(n,t,e){var l=!0;return"cdkObserveContent"===t&&(l=!1!==n.component._onLabelTextChange()&&l),l},null,null)),l._8(13,1196032,null,0,Ks,[Qs,l.l,l.B],null,{event:"cdkObserveContent"}),(n()(),l._9(14,0,null,null,1,"span",[["style","display:none"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\xa0"])),l._21(null,0)],function(n,t){var e=t.component;n(t,6,0,e._rippleConfig.centered,e._rippleConfig.radius,e._rippleConfig.speedFactor,e._isRippleDisabled(),l._22(t,2))},function(n,t){var e=t.component;n(t,2,0,e.inputId),n(t,3,0,!l._22(t,12).textContent||!l._22(t,12).textContent.trim()),n(t,4,1,[e.inputId,e.required,e.checked,e.value,e.disabled,e.name,e.tabIndex,e.indeterminate,e.ariaLabel,e.ariaLabelledby,e._getAriaChecked()]),n(t,5,0,l._22(t,6).unbounded)})}var jm=l._7({encapsulation:2,styles:[".mat-slider{display:inline-block;position:relative;box-sizing:border-box;padding:8px;outline:0;vertical-align:middle}.mat-slider-wrapper{position:absolute}.mat-slider-track-wrapper{position:absolute;top:0;left:0;overflow:hidden}.mat-slider-track-fill{position:absolute;transform-origin:0 0;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-track-background{position:absolute;transform-origin:100% 100%;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-ticks-container{position:absolute;left:0;top:0;overflow:hidden}.mat-slider-ticks{background-repeat:repeat;background-clip:content-box;box-sizing:border-box;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-thumb-container{position:absolute;z-index:1;transition:transform .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-focus-ring{position:absolute;width:30px;height:30px;border-radius:50%;transform:scale(0);opacity:0;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),opacity .4s cubic-bezier(.25,.8,.25,1)}.cdk-keyboard-focused .mat-slider-focus-ring,.cdk-program-focused .mat-slider-focus-ring{transform:scale(1);opacity:1}.mat-slider:not(.mat-slider-disabled) .mat-slider-thumb,.mat-slider:not(.mat-slider-disabled) .mat-slider-thumb-label{cursor:-webkit-grab;cursor:grab}.mat-slider-sliding:not(.mat-slider-disabled) .mat-slider-thumb,.mat-slider-sliding:not(.mat-slider-disabled) .mat-slider-thumb-label,.mat-slider:not(.mat-slider-disabled) .mat-slider-thumb-label:active,.mat-slider:not(.mat-slider-disabled) .mat-slider-thumb:active{cursor:-webkit-grabbing;cursor:grabbing}.mat-slider-thumb{position:absolute;right:-10px;bottom:-10px;box-sizing:border-box;width:20px;height:20px;border:3px solid transparent;border-radius:50%;transform:scale(.7);transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),border-color .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-thumb-label{display:none;align-items:center;justify-content:center;position:absolute;width:28px;height:28px;border-radius:50%;transition:transform .4s cubic-bezier(.25,.8,.25,1),border-radius .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-thumb-label-text{z-index:1;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-sliding .mat-slider-thumb-container,.mat-slider-sliding .mat-slider-track-background,.mat-slider-sliding .mat-slider-track-fill{transition-duration:0s}.mat-slider-has-ticks .mat-slider-wrapper::after{content:'';position:absolute;border-width:0;border-style:solid;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-has-ticks.cdk-focused:not(.mat-slider-hide-last-tick) .mat-slider-wrapper::after,.mat-slider-has-ticks:hover:not(.mat-slider-hide-last-tick) .mat-slider-wrapper::after{opacity:1}.mat-slider-has-ticks.cdk-focused:not(.mat-slider-disabled) .mat-slider-ticks,.mat-slider-has-ticks:hover:not(.mat-slider-disabled) .mat-slider-ticks{opacity:1}.mat-slider-thumb-label-showing .mat-slider-focus-ring{transform:scale(0);opacity:0}.mat-slider-thumb-label-showing .mat-slider-thumb-label{display:flex}.mat-slider-axis-inverted .mat-slider-track-fill{transform-origin:100% 100%}.mat-slider-axis-inverted .mat-slider-track-background{transform-origin:0 0}.mat-slider:not(.mat-slider-disabled).cdk-focused.mat-slider-thumb-label-showing .mat-slider-thumb{transform:scale(0)}.mat-slider:not(.mat-slider-disabled).cdk-focused .mat-slider-thumb-label{border-radius:50% 50% 0}.mat-slider:not(.mat-slider-disabled).cdk-focused .mat-slider-thumb-label-text{opacity:1}.mat-slider:not(.mat-slider-disabled).cdk-mouse-focused .mat-slider-thumb,.mat-slider:not(.mat-slider-disabled).cdk-program-focused .mat-slider-thumb,.mat-slider:not(.mat-slider-disabled).cdk-touch-focused .mat-slider-thumb{border-width:2px;transform:scale(1)}.mat-slider-disabled .mat-slider-focus-ring{transform:scale(0);opacity:0}.mat-slider-disabled .mat-slider-thumb{border-width:4px;transform:scale(.5)}.mat-slider-disabled .mat-slider-thumb-label{display:none}.mat-slider-horizontal{height:48px;min-width:128px}.mat-slider-horizontal .mat-slider-wrapper{height:2px;top:23px;left:8px;right:8px}.mat-slider-horizontal .mat-slider-wrapper::after{height:2px;border-left-width:2px;right:0;top:0}.mat-slider-horizontal .mat-slider-track-wrapper{height:2px;width:100%}.mat-slider-horizontal .mat-slider-track-fill{height:2px;width:100%;transform:scaleX(0)}.mat-slider-horizontal .mat-slider-track-background{height:2px;width:100%;transform:scaleX(1)}.mat-slider-horizontal .mat-slider-ticks-container{height:2px;width:100%}.mat-slider-horizontal .mat-slider-ticks{height:2px;width:100%}.mat-slider-horizontal .mat-slider-thumb-container{width:100%;height:0;top:50%}.mat-slider-horizontal .mat-slider-focus-ring{top:-15px;right:-15px}.mat-slider-horizontal .mat-slider-thumb-label{right:-14px;top:-40px;transform:translateY(26px) scale(.01) rotate(45deg)}.mat-slider-horizontal .mat-slider-thumb-label-text{transform:rotate(-45deg)}.mat-slider-horizontal.cdk-focused .mat-slider-thumb-label{transform:rotate(45deg)}.mat-slider-vertical{width:48px;min-height:128px}.mat-slider-vertical .mat-slider-wrapper{width:2px;top:8px;bottom:8px;left:23px}.mat-slider-vertical .mat-slider-wrapper::after{width:2px;border-top-width:2px;bottom:0;left:0}.mat-slider-vertical .mat-slider-track-wrapper{height:100%;width:2px}.mat-slider-vertical .mat-slider-track-fill{height:100%;width:2px;transform:scaleY(0)}.mat-slider-vertical .mat-slider-track-background{height:100%;width:2px;transform:scaleY(1)}.mat-slider-vertical .mat-slider-ticks-container{width:2px;height:100%}.mat-slider-vertical .mat-slider-focus-ring{bottom:-15px;left:-15px}.mat-slider-vertical .mat-slider-ticks{width:2px;height:100%}.mat-slider-vertical .mat-slider-thumb-container{height:100%;width:0;left:50%}.mat-slider-vertical .mat-slider-thumb{-webkit-backface-visibility:hidden;backface-visibility:hidden}.mat-slider-vertical .mat-slider-thumb-label{bottom:-14px;left:-40px;transform:translateX(26px) scale(.01) rotate(-45deg)}.mat-slider-vertical .mat-slider-thumb-label-text{transform:rotate(45deg)}.mat-slider-vertical.cdk-focused .mat-slider-thumb-label{transform:rotate(-45deg)}[dir=rtl] .mat-slider-wrapper::after{left:0;right:auto}[dir=rtl] .mat-slider-horizontal .mat-slider-track-fill{transform-origin:100% 100%}[dir=rtl] .mat-slider-horizontal .mat-slider-track-background{transform-origin:0 0}[dir=rtl] .mat-slider-horizontal.mat-slider-axis-inverted .mat-slider-track-fill{transform-origin:0 0}[dir=rtl] .mat-slider-horizontal.mat-slider-axis-inverted .mat-slider-track-background{transform-origin:100% 100%}"],data:{}});function Im(n){return l._33(2,[l._29(402653184,1,{_sliderWrapper:0}),(n()(),l._9(1,0,[[1,0],["sliderWrapper",1]],null,16,"div",[["class","mat-slider-wrapper"]],null,null,null,null,null)),(n()(),l._9(2,0,null,null,4,"div",[["class","mat-slider-track-wrapper"]],null,null,null,null,null)),(n()(),l._9(3,0,null,null,1,"div",[["class","mat-slider-track-background"]],null,null,null,null,null)),l._8(4,278528,null,0,R,[l.v,l.l,l.G],{ngStyle:[0,"ngStyle"]},null),(n()(),l._9(5,0,null,null,1,"div",[["class","mat-slider-track-fill"]],null,null,null,null,null)),l._8(6,278528,null,0,R,[l.v,l.l,l.G],{ngStyle:[0,"ngStyle"]},null),(n()(),l._9(7,0,null,null,3,"div",[["class","mat-slider-ticks-container"]],null,null,null,null,null)),l._8(8,278528,null,0,R,[l.v,l.l,l.G],{ngStyle:[0,"ngStyle"]},null),(n()(),l._9(9,0,null,null,1,"div",[["class","mat-slider-ticks"]],null,null,null,null,null)),l._8(10,278528,null,0,R,[l.v,l.l,l.G],{ngStyle:[0,"ngStyle"]},null),(n()(),l._9(11,0,null,null,6,"div",[["class","mat-slider-thumb-container"]],null,null,null,null,null)),l._8(12,278528,null,0,R,[l.v,l.l,l.G],{ngStyle:[0,"ngStyle"]},null),(n()(),l._9(13,0,null,null,0,"div",[["class","mat-slider-focus-ring"]],null,null,null,null,null)),(n()(),l._9(14,0,null,null,0,"div",[["class","mat-slider-thumb"]],null,null,null,null,null)),(n()(),l._9(15,0,null,null,2,"div",[["class","mat-slider-thumb-label"]],null,null,null,null,null)),(n()(),l._9(16,0,null,null,1,"span",[["class","mat-slider-thumb-label-text"]],null,null,null,null,null)),(n()(),l._31(17,null,["",""]))],function(n,t){var e=t.component;n(t,4,0,e._trackBackgroundStyles),n(t,6,0,e._trackFillStyles),n(t,8,0,e._ticksContainerStyles),n(t,10,0,e._ticksStyles),n(t,12,0,e._thumbContainerStyles)},function(n,t){n(t,17,0,t.component.displayValue)})}var Rm=function(){function n(n,t){var e=this;this.dialogRef=n,this.walletService=t,this.wallets=[],this.walletService.all().first().subscribe(function(n){return e.wallets=n})}return n.prototype.closePopup=function(){this.dialogRef.close()},n.prototype.select=function(n){this.dialogRef.close(n)},n}(),Hm=function(){function n(n,t,e,l){this.dialogRef=n,this.data=t,this.formBuilder=e,this.msgBarService=l}return n.prototype.ngOnInit=function(){this.form=this.formBuilder.group({data:[this.data]})},n.prototype.ngOnDestroy=function(){this.msgBarService.hide()},n.prototype.processData=function(){try{if(0===this.form.value.data.trim().length)return void this.msgBarService.showError("send.bulk-send.error-no-data");var n=this.form.value.data.split(/\r?\n/);if(!n||0===n.length)return void this.msgBarService.showError("send.bulk-send.error-no-data");var t=(n=n.filter(function(n){return n.trim().length>0}))[0].split(",").length;if(2!==t&&3!==t)return void this.msgBarService.showError("send.bulk-send.error-invalid-data");var e=[],l=!0;if(n.forEach(function(n,r){e[r]=n.split(","),e[r].length!==t&&(l=!1)}),!l)return void this.msgBarService.showError("send.bulk-send.error-inconsistent-data");var r=[];e.forEach(function(n,t){r[t]=[],n.forEach(function(n,e){r[t][e]=n.trim()})}),this.dialogRef.close(r)}catch(n){this.msgBarService.showError("send.bulk-send.error-invalid-data")}},n}(),Nm=function(){function n(n,t,e,r,i,o,s,a,u,c,d){this.blockchainService=n,this.walletService=t,this.appService=e,this.formBuilder=r,this.dialog=i,this.msgBarService=o,this.navbarService=s,this.hwWalletService=a,this.translate=u,this.priceService=c,this.changeDetector=d,this.onFormSubmitted=new l.o,this.maxNoteChars=am.MAX_NOTE_CHARS,this.addresses=[],this.allUnspentOutputs=[],this.unspentOutputs=[],this.loadingUnspentOutputs=!1,this.availableCoins=new Ae.BigNumber(0),this.availableHours=new Ae.BigNumber(0),this.minimumFee=new Ae.BigNumber(0),this.autoHours=!0,this.autoOptions=!1,this.autoShareValue="0.5",this.busy=!1,this.doubleButtonActive=Fp,this.selectedCurrency=Fp.LeftButton,this.totalCoins=new Ae.BigNumber(0),this.totalConvertedCoins=new Ae.BigNumber(0),this.totalHours=new Ae.BigNumber(0),this.subscriptionsGroup=[],this.destinationSubscriptions=[],this.destinationHoursSubscriptions=[]}return n.prototype.ngOnInit=function(){var n=this;this.navbarService.showSwitch("send.simple","send.advanced",Fp.RightButton),this.form=this.formBuilder.group({wallet:["",Xi.required],addresses:[null],outputs:[null],changeAddress:[""],destinations:this.formBuilder.array([this.createDestinationFormGroup()],this.validateDestinations.bind(this)),note:[""]}),this.subscriptionsGroup.push(this.form.get("wallet").valueChanges.subscribe(function(t){n.wallet=t,n.closeGetOutputsSubscriptions(),n.allUnspentOutputs=[],n.unspentOutputs=[],n.loadingUnspentOutputs=!0,n.getOutputsSubscriptions=n.walletService.getWalletUnspentOutputs(t).retryWhen(function(n){return n.delay(1e3).take(10).concat(o.a.throw(""))}).subscribe(function(t){n.loadingUnspentOutputs=!1,n.allUnspentOutputs=t,n.unspentOutputs=n.filterUnspentOutputs()},function(){return n.loadingUnspentOutputs=!1}),n.addresses=t.addresses.filter(function(n){return n.coins>0}),n.form.get("addresses").setValue(null),n.form.get("outputs").setValue(null),n.updateAvailableBalance(),n.form.get("destinations").updateValueAndValidity()})),this.subscriptionsGroup.push(this.form.get("addresses").valueChanges.subscribe(function(){n.form.get("outputs").setValue(null),n.unspentOutputs=n.filterUnspentOutputs(),n.updateAvailableBalance(),n.form.get("destinations").updateValueAndValidity()})),this.subscriptionsGroup.push(this.form.get("outputs").valueChanges.subscribe(function(){n.updateAvailableBalance(),n.form.get("destinations").updateValueAndValidity()})),this.subscriptionsGroup.push(this.priceService.price.subscribe(function(t){n.price=t,n.updateValues()})),this.formData&&this.fillForm(),this.subscriptionsGroup.push(this.walletService.all().first().subscribe(function(t){n.wallets=t,1===t.length&&n.form.get("wallet").setValue(t[0])}))},n.prototype.ngOnDestroy=function(){this.processingSubscription&&!this.processingSubscription.closed&&this.processingSubscription.unsubscribe(),this.closeGetOutputsSubscriptions(),this.closeSyncCheckSubscription(),this.subscriptionsGroup.forEach(function(n){return n.unsubscribe()}),this.navbarService.hideSwitch(),this.msgBarService.hide(),this.destinationSubscriptions.forEach(function(n){return n.unsubscribe()}),this.destinationHoursSubscriptions.forEach(function(n){return n.unsubscribe()})},n.prototype.preview=function(){this.previewTx=!0,this.checkBeforeSending(),this.changeDetector.detectChanges()},n.prototype.send=function(){this.previewTx=!1,this.checkBeforeSending()},n.prototype.changeActiveCurrency=function(n){n!==this.selectedCurrency&&(this.selectedCurrency=n,this.askIfConvertAmount(),this.updateValues(),this.form.get("destinations").updateValueAndValidity())},n.prototype.askIfConvertAmount=function(){var n=this,t=0;if(this.destControls.forEach(function(n,e){var l=n.get("coins").value;l=l?l.trim():l;var r=new Ae.BigNumber(l);l&&!r.isNaN()&&(t+=1)}),0!==t){var e,l,r=this.translate.instant("common.usd"),i=this.appService.coinName;this.selectedCurrency===Fp.LeftButton?(e=r,l=i):(e=i,l=r);var o={text:this.translate.instant(1===t?"send.convert-confirmation":"send.convert-confirmation-plural",{from:e,to:l}),headerText:"confirmation.header-text",confirmButtonText:"confirmation.confirm-button",cancelButtonText:"confirmation.cancel-button"};Wc(this.dialog,o).afterClosed().subscribe(function(t){t&&n.convertAmounts()})}},n.prototype.convertAmounts=function(){var n=this;this.msgBarService.hide();var t=0,e=0;this.destControls.forEach(function(l,r){var i=l.get("coins").value;i=i?i.trim():i;var o=new Ae.BigNumber(i);if(i){if(!i||o.isNaN())return void(t+=1);var s;n.selectedCurrency===Fp.LeftButton?((s=o.dividedBy(n.price).decimalPlaces(n.blockchainService.currentMaxDecimals)).multipliedBy(n.price).decimalPlaces(um.MaxUsdDecimals,Ae.BigNumber.ROUND_FLOOR).isEqualTo(o)||(e+=1),l.get("coins").setValue(s.toString())):((s=o.multipliedBy(n.price).decimalPlaces(um.MaxUsdDecimals,Ae.BigNumber.ROUND_FLOOR)).dividedBy(n.price).decimalPlaces(n.blockchainService.currentMaxDecimals).isEqualTo(o)||(e+=1),l.get("coins").setValue(s.toString()))}}),t>0&&e>0?this.msgBarService.showWarning(this.translate.instant("send.multiple-problems-warning")):1===t?this.msgBarService.showWarning(this.translate.instant("send.invaid-amount-warning")):t>1?this.msgBarService.showWarning(this.translate.instant("send.invaid-amounts-warning")):1===e?this.msgBarService.showWarning(this.translate.instant("send.precision-error-warning")):e>1&&this.msgBarService.showWarning(this.translate.instant("send.precision-errors-warning"))},n.prototype.assignAll=function(n){this.msgBarService.hide();var t=this.form.get("wallet").value&&this.form.get("wallet").value.coins?this.form.get("wallet").value.coins:new Ae.BigNumber(-1);t.isEqualTo(-1)?this.msgBarService.showError(this.translate.instant("send.no-wallet-selected")):(this.selectedCurrency===Fp.RightButton&&(t=t.multipliedBy(this.price).decimalPlaces(um.MaxUsdDecimals,Ae.BigNumber.ROUND_FLOOR)),this.destControls.forEach(function(e,l){if(l!==n){var r=Number.parseFloat(e.get("coins").value.trim());if(!r||isNaN(r))return;t=t.minus(r)}}),(t=t.decimalPlaces(this.selectedCurrency===Fp.LeftButton?this.blockchainService.currentMaxDecimals:um.MaxUsdDecimals,Ae.BigNumber.ROUND_FLOOR)).isLessThan(0)?this.msgBarService.showError(this.translate.instant("send.no-coins-left")):this.destControls[n].get("coins").setValue(t.toString()))},n.prototype.updateValues=function(){var n=this;this.price?(this.values=[],this.totalCoins=new Ae.BigNumber(0),this.totalConvertedCoins=new Ae.BigNumber(0),this.totalHours=new Ae.BigNumber(0),this.destControls.forEach(function(t,e){var l=t.get("coins").value,r=n.getAmount(l,!0);if(r)if(n.selectedCurrency===Fp.LeftButton){var i=r.multipliedBy(n.price).decimalPlaces(2);n.totalCoins=n.totalCoins.plus(r),n.totalConvertedCoins=n.totalConvertedCoins.plus(i),n.values[e]=i.toNumber()}else i=r.dividedBy(n.price).decimalPlaces(n.blockchainService.currentMaxDecimals),n.totalCoins=n.totalCoins.plus(i),n.totalConvertedCoins=n.totalConvertedCoins.plus(r),n.values[e]=i.toNumber();else n.values[e]=-1}),this.autoHours||this.destControls.forEach(function(t,e){var l=t.get("hours").value,r=n.getAmount(l,!1);r&&(n.totalHours=n.totalHours.plus(r))})):this.values=null},n.prototype.checkBeforeSending=function(){var n=this;!this.form.valid||this.previewButton.isLoading()||this.sendButton.isLoading()||(this.closeSyncCheckSubscription(),this.syncCheckSubscription=this.blockchainService.synchronized.first().subscribe(function(t){t?n.prepareTransaction():n.showSynchronizingWarning()}))},n.prototype.showSynchronizingWarning=function(){var n=this;Wc(this.dialog,{text:"send.synchronizing-warning",headerText:"confirmation.header-text",confirmButtonText:"confirmation.confirm-button",cancelButtonText:"confirmation.cancel-button"}).afterClosed().subscribe(function(t){t&&n.prepareTransaction()})},n.prototype.prepareTransaction=function(){var n=this;if(this.msgBarService.hide(),this.previewButton.resetState(),this.sendButton.resetState(),!this.form.value.wallet.encrypted||this.form.value.wallet.isHardware||this.previewTx)!this.form.value.wallet.isHardware||this.previewTx?this.createTransaction():(this.showBusy(),this.processingSubscription=this.hwWalletService.checkIfCorrectHwConnected(this.form.value.wallet.addresses[0].address).subscribe(function(){return n.createTransaction()},function(t){return n.showError(Tc(n.translate,t))}));else{var t=new oa;t.data={wallet:this.form.value.wallet},this.dialog.open(Zp,t).componentInstance.passwordSubmit.subscribe(function(t){n.createTransaction(t)})}},n.prototype.addDestination=function(){this.form.get("destinations").push(this.createDestinationFormGroup()),this.updateValues()},n.prototype.removeDestination=function(n){this.form.get("destinations").removeAt(n),this.destinationSubscriptions[n].unsubscribe(),this.destinationSubscriptions.splice(n,1),this.destinationHoursSubscriptions[n].unsubscribe(),this.destinationHoursSubscriptions.splice(n,1),this.updateValues()},n.prototype.setShareValue=function(n){this.autoShareValue=parseFloat(n.value).toFixed(2)},n.prototype.selectChangeAddress=function(n){var t=this,e=new oa;e.width="566px",e.autoFocus=!1,this.dialog.open(Rm,e).afterClosed().subscribe(function(n){n&&t.form.get("changeAddress").setValue(n)})},n.prototype.openMultipleDestinationsPopup=function(){var n=this,t="";this.destControls.map(function(e,l){(e.get("address").value.trim().length>0||e.get("coins").value.trim().length>0||!n.autoHours&&e.get("hours").value.trim().length>0)&&(t+=e.get("address").value.replace(",",""),t+=", "+e.get("coins").value.replace(",",""),n.autoHours||(t+=", "+e.get("hours").value.replace(",","")),t+="\r\n")}),t.length>0&&(t=t.substr(0,t.length-1));var e=new oa;e.width="566px",e.data=t,this.dialog.open(Hm,e).afterClosed().subscribe(function(t){if(t){for(;n.destControls.length>0;)n.form.get("destinations").removeAt(0);t.length>0?(n.autoHours=2===t[0].length,t.forEach(function(t,e){n.addDestination(),n.destControls[e].get("address").setValue(t[0]),n.destControls[e].get("coins").setValue(t[1]),n.autoHours||n.destControls[e].get("hours").setValue(t[2])})):n.addDestination()}}),this.updateValues()},n.prototype.toggleOptions=function(n){n.stopPropagation(),n.preventDefault(),this.autoOptions=!this.autoOptions},n.prototype.setAutoHours=function(n){this.autoHours=n.checked,this.form.get("destinations").updateValueAndValidity(),this.updateValues(),this.autoHours||(this.autoOptions=!1)},n.prototype.fillForm=function(){var n=this;this.addresses=this.formData.form.wallet.addresses,["wallet","addresses","changeAddress","note"].forEach(function(t){n.form.get(t).setValue(n.formData.form[t])});for(var t=0;tthis.blockchainService.currentMaxDecimals)return null}else if(2===l.length&&l[1].length>um.MaxUsdDecimals)return null}else if("hours"===name&&!e.isEqualTo(e.decimalPlaces(0)))return null;return e},n.prototype.createDestinationFormGroup=function(){var n=this,t=this.formBuilder.group({address:"",coins:"",hours:""});return this.destinationSubscriptions.push(t.get("coins").valueChanges.subscribe(function(t){n.updateValues()})),this.destinationHoursSubscriptions.push(t.get("hours").valueChanges.subscribe(function(t){n.updateValues()})),t},n.prototype.showBusy=function(){this.previewTx?(this.previewButton.setLoading(),this.sendButton.setDisabled()):(this.sendButton.setLoading(),this.previewButton.setDisabled()),this.busy=!0,this.navbarService.disableSwitch()},n.prototype.createTransaction=function(n){var t=this;this.showBusy();var e=this.form.get("addresses").value&&this.form.get("addresses").value.length>0?this.form.get("addresses").value.map(function(n){return n.address}):null,l=this.form.get("outputs").value&&this.form.get("outputs").value.length>0?this.form.get("outputs").value.map(function(n){return n.hash}):null;this.processingSubscription=this.walletService.createTransaction(this.form.value.wallet,e||this.form.value.wallet.addresses.map(function(n){return n.address}),l,this.destinations,this.hoursSelection,this.form.get("changeAddress").value?this.form.get("changeAddress").value:null,n?n.password:null,this.previewTx).subscribe(function(e){n&&n.close();var l=t.form.value.note.trim();if(t.previewTx){var r=new Ae.BigNumber("0");t.destinations.map(function(n){return r=r.plus(n.coins)}),t.onFormSubmitted.emit({form:{wallet:t.form.get("wallet").value,addresses:t.form.get("addresses").value,changeAddress:t.form.get("changeAddress").value,destinations:t.destinations,hoursSelection:t.hoursSelection,autoOptions:t.autoOptions,allUnspentOutputs:t.loadingUnspentOutputs?null:t.allUnspentOutputs,outputs:t.form.get("outputs").value,currency:t.selectedCurrency,note:l},amount:r,to:t.destinations.map(function(n){return n.address}),transaction:e}),t.busy=!1,t.navbarService.enableSwitch()}else t.processingSubscription=t.walletService.injectTransaction(e.encoded,l).subscribe(function(n){var e=!0;l&&!n&&(t.msgBarService.showWarning(t.translate.instant("send.error-saving-note")),e=!1),t.showSuccess(e)},function(n){return t.showError(n)})},function(e){n&&n.error(e),t.showError(e&&e.result?Tc(t.translate,e):e)})},n.prototype.resetForm=function(){for(this.form.get("wallet").setValue("",{emitEvent:!1}),this.form.get("addresses").setValue(null),this.form.get("outputs").setValue(null),this.form.get("changeAddress").setValue(""),this.form.get("note").setValue(""),this.wallet=null;this.destControls.length>0;)this.form.get("destinations").removeAt(0);this.addDestination(),this.autoHours=!0,this.autoOptions=!1,this.autoShareValue="0.5",this.updateValues()},Object.defineProperty(n.prototype,"destinations",{get:function(){var n=this;return this.destControls.map(function(t,e){var l={address:t.get("address").value.trim(),coins:(n.selectedCurrency===Fp.LeftButton?t.get("coins").value:n.values[e].toString()).trim(),originalAmount:t.get("coins").value};return n.autoHours||(l.hours=t.get("hours").value),l})},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"hoursSelection",{get:function(){var n={type:"manual"};return this.autoHours&&(n={type:"auto",mode:"share",share_factor:this.autoShareValue}),n},enumerable:!0,configurable:!0}),n.prototype.updateAvailableBalance=function(){var n=this;if(this.form.get("wallet").value){this.availableCoins=new Ae.BigNumber(0),this.availableHours=new Ae.BigNumber(0);var t=this.form.get("outputs").value,e=this.form.get("addresses").value;if(t&&t.length>0)t.map(function(t){n.availableCoins=n.availableCoins.plus(t.coins),n.availableHours=n.availableHours.plus(t.calculated_hours)});else if(e&&e.length>0)e.map(function(t){n.availableCoins=n.availableCoins.plus(t.coins),n.availableHours=n.availableHours.plus(t.hours)});else if(this.form.get("wallet").value){var l=this.form.get("wallet").value;this.availableCoins=l.coins,this.availableHours=l.hours}if(this.availableCoins.isGreaterThan(0)){var r=new Ae.BigNumber(1).minus(new Ae.BigNumber(1).dividedBy(this.appService.burnRate)),i=this.availableHours.multipliedBy(r).decimalPlaces(0,Ae.BigNumber.ROUND_FLOOR);this.minimumFee=this.availableHours.minus(i),this.availableHours=i}else this.minimumFee=new Ae.BigNumber(0),this.availableHours=new Ae.BigNumber(0)}},n.prototype.filterUnspentOutputs=function(){var n=this;return 0===this.allUnspentOutputs.length?[]:this.form.get("addresses").value&&0!==this.form.get("addresses").value.length?this.allUnspentOutputs.filter(function(t){return n.form.get("addresses").value.some(function(n){return n.address===t.address})}):this.allUnspentOutputs},n.prototype.closeGetOutputsSubscriptions=function(){this.loadingUnspentOutputs=!1,this.getOutputsSubscriptions&&this.getOutputsSubscriptions.unsubscribe()},n.prototype.closeSyncCheckSubscription=function(){this.syncCheckSubscription&&this.syncCheckSubscription.unsubscribe()},n.prototype.showSuccess=function(n){var t=this;this.busy=!1,this.navbarService.enableSwitch(),this.resetForm(),n?(this.msgBarService.showDone("send.sent"),this.sendButton.resetState()):(this.sendButton.setSuccess(),setTimeout(function(){t.sendButton.resetState()},3e3))},n.prototype.showError=function(n){this.busy=!1,this.msgBarService.showError(n),this.navbarService.enableSwitch(),this.previewButton.resetState().setEnabled(),this.sendButton.resetState().setEnabled()},n}(),Fm=l._7({encapsulation:0,styles:[[".form-field[_ngcontent-%COMP%] mat-spinner[_ngcontent-%COMP%]{height:12px!important;width:12px!important;opacity:.5;margin:0!important;display:inline-block;position:relative;top:2px}.form-field[_ngcontent-%COMP%] mat-spinner[_ngcontent-%COMP%] svg{height:12px!important;width:12px!important}.-destination[_ngcontent-%COMP%]:not(:last-child){margin-bottom:5px}.-destination[_ngcontent-%COMP%] .-icons[_ngcontent-%COMP%]{text-align:right;padding-top:5px}.-destination[_ngcontent-%COMP%] .-icons[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{width:32px;cursor:pointer}mat-checkbox[_ngcontent-%COMP%]{font-size:12px}mat-select[_ngcontent-%COMP%]{background:#fff;border:2px solid rgba(0,0,0,.05);border-radius:6px}mat-select[_ngcontent-%COMP%] .mat-select-trigger{padding:10px 30px 10px 10px;display:block;font-size:11px;height:100%;line-height:20px}mat-select[_ngcontent-%COMP%] .mat-select-arrow{border:none}mat-select[_ngcontent-%COMP%] .mat-select-placeholder{color:unset!important;-webkit-transition:unset!important;transition:unset!important}mat-option[_ngcontent-%COMP%] .mat-pseudo-checkbox-checked{background:#0072ff}.-autohours[_ngcontent-%COMP%]{margin:40px 0 20px}.-autohours[_ngcontent-%COMP%] .-check[_ngcontent-%COMP%] .mat-checkbox-checkmark-path{stroke:#0072ff!important}.-autohours[_ngcontent-%COMP%] .-check[_ngcontent-%COMP%] .mat-checkbox-background, .-autohours[_ngcontent-%COMP%] .-check[_ngcontent-%COMP%] .mat-checkbox-frame{width:20px;height:20px;background:rgba(30,34,39,.05);border-radius:6px;border-color:transparent}.-autohours[_ngcontent-%COMP%] .-check[_ngcontent-%COMP%] .mat-checkbox-label{line-height:20px;font-size:13px;color:#1e2227;-webkit-box-flex:1;-ms-flex:1;flex:1}.-autohours[_ngcontent-%COMP%] .-check[_ngcontent-%COMP%] .mat-checkbox-layout{display:-webkit-box;display:-ms-flexbox;display:flex}.-autohours[_ngcontent-%COMP%] .-options-wrapper[_ngcontent-%COMP%]{margin-top:20px}.-autohours[_ngcontent-%COMP%] .-options-wrapper[_ngcontent-%COMP%] mat-slider[_ngcontent-%COMP%]{width:100%;padding:0;height:40px;border:2px solid rgba(0,0,0,.05);border-radius:6px;background:#fff}.-autohours[_ngcontent-%COMP%] .-options-wrapper[_ngcontent-%COMP%] mat-slider[_ngcontent-%COMP%] .mat-slider-thumb, .-autohours[_ngcontent-%COMP%] .-options-wrapper[_ngcontent-%COMP%] mat-slider[_ngcontent-%COMP%] .mat-slider-thumb-label{background-color:#0072ff!important;-webkit-transform:scale(1)!important;transform:scale(1)!important;border-width:0!important}.-autohours[_ngcontent-%COMP%] .-options-wrapper[_ngcontent-%COMP%] mat-slider[_ngcontent-%COMP%] .mat-slider-thumb{right:-6px;width:12px;height:32px;border-radius:3px}.-autohours[_ngcontent-%COMP%] .-options-wrapper[_ngcontent-%COMP%] mat-slider[_ngcontent-%COMP%] .mat-slider-track-background, .-autohours[_ngcontent-%COMP%] .-options-wrapper[_ngcontent-%COMP%] mat-slider[_ngcontent-%COMP%] .mat-slider-track-fill{background-color:#fff!important}.-options[_ngcontent-%COMP%]{padding-left:5px;color:#0072ff;cursor:pointer;font-size:13px}.-options[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{color:#0072ff;padding:0;display:inline;vertical-align:middle;font-size:13px}.-buttons[_ngcontent-%COMP%]{text-align:center}.-hidden[_ngcontent-%COMP%]{display:none}.-space-between[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}label[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{display:inline;font-size:14px;color:rgba(121,135,152,.5);vertical-align:text-bottom;padding-left:5px}.-available-msg[_ngcontent-%COMP%]{background-color:#f7f7f7;border:1px dotted rgba(30,34,39,.2);border-radius:6px;padding:10px;font-size:11px;text-align:center}.-available-msg[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{opacity:.7}.-available-msg[_ngcontent-%COMP%] .value[_ngcontent-%COMP%]{opacity:1!important;font-weight:700;font-size:13px}.destinations-label[_ngcontent-%COMP%]{display:inline-block}"]],data:{}});function Bm(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,5,"option",[],[[8,"disabled",0]],null,null,null,null)),l._8(3,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(4,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(5,null,["\n "," - ","\n (",")\n "])),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.context.$implicit),n(t,4,0,t.context.$implicit)},function(n,t){n(t,2,0,!t.context.$implicit.coins||t.context.$implicit.coins.isLessThanOrEqualTo(0)),n(t,5,0,t.context.$implicit.label,l._32(t,5,1,l._22(t,6).transform(t.context.$implicit.coins?t.context.$implicit.coins.toString():0)),l._32(t,5,2,l._22(t,7).transform(t.context.$implicit.hours.toString(),!1)))})}function Vm(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Bm)),l._8(3,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.component.wallets)},null)}function Wm(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"mat-option",[["class","mat-option"],["role","option"]],[[1,"tabindex",0],[2,"mat-selected",null],[2,"mat-option-multiple",null],[2,"mat-active",null],[8,"id",0],[1,"aria-selected",0],[1,"aria-disabled",0],[2,"mat-option-disabled",null]],[[null,"click"],[null,"keydown"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,1)._selectViaInteraction()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),r},wm,bm)),l._8(1,49152,[[3,4]],0,pr,[l.l,l.h,[2,hr],[2,cr]],{value:[0,"value"]},null),(n()(),l._31(2,0,["\n "," - ","\n (",")\n "])),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf])],function(n,t){n(t,1,0,t.context.$implicit)},function(n,t){n(t,0,0,l._22(t,1)._getTabIndex(),l._22(t,1).selected,l._22(t,1).multiple,l._22(t,1).active,l._22(t,1).id,l._22(t,1).selected.toString(),l._22(t,1).disabled.toString(),l._22(t,1).disabled),n(t,2,0,t.context.$implicit.address,l._32(t,2,1,l._22(t,3).transform(t.context.$implicit.coins?t.context.$implicit.coins.toString():0)),l._32(t,2,2,l._22(t,4).transform(t.context.$implicit.hours.toString(),!1)))})}function zm(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"div",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," - ","\n (",")\n "])),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf])],null,function(n,t){n(t,1,0,t.context.$implicit.address,l._32(t,1,1,l._22(t,2).transform(t.context.$implicit.coins?t.context.$implicit.coins.toString():0)),l._32(t,1,2,l._22(t,3).transform(t.context.$implicit.hours.toString(),!1)))})}function Um(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-spinner",[["class","mat-spinner mat-progress-spinner"],["mode","indeterminate"],["role","progressbar"]],[[4,"width","px"],[4,"height","px"]],null,null,Pf,Lf)),l._8(1,573440,null,0,Wu,[l.l,Hl,[2,sn]],null,null)],null,function(n,t){n(t,0,0,l._22(t,1)._elementSize,l._22(t,1)._elementSize)})}function Gm(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"mat-option",[["class","mat-option"],["role","option"]],[[1,"tabindex",0],[2,"mat-selected",null],[2,"mat-option-multiple",null],[2,"mat-active",null],[8,"id",0],[1,"aria-selected",0],[1,"aria-disabled",0],[2,"mat-option-disabled",null]],[[null,"click"],[null,"keydown"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,1)._selectViaInteraction()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),r},wm,bm)),l._8(1,49152,[[6,4]],0,pr,[l.l,l.h,[2,hr],[2,cr]],{value:[0,"value"]},null),(n()(),l._31(2,0,["\n "," - ","\n (",")\n "])),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf])],function(n,t){n(t,1,0,t.context.$implicit)},function(n,t){n(t,0,0,l._22(t,1)._getTabIndex(),l._22(t,1).selected,l._22(t,1).multiple,l._22(t,1).active,l._22(t,1).id,l._22(t,1).selected.toString(),l._22(t,1).disabled.toString(),l._22(t,1).disabled),n(t,2,0,t.context.$implicit.hash,l._32(t,2,1,l._22(t,3).transform(t.context.$implicit.coins?t.context.$implicit.coins.toString():0)),l._32(t,2,2,l._22(t,4).transform(t.context.$implicit.calculated_hours.toString(),!1)))})}function qm(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"div",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," - ","\n (",")\n "])),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf])],null,function(n,t){n(t,1,0,t.context.$implicit.hash,l._32(t,1,1,l._22(t,2).transform(t.context.$implicit.coins?t.context.$implicit.coins.toString():0)),l._32(t,1,2,l._22(t,3).transform(t.context.$implicit.calculated_hours.toString(),!1)))})}function Jm(n){return l._33(0,[(n()(),l._9(0,0,null,null,5,"mat-select-trigger",[],null,null,null,null,null)),l._8(1,16384,[[8,4]],0,Lu,[],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,qm)),l._8(4,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,4,0,t.component.form.get("outputs").value)},null)}function Qm(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"mat-select-trigger",[],null,null,null,null,null)),l._8(1,16384,[[8,4]],0,Lu,[],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(3,0,null,null,2,"div",[],null,null,null,null,null)),(n()(),l._31(4,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("send.all-outputs")))})}function Km(n){return l._33(0,[(n()(),l._9(0,0,null,null,116,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,39,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,8,"label",[],[[8,"htmlFor",0]],[[null,"click"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==(n.component.busy?null:l._22(n,23).open())&&r),r},null,null)),(n()(),l._31(5,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(7,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,9).show()&&r),"keydown"===t&&(r=!1!==l._22(n,9)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,9).hide(1500)&&r),r},Hf,Rf)),l._8(8,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(9,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,26,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,23,"mat-select",[["class","mat-select"],["formControlName","addresses"],["id","addresses"],["multiple",""],["role","listbox"]],[[1,"disabled",0],[1,"id",0],[1,"tabindex",0],[1,"aria-label",0],[1,"aria-labelledby",0],[1,"aria-required",0],[1,"aria-disabled",0],[1,"aria-invalid",0],[1,"aria-owns",0],[1,"aria-multiselectable",0],[1,"aria-describedby",0],[1,"aria-activedescendant",0],[2,"mat-select-disabled",null],[2,"mat-select-invalid",null],[2,"mat-select-required",null],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown"],[null,"focus"],[null,"blur"]],function(n,t,e){var r=!0;return"keydown"===t&&(r=!1!==l._22(n,23)._handleKeydown(e)&&r),"focus"===t&&(r=!1!==l._22(n,23)._onFocus()&&r),"blur"===t&&(r=!1!==l._22(n,23)._onBlur()&&r),r},Am,Sm)),l._28(6144,null,hr,null,[Pu]),l._28(6144,null,Os,null,[Pu]),l._8(19,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(20,{"element-disabled":0}),l._8(21,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[8,null]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(23,2080768,[["selectAddresses",4]],3,Pu,[Xr,l.h,l.B,Kl,l.l,[2,Dl],[2,Wo],[2,qo],[2,Ps],[2,uo],[8,null],Ou],{placeholder:[0,"placeholder"],multiple:[1,"multiple"],compareWith:[2,"compareWith"],id:[3,"id"]},null),l._29(603979776,3,{options:1}),l._29(603979776,4,{optionGroups:1}),l._29(335544320,5,{customTrigger:0}),l._25(131072,De.i,[De.j,l.h]),l._8(28,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,1,["\n "])),(n()(),l._4(16777216,null,1,1,null,Wm)),l._8(31,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,1,["\n "])),(n()(),l._9(33,0,null,0,5,"mat-select-trigger",[],null,null,null,null,null)),l._8(34,16384,[[5,4]],0,Lu,[],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,zm)),l._8(37,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,1,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(43,0,null,null,41,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(45,0,null,null,11,"label",[],[[8,"htmlFor",0]],[[null,"click"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==(n.component.busy?null:l._22(n,67).open())&&r),r},null,null)),(n()(),l._31(46,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(48,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,50).show()&&r),"keydown"===t&&(r=!1!==l._22(n,50)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,50).hide(1500)&&r),r},Hf,Rf)),l._8(49,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(50,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Um)),l._8(55,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(58,0,null,null,25,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(60,0,null,null,22,"mat-select",[["class","mat-select"],["formControlName","outputs"],["id","outputs"],["multiple",""],["role","listbox"]],[[1,"disabled",0],[1,"id",0],[1,"tabindex",0],[1,"aria-label",0],[1,"aria-labelledby",0],[1,"aria-required",0],[1,"aria-disabled",0],[1,"aria-invalid",0],[1,"aria-owns",0],[1,"aria-multiselectable",0],[1,"aria-describedby",0],[1,"aria-activedescendant",0],[2,"mat-select-disabled",null],[2,"mat-select-invalid",null],[2,"mat-select-required",null],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown"],[null,"focus"],[null,"blur"]],function(n,t,e){var r=!0;return"keydown"===t&&(r=!1!==l._22(n,67)._handleKeydown(e)&&r),"focus"===t&&(r=!1!==l._22(n,67)._onFocus()&&r),"blur"===t&&(r=!1!==l._22(n,67)._onBlur()&&r),r},Am,Sm)),l._28(6144,null,hr,null,[Pu]),l._28(6144,null,Os,null,[Pu]),l._8(63,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(64,{"element-disabled":0}),l._8(65,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[8,null]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(67,2080768,[["selectOutputs",4]],3,Pu,[Xr,l.h,l.B,Kl,l.l,[2,Dl],[2,Wo],[2,qo],[2,Ps],[2,uo],[8,null],Ou],{placeholder:[0,"placeholder"],multiple:[1,"multiple"],compareWith:[2,"compareWith"],id:[3,"id"]},null),l._29(603979776,6,{options:1}),l._29(603979776,7,{optionGroups:1}),l._29(603979776,8,{customTrigger:0}),l._25(131072,De.i,[De.j,l.h]),l._8(72,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,1,["\n "])),(n()(),l._4(16777216,null,1,1,null,Gm)),l._8(75,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,1,["\n "])),(n()(),l._4(16777216,null,0,1,null,Jm)),l._8(78,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,1,["\n "])),(n()(),l._4(16777216,null,0,1,null,Qm)),l._8(81,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,1,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(86,0,null,null,29,"div",[["class","form-field -available-msg"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(88,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(89,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(92,0,null,null,2,"span",[["class","value"]],null,null,null,null,null)),(n()(),l._31(93,null,["\n ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(96,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(97,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(100,0,null,null,2,"span",[["class","value"]],null,null,null,null,null)),(n()(),l._31(101,null,["\n ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(104,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(105,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(108,0,null,null,2,"span",[["class","value"]],null,null,null,null,null)),(n()(),l._31(109,null,["\n ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(112,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(113,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,8,0),n(t,9,0,l._32(t,9,0,l._22(t,10).transform("send.addresses-help"))),n(t,19,0,n(t,20,0,e.busy)),n(t,21,0,"addresses"),n(t,23,0,l._32(t,23,0,l._22(t,27).transform("send.all-addresses")),"",e.addressCompare,"addresses"),n(t,31,0,e.addresses),n(t,37,0,e.form.get("addresses").value),n(t,49,0),n(t,50,0,l._32(t,50,0,l._22(t,51).transform("send.outputs-help"))),n(t,55,0,e.loadingUnspentOutputs),n(t,63,0,n(t,64,0,e.busy)),n(t,65,0,"outputs"),n(t,67,0,l._32(t,67,0,l._22(t,71).transform("send.all-outputs")),"",e.outputCompare,"outputs"),n(t,75,0,e.unspentOutputs),n(t,78,0,e.form.get("outputs").value&&e.form.get("outputs").value.length>0),n(t,81,0,!e.form.get("outputs").value||0===e.form.get("outputs").value.length)},function(n,t){var e=t.component;n(t,4,0,e.busy?"":"addresses"),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("send.addresses-label"))),n(t,16,1,[e.busy?"true":null,l._22(t,23).id,l._22(t,23).tabIndex,l._22(t,23)._ariaLabel,l._22(t,23).ariaLabelledby,l._22(t,23).required.toString(),l._22(t,23).disabled.toString(),l._22(t,23).errorState,l._22(t,23).panelOpen?l._22(t,23)._optionIds:null,l._22(t,23).multiple,l._22(t,23)._ariaDescribedby||null,l._22(t,23)._getAriaActiveDescendant(),l._22(t,23).disabled,l._22(t,23).errorState,l._22(t,23).required,l._22(t,28).ngClassUntouched,l._22(t,28).ngClassTouched,l._22(t,28).ngClassPristine,l._22(t,28).ngClassDirty,l._22(t,28).ngClassValid,l._22(t,28).ngClassInvalid,l._22(t,28).ngClassPending]),n(t,45,0,e.busy?null:"outputs"),n(t,46,0,l._32(t,46,0,l._22(t,47).transform("send.outputs-label"))),n(t,60,1,[e.busy?"true":null,l._22(t,67).id,l._22(t,67).tabIndex,l._22(t,67)._ariaLabel,l._22(t,67).ariaLabelledby,l._22(t,67).required.toString(),l._22(t,67).disabled.toString(),l._22(t,67).errorState,l._22(t,67).panelOpen?l._22(t,67)._optionIds:null,l._22(t,67).multiple,l._22(t,67)._ariaDescribedby||null,l._22(t,67)._getAriaActiveDescendant(),l._22(t,67).disabled,l._22(t,67).errorState,l._22(t,67).required,l._22(t,72).ngClassUntouched,l._22(t,72).ngClassTouched,l._22(t,72).ngClassPristine,l._22(t,72).ngClassDirty,l._22(t,72).ngClassValid,l._22(t,72).ngClassInvalid,l._22(t,72).ngClassPending]),n(t,89,0,l._32(t,89,0,l._22(t,90).transform("send.available-msg-part1"))),n(t,93,0,l._32(t,93,0,l._22(t,94).transform(e.availableCoins.toString()))),n(t,97,0,l._32(t,97,0,l._22(t,98).transform("send.available-msg-part2"))),n(t,101,0,l._32(t,101,0,l._22(t,102).transform(e.availableHours.toString(),!1))),n(t,105,0,l._32(t,105,0,l._22(t,106).transform("send.available-msg-part3"))),n(t,109,0,l._32(t,109,0,l._22(t,110).transform(e.minimumFee.toString(),!1))),n(t,113,0,l._32(t,113,0,l._22(t,114).transform("send.available-msg-part4")))})}function Xm(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,"div",[["class","coin-selector-container"]],null,null,null,null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(2,{"element-disabled":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,3,"app-double-button",[["className","light small"]],null,[[null,"onStateChange"]],function(n,t,e){var l=!0;return"onStateChange"===t&&(l=!1!==n.component.changeActiveCurrency(e)&&l),l},M_,x_)),l._8(5,49152,null,0,Bp,[],{rightButtonText:[0,"rightButtonText"],leftButtonText:[1,"leftButtonText"],activeButton:[2,"activeButton"],className:[3,"className"]},{onStateChange:"onStateChange"}),l._25(131072,De.i,[De.j,l.h]),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,1,0,"coin-selector-container",n(t,2,0,e.busy)),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("common.usd")),l._32(t,5,1,l._22(t,7).transform("coin")),e.selectedCurrency,"light small")},null)}function Zm(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("send.invalid-amount")))})}function $m(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ~ "," ","\n "])),l._27(2,2),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,n(t,2,0,l._22(t.parent.parent,0),e.values[t.parent.context.index],"1.0-2")),l._32(t,1,1,l._22(t,3).transform("common.usd")))})}function ng(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ~ ","\n "])),l._25(0,If,[tn,qc,gf])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform(e.values[t.parent.context.index])))})}function tg(n){return l._33(0,[(n()(),l._9(0,0,null,null,0,"img",[["alt","plus"],["src","../../../../../assets/img/plus-green.png"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addDestination()&&l),l},null,null))],null,null)}function eg(n){return l._33(0,[(n()(),l._9(0,0,null,null,0,"img",[["alt","minus"],["src","../../../../../assets/img/minus-grey.png"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.removeDestination(n.parent.context.index)&&l),l},null,null))],null,null)}function lg(n){return l._33(0,[(n()(),l._9(0,0,null,null,86,"div",[["class","-destination"],["formArrayName","destinations"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),l._8(1,212992,null,0,Qo,[[3,qi],[8,null],[8,null]],{name:[0,"name"]},null),l._28(2048,null,qi,null,[Qo]),l._8(3,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,80,"div",[["class","row"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),l._8(6,212992,null,0,Jo,[[3,qi],[8,null],[8,null]],{name:[0,"name"]},null),l._28(2048,null,qi,null,[Jo]),l._8(8,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,8,"div",[["class","col-lg-5 col-md-4"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,5,"input",[["formControlName","address"]],[[8,"id",0],[1,"disabled",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,13)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,13).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,13)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,13)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(13,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(15,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(17,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,34,"div",[["class","col-md-3"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,13,"div",[["class","-input-addon"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,0,null,null,5,"input",[["formControlName","coins"]],[[1,"disabled",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,25)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,25).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,25)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,25)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(25,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(27,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(29,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(31,0,null,null,3,"span",[],null,null,null,null,null)),(n()(),l._31(32,null,["",""])),l._25(0,l_,[gf]),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(37,0,null,null,16,"div",[["class","coins-value-label"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Zm)),l._8(40,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,$m)),l._8(43,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ng)),l._8(46,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(48,0,null,null,4,"div",[["class","link"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.assignAll(n.context.index)&&l),l},null,null)),l._8(49,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(50,{"centerd-link":0}),(n()(),l._31(51,null,["(",")"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(56,0,null,null,17,"div",[["class","col-lg-3 col-md-4"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(58,0,null,null,14,"div",[],null,null,null,null,null)),l._8(59,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(60,{"-input-addon":0,"-hidden":1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(62,0,null,null,5,"input",[["formControlName","hours"]],[[1,"disabled",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,63)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,63).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,63)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,63)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(63,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(65,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(67,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(69,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(70,null,["",""])),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(75,0,null,null,9,"div",[["class","col-md-1 -icons"]],null,null,null,null,null)),l._8(76,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(77,{"element-disabled":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,tg)),l._8(80,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,eg)),l._8(83,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,1,0,"destinations"),n(t,6,0,t.context.index),n(t,15,0,"address"),n(t,27,0,"coins"),n(t,40,0,e.price&&e.values[t.context.index]<0),n(t,43,0,e.price&&e.values[t.context.index]>=0&&e.selectedCurrency===e.doubleButtonActive.LeftButton),n(t,46,0,e.price&&e.values[t.context.index]>=0&&e.selectedCurrency===e.doubleButtonActive.RightButton),n(t,49,0,"link",n(t,50,0,!e.price)),n(t,59,0,n(t,60,0,!0,e.autoHours)),n(t,65,0,"hours"),n(t,76,0,"col-md-1 -icons",n(t,77,0,e.busy)),n(t,80,0,0===t.context.index),n(t,83,0,0!==t.context.index)},function(n,t){var e=t.component;n(t,0,0,l._22(t,3).ngClassUntouched,l._22(t,3).ngClassTouched,l._22(t,3).ngClassPristine,l._22(t,3).ngClassDirty,l._22(t,3).ngClassValid,l._22(t,3).ngClassInvalid,l._22(t,3).ngClassPending),n(t,5,0,l._22(t,8).ngClassUntouched,l._22(t,8).ngClassTouched,l._22(t,8).ngClassPristine,l._22(t,8).ngClassDirty,l._22(t,8).ngClassValid,l._22(t,8).ngClassInvalid,l._22(t,8).ngClassPending),n(t,12,0,0===t.context.index?"destination":"",e.busy?"true":null,l._22(t,17).ngClassUntouched,l._22(t,17).ngClassTouched,l._22(t,17).ngClassPristine,l._22(t,17).ngClassDirty,l._22(t,17).ngClassValid,l._22(t,17).ngClassInvalid,l._22(t,17).ngClassPending),n(t,24,0,e.busy?"true":null,l._22(t,29).ngClassUntouched,l._22(t,29).ngClassTouched,l._22(t,29).ngClassPristine,l._22(t,29).ngClassDirty,l._22(t,29).ngClassValid,l._22(t,29).ngClassInvalid,l._22(t,29).ngClassPending),n(t,32,0,l._32(t,32,0,e.selectedCurrency===e.doubleButtonActive.LeftButton?l._22(t,33).transform("coin"):l._22(t,34).transform("common.usd"))),n(t,51,0,l._32(t,51,0,l._22(t,52).transform("send.send-all-available-coins"))),n(t,62,0,e.busy?"true":null,l._22(t,67).ngClassUntouched,l._22(t,67).ngClassTouched,l._22(t,67).ngClassPristine,l._22(t,67).ngClassDirty,l._22(t,67).ngClassValid,l._22(t,67).ngClassInvalid,l._22(t,67).ngClassPending),n(t,70,0,l._32(t,70,0,l._22(t,71).transform("hours")))})}function rg(n){return l._33(0,[(n()(),l._9(0,0,null,null,9,"div",[["class","col-lg-3 col-md-4"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,6,"div",[["class","coins-value-label"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(7,null,[" ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,5,0,l._32(t,5,0,l._22(t,6).transform("send.total"))),n(t,7,0,l._32(t,7,0,l._22(t,8).transform(e.totalHours.toString(),!1)))})}function ig(n){return l._33(0,[(n()(),l._9(0,0,null,null,19,"div",[["class","row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,0,"div",[["class","col-lg-5 col-md-4"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,11,"div",[["class","col-md-3"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,8,"div",[["class","coins-value-label"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(11,null,[" "," / "," ","\n "])),l._25(0,If,[tn,qc,gf]),l._27(13,2),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,rg)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,18,0,!t.component.autoHours)},function(n,t){var e=t.component;n(t,9,0,l._32(t,9,0,l._22(t,10).transform("send.total"))),n(t,11,0,l._32(t,11,0,l._22(t,12).transform(e.totalCoins.toString())),l._32(t,11,1,n(t,13,0,l._22(t.parent,0),e.totalConvertedCoins.toString(),"1.0-2")),l._32(t,11,2,l._22(t,14).transform("common.usd")))})}function og(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"span",[["class","-options"]],null,[[null,"mousedown"],[null,"click"]],function(n,t,e){var l=!0,r=n.component;return"mousedown"===t&&(l=!1!==e.stopPropagation()&&l),"click"===t&&(l=!1!==r.toggleOptions(e)&&l),l},null,null)),(n()(),l._31(1,null,["\n "," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(3,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(4,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(5,0,["",""])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,4,0)},function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform("send.options-label"))),n(t,5,0,e.autoOptions?"keyboard_arrow_up":"keyboard_arrow_down")})}function sg(n){return l._33(0,[l._25(0,tn,[l.w]),l._29(402653184,1,{previewButton:0}),l._29(402653184,2,{sendButton:0}),(n()(),l._9(3,0,null,null,178,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,4).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,4).onReset()&&r),r},null,null)),l._8(4,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(6,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,27,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"label",[["for","wallets"]],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,20,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,17,"select",[["formControlName","wallet"],["id","wallets"]],[[1,"disabled",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(n,t,e){var r=!0;return"change"===t&&(r=!1!==l._22(n,19).onChange(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,19).onTouched()&&r),r},null,null)),l._8(17,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(18,{"element-disabled":0}),l._8(19,16384,null,0,_o,[l.G,l.l],null,null),l._28(1024,null,to,function(n){return[n]},[_o]),l._8(21,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(23,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,4,"option",[["disabled",""],["hidden",""]],null,null,null,null,null)),l._8(26,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(27,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(28,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Vm)),l._8(32,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Km)),l._8(38,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(40,0,null,null,30,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(42,0,null,null,8,"label",[["class","destinations-label"],["for","destination"]],null,null,null,null,null)),(n()(),l._31(43,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(45,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,47).show()&&r),"keydown"===t&&(r=!1!==l._22(n,47)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,47).hide(1500)&&r),r},Hf,Rf)),l._8(46,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(47,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Xm)),l._8(53,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(55,0,null,null,8,"span",[["class","-options"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.openMultipleDestinationsPopup()&&l),l},null,null)),l._8(56,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(57,{"element-disabled":0}),(n()(),l._31(58,null,["\n "," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(60,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(61,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["keyboard_arrow_down"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,lg)),l._8(66,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ig)),l._8(69,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(72,0,null,null,28,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(74,0,null,null,18,"label",[["for","change-address"]],null,null,null,null,null)),(n()(),l._31(75,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(77,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,79).show()&&r),"keydown"===t&&(r=!1!==l._22(n,79)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,79).hide(1500)&&r),r},Hf,Rf)),l._8(78,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(79,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(83,0,null,null,8,"span",[["class","-options"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.selectChangeAddress(e)&&l),l},null,null)),l._8(84,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(85,{"element-disabled":0}),(n()(),l._31(86,null,["\n "," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(88,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(89,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["keyboard_arrow_down"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(94,0,null,null,5,"input",[["formControlName","changeAddress"],["id","change-address"]],[[1,"disabled",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,95)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,95).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,95)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,95)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(95,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(97,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(99,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(102,0,null,null,20,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(104,0,null,null,8,"label",[["for","note"]],null,null,null,null,null)),(n()(),l._31(105,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(107,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,109).show()&&r),"keydown"===t&&(r=!1!==l._22(n,109)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,109).hide(1500)&&r),r},Hf,Rf)),l._8(108,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(109,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(114,0,null,null,7,"input",[["formControlName","note"],["id","note"]],[[1,"disabled",0],[1,"maxlength",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,115)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,115).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,115)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,115)._compositionEnd(e.target.value)&&r),"keydown.enter"===t&&(r=!1!==i.preview()&&r),r},null,null)),l._8(115,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(116,540672,null,0,$o,[],{maxlength:[0,"maxlength"]},null),l._28(1024,null,Qi,function(n){return[n]},[$o]),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(119,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(121,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(124,0,null,null,56,"div",[["class","-autohours"]],null,null,null,null,null)),l._8(125,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(126,{"element-disabled":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(128,0,null,null,19,"div",[["class","row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(130,0,null,null,16,"div",[["class","col-xl-4 col-lg-5 col-md-7"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(132,0,null,null,13,"mat-checkbox",[["class","-check mat-checkbox"]],[[1,"disabled",0],[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setAutoHours(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(134,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{checked:[0,"checked"]},{change:"change"}),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(136,0,null,0,8,"div",[["class","-space-between"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(138,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(139,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,og)),l._8(143,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(149,0,null,null,30,"div",[],null,null,null,null,null)),l._8(150,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(151,{"row -options-wrapper":0,"-hidden":1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(153,0,null,null,25,"div",[["class","col-md-5"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(155,0,null,null,22,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(157,0,null,null,15,"label",[["class","-space-between"],["for","value"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(159,0,null,null,8,"span",[],null,null,null,null,null)),(n()(),l._31(160,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(162,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,164).show()&&r),"keydown"===t&&(r=!1!==l._22(n,164)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,164).hide(1500)&&r),r},Hf,Rf)),l._8(163,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(164,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(169,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(170,null,["",""])),l._27(171,2),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(174,0,null,null,2,"mat-slider",[["class","-slider mat-slider"],["id","value"],["max","1"],["min","0.1"],["role","slider"],["step","0.01"]],[[1,"disabled",0],[8,"tabIndex",0],[1,"aria-disabled",0],[1,"aria-valuemax",0],[1,"aria-valuemin",0],[1,"aria-valuenow",0],[1,"aria-orientation",0],[2,"mat-slider-disabled",null],[2,"mat-slider-has-ticks",null],[2,"mat-slider-horizontal",null],[2,"mat-slider-axis-inverted",null],[2,"mat-slider-sliding",null],[2,"mat-slider-thumb-label-showing",null],[2,"mat-slider-vertical",null],[2,"mat-slider-min-value",null],[2,"mat-slider-hide-last-tick",null]],[[null,"input"],[null,"focus"],[null,"blur"],[null,"click"],[null,"keydown"],[null,"keyup"],[null,"mouseenter"],[null,"slide"],[null,"slideend"],[null,"slidestart"]],function(n,t,e){var r=!0,i=n.component;return"focus"===t&&(r=!1!==l._22(n,176)._onFocus()&&r),"blur"===t&&(r=!1!==l._22(n,176)._onBlur()&&r),"click"===t&&(r=!1!==l._22(n,176)._onClick(e)&&r),"keydown"===t&&(r=!1!==l._22(n,176)._onKeydown(e)&&r),"keyup"===t&&(r=!1!==l._22(n,176)._onKeyup()&&r),"mouseenter"===t&&(r=!1!==l._22(n,176)._onMouseenter()&&r),"slide"===t&&(r=!1!==l._22(n,176)._onSlide(e)&&r),"slideend"===t&&(r=!1!==l._22(n,176)._onSlideEnd()&&r),"slidestart"===t&&(r=!1!==l._22(n,176)._onSlideStart(e)&&r),"input"===t&&(r=!1!==i.setShareValue(e)&&r),r},Im,jm)),l._28(5120,null,to,function(n){return[n]},[Uu]),l._8(176,245760,null,0,Uu,[l.l,Rr,l.h,[2,Dl],[8,null]],{max:[0,"max"],min:[1,"min"],step:[2,"step"],value:[3,"value"]},{input:"input"}),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n\n"])),(n()(),l._9(183,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(185,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.preview()&&l),l},w_,g_)),l._8(186,49152,[[1,4],["previewButton",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(187,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(190,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.send()&&l),l},w_,g_)),l._8(191,49152,[[2,4],["sendButton",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(192,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,4,0,e.form),n(t,17,0,n(t,18,0,e.busy)),n(t,21,0,"wallet"),n(t,26,0,""),n(t,27,0,""),n(t,32,0,e.wallets),n(t,38,0,e.wallet),n(t,46,0),n(t,47,0,l._32(t,47,0,l._22(t,48).transform("send.destinations-help"+(e.autoHours?"1":"2")))),n(t,53,0,e.price),n(t,56,0,"-options",n(t,57,0,e.busy)),n(t,61,0),n(t,66,0,e.destControls),n(t,69,0,e.destControls.length>1),n(t,78,0),n(t,79,0,l._32(t,79,0,l._22(t,80).transform("send.change-address-help"))),n(t,84,0,"-options",n(t,85,0,e.busy)),n(t,89,0),n(t,97,0,"changeAddress"),n(t,108,0),n(t,109,0,l._32(t,109,0,l._22(t,110).transform("send.personal-note-help"))),n(t,116,0,e.maxNoteChars),n(t,119,0,"note"),n(t,125,0,"-autohours",n(t,126,0,e.busy)),n(t,134,0,e.autoHours),n(t,143,0,e.autoHours),n(t,150,0,n(t,151,0,!0,!e.autoOptions)),n(t,163,0),n(t,164,0,l._32(t,164,0,l._22(t,165).transform("send.value-help"))),n(t,176,0,"1","0.1","0.01",e.autoShareValue),n(t,186,0,!e.form.valid),n(t,191,0,!e.form.valid)},function(n,t){var e=t.component;n(t,3,0,l._22(t,6).ngClassUntouched,l._22(t,6).ngClassTouched,l._22(t,6).ngClassPristine,l._22(t,6).ngClassDirty,l._22(t,6).ngClassValid,l._22(t,6).ngClassInvalid,l._22(t,6).ngClassPending),n(t,11,0,l._32(t,11,0,l._22(t,12).transform("send.wallet-label"))),n(t,16,0,e.busy?"true":null,l._22(t,23).ngClassUntouched,l._22(t,23).ngClassTouched,l._22(t,23).ngClassPristine,l._22(t,23).ngClassDirty,l._22(t,23).ngClassValid,l._22(t,23).ngClassInvalid,l._22(t,23).ngClassPending),n(t,28,0,l._32(t,28,0,l._22(t,29).transform("send.select-wallet"))),n(t,43,0,l._32(t,43,0,l._22(t,44).transform("send.destinations-label"))),n(t,58,0,l._32(t,58,0,l._22(t,59).transform("send.bulk-send.title"))),n(t,75,0,l._32(t,75,0,l._22(t,76).transform("send.change-address-label"))),n(t,86,0,l._32(t,86,0,l._22(t,87).transform("send.change-address-select"))),n(t,94,0,e.busy?"true":null,l._22(t,99).ngClassUntouched,l._22(t,99).ngClassTouched,l._22(t,99).ngClassPristine,l._22(t,99).ngClassDirty,l._22(t,99).ngClassValid,l._22(t,99).ngClassInvalid,l._22(t,99).ngClassPending),n(t,105,0,l._32(t,105,0,l._22(t,106).transform("send.personal-note-label"))),n(t,114,0,e.busy?"true":null,l._22(t,116).maxlength?l._22(t,116).maxlength:null,l._22(t,121).ngClassUntouched,l._22(t,121).ngClassTouched,l._22(t,121).ngClassPristine,l._22(t,121).ngClassDirty,l._22(t,121).ngClassValid,l._22(t,121).ngClassInvalid,l._22(t,121).ngClassPending),n(t,132,0,e.busy?"true":null,l._22(t,134).id,l._22(t,134).indeterminate,l._22(t,134).checked,l._22(t,134).disabled,"before"==l._22(t,134).labelPosition),n(t,139,0,l._32(t,139,0,l._22(t,140).transform("send.hours-allocation-label"))),n(t,160,0,l._32(t,160,0,l._22(t,161).transform("send.value-label"))),n(t,170,0,l._32(t,170,0,n(t,171,0,l._22(t,0),e.autoShareValue,"1.0-2"))),n(t,174,1,[e.busy?"true":null,l._22(t,176).tabIndex,l._22(t,176).disabled,l._22(t,176).max,l._22(t,176).min,l._22(t,176).value,l._22(t,176).vertical?"vertical":"horizontal",l._22(t,176).disabled,l._22(t,176).tickInterval,!l._22(t,176).vertical,l._22(t,176)._invertAxis,l._22(t,176)._isSliding,l._22(t,176).thumbLabel,l._22(t,176).vertical,l._22(t,176)._isMinValue,l._22(t,176).disabled||l._22(t,176)._isMinValue&&l._22(t,176)._thumbGap&&l._22(t,176)._invertAxis]),n(t,187,0,l._32(t,187,0,l._22(t,188).transform("send.preview-button"))),n(t,192,0,l._32(t,192,0,l._22(t,193).transform("send.send-button")))})}var ag=function(){function n(){}return n.prototype.transform=function(n){return zp.unix(n).format("YYYY-MM-DD HH:mm")},n}(),ug=function(){function n(n,t){var e=this;this.priceService=n,this.dialog=t,this.showInputsOutputs=!1,this.subscription=this.priceService.price.subscribe(function(n){return e.price=n})}return Object.defineProperty(n.prototype,"hoursText",{get:function(){if(!this.transaction)return"";if(!this.isPreview){if(this.transaction.coinsMovedInternally)return"tx.hours-moved";if(this.transaction.balance.isGreaterThan(0))return"tx.hours-received"}return"tx.hours-sent"},enumerable:!0,configurable:!0}),n.prototype.ngOnInit=function(){var n=this;this.isPreview&&(this.transaction.hoursSent=new Ae.BigNumber("0"),this.transaction.outputs.filter(function(t){return n.transaction.to.find(function(n){return n===t.address})}).map(function(t){return n.transaction.hoursSent=n.transaction.hoursSent.plus(new Ae.BigNumber(t.hours))}))},n.prototype.ngOnDestroy=function(){this.subscription.unsubscribe()},n.prototype.toggleInputsOutputs=function(n){n.preventDefault(),this.showInputsOutputs=!this.showInputsOutputs},n.prototype.editNote=function(){var n=this,t=new oa;t.width="566px",t.data=this.transaction,this.dialog.open(am,t).afterClosed().subscribe(function(t){(t||""===t)&&(n.transaction.note=t)})},n}(),cg=l._7({encapsulation:0,styles:[["h4[_ngcontent-%COMP%]{font-size:14px;margin:0 0 30px}.-item[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:13px}.-item[_ngcontent-%COMP%]:not(:last-child){margin-bottom:10px}.-item[_ngcontent-%COMP%] .-number[_ngcontent-%COMP%]{padding:10px;background:#f7f7f7;-ms-flex-item-align:start;align-self:flex-start;border-radius:10px}.-item[_ngcontent-%COMP%] .-info[_ngcontent-%COMP%]{margin-left:10px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.-item[_ngcontent-%COMP%] .-info[_ngcontent-%COMP%] div[_ngcontent-%COMP%]{word-break:break-all}.-item[_ngcontent-%COMP%] .-info[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%]{padding:10px 0;margin-bottom:5px}.-data[_ngcontent-%COMP%]{font-size:12px;display:-webkit-box;display:-ms-flexbox;display:flex}.-data[_ngcontent-%COMP%]:not(:last-child){margin-bottom:5px}.-data[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-child{color:rgba(30,34,39,.5);display:inline-block;width:60px;-ms-flex-negative:0;flex-shrink:0}.-data[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:nth-child(2){word-break:break-word}.-data[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{font-size:20px;padding-left:5px;color:#0072ff;cursor:pointer}.-data[_ngcontent-%COMP%] .-grey[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}.-data.-more[_ngcontent-%COMP%]{margin-bottom:0!important}.-data.-more[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{width:auto!important;margin-top:20px;color:#0072ff;cursor:pointer}.-data.-more[_ngcontent-%COMP%] span[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{display:inline;vertical-align:middle;font-size:13px}.-tx-meta[_ngcontent-%COMP%] .-data[_ngcontent-%COMP%]{margin-bottom:10px}.-tx-price[_ngcontent-%COMP%]{text-align:center;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.-tx-price[_ngcontent-%COMP%] .-icon.-incoming[_ngcontent-%COMP%]{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.-tx-price[_ngcontent-%COMP%] .-icon[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{width:30px}.-tx-price[_ngcontent-%COMP%] h4[_ngcontent-%COMP%]{color:#1e2227;font-size:16px;font-weight:700;margin:10px 0 5px}.-tx-price[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);font-size:12px;margin:0}.-tx-price[_ngcontent-%COMP%] p[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:rgba(121,135,152,.5)}.-margin-top[_ngcontent-%COMP%]{margin-top:30px}"]],data:{}});function dg(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"h4",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("tx.confirm-transaction")))})}function hg(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"h4",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("tx.transaction")))})}function pg(n){return l._33(0,[(n()(),l._9(0,0,null,null,21,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,8,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(5,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,[" "])),(n()(),l._9(8,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,8,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(15,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,[" "])),(n()(),l._9(18,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(19,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,5,0,l._32(t,5,0,l._22(t,6).transform("tx.from"))),n(t,9,0,e.transaction.from),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("tx.to"))),n(t,19,0,e.transaction.to.join(", "))})}function fg(n){return l._33(0,[(n()(),l._9(0,0,null,null,23,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,9,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(5,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,[" "])),(n()(),l._9(8,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._27(10,1),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,9,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(16,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,[" "])),(n()(),l._9(19,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(20,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,5,0,l._32(t,5,0,l._22(t,6).transform("tx.date"))),n(t,9,0,l._32(t,9,0,n(t,10,0,l._22(t.parent,0),e.transaction.timestamp))),n(t,16,0,l._32(t,16,0,l._22(t,17).transform("tx.status"))),n(t,20,0,l._32(t,20,0,l._22(t,21).transform(e.transaction.confirmed?"tx.confirmed":"tx.pending")))})}function _g(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(3,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,[" "])),(n()(),l._9(6,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,l._22(t,4).transform("tx.id"))),n(t,7,0,e.transaction.txid)})}function mg(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.component.transaction.note)})}function gg(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[["class","-grey"]],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("tx.without-note")))})}function yg(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.editNote()&&l),l},Hf,Rf)),l._8(1,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["edit"]))],function(n,t){n(t,1,0)},null)}function bg(n){return l._33(0,[(n()(),l._9(0,0,null,null,14,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(3,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,mg)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,gg)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,yg)),l._8(13,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,7,0,e.transaction.note),n(t,10,0,!e.transaction.note),n(t,13,0,!e.isPreview)},function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("tx.note")))})}function vg(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(-1,null,["*"]))],null,null)}function wg(n){return l._33(0,[(n()(),l._9(0,16777216,null,null,7,"p",[],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,1).show()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,1).hide(1500)&&r),r},null,null)),l._8(1,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(3,null,["\n ",""])),l._27(4,4),(n()(),l._4(16777216,null,null,1,null,vg)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(0,null,null,0))],function(n,t){var e=t.component;n(t,1,0,e.isPreview?"":l._32(t,1,0,l._22(t,2).transform("tx.current-rate"))),n(t,6,0,!e.isPreview)},function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,n(t,4,0,l._22(t.parent,1),e.transaction.balance*e.price,"USD","symbol","1.2-2")))})}function xg(n){return l._33(0,[(n()(),l._9(0,0,null,null,9,"div",[["class","-data -more"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,6,"span",[],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.toggleInputsOutputs(e)&&l),l},null,null)),(n()(),l._31(3,null,["\n "," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(5,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(6,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["keyboard_arrow_down"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,6,0)},function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("tx.show-more")))})}function Mg(n){return l._33(0,[(n()(),l._9(0,0,null,null,26,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"div",[["class","-number"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,20,"div",[["class","-info"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,1,"div",[["class","-address"]],null,null,null,null,null)),(n()(),l._31(8,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,6,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(13,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(15,null,[" ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,6,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(21,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(23,null,[" ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,3,0,t.context.index+1),n(t,8,0,e.isPreview?t.context.$implicit.address:t.context.$implicit.owner),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("tx.coins"))),n(t,15,0,l._32(t,15,0,l._22(t,16).transform(t.context.$implicit.coins,!0,"first"))),n(t,21,0,l._32(t,21,0,l._22(t,22).transform("tx.hours"))),n(t,23,0,l._32(t,23,0,l._22(t,24).transform(t.context.$implicit.calculated_hours,!1,"first")))})}function kg(n){return l._33(0,[(n()(),l._9(0,0,null,null,26,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"div",[["class","-number"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,20,"div",[["class","-info"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,1,"div",[["class","-address"]],null,null,null,null,null)),(n()(),l._31(8,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,6,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(13,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(15,null,[" ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,6,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(21,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(23,null,[" ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,3,0,t.context.index+1),n(t,8,0,e.isPreview?t.context.$implicit.address:t.context.$implicit.dst),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("tx.coins"))),n(t,15,0,l._32(t,15,0,l._22(t,16).transform(t.context.$implicit.coins,!0,"first"))),n(t,21,0,l._32(t,21,0,l._22(t,22).transform("tx.hours"))),n(t,23,0,l._32(t,23,0,l._22(t,24).transform(t.context.$implicit.hours,!1,"first")))})}function Cg(n){return l._33(0,[(n()(),l._9(0,0,null,null,21,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,8,"div",[["class","col-md-6 -margin-top"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"h4",[],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Mg)),l._8(9,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,8,"div",[["class","col-md-6 -margin-top"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"h4",[],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,kg)),l._8(19,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,9,0,e.transaction.inputs),n(t,19,0,e.transaction.outputs)},function(n,t){n(t,5,0,l._32(t,5,0,l._22(t,6).transform("tx.inputs"))),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("tx.outputs")))})}function Sg(n){return l._33(0,[l._25(0,ag,[]),l._25(0,ln,[l.w]),(n()(),l._9(2,0,null,null,65,"div",[["class","row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,59,"div",[["class","col-md-12"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,dg)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,hg)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,47,"div",[["class","row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,27,"div",[["class","col-md-9 -tx-meta"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,pg)),l._8(17,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,fg)),l._8(20,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,12,"div",[["class","-data"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(25,null,["",":"])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,0,null,null,5,"span",[],null,null,null,null,null)),(n()(),l._31(29,null,["\n "," ","\n |\n "," ","\n "])),l._25(0,If,[tn,qc,gf]),l._25(131072,De.i,[De.j,l.h]),l._25(0,If,[tn,qc,gf]),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,_g)),l._8(37,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,bg)),l._8(40,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(43,0,null,null,15,"div",[["class","col-md-3 -tx-price"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(45,0,null,null,5,"div",[["class","-icon"]],null,null,null,null,null)),l._8(46,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(47,{"-incoming":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(49,0,null,null,0,"img",[["src","/assets/img/send-blue.png"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(52,0,null,null,2,"h4",[],null,null,null,null,null)),(n()(),l._31(53,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,wg)),l._8(57,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,xg)),l._8(62,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Cg)),l._8(66,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,7,0,e.isPreview),n(t,10,0,!e.isPreview),n(t,17,0,e.isPreview),n(t,20,0,!e.isPreview),n(t,37,0,!e.isPreview),n(t,40,0,e.transaction.note||!e.isPreview),n(t,46,0,"-icon",n(t,47,0,!e.isPreview&&e.transaction.balance.isGreaterThan(0)&&!e.transaction.coinsMovedInternally)),n(t,57,0,e.price),n(t,62,0,!e.showInputsOutputs),n(t,66,0,e.showInputsOutputs)},function(n,t){var e=t.component;n(t,25,0,l._32(t,25,0,l._22(t,26).transform("tx.hours"))),n(t,29,0,l._32(t,29,0,l._22(t,30).transform(e.transaction.hoursSent.toString(),!1,"first")),l._32(t,29,1,l._22(t,31).transform(e.hoursText)),l._32(t,29,2,l._22(t,32).transform(e.transaction.hoursBurned.toString(),!1,"first")),l._32(t,29,3,l._22(t,33).transform("tx.hours-burned"))),n(t,53,0,l._32(t,53,0,l._22(t,54).transform(e.transaction.balance.toString())))})}var Og=function(){function n(n,t,e,r,i){this.walletService=n,this.msgBarService=t,this.dialog=e,this.hwWalletService=r,this.translate=i,this.onBack=new l.o}return n.prototype.ngOnDestroy=function(){this.msgBarService.hide(),this.sendSubscription&&this.sendSubscription.unsubscribe()},n.prototype.back=function(){this.onBack.emit(!1)},n.prototype.send=function(){var n=this;if(!this.sendButton.isLoading())if(this.msgBarService.hide(),this.sendButton.resetState(),this.transaction.wallet.encrypted&&!this.transaction.wallet.isHardware){var t=new oa;t.data={wallet:this.transaction.wallet},this.dialog.open(Zp,t).componentInstance.passwordSubmit.subscribe(function(t){n.finishSending(t)})}else this.transaction.wallet.isHardware?(this.showBusy(),this.sendSubscription=this.hwWalletService.checkIfCorrectHwConnected(this.transaction.wallet.addresses[0].address).subscribe(function(){return n.finishSending()},function(t){return n.showError(Tc(n.translate,t))})):this.finishSending()},n.prototype.showBusy=function(){this.sendButton.setLoading(),this.backButton.setDisabled()},n.prototype.finishSending=function(n){var t=this;this.showBusy();var e=this.transaction.note.trim();this.sendSubscription=this.walletService.signTransaction(this.transaction.wallet,n?n.password:null,this.transaction).flatMap(function(l){return n&&n.close(),t.walletService.injectTransaction(l.encoded,e)}).subscribe(function(n){e&&!n?setTimeout(function(){return t.msgBarService.showWarning(t.translate.instant("send.error-saving-note"))}):setTimeout(function(){return t.msgBarService.showDone("send.sent")}),t.walletService.startDataRefreshSubscription(),t.onBack.emit(!0)},function(e){n&&n.error(e),t.showError(e&&e.result?Tc(t.translate,e):e)})},n.prototype.showError=function(n){this.msgBarService.showError(n),this.sendButton.resetState(),this.backButton.resetState().setEnabled()},n}(),Tg=l._7({encapsulation:0,styles:[[".-buttons[_ngcontent-%COMP%]{margin-top:10px;text-align:center}"]],data:{}});function Lg(n){return l._33(0,[l._29(402653184,1,{sendButton:0}),l._29(402653184,2,{backButton:0}),(n()(),l._9(2,0,null,null,1,"app-transaction-info",[],null,null,null,Sg,cg)),l._8(3,245760,null,0,ug,[rf,fa],{transaction:[0,"transaction"],isPreview:[1,"isPreview"]},null),(n()(),l._31(-1,null,["\n\n"])),(n()(),l._9(5,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.back()&&l),l},w_,g_)),l._8(8,49152,[[2,4],["backButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(9,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.send()&&l),l},w_,g_)),l._8(13,49152,[[1,4],["sendButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(14,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){n(t,3,0,t.component.transaction,!0)},function(n,t){n(t,9,0,l._32(t,9,0,l._22(t,10).transform("send.back-button"))),n(t,14,0,l._32(t,14,0,l._22(t,15).transform("send.send-button")))})}var Pg=l._7({encapsulation:0,styles:[[".-buttons[_ngcontent-%COMP%]{text-align:center}.-paper[_ngcontent-%COMP%]{background-color:#fbfbfb;border-radius:10px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);padding:30px;margin:30px}"]],data:{}});function Dg(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-send-form",[],null,[[null,"onFormSubmitted"]],function(n,t,e){var l=!0;return"onFormSubmitted"===t&&(l=!1!==n.component.onFormSubmitted(e)&&l),l},ym,cm)),l._8(1,245760,null,0,um,[ns,qc,Sc,fa,jc,Vp,oc,De.j,l.h,gf,rf],{formData:[0,"formData"]},{onFormSubmitted:"onFormSubmitted"})],function(n,t){n(t,1,0,t.component.formData)},null)}function Ag(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-send-form-advanced",[],null,[[null,"onFormSubmitted"]],function(n,t,e){var l=!0;return"onFormSubmitted"===t&&(l=!1!==n.component.onFormSubmitted(e)&&l),l},sg,Fm)),l._8(1,245760,null,0,Nm,[qc,Sc,gf,ns,fa,jc,Vp,oc,De.j,rf,l.h],{formData:[0,"formData"]},{onFormSubmitted:"onFormSubmitted"})],function(n,t){n(t,1,0,t.component.formData)},null)}function Eg(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-send-preview",[],null,[[null,"onBack"]],function(n,t,e){var l=!0;return"onBack"===t&&(l=!1!==n.component.onBack(e)&&l),l},Lg,Tg)),l._8(1,180224,null,0,Og,[Sc,jc,fa,oc,De.j],{transaction:[0,"transaction"]},{onBack:"onBack"})],function(n,t){n(t,1,0,t.component.transaction)},null)}function Yg(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(1,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(4,0,null,null,13,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,10,"div",[["class","-paper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Dg)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ag)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Eg)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform("title.wallets"))),n(t,9,0,e.showForm&&e.activeForm===e.activeForms.LeftButton),n(t,12,0,e.showForm&&e.activeForm===e.activeForms.RightButton),n(t,15,0,!e.showForm)},null)}var jg=l._5("app-send-skycoin",Wp,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-send-skycoin",[],null,null,null,Yg,Pg)),l._8(1,180224,null,0,Wp,[Vp,l.h],null,null)],null,null)},{},{},[]),Ig=function(){this.isLoading=!0},Rg=l._7({encapsulation:0,styles:[[".-content[_ngcontent-%COMP%]{text-align:center;margin:50px 0;color:rgba(30,34,39,.5);font-size:13px}.-content[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin-top:15px}.-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%]{color:rgba(30,34,39,.2);font-size:40px}.-content[_ngcontent-%COMP%] mat-spinner[_ngcontent-%COMP%]{display:inline-block}.-content[_ngcontent-%COMP%] mat-spinner[_ngcontent-%COMP%] circle{stroke:rgba(30,34,39,.2)}"]],data:{}});function Hg(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"mat-spinner",[["class","mat-spinner mat-progress-spinner"],["mode","indeterminate"],["role","progressbar"]],[[4,"width","px"],[4,"height","px"]],null,null,Pf,Lf)),l._8(3,573440,null,0,Wu,[l.l,Hl,[2,sn]],{diameter:[0,"diameter"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(6,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,40)},function(n,t){n(t,2,0,l._22(t,3)._elementSize,l._22(t,3)._elementSize),n(t,6,0,l._32(t,6,0,l._22(t,7).transform("common.loading")))})}function Ng(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"i",[["class","material-icons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["announcement"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(6,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,6,0,l._32(t,6,0,l._22(t,7).transform(e.noDataText)))})}function Fg(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[["class","-content"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Hg)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ng)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,e.isLoading),n(t,6,0,!e.isLoading)},null)}var Bg=l._7({encapsulation:0,styles:[[".form-field[_ngcontent-%COMP%]{margin:10px 40px -20px;display:-webkit-box;display:-ms-flexbox;display:flex}.form-field[_ngcontent-%COMP%] .x-button[_ngcontent-%COMP%]{width:24px;height:24px;margin-top:10px;cursor:pointer}.bottom-line[_ngcontent-%COMP%]{border-bottom:2px solid rgba(0,0,0,.02)}mat-select[_ngcontent-%COMP%] .mat-select-trigger{padding:10px 30px 10px 10px;display:block;font-size:11px;height:100%;line-height:20px}mat-select[_ngcontent-%COMP%] .mat-select-value{font-size:13px;line-height:22px}mat-select[_ngcontent-%COMP%] .mat-select-arrow{border:none}mat-select[_ngcontent-%COMP%] .mat-select-placeholder{-webkit-transition:unset!important;transition:unset!important;color:rgba(30,34,39,.5)}mat-select[_ngcontent-%COMP%] .mat-select-placeholder::before{content:'filter_list';font-family:'Material Icons';font-weight:400;font-style:normal;font-size:13px;margin-right:10px}mat-select[_ngcontent-%COMP%] mat-select-trigger[_ngcontent-%COMP%]::before{content:'filter_list';font-family:'Material Icons';font-weight:400;font-style:normal;font-size:13px;margin-right:10px}mat-select[_ngcontent-%COMP%] .filter[_ngcontent-%COMP%]{font-size:13px;margin-left:28px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;color:rgba(30,34,39,.5)}mat-option[_ngcontent-%COMP%] .mat-pseudo-checkbox-checked{background:#0072ff}.mat-option-disabled[_ngcontent-%COMP%] .mat-pseudo-checkbox-disabled{opacity:.5}.-paper[_ngcontent-%COMP%]{background-color:#fbfbfb;border-radius:10px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);margin:30px}.-transaction[_ngcontent-%COMP%]{background-color:#fafafa;border-bottom:1px solid #eff0f0;cursor:pointer;display:-webkit-box;display:-ms-flexbox;display:flex;padding:20px 12px}.-transaction[_ngcontent-%COMP%]:first-child{border-top-left-radius:15px;border-top-right-radius:15px}.-transaction[_ngcontent-%COMP%]:last-child{border-bottom-left-radius:15px;border-bottom-right-radius:15px}.-transaction[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]{padding:0 8px}.-transaction[_ngcontent-%COMP%] .-icon[_ngcontent-%COMP%]{margin-top:5px}.-transaction[_ngcontent-%COMP%] .-icon[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{width:32px}.-transaction[_ngcontent-%COMP%] .-icon.-incoming[_ngcontent-%COMP%]{-webkit-transform:scaleX(-1);transform:scaleX(-1);-webkit-filter:FlipH;filter:FlipH;-ms-filter:FlipH}.-transaction[_ngcontent-%COMP%] .-icon.-pending[_ngcontent-%COMP%]{opacity:.5}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%]{-webkit-box-flex:1;-ms-flex:1;flex:1}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%] h4[_ngcontent-%COMP%]{color:#1e2227;font-size:13px;font-weight:700;line-height:15px;margin:0 0 8px}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{font-size:10px;line-height:12px;padding-left:5px;font-weight:300}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] .-pending[_ngcontent-%COMP%]{color:#fdb51e}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] .-timestamp[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%] .-item[_ngcontent-%COMP%]:not(:last-child){margin-bottom:5px}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%] .-item[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{display:inline-block;height:17px;vertical-align:middle;width:17px;margin-right:4px}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%] .-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);display:inline-block;font-size:13px;line-height:15px;margin:0}.-transaction[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%] .-item[_ngcontent-%COMP%] .note[_ngcontent-%COMP%]{color:#1e2227;word-break:break-word;display:inline}.-transaction[_ngcontent-%COMP%] .-balance[_ngcontent-%COMP%]{width:200px;text-align:right}.-transaction[_ngcontent-%COMP%] .-balance[_ngcontent-%COMP%] h4[_ngcontent-%COMP%]{color:#1e2227;font-size:13px;font-weight:700;line-height:15px;margin:0 0 8px}.-transaction[_ngcontent-%COMP%] .-balance[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);display:inline-block;font-size:13px;line-height:15px;margin:0}.-transaction[_ngcontent-%COMP%] .-balance[_ngcontent-%COMP%] p[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:rgba(121,135,152,.5)}"]],data:{}});function Vg(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"mat-option",[["class","mat-option"],["role","option"]],[[1,"tabindex",0],[2,"mat-selected",null],[2,"mat-option-multiple",null],[2,"mat-active",null],[8,"id",0],[1,"aria-selected",0],[1,"aria-disabled",0],[2,"mat-option-disabled",null]],[[null,"click"],[null,"keydown"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,1)._selectViaInteraction()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),r},wm,bm)),l._8(1,49152,[[1,4]],0,pr,[l.l,l.h,[2,hr],[2,cr]],{value:[0,"value"]},null),(n()(),l._31(2,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.parent.context.$implicit)},function(n,t){n(t,0,0,l._22(t,1)._getTabIndex(),l._22(t,1).selected,l._22(t,1).multiple,l._22(t,1).active,l._22(t,1).id,l._22(t,1).selected.toString(),l._22(t,1).disabled.toString(),l._22(t,1).disabled),n(t,2,0,l._32(t,2,0,l._22(t,3).transform("history.all-addresses")))})}function Wg(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"mat-option",[["class","mat-option"],["role","option"]],[[1,"tabindex",0],[2,"mat-selected",null],[2,"mat-option-multiple",null],[2,"mat-active",null],[8,"id",0],[1,"aria-selected",0],[1,"aria-disabled",0],[2,"mat-option-disabled",null]],[[null,"click"],[null,"keydown"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,1)._selectViaInteraction()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),r},wm,bm)),l._8(1,49152,[[1,4]],0,pr,[l.l,l.h,[2,hr],[2,cr]],{value:[0,"value"],disabled:[1,"disabled"]},null),(n()(),l._31(2,0,["\n "," - ","\n (",")\n "])),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf])],function(n,t){n(t,1,0,t.context.$implicit,t.parent.context.$implicit.allAddressesSelected)},function(n,t){n(t,0,0,l._22(t,1)._getTabIndex(),l._22(t,1).selected,l._22(t,1).multiple,l._22(t,1).active,l._22(t,1).id,l._22(t,1).selected.toString(),l._22(t,1).disabled.toString(),l._22(t,1).disabled),n(t,2,0,t.context.$implicit.address,l._32(t,2,1,l._22(t,3).transform(t.context.$implicit.coins)),l._32(t,2,2,l._22(t,4).transform(t.context.$implicit.hours,!1)))})}function zg(n){return l._33(0,[(n()(),l._9(0,0,null,null,10,"mat-optgroup",[["class","mat-optgroup"],["role","group"]],[[2,"mat-optgroup-disabled",null],[1,"aria-disabled",0],[1,"aria-labelledby",0]],null,null,Mm,xm)),l._8(1,49152,[[2,4]],0,cr,[],{label:[0,"label"]},null),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,0,1,null,Vg)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,0,1,null,Wg)),l._8(9,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,1,0,l._12(3,"\n ",t.context.$implicit.label," - ",l._32(t,1,0,l._22(t,2).transform(t.context.$implicit.coins)),"\n (",l._32(t,1,0,l._22(t,3).transform(t.context.$implicit.hours,!1)),")\n ")),n(t,6,0,t.context.$implicit.addresses.length>1),n(t,9,0,t.context.$implicit.addresses)},function(n,t){n(t,0,0,l._22(t,1).disabled,l._22(t,1).disabled.toString(),l._22(t,1)._labelId)})}function Ug(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("history.filter")))})}function Gg(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("history.filters")))})}function qg(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.parent.parent.context.$implicit.label)})}function Jg(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.parent.parent.context.$implicit.address)})}function Qg(n){return l._33(0,[(n()(),l._9(0,0,null,null,9,"div",[["class","filter"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,qg)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Jg)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(7,null,["\n - ","\n (",")\n "])),l._25(0,If,[tn,qc,gf]),l._25(0,If,[tn,qc,gf])],function(n,t){n(t,3,0,t.parent.context.$implicit.label),n(t,6,0,!t.parent.context.$implicit.label)},function(n,t){n(t,7,0,l._32(t,7,0,l._22(t,8).transform(t.parent.context.$implicit.coins)),l._32(t,7,1,l._22(t,9).transform(t.parent.context.$implicit.hours,!1)))})}function Kg(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Qg)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.context.$implicit.label||!t.context.$implicit.showingWholeWallet)},null)}function Xg(n){return l._33(0,[(n()(),l._9(0,0,null,null,0,"img",[["class","x-button"],["src","assets/img/close-grey.png"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.removeFilters()&&l),l},null,null))],null,null)}function Zg(n){return l._33(0,[(n()(),l._9(0,0,null,null,38,"div",[["class","form-field"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,1).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,1).onReset()&&r),r},null,null)),l._8(1,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(3,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,29,"mat-select",[["class","mat-select"],["formControlName","filter"],["id","filter"],["multiple",""],["role","listbox"]],[[1,"id",0],[1,"tabindex",0],[1,"aria-label",0],[1,"aria-labelledby",0],[1,"aria-required",0],[1,"aria-disabled",0],[1,"aria-invalid",0],[1,"aria-owns",0],[1,"aria-multiselectable",0],[1,"aria-describedby",0],[1,"aria-activedescendant",0],[2,"mat-select-disabled",null],[2,"mat-select-invalid",null],[2,"mat-select-required",null],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown"],[null,"focus"],[null,"blur"]],function(n,t,e){var r=!0;return"keydown"===t&&(r=!1!==l._22(n,12)._handleKeydown(e)&&r),"focus"===t&&(r=!1!==l._22(n,12)._onFocus()&&r),"blur"===t&&(r=!1!==l._22(n,12)._onBlur()&&r),r},Am,Sm)),l._28(6144,null,hr,null,[Pu]),l._28(6144,null,Os,null,[Pu]),l._8(8,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(9,{"bottom-line":0}),l._8(10,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[8,null]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(12,2080768,null,3,Pu,[Xr,l.h,l.B,Kl,l.l,[2,Dl],[2,Wo],[2,qo],[2,Ps],[2,uo],[8,null],Ou],{placeholder:[0,"placeholder"],multiple:[1,"multiple"],id:[2,"id"]},null),l._29(603979776,1,{options:1}),l._29(603979776,2,{optionGroups:1}),l._29(335544320,3,{customTrigger:0}),l._25(131072,De.i,[De.j,l.h]),l._8(17,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,1,["\n "])),(n()(),l._4(16777216,null,1,1,null,zg)),l._8(20,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,1,["\n "])),(n()(),l._9(22,0,null,0,11,"mat-select-trigger",[],null,null,null,null,null)),l._8(23,16384,[[3,4]],0,Lu,[],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ug)),l._8(26,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Gg)),l._8(29,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Kg)),l._8(32,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,1,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Xg)),l._8(37,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,1,0,e.form),n(t,8,0,n(t,9,0,!e.transactions||0===e.transactions.length)),n(t,10,0,"filter"),n(t,12,0,l._32(t,12,0,l._22(t,16).transform("history.no-filter")),"","filter"),n(t,20,0,e.wallets),n(t,26,0,1===e.form.get("filter").value.length),n(t,29,0,e.form.get("filter").value.length>1),n(t,32,0,e.form.get("filter").value),n(t,37,0,e.form.get("filter").value.length>0)},function(n,t){n(t,0,0,l._22(t,3).ngClassUntouched,l._22(t,3).ngClassTouched,l._22(t,3).ngClassPristine,l._22(t,3).ngClassDirty,l._22(t,3).ngClassValid,l._22(t,3).ngClassInvalid,l._22(t,3).ngClassPending),n(t,5,1,[l._22(t,12).id,l._22(t,12).tabIndex,l._22(t,12)._ariaLabel,l._22(t,12).ariaLabelledby,l._22(t,12).required.toString(),l._22(t,12).disabled.toString(),l._22(t,12).errorState,l._22(t,12).panelOpen?l._22(t,12)._optionIds:null,l._22(t,12).multiple,l._22(t,12)._ariaDescribedby||null,l._22(t,12)._getAriaActiveDescendant(),l._22(t,12).disabled,l._22(t,12).errorState,l._22(t,12).required,l._22(t,17).ngClassUntouched,l._22(t,17).ngClassTouched,l._22(t,17).ngClassPristine,l._22(t,17).ngClassDirty,l._22(t,17).ngClassValid,l._22(t,17).ngClassInvalid,l._22(t,17).ngClassPending])})}function $g(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-loading-content",[],null,null,null,Fg,Rg)),l._8(1,49152,null,0,Ig,[],{isLoading:[0,"isLoading"],noDataText:[1,"noDataText"]},null)],function(n,t){var e=t.component;n(t,1,0,!e.allTransactions,e.allTransactions&&0!==e.allTransactions.length?"history.no-txs-filter":"history.no-txs")},null)}function ny(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"h4",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h]),l._25(0,l_,[gf]),(n()(),l._9(4,0,null,null,2,"span",[["class","-timestamp"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._27(6,1),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("history.sent")),l._32(t,1,1,l._22(t,3).transform("coin"))),n(t,5,0,l._32(t,5,0,n(t,6,0,l._22(t.parent.parent.parent.parent,0),t.parent.parent.context.$implicit.timestamp)))})}function ty(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"h4",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h]),l._25(0,l_,[gf]),(n()(),l._9(4,0,null,null,2,"span",[["class","-pending"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("history.sending")),l._32(t,1,1,l._22(t,3).transform("coin"))),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("history.pending")))})}function ey(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"h4",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h]),l._25(0,l_,[gf]),(n()(),l._9(4,0,null,null,2,"span",[["class","-timestamp"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._27(6,1),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("history.received")),l._32(t,1,1,l._22(t,3).transform("coin"))),n(t,5,0,l._32(t,5,0,n(t,6,0,l._22(t.parent.parent.parent.parent,0),t.parent.parent.context.$implicit.timestamp)))})}function ly(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"h4",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h]),l._25(0,l_,[gf]),(n()(),l._9(4,0,null,null,2,"span",[["class","-pending"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("history.receiving")),l._32(t,1,1,l._22(t,3).transform("coin"))),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("history.pending")))})}function ry(n){return l._33(0,[(n()(),l._9(0,0,null,null,13,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ny)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ty)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ey)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ly)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.parent.context.$implicit.balance.isLessThan(0)&&t.parent.context.$implicit.confirmed),n(t,6,0,t.parent.context.$implicit.balance.isLessThan(0)&&!t.parent.context.$implicit.confirmed),n(t,9,0,t.parent.context.$implicit.balance.isGreaterThan(0)&&t.parent.context.$implicit.confirmed),n(t,12,0,t.parent.context.$implicit.balance.isGreaterThan(0)&&!t.parent.context.$implicit.confirmed)},null)}function iy(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"h4",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h]),l._25(0,l_,[gf]),(n()(),l._9(4,0,null,null,2,"span",[["class","-timestamp"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._27(6,1),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("history.moved")),l._32(t,1,1,l._22(t,3).transform("coin"))),n(t,5,0,l._32(t,5,0,n(t,6,0,l._22(t.parent.parent.parent.parent,0),t.parent.parent.context.$implicit.timestamp)))})}function oy(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"h4",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h]),l._25(0,l_,[gf]),(n()(),l._9(4,0,null,null,2,"span",[["class","-pending"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("history.moving")),l._32(t,1,1,l._22(t,3).transform("coin"))),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("history.pending")))})}function sy(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,iy)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,oy)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.parent.context.$implicit.confirmed),n(t,6,0,!t.parent.context.$implicit.confirmed)},null)}function ay(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,0,"img",[["class","qr-code-button"],["src","../../../../assets/img/qr-code-black.png"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.showQrCode(e,n.context.$implicit)&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,5,0,t.context.$implicit)})}function uy(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,4,"span",[],null,null,null,null,null)),(n()(),l._31(3,null,["",": "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(5,0,null,null,1,"span",[["class","note"]],null,null,null,null,null)),(n()(),l._31(6,null,["",""])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("history.note"))),n(t,6,0,t.parent.context.$implicit.note)})}function cy(n){return l._33(0,[(n()(),l._9(0,16777216,null,null,7,"p",[],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,1).show()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,1).hide(1500)&&r),r},null,null)),l._8(1,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(3,null,["\n ",""])),l._27(4,4),(n()(),l._9(5,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(-1,null,["*"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(0,null,null,0))],function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("tx.current-rate")))},function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,n(t,4,0,l._22(t.parent.parent.parent,1),t.parent.context.$implicit.balance*e.price,"USD","symbol","1.2-2")))})}function dy(n){return l._33(0,[(n()(),l._9(0,0,null,null,36,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,33,"div",[["class","-transaction"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.showTransaction(n.context.$implicit)&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,5,"div",[["class","-icon"]],null,null,null,null,null)),l._8(5,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(6,{"-incoming":0,"-pending":1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,0,"img",[["src","/assets/img/send-blue.png"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,13,"div",[["class","-address"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ry)),l._8(14,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,sy)),l._8(17,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ay)),l._8(20,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,uy)),l._8(23,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(26,0,null,null,8,"div",[["class","-balance"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,0,null,null,2,"h4",[],null,null,null,null,null)),(n()(),l._31(29,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,cy)),l._8(33,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,5,0,"-icon",n(t,6,0,t.context.$implicit.balance.isGreaterThan(0)&&!t.context.$implicit.coinsMovedInternally,!t.context.$implicit.confirmed)),n(t,14,0,!t.context.$implicit.coinsMovedInternally),n(t,17,0,t.context.$implicit.coinsMovedInternally),n(t,20,0,t.context.$implicit.addresses),n(t,23,0,t.context.$implicit.note),n(t,33,0,e.price)},function(n,t){n(t,29,0,l._32(t,29,0,l._22(t,30).transform(t.context.$implicit.balance.toString())))})}function hy(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[["class","-paper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,dy)),l._8(3,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.component.transactions)},null)}function py(n){return l._33(0,[l._25(0,ag,[]),l._25(0,ln,[l.w]),(n()(),l._9(2,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(3,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(6,0,null,null,10,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Zg)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,$g)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,hy)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,l._22(t,4).transform("title.transactions"))),n(t,9,0,e.allTransactions),n(t,12,0,!e.transactions||0===e.transactions.length),n(t,15,0,e.transactions&&e.transactions.length>0)},null)}var fy=l._5("app-transaction-list",sf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-transaction-list",[],null,null,null,py,Bg)),l._8(1,245760,null,0,sf,[fa,rf,Sc,ns,Ch],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),_y=function(){function n(){this.statuses=["done","waiting_confirm","waiting_deposit","waiting_send"]}return n.prototype.transform=function(n){return this.statuses.find(function(t){return t===n})?"teller."+n.replace("_","-"):"teller.unknown"},n}(),my=l._7({encapsulation:0,styles:[[".-background-container[_ngcontent-%COMP%]{background-color:#fbfbfb;padding-top:30px;max-width:100%;min-height:calc(100% - 190px);overflow:hidden;position:relative}.-background-image[_ngcontent-%COMP%]{display:none}@media (min-width:768px){.-background-image[_ngcontent-%COMP%]{display:block;left:50%;width:80%;position:absolute;top:0}}@media (min-width:992px){.-background-image[_ngcontent-%COMP%]{left:40%;width:90%;max-width:850px}}@media (min-width:1200px){.-background-image[_ngcontent-%COMP%]{left:40%;width:80%;max-width:850px}}.-paper[_ngcontent-%COMP%]{background-color:#fbfbfb;border-radius:10px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);padding:30px;position:relative;margin-top:30px;max-width:540px;z-index:5}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:30px}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-number[_ngcontent-%COMP%]{width:60px}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-number[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{border-radius:50%;color:#fff;display:inline-block;font-size:16px;font-weight:700;height:40px;line-height:46px;text-align:center;width:40px}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%]{-webkit-box-flex:1;-ms-flex:1 1;flex:1 1}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] button{margin-left:0}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]{color:#1e2227;font-size:16px;font-weight:700;margin:0;line-height:46px}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{color:rgba(30,34,39,.8);font-size:14px;font-weight:300;line-height:20px;margin-top:0}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] .-address[_ngcontent-%COMP%], .-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] .-status[_ngcontent-%COMP%]{background-color:#fff;border:2px solid rgba(0,0,0,.05);border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;color:rgba(30,34,39,.8);display:block;font-size:14px;line-height:20px;margin-bottom:15px;padding:10px;width:100%}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] .-coins[_ngcontent-%COMP%]{color:#0072ff}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] .form-field[_ngcontent-%COMP%]{margin-bottom:15px}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] .-subtitle[_ngcontent-%COMP%]{color:#8c8e90;font-size:12px;line-height:18px;font-weight:300;opacity:.8}.-paper[_ngcontent-%COMP%] .-step[_ngcontent-%COMP%] .-instructions[_ngcontent-%COMP%] .-wallet[_ngcontent-%COMP%]{color:rgba(30,34,39,.8);font-size:14px}"]],data:{}});function gy(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"option",[],null,null,null,null,null)),l._8(1,147456,null,0,mo,[l.l,l.G,[2,_o]],{value:[0,"value"]},null),l._8(2,147456,null,0,bo,[l.l,l.G,[8,null]],{value:[0,"value"]},null),(n()(),l._31(3,null,["\n "," - "])),(n()(),l._9(4,0,null,null,2,"span",[["class","-coins"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,1,0,t.context.$implicit.filename),n(t,2,0,t.context.$implicit.filename)},function(n,t){n(t,3,0,t.context.$implicit.label),n(t,5,0,l._32(t,5,0,l._22(t,6).transform(t.context.$implicit.coins)))})}function yy(n){return l._33(0,[(n()(),l._9(0,0,null,null,26,"div",[["class","-step"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,4,"div",[["class","-number"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,1,"span",[["class","primary-gradient-background"]],null,null,null,null,null)),(n()(),l._31(-1,null,["2"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,17,"div",[["class","-instructions flex-fill"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"h3",[],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,3,"p",[],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._26(16,{rate:0}),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(19,0,null,null,1,"span",[["class","-address"]],null,null,null,null,null)),(n()(),l._31(20,null,["\n ","\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,2,"span",[["class","-subtitle"]],null,null,null,null,null)),(n()(),l._31(23,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,11,0,l._32(t,11,0,l._22(t,12).transform("buy.send"))),n(t,15,0,l._32(t,15,0,l._22(t,17).transform("buy.send-desc",n(t,16,0,e.config.sky_btc_exchange_rate)))),n(t,20,0,e.order.deposit_address),n(t,23,0,l._32(t,23,0,l._22(t,24).transform("buy.fraction-warning")))})}function by(n){return l._33(0,[(n()(),l._9(0,0,null,null,34,"div",[["class","-step"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,4,"div",[["class","-number"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,1,"span",[["class","primary-gradient-background"]],null,null,null,null,null)),(n()(),l._31(-1,null,["3"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,25,"div",[["class","-instructions flex-fill"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"h3",[],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,4,"span",[["class","-status"]],null,null,null,null,null)),(n()(),l._31(19,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h]),l._27(21,1),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.checkStatus()&&l),l},w_,g_)),l._8(25,49152,[[1,4],["button",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(26,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(29,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.removeOrder()&&l),l},w_,g_)),l._8(30,49152,[[1,4],["button",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(31,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,11,0,l._32(t,11,0,l._22(t,12).transform("buy.receive"))),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("buy.receive-desc"))),n(t,19,0,l._32(t,19,0,l._22(t,20).transform("buy.status-button")),l._32(t,19,1,l._22(t,22).transform(l._32(t,19,1,n(t,21,0,l._22(t.parent.parent,0),e.order.status))))),n(t,26,0,l._32(t,26,0,l._22(t,27).transform("buy.check-status-button"))),n(t,31,0,l._32(t,31,0,l._22(t,32).transform("buy.new-order-button")))})}function vy(n){return l._33(0,[(n()(),l._9(0,0,null,null,59,"div",[["class","-paper"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,1).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,1).onReset()&&r),r},null,null)),l._8(1,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(3,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,47,"div",[["class","-step"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,4,"div",[["class","-number"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,1,"span",[["class","primary-gradient-background"]],null,null,null,null,null)),(n()(),l._31(-1,null,["1"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,38,"div",[["class","-instructions flex-fill"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,2,"h3",[],null,null,null,null,null)),(n()(),l._31(16,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(19,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(20,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(23,0,null,null,23,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,20,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(27,0,null,null,17,"select",[["class","-wallet"],["formControlName","wallet"],["id","wallet"],["required",""]],[[1,"required",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(n,t,e){var r=!0;return"change"===t&&(r=!1!==l._22(n,28).onChange(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,28).onTouched()&&r),r},null,null)),l._8(28,16384,null,0,_o,[l.G,l.l],null,null),l._8(29,16384,null,0,Zo,[],{required:[0,"required"]},null),l._28(1024,null,Qi,function(n){return[n]},[Zo]),l._28(1024,null,to,function(n){return[n]},[_o]),l._8(32,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(34,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(36,0,null,null,4,"option",[["disabled",""],["selected",""]],null,null,null,null,null)),l._8(37,147456,null,0,mo,[l.l,l.G,[2,_o]],null,null),l._8(38,147456,null,0,bo,[l.l,l.G,[8,null]],null,null),(n()(),l._31(39,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,gy)),l._8(43,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(48,0,null,null,2,"span",[["class","-subtitle"]],null,null,null,null,null)),(n()(),l._31(49,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,yy)),l._8(55,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,by)),l._8(58,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,1,0,e.form),n(t,29,0,""),n(t,32,0,"wallet"),n(t,43,0,e.wallets),n(t,55,0,e.order),n(t,58,0,e.order)},function(n,t){n(t,0,0,l._22(t,3).ngClassUntouched,l._22(t,3).ngClassTouched,l._22(t,3).ngClassPristine,l._22(t,3).ngClassDirty,l._22(t,3).ngClassValid,l._22(t,3).ngClassInvalid,l._22(t,3).ngClassPending),n(t,16,0,l._32(t,16,0,l._22(t,17).transform("buy.deposit-location"))),n(t,20,0,l._32(t,20,0,l._22(t,21).transform("buy.deposit-location-desc"))),n(t,27,0,l._22(t,29).required?"":null,l._22(t,34).ngClassUntouched,l._22(t,34).ngClassTouched,l._22(t,34).ngClassPristine,l._22(t,34).ngClassDirty,l._22(t,34).ngClassValid,l._22(t,34).ngClassInvalid,l._22(t,34).ngClassPending),n(t,39,0,l._32(t,39,0,l._22(t,40).transform("buy.make-choice"))),n(t,49,0,l._32(t,49,0,l._22(t,50).transform("buy.wallets-desc")))})}function wy(n){return l._33(0,[l._25(0,_y,[]),l._29(671088640,1,{button:0}),(n()(),l._9(2,0,null,null,1,"app-header",[],null,null,null,K_,D_)),l._8(3,245760,null,0,P_,[gf,nf,qc,rf,Sc],null,null),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(5,0,null,null,9,"div",[["class","-background-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,6,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,vy)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,0,"img",[["class","-background-image"],["src","../../../../assets/img/otc-background.jpg"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0),n(t,10,0,e.config)},null)}var xy=l._5("app-buy",lf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-buy",[],null,null,null,wy,my)),l._8(1,245760,null,0,lf,[ns,ef,jc,Sc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]);o.a.merge=Jr.a;var My=function(){function n(n,t,e,r,i,o,s){this.exchangeService=n,this.walletService=t,this.formBuilder=e,this.msgBarService=r,this.dialog=i,this.blockchainService=o,this.translateService=s,this.defaultFromCoin="BTC",this.defaultFromAmount="0.1",this.toCoin="SKY",this.submitted=new l.o,this.problemGettingPairs=!1,this.agreement=!1,this.subscriptionsGroup=[]}return Object.defineProperty(n.prototype,"toAmount",{get:function(){if(!this.activeTradingPair)return 0;var n=this.form.get("fromAmount").value;return isNaN(n)?0:(this.form.get("fromAmount").value*this.activeTradingPair.price).toFixed(this.blockchainService.currentMaxDecimals)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"sendAmount",{get:function(){var n=this.form.get("fromAmount").value;return isNaN(parseFloat(n))?0:n},enumerable:!0,configurable:!0}),n.prototype.ngOnInit=function(){this.createForm(),this.loadData()},n.prototype.ngOnDestroy=function(){this.subscriptionsGroup.forEach(function(n){return n.unsubscribe()}),this.removeExchangeSubscription(),this.msgBarService.hide(),this.priceUpdateSubscription&&this.priceUpdateSubscription.unsubscribe()},n.prototype.setAgreement=function(n){this.agreement=n.checked,this.form.updateValueAndValidity()},n.prototype.selectAddress=function(){var n=this,t=new oa;t.width="566px",t.autoFocus=!1,this.dialog.open(Rm,t).afterClosed().subscribe(function(t){t&&n.form.get("toAddress").setValue(t)})},n.prototype.exchange=function(){var n=this;if(this.form.valid&&!this.exchangeButton.isLoading()){this.msgBarService.hide(),this.exchangeButton.resetState(),this.exchangeButton.setLoading(),this.exchangeButton.setDisabled();var t=parseFloat(this.form.get("fromAmount").value),e=this.form.get("toAddress").value.trim();this.removeExchangeSubscription(),this.exchangeSubscription=this.walletService.verifyAddress(e).subscribe(function(l){l?n.exchangeSubscription=n.exchangeService.exchange(n.activeTradingPair.pair,t,e,n.activeTradingPair.price).subscribe(function(t){n.submitted.emit({id:t.id,pair:t.pair,fromAmount:t.fromAmount,toAmount:t.toAmount,address:t.toAddress,timestamp:zp().unix(),price:n.activeTradingPair.price})},function(t){n.exchangeButton.resetState(),n.exchangeButton.setEnabled(),n.msgBarService.showError(t)}):n.showInvalidAddress()},function(){n.showInvalidAddress()})}},n.prototype.showInvalidAddress=function(){this.exchangeButton.resetState(),this.exchangeButton.setEnabled();var n=this.translateService.instant("exchange.invalid-address");this.msgBarService.showError(n)},n.prototype.createForm=function(){var n=this;this.form=this.formBuilder.group({fromCoin:[this.defaultFromCoin,Xi.required],fromAmount:[this.defaultFromAmount,Xi.required],toAddress:["",Xi.required]},{validator:this.validate.bind(this)}),this.subscriptionsGroup.push(this.form.get("fromCoin").valueChanges.subscribe(function(){n.updateActiveTradingPair()}))},n.prototype.loadData=function(){var n=this;this.subscriptionsGroup.push(this.exchangeService.tradingPairs().retryWhen(function(n){return n.delay(2e3).take(10).concat(o.a.throw(""))}).subscribe(function(t){n.tradingPairs=[],t.forEach(function(t){t.to===n.toCoin&&n.tradingPairs.push(t)}),n.updateActiveTradingPair(),n.updatePrices()},function(){n.problemGettingPairs=!0}))},n.prototype.updatePrices=function(){var n=this;this.priceUpdateSubscription=o.a.of(1).delay(6e4).flatMap(function(){return n.exchangeService.tradingPairs()}).retryWhen(function(n){return n.delay(6e4)}).subscribe(function(t){t.forEach(function(t){if(t.to===n.toCoin){var e=n.tradingPairs.find(function(n){return n.from===t.from});e&&(e.price=t.price)}}),n.updatePrices()})},n.prototype.updateActiveTradingPair=function(){var n=this;this.activeTradingPair=this.tradingPairs.find(function(t){return t.from===n.form.get("fromCoin").value}),!this.activeTradingPair&&this.tradingPairs.length>0&&(this.activeTradingPair=this.tradingPairs[0],this.form.get("fromCoin").setValue(this.activeTradingPair.from))},n.prototype.validate=function(n){if(!n||!this.activeTradingPair)return null;var t=n.get("fromAmount").value;if(isNaN(t))return{invalid:!0};if(tthis.activeTradingPair.max)return{max:this.activeTradingPair.max};var e=t.split(".");return e.length>1&&e[1].length>6?{decimals:!0}:this.agreement?null:{agreement:!0}},n.prototype.removeExchangeSubscription=function(){this.exchangeSubscription&&this.exchangeSubscription.unsubscribe()},n}(),ky=l._7({encapsulation:0,styles:[[".-create[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex}.-create[_ngcontent-%COMP%] .-form[_ngcontent-%COMP%]{-webkit-box-flex:.6;-ms-flex:.6;flex:.6}.-create[_ngcontent-%COMP%] .-info[_ngcontent-%COMP%]{-webkit-box-flex:.4;-ms-flex:.4;flex:.4;margin-left:40px;margin-top:5px}.form-field[_ngcontent-%COMP%]{width:100%}.form-field[_ngcontent-%COMP%] .-error[_ngcontent-%COMP%]{color:#ff004e;margin-left:20px}.form-field[_ngcontent-%COMP%] .-inputs[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex}.form-field[_ngcontent-%COMP%] .-inputs[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{-webkit-box-flex:.7;-ms-flex:.7;flex:.7;border-top-right-radius:0;border-bottom-right-radius:0}.form-field[_ngcontent-%COMP%] .-inputs[_ngcontent-%COMP%] .-input[_ngcontent-%COMP%], .form-field[_ngcontent-%COMP%] .-inputs[_ngcontent-%COMP%] .-select[_ngcontent-%COMP%]{-webkit-box-flex:.3;-ms-flex:.3;flex:.3}.form-field[_ngcontent-%COMP%] .-inputs[_ngcontent-%COMP%] .-input[_ngcontent-%COMP%] input[_ngcontent-%COMP%], .form-field[_ngcontent-%COMP%] .-inputs[_ngcontent-%COMP%] .-input[_ngcontent-%COMP%] select[_ngcontent-%COMP%], .form-field[_ngcontent-%COMP%] .-inputs[_ngcontent-%COMP%] .-select[_ngcontent-%COMP%] input[_ngcontent-%COMP%], .form-field[_ngcontent-%COMP%] .-inputs[_ngcontent-%COMP%] .-select[_ngcontent-%COMP%] select[_ngcontent-%COMP%]{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.form-field[_ngcontent-%COMP%] .-not-allowed[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{cursor:not-allowed}.-item[_ngcontent-%COMP%]{font-size:13px}.-item[_ngcontent-%COMP%]:not(:last-child){margin-bottom:20px}.-item[_ngcontent-%COMP%] .-key[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);margin-bottom:5px}.-item[_ngcontent-%COMP%] .-value[_ngcontent-%COMP%]{word-break:break-all}.-buttons[_ngcontent-%COMP%]{text-align:center}.-buttons[_ngcontent-%COMP%] mat-checkbox[_ngcontent-%COMP%]{margin-right:20px}.-check[_ngcontent-%COMP%] .mat-checkbox-layout{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.-check[_ngcontent-%COMP%] .mat-checkbox-checkmark-path{position:absolute;width:18px;height:8px;left:4.59px;top:9px;stroke:#0072ff!important}.-check[_ngcontent-%COMP%] .mat-checkbox-background, .-check[_ngcontent-%COMP%] .mat-checkbox-frame{top:0;left:0;right:0;bottom:0;position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;pointer-events:none;width:20px;height:20px;background:rgba(30,34,39,.05);border-radius:6px;border-color:transparent}.-check[_ngcontent-%COMP%] span{font-family:Skycoin;line-height:normal;font-size:13px;color:#1e2227}.-check[_ngcontent-%COMP%] span a{color:#0072ff;text-decoration:none}.-select-address[_ngcontent-%COMP%]{padding-left:5px;color:#0072ff;cursor:pointer}.-select-address[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{color:#0072ff;padding:0;display:inline;vertical-align:middle;font-size:13px}"]],data:{}});function Cy(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-loading-content",[],null,null,null,Fg,Rg)),l._8(1,49152,null,0,Ig,[],{isLoading:[0,"isLoading"],noDataText:[1,"noDataText"]},null)],function(n,t){var e=t.component;n(t,1,0,!e.tradingPairs&&!e.problemGettingPairs,e.problemGettingPairs?"exchange.problem-connecting":"exchange.offline")},null)}function Sy(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[["class","-error"]],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform("exchange.min-amount")),e.form.getError("min"))})}function Oy(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[["class","-error"]],null,null,null,null,null)),(n()(),l._31(1,null,["\n "," ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform("exchange.max-amount")),e.form.getError("max"))})}function Ty(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"option",[],null,null,null,null,null)),l._8(1,147456,null,0,mo,[l.l,l.G,[2,_o]],{value:[0,"value"]},null),l._8(2,147456,null,0,bo,[l.l,l.G,[8,null]],{value:[0,"value"]},null),(n()(),l._31(3,null,["",""]))],function(n,t){n(t,1,0,t.context.$implicit.from),n(t,2,0,t.context.$implicit.from)},function(n,t){n(t,3,0,t.context.$implicit.from)})}function Ly(n){return l._33(0,[(n()(),l._9(0,0,null,null,52,"div",[["class","-info"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(9,null,[""," ",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(12,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(19,null,["\u2248 "," ",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(22,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,0,null,null,3,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(25,null,["",""])),l._26(26,{coin:0}),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(29,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(30,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(33,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(35,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(36,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(39,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(40,null,["1 "," \u2248 "," ",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(43,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(45,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(46,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(49,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\u2248 15 minutes"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,5,0,l._32(t,5,0,l._22(t,6).transform("exchange.you-send"))),n(t,9,0,e.sendAmount,e.form.get("fromCoin").value),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("exchange.you-get"))),n(t,19,0,e.toAmount,e.toCoin),n(t,25,0,l._32(t,25,0,l._22(t,27).transform("exchange.to-address",n(t,26,0,e.toCoin)))),n(t,30,0,e.form.get("toAddress").value||"-"),n(t,36,0,l._32(t,36,0,l._22(t,37).transform("exchange.price"))),n(t,40,0,e.form.get("fromCoin").value,e.activeTradingPair.price.toFixed(6),e.toCoin),n(t,46,0,l._32(t,46,0,l._22(t,47).transform("exchange.time-15")))})}function Py(n){return l._33(0,[(n()(),l._9(0,0,null,null,113,"div",[["class","-create"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,107,"div",[["class","-form"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,3).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,3).onReset()&&r),r},null,null)),l._8(3,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(5,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,35,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,8,"label",[["for","fromAmount"]],null,null,null,null,null)),(n()(),l._31(10,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._4(16777216,null,null,1,null,Sy)),l._8(13,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Oy)),l._8(16,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(19,0,null,null,22,"div",[["class","-inputs"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(21,0,null,null,5,"input",[["formControlName","fromAmount"],["id","fromAmount"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,22)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,22).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,22)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,22)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(22,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(24,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(26,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,0,null,null,12,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(30,0,null,null,9,"select",[["formControlName","fromCoin"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(n,t,e){var r=!0;return"change"===t&&(r=!1!==l._22(n,31).onChange(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,31).onTouched()&&r),r},null,null)),l._8(31,16384,null,0,_o,[l.G,l.l],null,null),l._28(1024,null,to,function(n){return[n]},[_o]),l._8(33,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(35,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ty)),l._8(38,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(44,0,null,null,15,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(46,0,null,null,2,"label",[["for","toAmount"]],null,null,null,null,null)),(n()(),l._31(47,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(50,0,null,null,8,"div",[["class","-inputs -not-allowed"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(52,0,null,null,0,"input",[["id","toAmount"],["readonly",""],["type","text"]],[[8,"value",0]],null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(54,0,null,null,3,"div",[["class","-input"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(56,0,null,null,0,"input",[["readonly",""],["type","text"]],[[8,"value",0]],null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(61,0,null,null,24,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(63,0,null,null,14,"label",[["for","toAddress"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(65,0,null,null,3,"span",[],null,null,null,null,null)),(n()(),l._31(66,null,["",""])),l._26(67,{coin:0}),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(70,0,null,null,6,"span",[["class","-select-address"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.selectAddress()&&l),l},null,null)),(n()(),l._31(71,null,["\n "," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(73,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(74,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["keyboard_arrow_down"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(79,0,null,null,5,"input",[["formControlName","toAddress"],["id","toAddress"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,80)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,80).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,80)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,80)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(80,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(82,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(84,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(87,0,null,null,21,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(89,0,null,null,13,"mat-checkbox",[["class","-check mat-checkbox"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setAgreement(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(91,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],null,{change:"change"}),(n()(),l._31(92,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(94,0,null,0,2,"a",[["href","https://swaplab.cc/terms"],["rel","noreferrer nofollow"],["target","_blank"]],null,null,null,null,null)),(n()(),l._31(95,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(97,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(99,0,null,0,2,"a",[["href","https://swaplab.cc/privacy"],["rel","noreferrer nofollow"],["target","_blank"]],null,null,null,null,null)),(n()(),l._31(100,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(104,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.exchange()&&l),l},w_,g_)),l._8(105,49152,[[1,4],["exchangeButton",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(106,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Ly)),l._8(112,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,e.form),n(t,13,0,e.form.hasError("min")),n(t,16,0,e.form.hasError("max")),n(t,24,0,"fromAmount"),n(t,33,0,"fromCoin"),n(t,38,0,e.tradingPairs),n(t,74,0),n(t,82,0,"toAddress"),n(t,105,0,!e.form.valid),n(t,112,0,e.activeTradingPair)},function(n,t){var e=t.component;n(t,2,0,l._22(t,5).ngClassUntouched,l._22(t,5).ngClassTouched,l._22(t,5).ngClassPristine,l._22(t,5).ngClassDirty,l._22(t,5).ngClassValid,l._22(t,5).ngClassInvalid,l._22(t,5).ngClassPending),n(t,10,0,l._32(t,10,0,l._22(t,11).transform("exchange.you-send"))),n(t,21,0,l._22(t,26).ngClassUntouched,l._22(t,26).ngClassTouched,l._22(t,26).ngClassPristine,l._22(t,26).ngClassDirty,l._22(t,26).ngClassValid,l._22(t,26).ngClassInvalid,l._22(t,26).ngClassPending),n(t,30,0,l._22(t,35).ngClassUntouched,l._22(t,35).ngClassTouched,l._22(t,35).ngClassPristine,l._22(t,35).ngClassDirty,l._22(t,35).ngClassValid,l._22(t,35).ngClassInvalid,l._22(t,35).ngClassPending),n(t,47,0,l._32(t,47,0,l._22(t,48).transform("exchange.you-get"))),n(t,52,0,e.toAmount),n(t,56,0,e.toCoin),n(t,66,0,l._32(t,66,0,l._22(t,68).transform("exchange.to-address",n(t,67,0,e.toCoin)))),n(t,71,0,l._32(t,71,0,l._22(t,72).transform("exchange.select"))),n(t,79,0,l._22(t,84).ngClassUntouched,l._22(t,84).ngClassTouched,l._22(t,84).ngClassPristine,l._22(t,84).ngClassDirty,l._22(t,84).ngClassValid,l._22(t,84).ngClassInvalid,l._22(t,84).ngClassPending),n(t,89,0,l._22(t,91).id,l._22(t,91).indeterminate,l._22(t,91).checked,l._22(t,91).disabled,"before"==l._22(t,91).labelPosition),n(t,92,0,l._32(t,92,0,l._22(t,93).transform("exchange.agree-1"))),n(t,95,0,l._32(t,95,0,l._22(t,96).transform("exchange.agree-2"))),n(t,97,0,l._32(t,97,0,l._22(t,98).transform("exchange.agree-3"))),n(t,100,0,l._32(t,100,0,l._22(t,101).transform("exchange.agree-4"))),n(t,106,0,l._32(t,106,0,l._22(t,107).transform("exchange.exchange-button")))})}function Dy(n){return l._33(0,[l._29(671088640,1,{exchangeButton:0}),(n()(),l._4(16777216,null,null,1,null,Cy)),l._8(2,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n"])),(n()(),l._4(16777216,null,null,1,null,Py)),l._8(5,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,!e.activeTradingPair),n(t,5,0,e.activeTradingPair)},null)}var Ay=this&&this.__assign||Object.assign||function(n){for(var t,e=1,l=arguments.length;e .-img[_ngcontent-%COMP%]{width:17px;margin-right:15px}.-item[_ngcontent-%COMP%]{font-size:13px}.-item[_ngcontent-%COMP%]:not(:last-child){margin-bottom:20px}.-item[_ngcontent-%COMP%] .-key[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);margin-bottom:5px}.-item[_ngcontent-%COMP%] .-value[_ngcontent-%COMP%]{word-break:break-all}.-item[_ngcontent-%COMP%] .-value[_ngcontent-%COMP%] .info-icon[_ngcontent-%COMP%]{display:inline;font-size:14px;color:rgba(121,135,152,.5);vertical-align:text-bottom}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.-external[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{line-height:13px;height:13px;width:13px;font-size:16px;vertical-align:middle;color:#0072ff;margin-left:10px}.expand[_ngcontent-%COMP%]{color:#0072ff;cursor:pointer;font-size:13px}.expand[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{color:#0072ff;padding:0;display:inline;vertical-align:middle;font-size:13px}.buttons[_ngcontent-%COMP%]{width:100%;text-align:center;margin-top:10px}"]],data:{}});function jy(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-loading-content",[["noDataText","exchange.order-not-found"]],null,null,null,Fg,Rg)),l._8(1,49152,null,0,Ig,[],{isLoading:[0,"isLoading"],noDataText:[1,"noDataText"]},null)],function(n,t){n(t,1,0,!t.component.showError,"exchange.order-not-found")},null)}function Iy(n){return l._33(0,[(n()(),l._9(0,0,null,null,13,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,0,"img",[["class","qr-code-button -img"],["src","../../../../../assets/img/qr-code-black.png"]],null,[[null,"click"]],function(n,t,e){var l=!0,r=n.component;return"click"===t&&(l=!1!==r.showQrCode(r.order.exchangeTag)&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,7,0,l._32(t,7,0,l._22(t,8).transform("exchange.details.exchange-addr-tag"))),n(t,11,0,e.order.exchangeTag)})}function Ry(n){return l._33(0,[(n()(),l._31(-1,null,["\n "])),(n()(),l._9(1,0,null,null,13,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(3,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(8,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(12,null,[""," ",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(16,0,null,null,13,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,0,"img",[["class","qr-code-button -img"],["src","../../../../../assets/img/qr-code-black.png"]],null,[[null,"click"]],function(n,t,e){var l=!0,r=n.component;return"click"===t&&(l=!1!==r.showQrCode(r.order.exchangeAddress)&&l),l},null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(23,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(26,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(27,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Iy)),l._8(32,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,32,0,t.component.order.exchangeTag)},function(n,t){var e=t.component;n(t,8,0,l._32(t,8,0,l._22(t,9).transform("exchange.you-send"))),n(t,12,0,e.order.fromAmount,e.fromCoin),n(t,23,0,l._32(t,23,0,l._22(t,24).transform("exchange.details.exchange-addr"))),n(t,27,0,e.order.exchangeAddress)})}function Hy(n){return l._33(0,[(n()(),l._9(0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function Ny(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Hy)),l._8(3,540672,null,0,H,[l.R],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,l._22(t.parent,55))},null)}function Fy(n){return l._33(0,[(n()(),l._9(0,0,null,null,20,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,15,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,8,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(11,null,["\n ","\n "])),(n()(),l._9(12,0,null,null,5,"a",[["class","-external"],["rel","noreferrer nofollow"],["target","_blank"]],[[8,"href",4]],null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(15,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["launch"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,15,0)},function(n,t){var e=t.component;n(t,7,0,l._32(t,7,0,l._22(t,8).transform("exchange.details.tx-id"))),n(t,11,0,e.order.toTx),n(t,12,0,e.appService.explorerUrl+"/transaction/"+e.order.toTx)})}function By(n){return l._33(0,[(n()(),l._9(0,0,null,null,13,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,7,0,l._32(t,7,0,l._22(t,8).transform("exchange.details.error-msg"))),n(t,11,0,e.order.message)})}function Vy(n){return l._33(0,[(n()(),l._9(0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function Wy(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Vy)),l._8(3,540672,null,0,H,[l.R],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,l._22(t.parent.parent,55))},null)}function zy(n){return l._33(0,[(n()(),l._9(0,0,null,null,67,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,14,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._27(14,1),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Wy)),l._8(19,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(21,0,null,null,14,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(23,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(27,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(28,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(31,0,null,null,2,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(32,null,[""," ",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(37,0,null,null,14,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(39,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(41,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(43,0,null,null,3,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(44,null,["",""])),l._26(45,{coin:0}),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(48,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(49,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(53,0,null,null,13,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(55,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(57,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(59,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(60,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(63,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(64,null,["1 "," \u2248 "," ",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,19,0,e.order.status!==e.statuses[0])},function(n,t){var e=t.component;n(t,9,0,l._32(t,9,0,l._22(t,10).transform("exchange.details.start-date"))),n(t,13,0,l._32(t,13,0,n(t,14,0,l._22(t.parent.parent,0),e._orderDetails.timestamp))),n(t,28,0,l._32(t,28,0,l._22(t,29).transform("exchange.you-get"))),n(t,32,0,l._32(t,32,0,l._22(t,33).transform(e.order.toAmount,!0,"first")),e.toCoin),n(t,44,0,l._32(t,44,0,l._22(t,46).transform("exchange.to-address",n(t,45,0,e.toCoin)))),n(t,49,0,e.order.toAddress),n(t,60,0,l._32(t,60,0,l._22(t,61).transform("exchange.details.initial-price"))),n(t,64,0,e.fromCoin,e._orderDetails.price,e.toCoin)})}function Uy(n){return l._33(0,[(n()(),l._9(0,0,null,null,82,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,31,"div",[["class","-wrapper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,23,"div",[["class","-status"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(7,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(8,{"-spin":0}),l._8(9,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(10,0,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,14,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,7,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(19,null,[""," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(21,16777216,null,null,4,"mat-icon",[["class","info-icon mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,23).show()&&r),"keydown"===t&&(r=!1!==l._22(n,23)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,23).hide(1500)&&r),r},Hf,Rf)),l._8(22,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(23,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(29,0,null,null,3,"span",[],null,null,null,null,null)),(n()(),l._31(30,null,["",""])),l._26(31,{from:0,to:1}),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(35,0,null,null,1,"mat-progress-bar",[["aria-valuemax","100"],["aria-valuemin","0"],["class","mat-progress-bar"],["role","progressbar"]],[[1,"aria-valuenow",0],[1,"mode",0],[2,"mat-primary",null],[2,"mat-accent",null],[2,"mat-warn",null]],null,null,u_,a_)),l._8(36,49152,null,0,Nu,[],{value:[0,"value"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(38,0,null,null,43,"div",[["class","-details"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(40,0,null,null,13,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(42,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(44,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(46,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(47,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(50,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(51,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(0,[["fromInfo",2]],null,0,null,Ry)),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Ny)),l._8(58,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Fy)),l._8(61,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,By)),l._8(64,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(66,0,null,null,11,"div",[["class","-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(68,0,null,null,0,"div",[["class","-img"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(70,0,null,null,6,"span",[["class","expand"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.toggleDetails()&&l),l},null,null)),(n()(),l._31(71,null,["\n "," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(73,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(74,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(75,0,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,zy)),l._8(80,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,7,0,n(t,8,0,"refresh"===e.statusIcon)),n(t,9,0),n(t,22,0),n(t,23,0,l._32(t,23,0,l._22(t,24).transform(e.translatedStatus.info))),n(t,36,0,e.progress),n(t,58,0,e.order.status===e.statuses[0]),n(t,61,0,e.order.status===e.statuses[5]),n(t,64,0,e.order.status===e.statuses[6]),n(t,74,0),n(t,80,0,e.expanded)},function(n,t){var e=t.component;n(t,10,0,e.statusIcon),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("exchange.status"))),n(t,19,0,l._32(t,19,0,l._22(t,20).transform(e.translatedStatus.text,e.translatedStatus.params))),n(t,30,0,l._32(t,30,0,l._22(t,32).transform("exchange.exchanging",n(t,31,0,e.fromCoin,e.toCoin)))),n(t,35,0,l._22(t,36).value,l._22(t,36).mode,"primary"==l._22(t,36).color,"accent"==l._22(t,36).color,"warn"==l._22(t,36).color),n(t,47,0,l._32(t,47,0,l._22(t,48).transform("exchange.details.order-id"))),n(t,51,0,e.order.id),n(t,71,0,l._32(t,71,0,l._22(t,72).transform("exchange.details.details"))),n(t,75,0,e.expanded?"keyboard_arrow_up":"keyboard_arrow_down")})}function Gy(n){return l._33(0,[l._25(0,ag,[]),(n()(),l._4(16777216,null,null,1,null,jy)),l._8(2,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n"])),(n()(),l._4(16777216,null,null,1,null,Uy)),l._8(5,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n"])),(n()(),l._9(7,0,null,null,6,"div",[["class","buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.close()&&l),l},w_,g_)),l._8(10,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(11,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.loading),n(t,5,0,!e.loading)},function(n,t){n(t,11,0,l._32(t,11,0,l._22(t,12).transform("exchange.details.back")))})}var qy=l._7({encapsulation:0,styles:[[".-paper[_ngcontent-%COMP%]{background-color:#fbfbfb;border-radius:10px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);padding:30px;margin:30px 30px 10px}.-contact[_ngcontent-%COMP%]{margin:15px 30px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.-contact[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{font-size:13px;margin:0 5px;opacity:.5;display:inline-block;vertical-align:middle}.-contact[_ngcontent-%COMP%] span[_ngcontent-%COMP%] a[_ngcontent-%COMP%]{text-decoration:none;color:#0072ff}.-contact[_ngcontent-%COMP%] .history[_ngcontent-%COMP%]{opacity:1}.-contact[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{font-size:18px;width:18px;height:18px;vertical-align:middle}.-contact[_ngcontent-%COMP%] .history-text[_ngcontent-%COMP%]{font-size:14px;opacity:1}"]],data:{}});function Jy(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-exchange-create",[],null,[[null,"submitted"]],function(n,t,e){var l=!0;return"submitted"===t&&(l=!1!==n.component.showStatus(e)&&l),l},Dy,ky)),l._8(1,245760,null,0,My,[pf,Sc,ns,jc,fa,qc,De.j],null,{submitted:"submitted"})],function(n,t){n(t,1,0)},null)}function Qy(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-exchange-status",[],null,[[null,"goBack"]],function(n,t,e){var l=!0;return"goBack"===t&&(l=!1!==n.component.goBack()&&l),l},Gy,Yy)),l._8(1,180224,null,0,Ey,[pf,fa,qc,gf],{orderDetails:[0,"orderDetails"]},{goBack:"goBack"})],function(n,t){n(t,1,0,t.component.currentOrderDetails)},null)}function Ky(n){return l._33(0,[(n()(),l._9(0,0,null,null,10,"span",[["class","history"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,7,"a",[["href","#"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.showHistory(e)&&l),l},null,null)),(n()(),l._9(3,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(4,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["history"])),(n()(),l._31(-1,null,[" "])),(n()(),l._9(7,0,null,null,2,"span",[["class","history-text"]],null,null,null,null,null)),(n()(),l._31(8,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,4,0)},function(n,t){n(t,8,0,l._32(t,8,0,l._22(t,9).transform("exchange.history")))})}function Xy(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(1,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(4,0,null,null,40,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,7,"div",[["class","-paper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Jy)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Qy)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,28,"div",[["class","-contact"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,null,null,4,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ky)),l._8(20,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(23,0,null,null,19,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,6,"span",[],null,null,null,null,null)),(n()(),l._31(26,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(28,0,null,null,2,"a",[["href","https://swaplabcc.freshdesk.com/support/home"],["rel","noreferrer nofollow"],["target","_blank"]],null,null,null,null,null)),(n()(),l._31(29,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(33,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(-1,null,["|"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(36,0,null,null,5,"span",[],null,null,null,null,null)),(n()(),l._31(37,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(39,0,null,null,1,"a",[["href","https://swaplab.cc"],["rel","noreferrer nofollow"],["target","_blank"]],null,null,null,null,null)),(n()(),l._31(-1,null,["SWAPLAB.CC"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform("title.exchange"))),n(t,9,0,!e.currentOrderDetails&&!e.loading),n(t,12,0,e.currentOrderDetails&&!e.loading),n(t,20,0,e.hasHistory)},function(n,t){n(t,26,0,l._32(t,26,0,l._22(t,27).transform("exchange.need-help"))),n(t,29,0,l._32(t,29,0,l._22(t,30).transform("exchange.support-portal"))),n(t,37,0,l._32(t,37,0,l._22(t,38).transform("exchange.powered-by")))})}var Zy=l._5("app-exchange",_f,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-exchange",[],null,null,null,Xy,qy)),l._8(1,245760,null,0,_f,[pf,fa],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),$y=l._7({encapsulation:0,styles:[[".-paper[_ngcontent-%COMP%]{background-color:#fbfbfb;border-radius:15px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);padding:20px;font-size:13px;margin:30px 30px 0}.-paper[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:first-child{margin-top:0}.-paper[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child{margin-bottom:0}.-text-muted[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}.-text-right[_ngcontent-%COMP%]{text-align:right}.-link[_ngcontent-%COMP%]{color:#0072ff;cursor:pointer}.-label[_ngcontent-%COMP%]{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}"]],data:{}});function nb(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-loading-content",[["noDataText","backup.no-wallets"]],null,null,null,Fg,Rg)),l._8(1,49152,null,0,Ig,[],{isLoading:[0,"isLoading"],noDataText:[1,"noDataText"]},null)],function(n,t){n(t,1,0,!1,"backup.no-wallets")},null)}function tb(n){return l._33(0,[(n()(),l._9(0,0,null,null,14,"div",[["class","-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"div",[["class","-width-250 -label"]],[[1,"title",0]],null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,1,"div",[["class","-width-150"]],null,null,null,null,null)),(n()(),l._31(6,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,5,"div",[["class","-flex-fill -text-right"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"span",[["class","-link"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.showSeed(n.context.$implicit)&&l),l},null,null)),(n()(),l._31(11,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,2,0,t.context.$implicit.label),n(t,3,0,t.context.$implicit.label),n(t,6,0,t.context.$implicit.filename),n(t,11,0,l._32(t,11,0,l._22(t,12).transform("backup.show-seed")))})}function eb(n){return l._33(0,[(n()(),l._9(0,0,null,null,20,"div",[["class","-table"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,11,"div",[["class","-headers"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"div",[["class","-width-250"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,2,"div",[["class","-width-150"]],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,0,"div",[["class","-flex-fill"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,4,"div",[["class","-body"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,tb)),l._8(18,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,18,0,t.component.onlyEncrypted)},function(n,t){n(t,5,0,l._32(t,5,0,l._22(t,6).transform("backup.wallet"))),n(t,9,0,l._32(t,9,0,l._22(t,10).transform("backup.filename")))})}function lb(n){return l._33(0,[(n()(),l._9(0,0,null,null,31,"div",[["class","sky-container sky-container-grey"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(3,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(6,0,null,null,24,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,15,"div",[["class","-paper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(11,null,[""," ",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,4,"p",[["class","-text-muted"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,1,"small",[],[[8,"innerHTML",1]],null,null,null,null)),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,nb)),l._8(26,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,eb)),l._8(29,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,l._22(t,4).transform("title.backup"))),n(t,26,0,0===e.onlyEncrypted.length),n(t,29,0,e.onlyEncrypted.length>0)},function(n,t){var e=t.component;n(t,11,0,l._32(t,11,0,l._22(t,12).transform("backup.wallet-directory")),e.folder),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("backup.seed-warning"))),n(t,20,0,l._32(t,20,0,l._22(t,21).transform("backup.desc")))})}var rb=l._5("app-backup",$p,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-backup",[],null,null,null,lb,$y)),l._8(1,245760,null,0,$p,[Sc,fa],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),ib=l._7({encapsulation:0,styles:[[".-wrapper[_ngcontent-%COMP%]{margin:30px}.-paper[_ngcontent-%COMP%]{background-color:#fbfbfb;border-radius:15px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);padding:20px;font-size:13px}.-item[_ngcontent-%COMP%]:not(:last-child){margin-bottom:20px}.-item[_ngcontent-%COMP%] .-key[_ngcontent-%COMP%]{color:rgba(30,34,39,.5);margin-bottom:5px}.-item[_ngcontent-%COMP%] .-value[_ngcontent-%COMP%]{word-break:break-all}"]],data:{}});function ob(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-loading-content",[],null,null,null,Fg,Rg)),l._8(1,49152,null,0,Ig,[],null,null)],null,null)}function sb(n){return l._33(0,[(n()(),l._9(0,0,null,null,101,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,98,"div",[["class","row -wrapper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,36,"div",[["class","col-md-6"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,33,"div",[["class","-paper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._27(16,1),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(19,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(21,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(22,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,2,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(26,null,["",""])),l._27(27,1),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(30,0,null,null,8,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(32,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(33,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(36,0,null,null,1,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(37,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(42,0,null,null,57,"div",[["class","col-md-6"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(44,0,null,null,54,"div",[["class","-paper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(46,0,null,null,51,"div",[["class","row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(48,0,null,null,23,"div",[["class","col-md-6"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(50,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(52,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(53,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(56,0,null,null,2,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(57,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(61,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(63,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(64,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(67,0,null,null,2,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(68,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(73,0,null,null,23,"div",[["class","col-md-6"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(75,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(77,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(78,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(81,0,null,null,2,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(82,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(86,0,null,null,9,"div",[["class","-item"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(88,0,null,null,2,"div",[["class","-key"]],null,null,null,null,null)),(n()(),l._31(89,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(92,0,null,null,2,"div",[["class","-value"]],null,null,null,null,null)),(n()(),l._31(93,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,11,0,l._32(t,11,0,l._22(t,12).transform("blockchain.blocks"))),n(t,15,0,l._32(t,15,0,n(t,16,0,l._22(t.parent,0),e.block.header.seq))),n(t,22,0,l._32(t,22,0,l._22(t,23).transform("blockchain.time"))),n(t,26,0,l._32(t,26,0,n(t,27,0,l._22(t.parent,1),e.block.header.timestamp))),n(t,33,0,l._32(t,33,0,l._22(t,34).transform("blockchain.hash"))),n(t,37,0,e.block.header.block_hash),n(t,53,0,l._32(t,53,0,l._22(t,54).transform("blockchain.current-supply"))),n(t,57,0,l._32(t,57,0,l._22(t,58).transform(e.coinSupply.current_supply,!0,"first"))),n(t,64,0,l._32(t,64,0,l._22(t,65).transform("blockchain.total-supply"))),n(t,68,0,l._32(t,68,0,l._22(t,69).transform(e.coinSupply.total_supply,!0,"first"))),n(t,78,0,l._32(t,78,0,l._22(t,79).transform("blockchain.current-coinhour-supply"))),n(t,82,0,l._32(t,82,0,l._22(t,83).transform(e.coinSupply.current_coinhour_supply,!1,"first"))),n(t,89,0,l._32(t,89,0,l._22(t,90).transform("blockchain.total-coinhour-supply"))),n(t,93,0,l._32(t,93,0,l._22(t,94).transform(e.coinSupply.total_coinhour_supply,!1,"first")))})}function ab(n){return l._33(0,[l._25(0,tn,[l.w]),l._25(0,ag,[]),(n()(),l._9(2,0,null,null,11,"div",[["class","sky-container sky-container-grey"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(5,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,ob)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,sb)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,5,0,l._32(t,5,0,l._22(t,6).transform("title.blockchain"))),n(t,9,0,!(e.block&&e.block.header&&e.coinSupply)),n(t,12,0,e.block&&e.block.header&&e.coinSupply)},null)}var ub=l._5("app-blockchain",Kp,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-blockchain",[],null,null,null,ab,ib)),l._8(1,245760,null,0,Kp,[qc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),cb=function(){function n(n){this.translateService=n}return n.prototype.transform=function(n){var t=zp().unix()-n;return t<60?this.translateService.instant("time-from-now.few-seconds"):t<120?this.translateService.instant("time-from-now.minute"):t<3600?this.translateService.instant("time-from-now.minutes",{time:Math.floor(t/60)}):t<7200?this.translateService.instant("time-from-now.hour"):t<86400?this.translateService.instant("time-from-now.hours",{time:Math.floor(t/3600)}):t<172800?this.translateService.instant("time-from-now.day"):this.translateService.instant("time-from-now.days",{time:Math.floor(t/86400)})},n}(),db=l._7({encapsulation:0,styles:[[".-last-seen[_ngcontent-%COMP%], .-port[_ngcontent-%COMP%], .-source[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}.-direction[_ngcontent-%COMP%]{width:72px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-negative:0;flex-shrink:0}.-direction[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{width:32px}.-direction[_ngcontent-%COMP%] img.-incoming[_ngcontent-%COMP%]{-webkit-transform:scaleX(-1);transform:scaleX(-1)}.-last-seen[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;font-size:12px;line-height:1;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.-last-seen[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{font-size:12px;display:inline;vertical-align:middle;padding-right:5px}.-trusted[_ngcontent-%COMP%]{display:inline;color:#0072ff;font-size:13px;vertical-align:middle}.-text-right[_ngcontent-%COMP%]{text-align:right}.-pl-0[_ngcontent-%COMP%]{padding-left:0!important}.-block-row[_ngcontent-%COMP%]{width:150px;-ms-flex-negative:0;flex-shrink:0}.-invisible[_ngcontent-%COMP%]{display:none}@media (max-width:991px){.-pl-0[_ngcontent-%COMP%]{width:160px!important}.-block-row[_ngcontent-%COMP%]{width:90px;-ms-flex-negative:0;flex-shrink:0}}"]],data:{}});function hb(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-loading-content",[],null,null,null,Fg,Rg)),l._8(1,49152,null,0,Ig,[],null,null)],null,null)}function pb(n){return l._33(0,[(n()(),l._9(0,0,null,null,46,"div",[["class","-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,7,"div",[["class","-direction"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,16777216,null,null,4,"img",[["src","/assets/img/send-blue.png"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,7).show()&&r),"keydown"===t&&(r=!1!==l._22(n,7)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,7).hide(1500)&&r),r},null,null)),l._8(5,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(6,{"-incoming":0}),l._8(7,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,4,"div",[["class","-width-200 -pl-0"]],null,null,null,null,null)),(n()(),l._31(12,null,["\n ",""])),(n()(),l._9(13,0,null,null,1,"span",[["class","-port"]],null,null,null,null,null)),(n()(),l._31(14,null,[":",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,null,null,2,"div",[["class","-flex-fill -source"]],null,null,null,null,null)),(n()(),l._31(18,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(21,0,null,null,1,"div",[["class","-block-row -text-right"]],null,null,null,null,null)),(n()(),l._31(22,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,0,null,null,21,"div",[["class","-width-200 -last-seen"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(26,0,null,null,8,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,30).show()&&r),"keydown"===t&&(r=!1!==l._22(n,30)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,30).hide(1500)&&r),r},Hf,Rf)),l._8(29,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(30,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["keyboard_arrow_up"])),(n()(),l._31(33,null,["\n ","\n "])),l._25(0,cb,[De.j]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(36,0,null,null,8,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(38,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,40).show()&&r),"keydown"===t&&(r=!1!==l._22(n,40)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,40).hide(1500)&&r),r},Hf,Rf)),l._8(39,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(40,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["keyboard_arrow_down"])),(n()(),l._31(43,null,["\n ","\n "])),l._25(0,cb,[De.j]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,5,0,n(t,6,0,!t.context.$implicit.outgoing)),n(t,7,0,l._32(t,7,0,l._22(t,8).transform(t.context.$implicit.outgoing?"network.out":"network.in"))),n(t,29,0),n(t,30,0,l._32(t,30,0,l._22(t,31).transform("network.last-sent"))),n(t,39,0),n(t,40,0,l._32(t,40,0,l._22(t,41).transform("network.last-received")))},function(n,t){n(t,12,0,t.context.$implicit.address.split(":")[0]),n(t,14,0,t.context.$implicit.listen_port),n(t,18,0,l._32(t,18,0,l._22(t,19).transform("network.sources."+t.context.$implicit.source))),n(t,22,0,t.context.$implicit.height),n(t,33,0,l._32(t,33,0,l._22(t,34).transform(t.context.$implicit.last_sent))),n(t,43,0,l._32(t,43,0,l._22(t,44).transform(t.context.$implicit.last_received)))})}function fb(n){return l._33(0,[(n()(),l._9(0,0,null,null,35,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,32,"div",[["class","-table"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,23,"div",[["class","-headers"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,0,"div",[["class","-direction"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,2,"div",[["class","-width-200 -pl-0"]],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"div",[["class","-flex-fill"]],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,2,"div",[["class","d-lg-block -invisible -block-row -text-right"]],null,null,null,null,null)),(n()(),l._31(17,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,2,"div",[["class","d-lg-none -block-row -text-right"]],null,null,null,null,null)),(n()(),l._31(21,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,0,null,null,2,"div",[["class","-width-200"]],null,null,null,null,null)),(n()(),l._31(25,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(29,0,null,null,4,"div",[["class","-body"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,pb)),l._8(32,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,32,0,t.component.peers)},function(n,t){n(t,9,0,l._32(t,9,0,l._22(t,10).transform("network.peer"))),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("network.source"))),n(t,17,0,l._32(t,17,0,l._22(t,18).transform("network.block-height"))),n(t,21,0,l._32(t,21,0,l._22(t,22).transform("network.block-height-short"))),n(t,25,0,l._32(t,25,0,l._22(t,26).transform("network.last-seen")))})}function _b(n){return l._33(0,[(n()(),l._9(0,0,null,null,11,"div",[["class","sky-container sky-container-grey"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(3,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,hb)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,fb)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,l._22(t,4).transform("title.network"))),n(t,7,0,!e.peers),n(t,10,0,e.peers)},null)}var mb=l._5("app-network",tf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-network",[],null,null,null,_b,db)),l._8(1,245760,null,0,tf,[nf],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),gb=l._7({encapsulation:0,styles:[[".-text-right[_ngcontent-%COMP%]{text-align:right}.-grey[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}.-hash[_ngcontent-%COMP%]{margin-left:27px;word-break:break-all}.-address[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}.-address[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{width:17px;vertical-align:middle;margin-right:10px}.-label[_ngcontent-%COMP%]{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}"]],data:{}});function yb(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-loading-content",[["noDataText","errors.no-outputs"]],null,null,null,Fg,Rg)),l._8(1,49152,null,0,Ig,[],{isLoading:[0,"isLoading"],noDataText:[1,"noDataText"]},null)],function(n,t){n(t,1,0,!t.component.wallets,"errors.no-outputs")},null)}function bb(n){return l._33(0,[(n()(),l._9(0,0,null,null,12,"div",[["class","-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"div",[["class","-flex-fill -hash"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,2,"div",[["class","-width-150 -text-right"]],null,null,null,null,null)),(n()(),l._31(6,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,2,"div",[["class","-width-150 -text-right -grey"]],null,null,null,null,null)),(n()(),l._31(10,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,t.context.$implicit.hash),n(t,6,0,l._32(t,6,0,l._22(t,7).transform(t.context.$implicit.coins,!0,"first"))),n(t,10,0,l._32(t,10,0,l._22(t,11).transform(t.context.$implicit.calculated_hours,!1,"first")))})}function vb(n){return l._33(0,[(n()(),l._9(0,0,null,null,12,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,6,"div",[["class","-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,3,"div",[["class","-flex-fill -address"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,0,"img",[["class","qr-code-button"],["src","../../../../../assets/img/qr-code-black.png"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.showQrCode(e,n.context.$implicit.address)&&l),l},null,null)),(n()(),l._31(7,null,["\n ","\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,bb)),l._8(11,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,11,0,t.context.$implicit.outputs)},function(n,t){n(t,7,0,t.context.$implicit.address)})}function wb(n){return l._33(0,[(n()(),l._9(0,0,null,null,21,"div",[["class","-table"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,12,"div",[["class","-headers"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,1,"div",[["class","-flex-fill -label"]],[[1,"title",0]],null,null,null,null)),(n()(),l._31(5,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,2,"div",[["class","-width-150 -text-right"]],null,null,null,null,null)),(n()(),l._31(8,null,["",""])),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,2,"div",[["class","-width-150 -text-right"]],null,null,null,null,null)),(n()(),l._31(12,null,["",""])),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,4,"div",[["class","-body"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,vb)),l._8(19,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,19,0,t.context.$implicit.addresses)},function(n,t){n(t,4,0,t.context.$implicit.label),n(t,5,0,t.context.$implicit.label),n(t,8,0,l._32(t,8,0,l._22(t,9).transform("coin"))),n(t,12,0,l._32(t,12,0,l._22(t,13).transform("hours")))})}function xb(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,wb)),l._8(3,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.component.wallets)},null)}function Mb(n){return l._33(0,[(n()(),l._9(0,0,null,null,11,"div",[["class","sky-container sky-container-grey"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(3,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,yb)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,xb)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,l._22(t,4).transform("title.outputs"))),n(t,7,0,!e.wallets||0===e.wallets.length||0===e.wallets[0].addresses[0].outputs.length),n(t,10,0,e.wallets&&e.wallets.length>0)},null)}var kb=l._5("app-outputs",Jp,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-outputs",[],null,null,null,Mb,gb)),l._8(1,180224,null,0,Jp,[Sc,Ch,fa],null,null)],null,null)},{},{},[]),Cb=l._7({encapsulation:0,styles:[[".-timestamp[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}.-txid[_ngcontent-%COMP%]{word-break:break-all}"]],data:{}});function Sb(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-loading-content",[["noDataText","pending-txs.none"]],null,null,null,Fg,Rg)),l._8(1,49152,null,0,Ig,[],{isLoading:[0,"isLoading"],noDataText:[1,"noDataText"]},null)],function(n,t){n(t,1,0,!t.component.transactions,"pending-txs.none")},null)}function Ob(n){return l._33(0,[(n()(),l._9(0,0,null,null,16,"div",[["class","-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"div",[["class","-flex-fill -txid"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,2,"div",[["class","-width-150"]],null,null,null,null,null)),(n()(),l._31(6,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,2,"div",[["class","-width-150"]],null,null,null,null,null)),(n()(),l._31(10,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,2,"div",[["class","-width-150 -timestamp"]],null,null,null,null,null)),(n()(),l._31(14,null,["",""])),l._27(15,1),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,t.context.$implicit.txid),n(t,6,0,l._32(t,6,0,l._22(t,7).transform(t.context.$implicit.amount,!0,"first"))),n(t,10,0,l._32(t,10,0,l._22(t,11).transform(t.context.$implicit.hours,!1,"first"))),n(t,14,0,l._32(t,14,0,n(t,15,0,l._22(t.parent.parent,0),t.context.$implicit.timestamp)))})}function Tb(n){return l._33(0,[(n()(),l._9(0,0,null,null,29,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,26,"div",[["class","-table"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,17,"div",[["class","-headers"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,2,"div",[["class","-flex-fill"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,2,"div",[["class","-width-150"]],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,2,"div",[["class","-width-150"]],null,null,null,null,null)),(n()(),l._31(15,null,["",""])),l._25(0,l_,[gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,2,"div",[["class","-width-150"]],null,null,null,null,null)),(n()(),l._31(19,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(23,0,null,null,4,"div",[["class","-body"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ob)),l._8(26,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,26,0,t.component.transactions)},function(n,t){n(t,7,0,l._32(t,7,0,l._22(t,8).transform("pending-txs.txid"))),n(t,11,0,l._32(t,11,0,l._22(t,12).transform("coin"))),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("hours"))),n(t,19,0,l._32(t,19,0,l._22(t,20).transform("pending-txs.timestamp")))})}function Lb(n){return l._33(0,[l._25(0,ag,[]),(n()(),l._9(1,0,null,null,11,"div",[["class","sky-container sky-container-grey"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(3,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(4,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Sb)),l._8(8,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Tb)),l._8(11,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,4,0,l._32(t,4,0,l._22(t,5).transform("title.pending-txs"))),n(t,8,0,!e.transactions||0===e.transactions.length),n(t,11,0,e.transactions&&e.transactions.length>0)},null)}var Pb=l._5("app-pending-transactions",Up,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-pending-transactions",[],null,null,null,Lb,Cb)),l._8(1,245760,null,0,Up,[Sc,Vp],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),Db=function(){function n(n){this.el=n,n.nativeElement.autocomplete="new-password",n.nativeElement.readOnly=!0}return n.prototype.onFocus=function(){this.el.nativeElement.readOnly=!1},n}(),Ab=l._7({encapsulation:0,styles:[[".dashed-border[_ngcontent-%COMP%]{border:1px dashed rgba(0,0,0,.25)}.show-pointer[_ngcontent-%COMP%]{cursor:pointer}.non-editable-field[_ngcontent-%COMP%]{font-size:12px;text-align:center;padding:15px;border-radius:6px;color:#171a1d}.non-editable-field[_ngcontent-%COMP%] .text-with-icon-container[_ngcontent-%COMP%]{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.non-editable-field[_ngcontent-%COMP%] .text-with-icon-container[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{margin-right:5px;opacity:1}.non-editable-field[_ngcontent-%COMP%] .text-with-icon-container[_ngcontent-%COMP%] .green[_ngcontent-%COMP%]{color:#00df80}.non-editable-field[_ngcontent-%COMP%] .text-with-icon-container[_ngcontent-%COMP%] .yellow[_ngcontent-%COMP%]{color:#ffc125}.normal-seed-field[_ngcontent-%COMP%]{font-size:14px}.seed-type-button[_ngcontent-%COMP%]{width:100%;height:10px;text-align:right}.seed-type-button[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]{display:inline-block;width:32px;height:32px;position:relative;left:16px;top:-10px;background-color:#fff;border-radius:100px;cursor:pointer}.seed-type-button[_ngcontent-%COMP%] > div[_ngcontent-%COMP%] > img[_ngcontent-%COMP%]{width:32px;height:32px}.onboarding-version[_ngcontent-%COMP%]{border:1px dashed rgba(255,255,255,.5);color:#fff}.transparent-text[_ngcontent-%COMP%]{opacity:.75}.red-disclaimer-box[_ngcontent-%COMP%]{color:#ff004e;font-size:12px;padding:0 10px;line-height:1.5}.white-disclaimer-box[_ngcontent-%COMP%]{color:#fafafa;font-size:12px;padding:0 10px;line-height:1.5}label[for=seed][_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex}label[for=seed][_ngcontent-%COMP%] > span[_ngcontent-%COMP%]:last-child{-webkit-box-flex:1;-ms-flex:1;flex:1}label[for=seed][_ngcontent-%COMP%] .generators[_ngcontent-%COMP%]{text-align:right}label[for=seed][_ngcontent-%COMP%] .generators[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{cursor:pointer;color:#0072ff}label[for=seed][_ngcontent-%COMP%] .generators[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{width:13px;height:10px;font-size:13px;position:relative;top:2px}label[for=seed][_ngcontent-%COMP%] .generators[_ngcontent-%COMP%] .divider[_ngcontent-%COMP%]{padding:0 5px;color:#1e2227}label[for=seed][_ngcontent-%COMP%] .-white-text[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:#fff!important}.-passwords[_ngcontent-%COMP%]{margin-left:24px}.-passwords[_ngcontent-%COMP%] .-info[_ngcontent-%COMP%]{margin:5px 0 15px;color:rgba(30,34,39,.5);font-size:12px;line-height:1.5}.-check[_ngcontent-%COMP%] .mat-checkbox-checkmark-path{position:absolute;width:18px;height:8px;left:4.59px;top:9px;stroke:#0072ff!important}.-check[_ngcontent-%COMP%] .mat-checkbox-background, .-check[_ngcontent-%COMP%] .mat-checkbox-frame{top:0;left:0;right:0;bottom:0;position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;pointer-events:none;width:20px;height:20px;background:rgba(30,34,39,.05);border-radius:6px;border-color:transparent}.-check[_ngcontent-%COMP%] span{font-family:Skycoin;line-height:normal;font-size:14px;color:#1e2227}.-check[_ngcontent-%COMP%] span img{width:38px;height:38px;vertical-align:middle}"]],data:{}});function Eb(n){return l._33(0,[(n()(),l._9(0,0,null,null,28,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"label",[["for","number_of_words"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,21,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,18,"select",[["formControlName","number_of_words"],["id","number_of_words"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(n,t,e){var r=!0;return"change"===t&&(r=!1!==l._22(n,9).onChange(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,9).onTouched()&&r),r},null,null)),l._8(9,16384,null,0,_o,[l.G,l.l],null,null),l._28(1024,null,to,function(n){return[n]},[_o]),l._8(11,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(13,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,4,"option",[],null,null,null,null,null)),l._8(16,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(17,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(18,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(21,0,null,null,4,"option",[],null,null,null,null,null)),l._8(22,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(23,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(24,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,11,0,"number_of_words"),n(t,16,0,12),n(t,17,0,12),n(t,22,0,24),n(t,23,0,24)},function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("wallet.new.words-number"))),n(t,8,0,l._22(t,13).ngClassUntouched,l._22(t,13).ngClassTouched,l._22(t,13).ngClassPristine,l._22(t,13).ngClassDirty,l._22(t,13).ngClassValid,l._22(t,13).ngClassInvalid,l._22(t,13).ngClassPending),n(t,18,0,l._32(t,18,0,l._22(t,19).transform("wallet.new.12-words"))),n(t,24,0,l._32(t,24,0,l._22(t,25).transform("wallet.new.24-words")))})}function Yb(n){return l._33(0,[(n()(),l._9(0,0,null,null,18,"span",[["class","generators"]],null,null,null,null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(2,{"-white-text":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,16777216,null,null,4,"span",[],null,[[null,"click"],[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0,i=n.component;return"longpress"===t&&(r=!1!==l._22(n,5).show()&&r),"keydown"===t&&(r=!1!==l._22(n,5)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,5).hide(1500)&&r),"click"===t&&(r=!1!==i.generateSeed(128)&&r),r},null,null)),l._8(5,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(7,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,1,"span",[["class","divider"]],null,null,null,null,null)),(n()(),l._31(-1,null,["|"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,16777216,null,null,4,"span",[],null,[[null,"click"],[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0,i=n.component;return"longpress"===t&&(r=!1!==l._22(n,14).show()&&r),"keydown"===t&&(r=!1!==l._22(n,14)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,14).hide(1500)&&r),"click"===t&&(r=!1!==i.generateSeed(256)&&r),r},null,null)),l._8(14,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(16,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,1,0,"generators",n(t,2,0,t.component.onboarding)),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("wallet.new.generate-12-seed"))),n(t,14,0,l._32(t,14,0,l._22(t,15).transform("wallet.new.generate-24-seed")))},function(n,t){n(t,7,0,l._32(t,7,0,l._22(t,8).transform("wallet.new.12-words"))),n(t,16,0,l._32(t,16,0,l._22(t,17).transform("wallet.new.24-words")))})}function jb(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[["class","normal-seed-field"]],null,null,null,null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.component.lastAssistedSeed)})}function Ib(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[],null,null,null,null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(2,{"transparent-text":0}),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,n(t,2,0,t.component.onboarding))},function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("wallet.new.seed.change-seed")))})}function Rb(n){return l._33(0,[(n()(),l._9(0,0,null,null,10,"div",[["class","text-with-icon-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"mat-icon",[["class","yellow mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(3,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["touch_app"])),(n()(),l._9(5,0,null,null,4,"span",[],null,null,null,null,null)),l._8(6,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(7,{"transparent-text":0}),(n()(),l._31(8,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0),n(t,6,0,n(t,7,0,e.onboarding))},function(n,t){n(t,8,0,l._32(t,8,0,l._22(t,9).transform("wallet.new.seed.enter-seed")))})}function Hb(n){return l._33(0,[(n()(),l._9(0,0,null,null,27,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,12,"div",[["class","dashed-border non-editable-field"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.enterSeed()&&l),l},null,null)),l._8(3,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(4,{"onboarding-version":0,"show-pointer":1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,jb)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ib)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Rb)),l._8(13,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,10,"div",[["class","seed-type-button"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(18,0,null,null,7,"div",[],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.changeSeedType()&&l),l},null,null)),l._8(19,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(20,{"dashed-border":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,16777216,null,null,2,"img",[["src","../../../../assets/img/lock-gold.png"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,23).show()&&r),"keydown"===t&&(r=!1!==l._22(n,23)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,23).hide(1500)&&r),r},null,null)),l._8(23,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,"dashed-border non-editable-field",n(t,4,0,e.onboarding,!e.create)),n(t,7,0,e.create||e.lastAssistedSeed),n(t,10,0,!e.create&&e.lastAssistedSeed),n(t,13,0,!e.create&&!e.lastAssistedSeed),n(t,19,0,n(t,20,0,!e.onboarding)),n(t,23,0,l._32(t,23,0,l._22(t,24).transform("wallet.new.seed.use-custom-seed")))},null)}function Nb(n){return l._33(0,[(n()(),l._9(0,0,null,null,20,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,5,"textarea",[["formControlName","seed"],["id","seed"],["rows","2"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,3)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,3).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,3)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,3)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(3,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(5,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(7,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,10,"div",[["class","seed-type-button"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,7,"div",[],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.changeSeedType()&&l),l},null,null)),l._8(12,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(13,{"dashed-border":0}),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,16777216,null,null,2,"img",[["src","../../../../assets/img/unlock-grey.png"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,16).show()&&r),"keydown"===t&&(r=!1!==l._22(n,16)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,16).hide(1500)&&r),r},null,null)),l._8(16,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,5,0,"seed"),n(t,12,0,n(t,13,0,!e.onboarding)),n(t,16,0,l._32(t,16,0,l._22(t,17).transform("wallet.new.seed.use-normal-seed")))},function(n,t){n(t,2,0,l._22(t,7).ngClassUntouched,l._22(t,7).ngClassTouched,l._22(t,7).ngClassPristine,l._22(t,7).ngClassDirty,l._22(t,7).ngClassValid,l._22(t,7).ngClassInvalid,l._22(t,7).ngClassPending)})}function Fb(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"p",[],null,null,null,null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(2,{"red-disclaimer-box":0,"white-disclaimer-box transparent-text":1}),(n()(),l._31(3,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,n(t,2,0,!e.onboarding,e.onboarding))},function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("wallet.new.seed-warning")))})}function Bb(n){return l._33(0,[(n()(),l._9(0,0,null,null,10,"div",[["class","text-with-icon-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"mat-icon",[["class","yellow mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(3,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["touch_app"])),(n()(),l._9(5,0,null,null,4,"span",[],null,null,null,null,null)),l._8(6,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(7,{"transparent-text":0}),(n()(),l._31(8,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0),n(t,6,0,n(t,7,0,e.onboarding))},function(n,t){n(t,8,0,l._32(t,8,0,l._22(t,9).transform("wallet.new.seed.confirm-seed")))})}function Vb(n){return l._33(0,[(n()(),l._9(0,0,null,null,11,"div",[["class","text-with-icon-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"mat-icon",[["class","green mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(3,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["done"])),(n()(),l._31(-1,null,[" "])),(n()(),l._9(6,0,null,null,4,"span",[],null,null,null,null,null)),l._8(7,278528,null,0,O,[l.u,l.v,l.l,l.G],{ngClass:[0,"ngClass"]},null),l._26(8,{"transparent-text":0}),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0),n(t,7,0,n(t,8,0,e.onboarding))},function(n,t){n(t,9,0,l._32(t,9,0,l._22(t,10).transform("wallet.new.seed.confirmed-seed")))})}function Wb(n){return l._33(0,[(n()(),l._9(0,0,null,null,12,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,9,"div",[["class","dashed-border non-editable-field"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.confirmNormalSeed()&&l),l},null,null)),l._8(3,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(4,{"onboarding-version":0,"show-pointer":1}),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Bb)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Vb)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,"dashed-border non-editable-field",n(t,4,0,e.onboarding,!e.assistedSeedConfirmed)),n(t,7,0,!e.assistedSeedConfirmed),n(t,10,0,e.assistedSeedConfirmed)},null)}function zb(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,5,"textarea",[["formControlName","confirm_seed"],["id","confirm_seed"],["rows","2"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,3)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,3).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,3)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,3)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(3,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(5,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(7,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,5,0,"confirm_seed")},function(n,t){n(t,2,0,l._22(t,7).ngClassUntouched,l._22(t,7).ngClassTouched,l._22(t,7).ngClassPristine,l._22(t,7).ngClassDirty,l._22(t,7).ngClassValid,l._22(t,7).ngClassInvalid,l._22(t,7).ngClassPending)})}function Ub(n){return l._33(0,[(n()(),l._9(0,0,null,null,11,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"label",[["for","confirm_seed"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Wb)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,zb)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,7,0,e.enterSeedWithAssistance),n(t,10,0,!e.enterSeedWithAssistance)},function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("wallet.new.confirm-seed-label")))})}function Gb(n){return l._33(0,[(n()(),l._9(0,0,null,null,16,"div",[["class","col-md-6"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,13,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"label",[["for","password"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,6,"input",[["appDontSavePassword",""],["formControlName","password"],["id","password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"focus"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,9)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,9).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,9)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,9)._compositionEnd(e.target.value)&&r),"focus"===t&&(r=!1!==l._22(n,14).onFocus()&&r),r},null,null)),l._8(9,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(11,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(13,16384,null,0,Eo,[uo],null,null),l._8(14,16384,null,0,Db,[l.l],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,11,0,"password")},function(n,t){n(t,5,0,l._32(t,5,0,l._22(t,6).transform("password.label"))),n(t,8,0,l._22(t,13).ngClassUntouched,l._22(t,13).ngClassTouched,l._22(t,13).ngClassPristine,l._22(t,13).ngClassDirty,l._22(t,13).ngClassValid,l._22(t,13).ngClassInvalid,l._22(t,13).ngClassPending)})}function qb(n){return l._33(0,[(n()(),l._9(0,0,null,null,16,"div",[["class","col-md-6"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,13,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,2,"label",[["for","confirm_password"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,6,"input",[["appDontSavePassword",""],["formControlName","confirm_password"],["id","confirm_password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"focus"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,9)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,9).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,9)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,9)._compositionEnd(e.target.value)&&r),"focus"===t&&(r=!1!==l._22(n,14).onFocus()&&r),"keydown.enter"===t&&(r=!1!==i.createWallet()&&r),r},null,null)),l._8(9,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(11,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(13,16384,null,0,Eo,[uo],null,null),l._8(14,16384,null,0,Db,[l.l],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,11,0,"confirm_password")},function(n,t){n(t,5,0,l._32(t,5,0,l._22(t,6).transform("password.confirm-label"))),n(t,8,0,l._22(t,13).ngClassUntouched,l._22(t,13).ngClassTouched,l._22(t,13).ngClassPristine,l._22(t,13).ngClassDirty,l._22(t,13).ngClassValid,l._22(t,13).ngClassInvalid,l._22(t,13).ngClassPending)})}function Jb(n){return l._33(0,[(n()(),l._9(0,0,null,null,28,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,9,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(4,0,null,null,6,"mat-checkbox",[["class","-check mat-checkbox"],["id","encrypt"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setEncrypt(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(6,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{id:[0,"id"],checked:[1,"checked"]},{change:"change"}),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(8,0,null,0,0,"img",[["src","../../../../../assets/img/lock-gold.png"]],null,null,null,null,null)),(n()(),l._31(9,0,[" ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,14,"div",[["class","row -passwords"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,5,"div",[["class","col-md-12"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,null,null,2,"p",[["class","-info"]],null,null,null,null,null)),(n()(),l._31(18,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Gb)),l._8(23,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,qb)),l._8(26,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,6,0,"encrypt",!0),n(t,23,0,e.encrypt),n(t,26,0,e.encrypt)},function(n,t){n(t,4,0,l._22(t,6).id,l._22(t,6).indeterminate,l._22(t,6).checked,l._22(t,6).disabled,"before"==l._22(t,6).labelPosition),n(t,9,0,l._32(t,9,0,l._22(t,10).transform("wallet.new.encrypt"))),n(t,18,0,l._32(t,18,0,l._22(t,19).transform("wallet.new.encrypt-warning")))})}function Qb(n){return l._33(0,[(n()(),l._9(0,0,null,null,22,"div",[["class","alert-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(3,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["error"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,15,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,2,"div",[["class","title"]],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"div",[],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,4,"mat-checkbox",[["class","-check mat-checkbox"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.onCustomSeedAcceptance(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(18,4374528,[["seedCheck",4]],0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{checked:[0,"checked"]},{change:"change"}),(n()(),l._31(19,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0),n(t,18,0,e.customSeedAccepted)},function(n,t){n(t,9,0,l._32(t,9,0,l._22(t,10).transform("wallet.new.unconventional-seed-title"))),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("wallet.new.unconventional-seed-text"))),n(t,16,0,l._22(t,18).id,l._22(t,18).indeterminate,l._22(t,18).checked,l._22(t,18).disabled,"before"==l._22(t,18).labelPosition),n(t,19,0,l._32(t,19,0,l._22(t,20).transform("wallet.new.unconventional-seed-check")))})}function Kb(n){return l._33(0,[(n()(),l._9(0,0,null,null,49,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,1).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,1).onReset()&&r),r},null,null)),l._8(1,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(3,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,12,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,2,"label",[["for","label"]],null,null,null,null,null)),(n()(),l._31(8,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,5,"input",[["formControlName","label"],["id","label"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,12)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,12).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,12)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,12)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(12,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(14,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(16,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Eb)),l._8(20,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,20,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,0,null,null,8,"label",[["for","seed"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(26,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(27,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Yb)),l._8(31,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Hb)),l._8(35,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Nb)),l._8(38,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Fb)),l._8(41,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ub)),l._8(45,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Jb)),l._8(48,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"])),(n()(),l._4(16777216,null,null,1,null,Qb)),l._8(52,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,e.form),n(t,14,0,"label"),n(t,20,0,!e.create&&e.enterSeedWithAssistance),n(t,31,0,e.create),n(t,35,0,e.enterSeedWithAssistance),n(t,38,0,!e.enterSeedWithAssistance),n(t,41,0,e.create),n(t,45,0,e.create),n(t,48,0,!e.onboarding),n(t,52,0,e.form.valid&&!e.customSeedIsNormal)},function(n,t){n(t,0,0,l._22(t,3).ngClassUntouched,l._22(t,3).ngClassTouched,l._22(t,3).ngClassPristine,l._22(t,3).ngClassDirty,l._22(t,3).ngClassValid,l._22(t,3).ngClassInvalid,l._22(t,3).ngClassPending),n(t,8,0,l._32(t,8,0,l._22(t,9).transform("wallet.new.name-label"))),n(t,11,0,l._22(t,16).ngClassUntouched,l._22(t,16).ngClassTouched,l._22(t,16).ngClassPristine,l._22(t,16).ngClassDirty,l._22(t,16).ngClassValid,l._22(t,16).ngClassInvalid,l._22(t,16).ngClassPending),n(t,27,0,l._32(t,27,0,l._22(t,28).transform("wallet.new.seed-label")))})}var Xb=function(){function n(n){this.dialogRef=n,this.acceptSafe=!1}return n.prototype.closePopup=function(){this.dialogRef.close(this.acceptSafe)},n.prototype.setAccept=function(n){this.acceptSafe=n.checked},n}(),Zb=function(){function n(n,t,e,r){var i=this;this.dialog=n,this.router=t,this.fill=null,this.onLabelAndSeedCreated=new l.o,this.showNewForm=!0,this.doubleButtonActive=Fp.LeftButton,this.hwCompatibilityActivated=!1,this.synchronized=!0,this.hwCompatibilityActivated=e.hwWalletCompatibilityActivated,this.synchronizedSubscription=r.synchronized.subscribe(function(n){return i.synchronized=n})}return n.prototype.ngOnInit=function(){var n=this;setTimeout(function(){n.formControl.initForm(null,n.fill)}),this.fill&&(this.doubleButtonActive=this.fill.creatingNewWallet?Fp.LeftButton:Fp.RightButton,this.showNewForm=this.fill.creatingNewWallet)},n.prototype.ngOnDestroy=function(){this.synchronizedSubscription.unsubscribe()},n.prototype.changeForm=function(n){this.showNewForm=n!==Fp.RightButton,this.doubleButtonActive=n,this.fill=null,this.formControl.initForm(this.showNewForm,this.fill)},n.prototype.createWallet=function(){var n=this;this.showSafe().afterClosed().subscribe(function(t){t&&n.emitCreatedData()})},n.prototype.loadWallet=function(){var n=this;this.synchronized?this.emitCreatedData():Wc(this.dialog,{headerText:"wallet.new.synchronizing-warning-title",text:"wallet.new.synchronizing-warning-text",confirmButtonText:"wallet.new.synchronizing-warning-continue",cancelButtonText:"wallet.new.synchronizing-warning-cancel"}).afterClosed().subscribe(function(t){t&&n.emitCreatedData()})},n.prototype.useHardwareWallet=function(){var n=this,t=new oa;t.width="566px",t.autoFocus=!1,t.data=!0,this.dialog.open(ud,t).afterClosed().subscribe(function(t){t&&n.router.navigate(["/wallets"])})},n.prototype.emitCreatedData=function(){this.onLabelAndSeedCreated.emit(this.formControl.getData())},n.prototype.showSafe=function(){var n=new oa;return n.width="450px",this.dialog.open(Xb,n)},n}(),$b=l._7({encapsulation:0,styles:[[".-header[_ngcontent-%COMP%]{color:#fafafa;position:relative;margin-top:20px;margin-bottom:10px;line-height:30px;font-size:20px;text-align:center}.-description[_ngcontent-%COMP%]{line-height:25px;font-size:14px;text-align:center;color:#fafafa;mix-blend-mode:normal;opacity:.5}.hw-link[_ngcontent-%COMP%]{cursor:pointer;color:#fff;font-size:13px;line-height:20px;margin-bottom:20px}.-buttons-footer[_ngcontent-%COMP%]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-flow:column;flex-flow:column;margin-bottom:20px}.-toggle-container[_ngcontent-%COMP%]{margin:10px auto}[_nghost-%COMP%] .-buttons-footer button{margin:2px 10px!important}.-text-align-center[_ngcontent-%COMP%]{text-align:center}label[for=seed][_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex}label[for=seed][_ngcontent-%COMP%] > span[_ngcontent-%COMP%]:last-child{-webkit-box-flex:1;-ms-flex:1;flex:1}label[for=seed][_ngcontent-%COMP%] .generators[_ngcontent-%COMP%]{text-align:right}label[for=seed][_ngcontent-%COMP%] .generators[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{cursor:pointer}label[for=seed][_ngcontent-%COMP%] .generators[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{width:13px;height:10px;font-size:13px;position:relative;top:2px}label[for=seed][_ngcontent-%COMP%] .generators[_ngcontent-%COMP%] .divider[_ngcontent-%COMP%]{padding:0 5px}"]],data:{}});function nv(n){return l._33(0,[(n()(),l._9(0,0,null,null,5,"div",[["class","row justify-content-center"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"span",[["class","hw-link"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.useHardwareWallet()&&l),l},null,null)),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("wizard.hardware-wallet-link")))})}function tv(n){return l._33(0,[l._29(402653184,1,{formControl:0}),(n()(),l._9(1,0,null,null,52,"div",[["class","onboarding-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(3,0,null,null,18,"div",[["class","row justify-content-center"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,15,"div",[["class","row-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,5,"div",[["class","-header"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(10,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,5,"div",[["class","-description"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(17,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(23,0,null,null,9,"div",[["class","row justify-content-center"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,6,"div",[["class","row-container -toggle-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(27,0,null,null,3,"app-double-button",[],null,[[null,"onStateChange"]],function(n,t,e){var l=!0;return"onStateChange"===t&&(l=!1!==n.component.changeForm(e)&&l),l},M_,x_)),l._8(28,49152,null,0,Bp,[],{rightButtonText:[0,"rightButtonText"],leftButtonText:[1,"leftButtonText"],activeButton:[2,"activeButton"]},{onStateChange:"onStateChange"}),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(34,0,null,null,7,"div",[["class","row justify-content-center"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(36,0,null,null,4,"div",[["class","row-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(38,0,null,null,1,"app-create-wallet-form",[],null,null,null,Kb,Ab)),l._8(39,245760,[[1,4],["formControl",4]],0,Gc,[Ye,fa,jc],{create:[0,"create"],onboarding:[1,"onboarding"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,nv)),l._8(44,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(46,0,null,null,6,"div",[["class","row -buttons-footer"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(48,0,null,null,3,"app-button",[["class","dark -button-min-margin"]],null,[[null,"action"]],function(n,t,e){var l=!0,r=n.component;return"action"===t&&(l=!1!==(r.showNewForm?r.createWallet():r.loadWallet())&&l),l},w_,g_)),l._8(49,49152,null,0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(50,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,28,0,l._32(t,28,0,l._22(t,29).transform("common.load")),l._32(t,28,1,l._22(t,30).transform("common.new")),e.doubleButtonActive),n(t,39,0,e.showNewForm,!0),n(t,44,0,e.hwCompatibilityActivated),n(t,49,0,!l._22(t,39).isValid)},function(n,t){n(t,10,0,l._32(t,10,0,l._22(t,11).transform("wallet.new.create-title"))),n(t,17,0,l._32(t,17,0,l._22(t,18).transform("wizard.wallet-desc"))),n(t,50,0,l._32(t,50,0,l._22(t,51).transform("wallet.new.create-button")))})}var ev=l._7({encapsulation:0,styles:[[".-header[_ngcontent-%COMP%]{color:#fafafa;position:relative;margin-top:20px;margin-bottom:10px;line-height:30px;font-size:20px;text-align:center}.-description[_ngcontent-%COMP%]{line-height:25px;font-size:14px;text-align:center;color:#fafafa;mix-blend-mode:normal;opacity:.5}.-buttons-footer[_ngcontent-%COMP%]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-flow:column;flex-flow:column;margin-bottom:20px}.-check-container[_ngcontent-%COMP%]{margin:10px auto;text-align:center}[_nghost-%COMP%] .-buttons-footer button{margin:2px 10px!important}.-text-align-center[_ngcontent-%COMP%]{text-align:center}.-check[_ngcontent-%COMP%] .mat-checkbox-checkmark-path{position:absolute;width:18px;height:8px;left:4.59px;top:9px;stroke:#fafafa!important}.-check[_ngcontent-%COMP%] .mat-checkbox-background, .-check[_ngcontent-%COMP%] .mat-checkbox-frame{top:0;left:0;right:0;bottom:0;position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;pointer-events:none;width:20px;height:20px;background:rgba(30,34,39,.05);border-radius:6px;border-color:transparent}.-check[_ngcontent-%COMP%] span{font-family:Skycoin;line-height:normal;font-size:14px;color:#fbfbfb}.-check[_ngcontent-%COMP%] span img{width:38px;height:38px;vertical-align:middle}.-input.disable[_ngcontent-%COMP%]{background:rgba(255,255,255,.1)}.-hidden[_ngcontent-%COMP%]{display:none}"]],data:{}});function lv(n){return l._33(0,[l._29(402653184,1,{button:0}),(n()(),l._9(1,0,null,null,95,"div",[["class","onboarding-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(3,0,null,null,18,"div",[["class","row justify-content-center"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,15,"div",[["class","row-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,5,"div",[["class","-header"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(10,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,5,"div",[["class","-description"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(17,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(23,0,null,null,12,"div",[["class","row justify-content-center"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(25,0,null,null,9,"div",[["class","row-container -check-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(27,0,null,null,6,"mat-checkbox",[["class","-check mat-checkbox"],["id","encrypt"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setEncrypt(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(29,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{id:[0,"id"],checked:[1,"checked"]},{change:"change"}),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(31,0,null,0,0,"img",[["src","../../../../../assets/img/lock-gold.png"]],null,null,null,null,null)),(n()(),l._31(32,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(37,0,null,null,43,"div",[["class","row justify-content-center"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(39,0,null,null,40,"div",[["class","row-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(41,0,null,null,37,"form",[["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,43).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,43).onReset()&&r),r},null,null)),l._8(42,16384,null,0,ts,[],null,null),l._8(43,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(45,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(47,0,null,null,14,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(49,0,null,null,2,"label",[["for","password"]],null,null,null,null,null)),(n()(),l._31(50,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(53,0,null,null,7,"input",[["class","-input"],["formControlName","password"],["id","password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,56)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,56).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,56)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,56)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(54,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(55,{disable:0}),l._8(56,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(58,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(60,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(63,0,null,null,14,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(65,0,null,null,2,"label",[["for","confirm"]],null,null,null,null,null)),(n()(),l._31(66,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(69,0,null,null,7,"input",[["class","-input"],["formControlName","confirm"],["id","confirm"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,72)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,72).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,72)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,72)._compositionEnd(e.target.value)&&r),"keydown.enter"===t&&(r=!1!==i.emitCreatedPassword()&&r),r},null,null)),l._8(70,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(71,{disable:0}),l._8(72,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(74,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(76,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(82,0,null,null,13,"div",[["class","row -buttons-footer"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(84,0,null,null,3,"app-button",[["class","dark -button-min-margin"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.emitCreatedPassword()&&l),l},w_,g_)),l._8(85,49152,[[1,4],["button",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(86,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(89,0,null,null,5,"app-button",[["class","ghost -button-min-margin"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.emitBack()&&l),l},w_,g_)),l._8(90,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(91,{"-hidden":0}),l._8(92,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(93,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,29,0,"encrypt",!0),n(t,43,0,e.form),n(t,54,0,"-input",n(t,55,0,e.form.disabled)),n(t,58,0,"password"),n(t,70,0,"-input",n(t,71,0,e.form.disabled)),n(t,74,0,"confirm"),n(t,85,0,e.form.enabled&&!e.form.valid),n(t,90,0,"ghost -button-min-margin",n(t,91,0,e.isWorking))},function(n,t){n(t,10,0,l._32(t,10,0,l._22(t,11).transform("wallet.new.encrypt-title"))),n(t,17,0,l._32(t,17,0,l._22(t,18).transform("wizard.encrypt-desc"))),n(t,27,0,l._22(t,29).id,l._22(t,29).indeterminate,l._22(t,29).checked,l._22(t,29).disabled,"before"==l._22(t,29).labelPosition),n(t,32,0,l._32(t,32,0,l._22(t,33).transform("wallet.new.encrypt"))),n(t,41,0,l._22(t,45).ngClassUntouched,l._22(t,45).ngClassTouched,l._22(t,45).ngClassPristine,l._22(t,45).ngClassDirty,l._22(t,45).ngClassValid,l._22(t,45).ngClassInvalid,l._22(t,45).ngClassPending),n(t,50,0,l._32(t,50,0,l._22(t,51).transform("password.label"))),n(t,53,0,l._22(t,60).ngClassUntouched,l._22(t,60).ngClassTouched,l._22(t,60).ngClassPristine,l._22(t,60).ngClassDirty,l._22(t,60).ngClassValid,l._22(t,60).ngClassInvalid,l._22(t,60).ngClassPending),n(t,66,0,l._32(t,66,0,l._22(t,67).transform("password.confirm-label"))),n(t,69,0,l._22(t,76).ngClassUntouched,l._22(t,76).ngClassTouched,l._22(t,76).ngClassPristine,l._22(t,76).ngClassDirty,l._22(t,76).ngClassValid,l._22(t,76).ngClassInvalid,l._22(t,76).ngClassPending),n(t,86,0,l._32(t,86,0,l._22(t,87).transform("wizard.finish-button"))),n(t,93,0,l._32(t,93,0,l._22(t,94).transform("wizard.back-button")))})}var rv=l._7({encapsulation:0,styles:[["button[_ngcontent-%COMP%]{position:fixed;right:30px;top:10px}.flag[_ngcontent-%COMP%]{width:16px;height:16px;position:relative;top:-3px}"]],data:{}});function iv(n){return l._33(0,[(n()(),l._9(0,0,null,null,5,"button",[["class","mat-icon-button"],["mat-icon-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.changelanguage()&&l),l},i_,r_)),l._8(1,180224,null,0,Bs,[l.l,Hl,Rr],null,null),l._8(2,16384,null,0,Fs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,0,"img",[["class","flag"]],[[8,"src",4]],null,null,null,null)),(n()(),l._31(-1,0,["\n"]))],null,function(n,t){var e=t.component;n(t,0,0,l._22(t,1).disabled||null),n(t,4,0,"assets/img/lang/"+e.language.iconName)})}function ov(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-onboarding-create-wallet",[],null,[[null,"onLabelAndSeedCreated"]],function(n,t,e){var l=!0;return"onLabelAndSeedCreated"===t&&(l=!1!==n.component.onLabelAndSeedCreated(e)&&l),l},tv,$b)),l._8(1,245760,null,0,Zb,[fa,cp,oc,qc],{fill:[0,"fill"]},{onLabelAndSeedCreated:"onLabelAndSeedCreated"})],function(n,t){n(t,1,0,t.component.fill)},null)}function sv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-onboarding-encrypt-wallet",[],null,[[null,"onPasswordCreated"],[null,"onBack"]],function(n,t,e){var l=!0,r=n.component;return"onPasswordCreated"===t&&(l=!1!==r.onPasswordCreated(e)&&l),"onBack"===t&&(l=!1!==r.onBack()&&l),l},lv,ev)),l._8(1,114688,[[1,4],["encryptForm",4]],0,uf,[ns],null,{onPasswordCreated:"onPasswordCreated",onBack:"onBack"})],function(n,t){n(t,1,0)},null)}function av(n){return l._33(0,[l._29(671088640,1,{encryptForm:0}),(n()(),l._4(16777216,null,null,1,null,iv)),l._8(2,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n"])),(n()(),l._4(16777216,null,null,1,null,ov)),l._8(5,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n"])),(n()(),l._4(16777216,null,null,1,null,sv)),l._8(8,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.language),n(t,5,0,1===e.step),n(t,8,0,2===e.step)},null)}var uv=l._5("app-onboarding",cf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-onboarding",[],null,null,null,av,rv)),l._8(1,245760,null,0,cf,[cp,Sc,Bc,fa,jc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),cv=l._7({encapsulation:0,styles:[[".-buttons[_ngcontent-%COMP%]{text-align:center}.-paper[_ngcontent-%COMP%]{background-color:#fbfbfb;border-radius:10px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);padding:30px;margin:30px}.-disabled[_ngcontent-%COMP%]{opacity:.5}"]],data:{}});function dv(n){return l._33(0,[l._29(402653184,1,{resetButton:0}),(n()(),l._9(1,0,null,null,2,"app-header",[],null,null,null,K_,D_)),l._8(2,245760,null,0,P_,[gf,nf,qc,rf,Sc],{headline:[0,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(5,0,null,null,74,"div",[["class","container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,71,"div",[["class","-paper"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,68,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,10).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,10).onReset()&&r),r},null,null)),l._8(10,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(12,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,12,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,2,"label",[["for","wallet"]],null,null,null,null,null)),(n()(),l._31(17,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,5,"input",[["class","-disabled"],["formControlName","wallet"],["id","wallet"],["readonly",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,21)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,21).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,21)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,21)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(21,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(23,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(25,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,0,null,null,12,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(30,0,null,null,2,"label",[["for","seed"]],null,null,null,null,null)),(n()(),l._31(31,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(34,0,null,null,5,"textarea",[["formControlName","seed"],["id","seed"],["row","2"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,35)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,35).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,35)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,35)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(35,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(37,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(39,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(42,0,null,null,12,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(44,0,null,null,2,"label",[["for","password"]],null,null,null,null,null)),(n()(),l._31(45,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(48,0,null,null,5,"input",[["formControlName","password"],["id","password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,49)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,49).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,49)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,49)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(49,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(51,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(53,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(56,0,null,null,12,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(58,0,null,null,2,"label",[["for","confirm"]],null,null,null,null,null)),(n()(),l._31(59,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(62,0,null,null,5,"input",[["formControlName","confirm"],["id","confirm"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,63)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,63).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,63)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,63)._compositionEnd(e.target.value)&&r),"keydown.enter"===t&&(r=!1!==i.reset()&&r),r},null,null)),l._8(63,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(65,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(67,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(70,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(72,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.reset()&&l),l},w_,g_)),l._8(73,49152,[[1,4],["resetButton",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(74,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,l._32(t,2,0,l._22(t,3).transform("title.reset"))),n(t,10,0,e.form),n(t,23,0,"wallet"),n(t,37,0,"seed"),n(t,51,0,"password"),n(t,65,0,"confirm"),n(t,73,0,!e.form.valid)},function(n,t){n(t,9,0,l._22(t,12).ngClassUntouched,l._22(t,12).ngClassTouched,l._22(t,12).ngClassPristine,l._22(t,12).ngClassDirty,l._22(t,12).ngClassValid,l._22(t,12).ngClassInvalid,l._22(t,12).ngClassPending),n(t,17,0,l._32(t,17,0,l._22(t,18).transform("reset.wallet-label"))),n(t,20,0,l._22(t,25).ngClassUntouched,l._22(t,25).ngClassTouched,l._22(t,25).ngClassPristine,l._22(t,25).ngClassDirty,l._22(t,25).ngClassValid,l._22(t,25).ngClassInvalid,l._22(t,25).ngClassPending),n(t,31,0,l._32(t,31,0,l._22(t,32).transform("reset.seed-label"))),n(t,34,0,l._22(t,39).ngClassUntouched,l._22(t,39).ngClassTouched,l._22(t,39).ngClassPristine,l._22(t,39).ngClassDirty,l._22(t,39).ngClassValid,l._22(t,39).ngClassInvalid,l._22(t,39).ngClassPending),n(t,45,0,l._32(t,45,0,l._22(t,46).transform("reset.password-label"))),n(t,48,0,l._22(t,53).ngClassUntouched,l._22(t,53).ngClassTouched,l._22(t,53).ngClassPristine,l._22(t,53).ngClassDirty,l._22(t,53).ngClassValid,l._22(t,53).ngClassInvalid,l._22(t,53).ngClassPending),n(t,59,0,l._32(t,59,0,l._22(t,60).transform("reset.confirm-label"))),n(t,62,0,l._22(t,67).ngClassUntouched,l._22(t,67).ngClassTouched,l._22(t,67).ngClassPristine,l._22(t,67).ngClassDirty,l._22(t,67).ngClassValid,l._22(t,67).ngClassInvalid,l._22(t,67).ngClassPending),n(t,74,0,l._32(t,74,0,l._22(t,75).transform("reset.reset-button")))})}var hv=l._5("app-reset-password",df,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-reset-password",[],null,null,null,dv,cv)),l._8(1,180224,null,0,df,[ns,Ch,cp,Sc,jc],null,null)],null,null)},{},{},[]),pv=function(){function n(n,t,e,l){this.walletService=n,this.dialogRef=t,this.formBuilder=e,this.purchaseService=l}return n.prototype.ngOnInit=function(){this.initForm()},n.prototype.generate=function(){var n=this;this.purchaseService.generate(this.form.value.address).subscribe(function(){return n.dialogRef.close()})},n.prototype.initForm=function(){this.form=this.formBuilder.group({address:["",Xi.required]})},n}(),fv=l._7({encapsulation:0,styles:[["mat-select[_ngcontent-%COMP%]{width:100%;padding:40px 0 20px}"]],data:{}});function _v(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"mat-option",[["class","mat-option"],["role","option"]],[[1,"tabindex",0],[2,"mat-selected",null],[2,"mat-option-multiple",null],[2,"mat-active",null],[8,"id",0],[1,"aria-selected",0],[1,"aria-disabled",0],[2,"mat-option-disabled",null]],[[null,"click"],[null,"keydown"]],function(n,t,e){var r=!0;return"click"===t&&(r=!1!==l._22(n,1)._selectViaInteraction()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),r},wm,bm)),l._8(1,49152,[[1,4]],0,pr,[l.l,l.h,[2,hr],[2,cr]],{value:[0,"value"]},null),(n()(),l._31(2,0,["\n ","\n "]))],function(n,t){n(t,1,0,t.context.$implicit.address)},function(n,t){n(t,0,0,l._22(t,1)._getTabIndex(),l._22(t,1).selected,l._22(t,1).multiple,l._22(t,1).active,l._22(t,1).id,l._22(t,1).selected.toString(),l._22(t,1).disabled.toString(),l._22(t,1).disabled),n(t,2,0,t.context.$implicit.address)})}function mv(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"p",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(4,0,null,null,21,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,5).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,5).onReset()&&r),r},null,null)),l._8(5,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(7,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(9,0,null,null,15,"mat-select",[["class","input-field mat-select"],["formControlName","address"],["role","listbox"]],[[1,"id",0],[1,"tabindex",0],[1,"aria-label",0],[1,"aria-labelledby",0],[1,"aria-required",0],[1,"aria-disabled",0],[1,"aria-invalid",0],[1,"aria-owns",0],[1,"aria-multiselectable",0],[1,"aria-describedby",0],[1,"aria-activedescendant",0],[2,"mat-select-disabled",null],[2,"mat-select-invalid",null],[2,"mat-select-required",null],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown"],[null,"focus"],[null,"blur"]],function(n,t,e){var r=!0;return"keydown"===t&&(r=!1!==l._22(n,14)._handleKeydown(e)&&r),"focus"===t&&(r=!1!==l._22(n,14)._onFocus()&&r),"blur"===t&&(r=!1!==l._22(n,14)._onBlur()&&r),r},Am,Sm)),l._28(6144,null,hr,null,[Pu]),l._28(6144,null,Os,null,[Pu]),l._8(12,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[8,null]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(14,2080768,null,3,Pu,[Xr,l.h,l.B,Kl,l.l,[2,Dl],[2,Wo],[2,qo],[2,Ps],[2,uo],[8,null],Ou],{placeholder:[0,"placeholder"]},null),l._29(603979776,1,{options:1}),l._29(603979776,2,{optionGroups:1}),l._29(335544320,3,{customTrigger:0}),l._25(131072,De.i,[De.j,l.h]),l._8(19,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,1,["\n "])),(n()(),l._4(16777216,null,1,2,null,_v)),l._8(22,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),l._25(131072,nn,[l.h]),(n()(),l._31(-1,1,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(27,0,null,null,7,"div",[["class","button-line"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(29,0,null,null,4,"a",[["class","mat-raised-button"],["mat-raised-button",""]],[[1,"tabindex",0],[1,"disabled",0],[1,"aria-disabled",0]],[[null,"click"]],function(n,t,e){var r=!0,i=n.component;return"click"===t&&(r=!1!==l._22(n,30)._haltDisabledEvents(e)&&r),"click"===t&&(r=!1!==i.generate()&&r),r},s_,o_)),l._8(30,180224,null,0,Vs,[Hl,Rr,l.l],null,null),l._8(31,16384,null,0,Ns,[],null,null),(n()(),l._31(32,0,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,5,0,e.form),n(t,12,0,"address"),n(t,14,0,l._32(t,14,0,l._22(t,18).transform("buy.select-address"))),n(t,22,0,l._32(t,22,0,l._22(t,23).transform(e.walletService.allAddresses())))},function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("buy.deposit-address"))),n(t,4,0,l._22(t,7).ngClassUntouched,l._22(t,7).ngClassTouched,l._22(t,7).ngClassPristine,l._22(t,7).ngClassDirty,l._22(t,7).ngClassValid,l._22(t,7).ngClassInvalid,l._22(t,7).ngClassPending),n(t,9,1,[l._22(t,14).id,l._22(t,14).tabIndex,l._22(t,14)._ariaLabel,l._22(t,14).ariaLabelledby,l._22(t,14).required.toString(),l._22(t,14).disabled.toString(),l._22(t,14).errorState,l._22(t,14).panelOpen?l._22(t,14)._optionIds:null,l._22(t,14).multiple,l._22(t,14)._ariaDescribedby||null,l._22(t,14)._getAriaActiveDescendant(),l._22(t,14).disabled,l._22(t,14).errorState,l._22(t,14).required,l._22(t,19).ngClassUntouched,l._22(t,19).ngClassTouched,l._22(t,19).ngClassPristine,l._22(t,19).ngClassDirty,l._22(t,19).ngClassValid,l._22(t,19).ngClassInvalid,l._22(t,19).ngClassPending]),n(t,29,0,l._22(t,30).disabled?-1:0,l._22(t,30).disabled||null,l._22(t,30).disabled.toString()),n(t,32,0,l._32(t,32,0,l._22(t,33).transform("buy.generate")))})}var gv=l._5("app-add-deposit-address",pv,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-add-deposit-address",[],null,null,null,mv,fv)),l._8(1,114688,null,0,pv,[Sc,ca,ns,ef],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),yv=function(){function n(){}return n.prototype.closePopup=function(){this.disableDismiss||this.dialog.close()},n.prototype.ngOnChanges=function(n){n.disableDismiss&&(this.dialog.disableClose=n.disableDismiss.currentValue)},n}(),bv=l._7({encapsulation:0,styles:[[".-header[_ngcontent-%COMP%]{background-color:#f7f7f7;border-top-left-radius:5px;border-top-right-radius:5px;line-height:50px;position:relative;text-align:center}.-header[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{cursor:pointer;height:32px;position:absolute;right:9px;top:9px}.-body[_ngcontent-%COMP%]{background-color:#fbfbfb;padding:0 24px}mat-dialog-content[_ngcontent-%COMP%]::after, mat-dialog-content[_ngcontent-%COMP%]::before{content:'';padding-top:24px;height:0;display:block}"]],data:{}});function vv(n){return l._33(0,[(n()(),l._9(0,0,null,null,0,"img",[["src","../../../../../assets/img/close-grey.png"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.closePopup()&&l),l},null,null))],null,null)}function wv(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[["class","-header"]],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n "])),(n()(),l._4(16777216,null,null,1,null,vv)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(6,0,null,null,7,"div",[["class","-body"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,4,"mat-dialog-content",[["class","mat-dialog-content"]],null,null,null,null,null)),l._8(9,16384,null,0,_a,[],null,null),(n()(),l._31(-1,null,["\n "])),l._21(null,0),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){n(t,3,0,!t.component.disableDismiss)},function(n,t){n(t,1,0,t.component.headline)})}var xv=l._7({encapsulation:0,styles:[[".-buttons[_ngcontent-%COMP%]{text-align:center}"]],data:{}});function Mv(n){return l._33(0,[l._29(402653184,1,{formControl:0}),l._29(402653184,2,{createButton:0}),l._29(402653184,3,{cancelButton:0}),(n()(),l._9(3,0,null,null,19,"app-modal",[],null,null,null,wv,bv)),l._8(4,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(7,0,null,0,1,"app-create-wallet-form",[],null,null,null,Kb,Ab)),l._8(8,245760,[[1,4],["formControl",4]],0,Gc,[Ye,fa,jc],{create:[0,"create"],onboarding:[1,"onboarding"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(10,0,null,0,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closePopup()&&l),l},w_,g_)),l._8(13,49152,[[3,4],["cancelButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(14,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.createWallet()&&l),l},w_,g_)),l._8(18,49152,[[2,4],["createButton",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(19,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,4,0,e.dialogRef,l._32(t,4,1,l._22(t,5).transform("wallet.new."+(e.data.create?"create":"load")+"-title")),e.disableDismiss),n(t,8,0,e.data.create,!1),n(t,18,0,!l._22(t,8).isValid)},function(n,t){var e=t.component;n(t,14,0,l._32(t,14,0,l._22(t,15).transform("wallet.new.cancel-button"))),n(t,19,0,l._32(t,19,0,l._22(t,20).transform("wallet.new."+(e.data.create?"create":"load")+"-button")))})}var kv=l._5("app-create-wallet",Jc,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-create-wallet",[],null,null,null,Mv,xv)),l._8(1,180224,null,0,Jc,[da,ca,Sc,fa,jc,qc],null,null)],null,null)},{},{},[]),Cv=l._7({encapsulation:0,styles:[[".content[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex}.content[_ngcontent-%COMP%] .icon-container[_ngcontent-%COMP%]{margin-right:20px}.content[_ngcontent-%COMP%] .icon-container[_ngcontent-%COMP%] mat-spinner[_ngcontent-%COMP%]{display:inline-block;height:36px!important;width:36px!important}.content[_ngcontent-%COMP%] .icon-container[_ngcontent-%COMP%] mat-spinner[_ngcontent-%COMP%] svg{height:36px!important;width:36px!important}.content[_ngcontent-%COMP%] .icon-container[_ngcontent-%COMP%] mat-spinner[_ngcontent-%COMP%] circle{stroke:rgba(30,34,39,.2)}.content[_ngcontent-%COMP%] .icon-container[_ngcontent-%COMP%] i[_ngcontent-%COMP%]{font-size:40px}.content[_ngcontent-%COMP%] .text-container[_ngcontent-%COMP%]{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.content[_ngcontent-%COMP%] .text-container[_ngcontent-%COMP%] .link[_ngcontent-%COMP%]{color:#0072ff;cursor:pointer}.content[_ngcontent-%COMP%] .text-container[_ngcontent-%COMP%] .list[_ngcontent-%COMP%]{padding:10px 0}.content[_ngcontent-%COMP%] .text-container[_ngcontent-%COMP%] .list[_ngcontent-%COMP%] .list-element[_ngcontent-%COMP%]{margin:10px 0;font-size:12px;color:#000;font-weight:700}.content[_ngcontent-%COMP%] .-red[_ngcontent-%COMP%]{color:#ff004e}.content[_ngcontent-%COMP%] .-yellow[_ngcontent-%COMP%]{color:#ffc125}.content[_ngcontent-%COMP%] .-grey[_ngcontent-%COMP%]{color:rgba(30,34,39,.2)}.content[_ngcontent-%COMP%] .-green[_ngcontent-%COMP%]{color:#00df80}.content[_ngcontent-%COMP%] .-blinking[_ngcontent-%COMP%]{-webkit-animation:1s linear infinite alert-blinking;animation:1s linear infinite alert-blinking}"]],data:{}});function Sv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"mat-spinner",[["class","mat-spinner mat-progress-spinner"],["mode","indeterminate"],["role","progressbar"]],[[4,"width","px"],[4,"height","px"]],null,null,Pf,Lf)),l._8(1,573440,null,0,Wu,[l.l,Hl,[2,sn]],null,null)],null,function(n,t){n(t,0,0,l._22(t,1)._elementSize,l._22(t,1)._elementSize)})}function Ov(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"i",[["class","material-icons -green"]],null,null,null,null,null)),(n()(),l._31(-1,null,["done"]))],null,null)}function Tv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"i",[["class","material-icons -red"]],null,null,null,null,null)),(n()(),l._31(-1,null,["error_outline"]))],null,null)}function Lv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"i",[["class","material-icons -grey"]],null,null,null,null,null)),(n()(),l._31(-1,null,["usb"]))],null,null)}function Pv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"i",[["class","material-icons -yellow"]],null,null,null,null,null)),(n()(),l._31(-1,null,["memory"]))],null,null)}function Dv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"i",[["class","material-icons -red -blinking"]],null,null,null,null,null)),(n()(),l._31(-1,null,["error"]))],null,null)}function Av(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"i",[["class","material-icons -yellow"]],null,null,null,null,null)),(n()(),l._31(-1,null,["touch_app"]))],null,null)}function Ev(n){return l._33(0,[(n()(),l._9(0,0,null,null,22,"div",[["class","icon-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Sv)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ov)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Tv)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Lv)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Pv)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Dv)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Av)),l._8(21,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.icon==e.icons.Spinner),n(t,6,0,e.icon==e.icons.Success),n(t,9,0,e.icon==e.icons.Error),n(t,12,0,e.icon==e.icons.Usb),n(t,15,0,e.icon==e.icons.HardwareWallet),n(t,18,0,e.icon==e.icons.Warning),n(t,21,0,e.icon==e.icons.Confirm)},null)}function Yv(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"span",[["class","big-text"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,t.component.upperBigText)})}function jv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.component.text)})}function Iv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[["class","link"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.activateLink()&&l),l},null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.component.linkText)})}function Rv(n){return l._33(0,[(n()(),l._9(0,0,null,null,14,"div",[["class","list-element"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(3,null,["\u2022 ",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,3,"span",[],null,null,null,null,null)),(n()(),l._31(7,null,[""," ",""])),l._25(131072,De.i,[De.j,l.h]),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(12,null,[""," ",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform(t.context.$implicit.coins.toString()))),n(t,7,0,l._32(t,7,0,l._22(t,8).transform("hardware-wallet.create-tx.send-p1")),l._32(t,7,1,l._22(t,9).transform(t.context.$implicit.hours.toString(),!1))),n(t,12,0,l._32(t,12,0,l._22(t,13).transform("hardware-wallet.create-tx.send-p2")),t.context.$implicit.address)})}function Hv(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[["class","list"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Rv)),l._8(3,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.component.outputsList)},null)}function Nv(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["",""]))],null,function(n,t){n(t,1,0,t.component.lowerText)})}function Fv(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"span",[["class","big-text"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,t.component.lowerBigText)})}function Bv(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"span",[["class","-grey"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,3,0,t.component.lowerLightText)})}function Vv(n){return l._33(0,[(n()(),l._9(0,0,null,null,28,"div",[["class","content"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ev)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,22,"div",[["class","text-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Yv)),l._8(8,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,jv)),l._8(11,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Iv)),l._8(14,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Hv)),l._8(17,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Nv)),l._8(20,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Fv)),l._8(23,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Bv)),l._8(26,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,e.icon!==e.icons.None),n(t,8,0,e.upperBigText),n(t,11,0,e.text),n(t,14,0,e.linkText),n(t,17,0,e.outputsList),n(t,20,0,e.lowerText),n(t,23,0,e.lowerBigText),n(t,26,0,e.lowerLightText)},null)}var Wv=l._7({encapsulation:0,styles:[["mat-input-container[_ngcontent-%COMP%]{width:100%}.-buttons[_ngcontent-%COMP%]{text-align:center}.info[_ngcontent-%COMP%]{margin:5px 0 25px;color:rgba(30,34,39,.5);font-size:12px;line-height:1.5}"]],data:{}});function zv(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"div",[["class","info"]],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("hardware-wallet.added.characters-warning")))})}function Uv(n){return l._33(0,[(n()(),l._9(0,0,null,null,39,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,zv)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,20,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,6).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,6).onReset()&&r),r},null,null)),l._8(6,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(8,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,14,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"label",[["for","label"]],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,7,"input",[["formControlName","label"],["id","label"]],[[1,"maxlength",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,17)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,17).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,17)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,17)._compositionEnd(e.target.value)&&r),"keydown.enter"===t&&(r=!1!==i.rename()&&r),r},null,null)),l._8(17,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(18,540672,null,0,$o,[],{maxlength:[0,"maxlength"]},null),l._28(1024,null,Qi,function(n){return[n]},[$o]),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(21,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(23,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(27,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(29,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closePopup()&&l),l},w_,g_)),l._8(30,49152,null,0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(31,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(34,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.rename()&&l),l},w_,g_)),l._8(35,49152,[[1,4],["button",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(36,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.showCharactersWarning),n(t,6,0,e.form),n(t,18,0,e.data.wallet.isHardware?e.maxHwWalletLabelLength:null),n(t,21,0,"label"),n(t,30,0,l._22(t,35)&&l._22(t,35).isLoading()),n(t,35,0,!e.form.valid)},function(n,t){n(t,5,0,l._22(t,8).ngClassUntouched,l._22(t,8).ngClassTouched,l._22(t,8).ngClassPristine,l._22(t,8).ngClassDirty,l._22(t,8).ngClassValid,l._22(t,8).ngClassInvalid,l._22(t,8).ngClassPending),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("wallet.rename.name-label"))),n(t,16,0,l._22(t,18).maxlength?l._22(t,18).maxlength:null,l._22(t,23).ngClassUntouched,l._22(t,23).ngClassTouched,l._22(t,23).ngClassPristine,l._22(t,23).ngClassDirty,l._22(t,23).ngClassValid,l._22(t,23).ngClassInvalid,l._22(t,23).ngClassPending),n(t,31,0,l._32(t,31,0,l._22(t,32).transform("wallet.rename.cancel-button"))),n(t,36,0,l._32(t,36,0,l._22(t,37).transform("wallet.rename.rename-button")))})}function Gv(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Confirm,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.general.confirm")))},null)}function qv(n){return l._33(0,[l._29(671088640,1,{button:0}),(n()(),l._9(1,0,null,null,9,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,Uv)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Gv)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("wallet.rename.title")),e.button&&e.button.isLoading()||e.currentState===e.states.WaitingForConfirmation),n(t,6,0,e.currentState===e.states.Initial),n(t,9,0,e.currentState===e.states.WaitingForConfirmation)},null)}var Jv=l._5("app-change-name",nd,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-change-name",[],null,null,null,qv,Wv)),l._8(1,245760,null,0,nd,[ca,da,ns,Sc,oc,De.j,jc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),Qv=l._7({encapsulation:0,styles:[[".qr-container[_ngcontent-%COMP%]{text-align:center;margin-bottom:24px}.qr-container[_ngcontent-%COMP%] .qr[_ngcontent-%COMP%]{height:180px;width:180px;display:inline-block}.separator[_ngcontent-%COMP%]{background-color:rgba(30,34,39,.2);height:1px;width:100%}.data-container[_ngcontent-%COMP%]{margin:14px 0}.data-container[_ngcontent-%COMP%] .title[_ngcontent-%COMP%]{color:#171a1d}.data-container[_ngcontent-%COMP%] .data[_ngcontent-%COMP%]{color:rgba(30,34,39,.75);cursor:pointer}.data-container[_ngcontent-%COMP%] .data[_ngcontent-%COMP%] .text[_ngcontent-%COMP%]{margin-right:5px}.data-container[_ngcontent-%COMP%] .data[_ngcontent-%COMP%] .copy[_ngcontent-%COMP%]{color:rgba(30,34,39,.75);opacity:.25}.data-container[_ngcontent-%COMP%] .data[_ngcontent-%COMP%]:hover .copy[_ngcontent-%COMP%]{opacity:.75}.data-container[_ngcontent-%COMP%] .data[_ngcontent-%COMP%]:active .copy[_ngcontent-%COMP%]{opacity:1}.link[_ngcontent-%COMP%]{color:#0072ff;cursor:pointer}.link[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{padding:0;display:inline;vertical-align:middle;font-size:13px}.invalid[_ngcontent-%COMP%]{color:#ff004e}"]],data:{}});function Kv(n){return l._33(0,[(n()(),l._9(0,0,null,null,11,"div",[["class","data-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"div",[["class","title"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,4,"div",[["class","data"]],null,[[null,"click"]],function(n,t,e){var l=!0,r=n.component;return"click"===t&&(l=!1!==r.copyText(r.currentQrContent)&&l),l},null,null)),(n()(),l._9(7,0,null,null,1,"span",[["class","text"]],null,null,null,null,null)),(n()(),l._31(8,null,["",""])),(n()(),l._9(9,0,null,null,1,"span",[["class","fa copy"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\uf0c5"])),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,l._22(t,4).transform("qr.data"))),n(t,8,0,e.currentQrContent)})}function Xv(n){return l._33(0,[(n()(),l._9(0,0,null,null,5,"div",[["class","link"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.startShowingForm()&&l),l},null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(3,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(4,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["keyboard_arrow_down"]))],function(n,t){n(t,4,0)},function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("qr.request-link")))})}function Zv(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[["class","invalid"]],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("qr.invalid")))})}function $v(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[["class","invalid"]],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("qr.invalid")))})}function nw(n){return l._33(0,[(n()(),l._9(0,0,null,null,58,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,1).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,1).onReset()&&r),r},null,null)),l._8(1,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(3,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,17,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,5,"label",[["for","coins"]],null,null,null,null,null)),(n()(),l._31(8,null,["\n "," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._4(16777216,null,null,1,null,Zv)),l._8(11,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,7,"input",[["formControlName","coins"],["id","coins"],["maxlength","20"]],[[1,"maxlength",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,15)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,15).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,15)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,15)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(15,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(16,540672,null,0,$o,[],{maxlength:[0,"maxlength"]},null),l._28(1024,null,Qi,function(n){return[n]},[$o]),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(19,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(21,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(24,0,null,null,17,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(26,0,null,null,5,"label",[["for","hours"]],null,null,null,null,null)),(n()(),l._31(27,null,["\n "," "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._4(16777216,null,null,1,null,$v)),l._8(30,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(33,0,null,null,7,"input",[["formControlName","hours"],["id","hours"],["maxlength","20"]],[[1,"maxlength",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,34)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,34).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,34)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,34)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(34,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(35,540672,null,0,$o,[],{maxlength:[0,"maxlength"]},null),l._28(1024,null,Qi,function(n){return[n]},[$o]),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(38,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(40,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(43,0,null,null,14,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(45,0,null,null,2,"label",[["for","note"]],null,null,null,null,null)),(n()(),l._31(46,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(49,0,null,null,7,"input",[["formControlName","note"],["id","note"],["maxlength","100"]],[[1,"maxlength",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,50)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,50).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,50)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,50)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(50,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(51,540672,null,0,$o,[],{maxlength:[0,"maxlength"]},null),l._28(1024,null,Qi,function(n){return[n]},[$o]),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(54,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(56,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,1,0,e.form),n(t,11,0,e.invalidCoins),n(t,16,0,"20"),n(t,19,0,"coins"),n(t,30,0,e.invalidHours),n(t,35,0,"20"),n(t,38,0,"hours"),n(t,51,0,"100"),n(t,54,0,"note")},function(n,t){n(t,0,0,l._22(t,3).ngClassUntouched,l._22(t,3).ngClassTouched,l._22(t,3).ngClassPristine,l._22(t,3).ngClassDirty,l._22(t,3).ngClassValid,l._22(t,3).ngClassInvalid,l._22(t,3).ngClassPending),n(t,8,0,l._32(t,8,0,l._22(t,9).transform("qr.amount"))),n(t,14,0,l._22(t,16).maxlength?l._22(t,16).maxlength:null,l._22(t,21).ngClassUntouched,l._22(t,21).ngClassTouched,l._22(t,21).ngClassPristine,l._22(t,21).ngClassDirty,l._22(t,21).ngClassValid,l._22(t,21).ngClassInvalid,l._22(t,21).ngClassPending),n(t,27,0,l._32(t,27,0,l._22(t,28).transform("qr.hours"))),n(t,33,0,l._22(t,35).maxlength?l._22(t,35).maxlength:null,l._22(t,40).ngClassUntouched,l._22(t,40).ngClassTouched,l._22(t,40).ngClassPristine,l._22(t,40).ngClassDirty,l._22(t,40).ngClassValid,l._22(t,40).ngClassInvalid,l._22(t,40).ngClassPending),n(t,46,0,l._32(t,46,0,l._22(t,47).transform("qr.message"))),n(t,49,0,l._22(t,51).maxlength?l._22(t,51).maxlength:null,l._22(t,56).ngClassUntouched,l._22(t,56).ngClassTouched,l._22(t,56).ngClassPristine,l._22(t,56).ngClassDirty,l._22(t,56).ngClassValid,l._22(t,56).ngClassInvalid,l._22(t,56).ngClassPending)})}function tw(n){return l._33(0,[l._29(402653184,1,{qr:0}),(n()(),l._9(1,0,null,null,32,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(5,0,null,0,3,"div",[["class","qr-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,[[1,0],["qr",1]],null,0,"div",[["class","qr"],["id","qr"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(10,0,null,0,0,"div",[["class","separator"]],null,null,null,null,null)),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,Kv)),l._8(13,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(15,0,null,0,11,"div",[["class","data-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,null,null,2,"div",[["class","title"]],null,null,null,null,null)),(n()(),l._31(18,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(21,0,null,null,4,"div",[["class","data"]],null,[[null,"click"]],function(n,t,e){var l=!0,r=n.component;return"click"===t&&(l=!1!==r.copyText(r.data.address)&&l),l},null,null)),(n()(),l._9(22,0,null,null,1,"span",[["class","text"]],null,null,null,null,null)),(n()(),l._31(23,null,["",""])),(n()(),l._9(24,0,null,null,1,"span",[["class","fa copy"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\uf0c5"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,Xv)),l._8(29,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,nw)),l._8(32,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform(e.data.hideCoinRequestForm?"qr.title-read-only":"qr.title"))),n(t,13,0,!e.data.ignoreCoinPrefix||!e.data.hideCoinRequestForm),n(t,29,0,!e.showForm&&!e.data.hideCoinRequestForm),n(t,32,0,e.showForm)},function(n,t){var e=t.component;n(t,18,0,l._32(t,18,0,l._22(t,19).transform("qr.address"))),n(t,23,0,e.data.address)})}var ew=l._5("app-qr-code",qp,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-qr-code",[],null,null,null,tw,Qv)),l._8(1,245760,null,0,qp,[da,ca,ns,jc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),lw=l._7({encapsulation:0,styles:[[""]],data:{}});function rw(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"app-modal",[],null,null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,2,"app-transaction-info",[],null,null,null,Sg,cg)),l._8(5,245760,null,0,ug,[rf,fa],{transaction:[0,"transaction"],isPreview:[1,"isPreview"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"]))],function(n,t){var e=t.component;n(t,1,0,e.dialogRef,l._32(t,1,1,l._22(t,2).transform("history.tx-detail"))),n(t,5,0,e.transaction,!1)},null)}var iw=l._5("app-transaction-detail",of,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-transaction-detail",[],null,null,null,rw,lw)),l._8(1,49152,null,0,of,[da,ca],null,null)],null,null)},{},{},[]),ow=l._7({encapsulation:0,styles:[[".-safe-description[_ngcontent-%COMP%]{font-family:Skycoin;line-height:20px;font-size:12px;color:#1e2227;mix-blend-mode:normal;opacity:.8}.-check-container[_ngcontent-%COMP%]{text-align:center;margin-top:50px}.-safe-check-text[_ngcontent-%COMP%]{font-family:Skycoin;line-height:normal;font-size:14px;color:#1e2227}.-check[_ngcontent-%COMP%] .mat-checkbox-checkmark-path{position:absolute;width:18px;height:8px;left:4.59px;top:9px;stroke:#0072ff!important}.-check[_ngcontent-%COMP%] .mat-checkbox-background, .-check[_ngcontent-%COMP%] .mat-checkbox-frame{top:0;left:0;right:0;bottom:0;position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;pointer-events:none;width:20px;height:20px;background:rgba(30,34,39,.05);border-radius:6px;border-color:transparent}.-text-center[_ngcontent-%COMP%]{text-align:center}.-no-bottom-margin[_ngcontent-%COMP%] button{margin:28px 10px 0!important}.-title[_ngcontent-%COMP%]{font-family:Skycoin;line-height:30px;font-size:14px;text-align:center;letter-spacing:.0769231em;color:#ff004e}"]],data:{}});function sw(n){return l._33(0,[(n()(),l._9(0,0,null,null,27,"app-modal",[["class","-title"]],null,null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,14,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,2,"span",[["class","-safe-description"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,7,"div",[["class","-check-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,4,"mat-checkbox",[["class","-safe-check-text -check mat-checkbox"],["id","terms"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setAccept(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(14,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{id:[0,"id"],checked:[1,"checked"]},{change:"change"}),(n()(),l._31(15,0,["","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(20,0,null,0,6,"div",[["class","-text-center"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,3,"app-button",[["class","primary -no-bottom-margin"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closePopup()&&l),l},w_,g_)),l._8(23,49152,null,0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(24,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,e.dialogRef,l._32(t,1,1,l._22(t,2).transform("wizard.confirm.title"))),n(t,14,0,"terms",e.acceptSafe),n(t,23,0,!e.acceptSafe)},function(n,t){n(t,7,0,l._32(t,7,0,l._22(t,8).transform("wizard.confirm.desc"))),n(t,12,0,l._22(t,14).id,l._22(t,14).indeterminate,l._22(t,14).checked,l._22(t,14).disabled,"before"==l._22(t,14).labelPosition),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("wizard.confirm.checkbox"))),n(t,24,0,l._32(t,24,0,l._22(t,25).transform("wizard.confirm.button")))})}var aw=l._5("app-onboarding-safeguard",Xb,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-onboarding-safeguard",[],null,null,null,sw,ow)),l._8(1,49152,null,0,Xb,[ca],null,null)],null,null)},{},{},[]),uw=l._7({encapsulation:0,styles:[[".-buttons[_ngcontent-%COMP%]{text-align:center}.-info[_ngcontent-%COMP%]{margin:5px 0 25px;color:rgba(30,34,39,.5);font-size:12px;line-height:1.5}.-warning[_ngcontent-%COMP%]{color:#ff004e}.link[_ngcontent-%COMP%]{font-size:13px;width:100%;display:inline-block;text-align:center;text-decoration:none;color:#0072ff}"]],data:{}});function cw(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"p",[["class","-info"]],null,null,null,null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(2,{"-warning":0}),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,"-info",n(t,2,0,t.component.data.warning))},function(n,t){var e=t.component;n(t,3,0,l._32(t,3,0,l._22(t,4).transform(e.data.description)))})}function dw(n){return l._33(0,[(n()(),l._9(0,0,null,null,13,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"label",[["for","confirm_password"]],null,null,null,null,null)),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,6,"input",[["appDontSavePassword",""],["formControlName","confirm_password"],["id","confirm_password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"focus"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,7)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,7).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,7)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,7)._compositionEnd(e.target.value)&&r),"focus"===t&&(r=!1!==l._22(n,12).onFocus()&&r),"keydown.enter"===t&&(r=!1!==i.proceed()&&r),r},null,null)),l._8(7,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(9,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(11,16384,null,0,Eo,[uo],null,null),l._8(12,16384,null,0,Db,[l.l],null,null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,9,0,"confirm_password")},function(n,t){n(t,3,0,l._32(t,3,0,l._22(t,4).transform("password.confirm-label"))),n(t,6,0,l._22(t,11).ngClassUntouched,l._22(t,11).ngClassTouched,l._22(t,11).ngClassPristine,l._22(t,11).ngClassDirty,l._22(t,11).ngClassValid,l._22(t,11).ngClassInvalid,l._22(t,11).ngClassPending)})}function hw(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"a",[["class","link"]],[[8,"href",4]],null,null,null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._26(2,{"element-disabled":0}),(n()(),l._31(3,null,["",""])),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,"link",n(t,2,0,t.component.working))},function(n,t){n(t,0,0,"#/reset/"+t.component.data.wallet.filename),n(t,3,0,l._32(t,3,0,l._22(t,4).transform("password.reset-link")))})}function pw(n){return l._33(0,[l._29(402653184,1,{button:0}),(n()(),l._9(1,0,null,null,42,"app-modal",[],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,cw)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(9,0,null,0,22,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,10).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,10).onReset()&&r),r},null,null)),l._8(10,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(12,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(14,0,null,null,13,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,2,"label",[["for","password"]],null,null,null,null,null)),(n()(),l._31(17,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,6,"input",[["appDontSavePassword",""],["formControlName","password"],["id","password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"focus"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,21)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,21).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,21)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,21)._compositionEnd(e.target.value)&&r),"focus"===t&&(r=!1!==l._22(n,26).onFocus()&&r),"keydown.enter"===t&&(r=!1!==i.proceed()&&r),r},null,null)),l._8(21,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(23,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(25,16384,null,0,Eo,[uo],null,null),l._8(26,16384,null,0,Db,[l.l],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,dw)),l._8(30,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,hw)),l._8(34,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(36,0,null,0,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(38,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.proceed()&&l),l},w_,g_)),l._8(39,49152,[[1,4],["button",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(40,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,e.data.title?l._22(t,3).transform(e.data.title):l._22(t,4).transform("password.title")),e.working),n(t,7,0,e.data.description),n(t,10,0,e.form),n(t,23,0,"password"),n(t,30,0,e.data.confirm),n(t,34,0,e.data.wallet),n(t,39,0,!e.form.valid)},function(n,t){n(t,9,0,l._22(t,12).ngClassUntouched,l._22(t,12).ngClassTouched,l._22(t,12).ngClassPristine,l._22(t,12).ngClassDirty,l._22(t,12).ngClassValid,l._22(t,12).ngClassInvalid,l._22(t,12).ngClassPending),n(t,17,0,l._32(t,17,0,l._22(t,18).transform("password.label"))),n(t,20,0,l._22(t,25).ngClassUntouched,l._22(t,25).ngClassTouched,l._22(t,25).ngClassPristine,l._22(t,25).ngClassDirty,l._22(t,25).ngClassValid,l._22(t,25).ngClassInvalid,l._22(t,25).ngClassPending),n(t,40,0,l._32(t,40,0,l._22(t,41).transform("password.button")))})}var fw=l._5("app-password-dialog",Zp,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-password-dialog",[],null,null,null,pw,uw)),l._8(1,245760,null,0,Zp,[da,ca,jc,De.j],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),_w=l._7({encapsulation:0,styles:[[".-buttons[_ngcontent-%COMP%]{text-align:center}"]],data:{}});function mw(n){return l._33(0,[(n()(),l._9(0,0,null,null,21,"app-modal",[],null,null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,8,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,2,"label",[["for","seed"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,1,"textarea",[["id","seed"],["readonly",""]],null,null,null,null,null)),(n()(),l._31(11,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(14,0,null,0,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.dialogRef.close()&&l),l},w_,g_)),l._8(17,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(18,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){n(t,1,0,t.component.dialogRef,l._32(t,1,1,l._22(t,2).transform("title.seed")))},function(n,t){var e=t.component;n(t,7,0,l._32(t,7,0,l._22(t,8).transform("backup.seed"))),n(t,11,0,e.data.seed),n(t,18,0,l._32(t,18,0,l._22(t,19).transform("backup.close-button")))})}var gw=l._5("app-seed-modal",Xp,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-seed-modal",[],null,null,null,mw,_w)),l._8(1,180224,null,0,Xp,[da,ca],null,null)],null,null)},{},{},[]),yw=l._7({encapsulation:0,styles:[["mat-input-container[_ngcontent-%COMP%]{width:100%}.-buttons[_ngcontent-%COMP%]{text-align:center}"]],data:{}});function bw(n){return l._33(0,[l._29(402653184,1,{button:0}),(n()(),l._9(1,0,null,null,37,"app-modal",[],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(5,0,null,0,19,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,6).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,6).onReset()&&r),r},null,null)),l._8(6,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(8,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,13,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"label",[["for","quantity"]],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,6,"input",[["formControlName","quantity"],["id","quantity"],["max","100"],["min","1"],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,17)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,17).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,17)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,17)._compositionEnd(e.target.value)&&r),"change"===t&&(r=!1!==l._22(n,18).onChange(e.target.value)&&r),"input"===t&&(r=!1!==l._22(n,18).onChange(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,18).onTouched()&&r),"keydown.enter"===t&&(r=!1!==i.continue()&&r),r},null,null)),l._8(17,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(18,16384,null,0,so,[l.G,l.l],null,null),l._28(1024,null,to,function(n,t){return[n,t]},[ro,so]),l._8(20,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(22,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(26,0,null,0,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closePopup()&&l),l},w_,g_)),l._8(29,49152,null,0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(30,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(33,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.continue()&&l),l},w_,g_)),l._8(34,49152,[[1,4],["button",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(35,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("wallet.add-addresses.title")),l._22(t,34).isLoading()),n(t,6,0,e.form),n(t,20,0,"quantity"),n(t,29,0,l._22(t,34)&&l._22(t,34).isLoading()),n(t,34,0,!e.form.valid)},function(n,t){n(t,5,0,l._22(t,8).ngClassUntouched,l._22(t,8).ngClassTouched,l._22(t,8).ngClassPristine,l._22(t,8).ngClassDirty,l._22(t,8).ngClassValid,l._22(t,8).ngClassInvalid,l._22(t,8).ngClassPending),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("wallet.add-addresses.name-quantity"))),n(t,16,0,l._22(t,22).ngClassUntouched,l._22(t,22).ngClassTouched,l._22(t,22).ngClassPristine,l._22(t,22).ngClassDirty,l._22(t,22).ngClassValid,l._22(t,22).ngClassInvalid,l._22(t,22).ngClassPending),n(t,30,0,l._32(t,30,0,l._22(t,31).transform("wallet.add-addresses.cancel-button"))),n(t,35,0,l._32(t,35,0,l._22(t,36).transform("wallet.add-addresses.create-button")))})}var vw=l._5("app-number-of-addresses",Nf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-number-of-addresses",[],null,null,null,bw,yw)),l._8(1,245760,null,0,Nf,[da,ca,jc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),ww=l._7({encapsulation:0,styles:[["button[_ngcontent-%COMP%]{width:100%;text-align:left;padding:10px;border-bottom:1px solid #eff0f0}.wallet-container[_ngcontent-%COMP%]{padding-top:30px;margin:0 -10px}.wallet-container[_ngcontent-%COMP%]:first-child{padding-top:0}.wallet-container[_ngcontent-%COMP%] .title[_ngcontent-%COMP%]{color:#171a1d;border-bottom:1px solid #eff0f0;padding:0 10px;font-size:18px;line-height:32px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.wallet-container[_ngcontent-%COMP%] .address[_ngcontent-%COMP%]{font-size:13px;line-height:22px;color:#171a1d}.wallet-container[_ngcontent-%COMP%] .balance[_ngcontent-%COMP%]{font-size:12px;line-height:18px;color:#171a1d}.wallet-container[_ngcontent-%COMP%] .balance[_ngcontent-%COMP%] .grey[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}"]],data:{}});function xw(n){return l._33(0,[(n()(),l._9(0,0,null,null,19,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.select(n.context.$implicit.address)&&l),l},i_,r_)),l._8(1,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(2,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,1,"div",[["class","address"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(7,0,null,0,11,"div",[["class","balance"]],null,null,null,null,null)),(n()(),l._31(8,null,["","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._9(10,0,null,null,2,"span",[["class","grey"]],null,null,null,null,null)),(n()(),l._31(11,null,[""," | "])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(13,null,["\n ","\n "])),l._25(0,If,[tn,qc,gf]),(n()(),l._9(15,0,null,null,2,"span",[["class","grey"]],null,null,null,null,null)),(n()(),l._31(16,null,["",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "]))],function(n,t){n(t,1,0,"primary")},function(n,t){n(t,0,0,l._22(t,1).disabled||null),n(t,5,0,t.context.$implicit.address),n(t,8,0,l._32(t,8,0,l._22(t,9).transform(t.context.$implicit.coins.toString(),!0,"first"))),n(t,11,0,l._32(t,11,0,l._22(t,12).transform(t.context.$implicit.coins.toString(),!0,"last"))),n(t,13,0,l._32(t,13,0,l._22(t,14).transform(t.context.$implicit.hours.toString(),!1,"first"))),n(t,16,0,l._32(t,16,0,l._22(t,17).transform(t.context.$implicit.hours.toString(),!1,"last")))})}function Mw(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[["class","wallet-container select-address-theme"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,1,"div",[["class","title"]],[[8,"title",0]],null,null,null,null)),(n()(),l._31(3,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,xw)),l._8(6,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,6,0,t.context.$implicit.addresses)},function(n,t){n(t,2,0,l._12(1,"",t.context.$implicit.label,"")),n(t,3,0,t.context.$implicit.label)})}function kw(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"app-modal",[],null,null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,Mw)),l._8(5,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,e.dialogRef,l._32(t,1,1,l._22(t,2).transform("title.select-address"))),n(t,5,0,e.wallets)},null)}var Cw=l._5("app-select-address",Rm,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-select-address",[],null,null,null,kw,ww)),l._8(1,49152,null,0,Rm,[ca,Sc],null,null)],null,null)},{},{},[]),Sw=l._7({encapsulation:0,styles:[[".alert-box[_ngcontent-%COMP%]{margin-top:25px}.options-label[_ngcontent-%COMP%]{color:#171a1d;margin-top:25px;margin-bottom:10px;font-weight:700}.option-buttons-container[_ngcontent-%COMP%]{margin:0 -10px}.option-buttons-container[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{width:100%;text-align:left;padding:10px;border-bottom:1px solid #eff0f0}.option-buttons-container[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:first-child{border-top:1px solid #eff0f0}.option-buttons-container[_ngcontent-%COMP%] button[_ngcontent-%COMP%] .label[_ngcontent-%COMP%]{font-size:13px;line-height:22px;color:#171a1d}.option-buttons-container[_ngcontent-%COMP%] button[_ngcontent-%COMP%] .-red[_ngcontent-%COMP%]{color:#ff004e}.-blinking[_ngcontent-%COMP%]{-webkit-animation:1s linear infinite alert-blinking;animation:1s linear infinite alert-blinking}"]],data:{}});function Ow(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function Tw(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"app-hw-message",[],null,[[null,"linkClicked"]],function(n,t,e){var l=!0;return"linkClicked"===t&&(l=!1!==n.component.wipe()&&l),l},Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"],linkText:[2,"linkText"]},{linkClicked:"linkClicked"}),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Error,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.general.refused"))+" "+l._32(t,1,1,l._22(t,3).transform("hardware-wallet.options.forgotten-pin1")),l._32(t,1,2,l._22(t,4).transform("hardware-wallet.options.forgotten-pin2")))},null)}function Lw(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"app-hw-message",[],null,[[null,"linkClicked"]],function(n,t,e){var l=!0;return"linkClicked"===t&&(l=!1!==n.component.wipe()&&l),l},Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"],linkText:[2,"linkText"]},{linkClicked:"linkClicked"}),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Error,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.general.error-incorrect-pin"))+" "+l._32(t,1,1,l._22(t,3).transform("hardware-wallet.options.forgotten-pin1")),l._32(t,1,2,l._22(t,4).transform("hardware-wallet.options.forgotten-pin2")))},null)}function Pw(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"],upperBigText:[2,"upperBigText"],lowerLightText:[3,"lowerLightText"]},null),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.msgIcons.HardwareWallet,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.options.unconfigured-detected")),l._32(t,1,2,l._22(t,3).transform("hardware-wallet.options.unconfigured-detected-title")),l._32(t,1,3,l._22(t,4).transform("hardware-wallet.options.firmware-version"))+" "+e.firmwareVersion)},null)}function Dw(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"],lowerBigText:[2,"lowerBigText"],lowerLightText:[3,"lowerLightText"]},null),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.msgIcons.HardwareWallet,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.options.configured-detected")),e.walletName,l._32(t,1,3,l._22(t,3).transform("hardware-wallet.options.firmware-version"))+" "+e.firmwareVersion)},null)}function Aw(n){return l._33(0,[(n()(),l._9(0,0,null,null,0,"br",[],null,null,null,null,null))],null,null)}function Ew(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,null,null,null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"div",[],null,null,null,null,null)),(n()(),l._31(3,null,[""," ",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Aw)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,7,0,t.context.index1?t.context.index+1+")":"",l._32(t,3,1,l._22(t,4).transform(t.context.$implicit)))})}function Yw(n){return l._33(0,[(n()(),l._9(0,0,null,null,15,"div",[["class","alert-box"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(3,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["error"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,8,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,2,"div",[["class","title"]],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Ew)),l._8(13,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0),n(t,13,0,e.securityWarnings)},function(n,t){var e=t.component;n(t,9,0,l._32(t,9,0,l._22(t,10).transform(e.securityWarnings.length>1?"hardware-wallet.options.security-warnings-title":"hardware-wallet.options.security-warning-title")))})}function jw(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.update()&&l),l},i_,r_)),l._8(1,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(2,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,2,"div",[["class","label -blinking"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "]))],function(n,t){n(t,1,0,"primary")},function(n,t){n(t,0,0,l._22(t,1).disabled||null),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("hardware-wallet.options.update-firmware")))})}function Iw(n){return l._33(0,[(n()(),l._9(0,0,null,null,19,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,7,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.generateMnemonic()&&l),l},i_,r_)),l._8(3,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(4,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(6,0,null,0,2,"div",[["class","label"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,7,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.restoreMnemonic()&&l),l},i_,r_)),l._8(12,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(13,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(15,0,null,0,2,"div",[["class","label"]],null,null,null,null,null)),(n()(),l._31(16,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,"primary"),n(t,12,0,"primary")},function(n,t){n(t,2,0,l._22(t,3).disabled||null),n(t,7,0,l._32(t,7,0,l._22(t,8).transform("hardware-wallet.options.configure-automatically"))),n(t,11,0,l._22(t,12).disabled||null),n(t,16,0,l._32(t,16,0,l._22(t,17).transform("hardware-wallet.options.restore-backup")))})}function Rw(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.backup()&&l),l},i_,r_)),l._8(1,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(2,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,2,"div",[["class","label"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "]))],function(n,t){n(t,1,0,"primary")},function(n,t){n(t,0,0,l._22(t,1).disabled||null),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("hardware-wallet.options.create-backup")))})}function Hw(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.confirmSeed()&&l),l},i_,r_)),l._8(1,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(2,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,2,"div",[["class","label"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "]))],function(n,t){n(t,1,0,"primary")},function(n,t){n(t,0,0,l._22(t,1).disabled||null),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("hardware-wallet.options.confirm-seed")))})}function Nw(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.removePin()&&l),l},i_,r_)),l._8(1,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(2,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,2,"div",[["class","label -red"]],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "]))],function(n,t){n(t,1,0,"primary")},function(n,t){n(t,0,0,l._22(t,1).disabled||null),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("hardware-wallet.options.delete-pin")))})}function Fw(n){return l._33(0,[(n()(),l._9(0,0,null,null,28,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Rw)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Hw)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,7,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.changePin()&&l),l},i_,r_)),l._8(9,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(10,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(12,0,null,0,2,"div",[["class","label"]],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Nw)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,7,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.wipe()&&l),l},i_,r_)),l._8(21,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(22,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(24,0,null,0,2,"div",[["class","label -red"]],null,null,null,null,null)),(n()(),l._31(25,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.needsBackup),n(t,6,0,!e.needsBackup),n(t,9,0,"primary"),n(t,18,0,!e.needsPin),n(t,21,0,"primary")},function(n,t){var e=t.component;n(t,8,0,l._22(t,9).disabled||null),n(t,13,0,l._32(t,13,0,l._22(t,14).transform(e.needsPin?"hardware-wallet.options.create-pin":"hardware-wallet.options.change-pin"))),n(t,20,0,l._22(t,21).disabled||null),n(t,25,0,l._32(t,25,0,l._22(t,26).transform("hardware-wallet.options.wipe")))})}function Bw(n){return l._33(0,[(n()(),l._9(0,0,null,null,26,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Pw)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Dw)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Yw)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(11,0,null,null,2,"div",[["class","options-label"]],null,null,null,null,null)),(n()(),l._31(12,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,10,"div",[["class","option-buttons-container select-address-theme"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,jw)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Iw)),l._8(21,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Fw)),l._8(24,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.newWalletConnected),n(t,6,0,!e.newWalletConnected),n(t,9,0,e.securityWarnings.length>0),n(t,18,0,e.outdatedFirmware),n(t,21,0,e.newWalletConnected),n(t,24,0,!e.newWalletConnected)},function(n,t){n(t,12,0,l._32(t,12,0,l._22(t,13).transform("hardware-wallet.options.options")))})}function Vw(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function Ww(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function zw(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),(n()(),l._9(1,0,null,null,21,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,Ow)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Tw)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Lw)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Bw)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Vw)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Ww)),l._8(21,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("wallet.hardware-wallet"))),n(t,6,0,e.currentState===e.states.ShowingResult),n(t,9,0,e.currentState===e.states.Other&&!e.otherStateBecauseWrongPin),n(t,12,0,e.currentState===e.states.Other&&e.otherStateBecauseWrongPin),n(t,15,0,e.currentState===e.states.Finished),n(t,18,0,e.currentState===e.states.Finished),n(t,21,0,e.currentState!==e.states.Finished)},null)}var Uw=l._5("app-hw-options-dialog",ud,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-options-dialog",[],null,null,null,zw,Sw)),l._8(1,180224,null,0,ud,[da,ca,oc,fa,Sc,jc],null,null)],null,null)},{},{},[]),Gw=l._7({encapsulation:0,styles:[[""]],data:{}});function qw(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[["class","-check-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,4,"mat-checkbox",[["class","-check mat-checkbox"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setDeleteFromList(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(4,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{checked:[0,"checked"]},{change:"change"}),(n()(),l._31(5,0,["","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,4,0,t.component.deleteFromList)},function(n,t){n(t,2,0,l._22(t,4).id,l._22(t,4).indeterminate,l._22(t,4).checked,l._22(t,4).disabled,"before"==l._22(t,4).labelPosition),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("hardware-wallet.wipe.confirm-delete")))})}function Jw(n){return l._33(0,[(n()(),l._9(0,0,null,null,21,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(3,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,qw)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(9,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(12,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(13,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.requestWipe()&&l),l},w_,g_)),l._8(17,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(18,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.msgIcons.Warning,l._32(t,3,1,l._22(t,4).transform("hardware-wallet.wipe.warning"))),n(t,7,0,e.showDeleteFromList)},function(n,t){n(t,13,0,l._32(t,13,0,l._22(t,14).transform("hardware-wallet.general.cancel"))),n(t,18,0,l._32(t,18,0,l._22(t,19).transform("hardware-wallet.general.continue")))})}function Qw(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Confirm,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.general.confirm")))},null)}function Kw(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function Xw(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function Zw(n){return l._33(0,[(n()(),l._9(0,0,null,null,10,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Qw)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Kw)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,Xw)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.currentState===e.states.Processing),n(t,6,0,e.currentState===e.states.ShowingResult),n(t,9,0,e.currentState!==e.states.Processing)},null)}function $w(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),(n()(),l._9(1,0,null,null,9,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,Jw)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Zw)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("hardware-wallet.options.wipe")),e.currentState===e.states.Processing),n(t,6,0,e.currentState===e.states.Initial),n(t,9,0,e.currentState!==e.states.Initial)},null)}var nx=l._5("app-hw-wipe-dialog",Xc,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-wipe-dialog",[],null,null,null,$w,Gw)),l._8(1,180224,null,0,Xc,[da,ca,oc,Sc],null,null)],null,null)},{},{},[]),tx=l._7({encapsulation:0,styles:[[".upper-text[_ngcontent-%COMP%]{margin-top:10px;margin-bottom:10px}.warning[_ngcontent-%COMP%]{margin:-20px 0 20px;color:rgba(30,34,39,.5)}"]],data:{}});function ex(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Spinner,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.added.configuring")))},null)}function lx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function rx(n){return l._33(0,[(n()(),l._9(0,0,null,null,35,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(3,49152,null,0,Rc,[],{icon:[0,"icon"],upperBigText:[1,"upperBigText"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(6,0,null,null,2,"div",[["class","upper-text"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,16,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,11).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,11).onReset()&&r),r},null,null)),l._8(11,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(13,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,10,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,[[2,0],["input",1]],null,7,"input",[["formControlName","label"],["id","label"]],[[1,"maxlength",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,18)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,18).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,18)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,18)._compositionEnd(e.target.value)&&r),"keydown.enter"===t&&(r=!1!==i.saveNameAndCloseModal()&&r),r},null,null)),l._8(18,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(19,540672,null,0,$o,[],{maxlength:[0,"maxlength"]},null),l._28(1024,null,Qi,function(n){return[n]},[$o]),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(22,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(24,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,0,null,null,2,"div",[["class","warning"]],null,null,null,null,null)),(n()(),l._31(29,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n \n "])),(n()(),l._9(32,0,null,null,2,"div",[],null,null,null,null,null)),(n()(),l._31(33,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.msgIcons.Success,l._32(t,3,1,l._22(t,4).transform("hardware-wallet.added.done"))),n(t,11,0,e.form),n(t,19,0,e.maxHwWalletLabelLength),n(t,22,0,"label")},function(n,t){n(t,7,0,l._32(t,7,0,l._22(t,8).transform("hardware-wallet.added.added1"))),n(t,10,0,l._22(t,13).ngClassUntouched,l._22(t,13).ngClassTouched,l._22(t,13).ngClassPristine,l._22(t,13).ngClassDirty,l._22(t,13).ngClassValid,l._22(t,13).ngClassInvalid,l._22(t,13).ngClassPending),n(t,17,0,l._22(t,19).maxlength?l._22(t,19).maxlength:null,l._22(t,24).ngClassUntouched,l._22(t,24).ngClassTouched,l._22(t,24).ngClassPristine,l._22(t,24).ngClassDirty,l._22(t,24).ngClassValid,l._22(t,24).ngClassInvalid,l._22(t,24).ngClassPending),n(t,29,0,l._32(t,29,0,l._22(t,30).transform("hardware-wallet.added.characters-warning"))),n(t,33,0,l._32(t,33,0,l._22(t,34).transform("hardware-wallet.added.added2")))})}function ix(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0,r=n.component;return"action"===t&&(l=!1!==(r.currentState===r.states.Finished?r.saveNameAndCloseModal():r.closeModal())&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.currentState===e.states.Finished&&!e.form.valid)},function(n,t){var e=t.component;n(t,4,0,l._32(t,4,0,l._22(t,5).transform(e.currentState===e.states.Finished?"hardware-wallet.added.ok":"hardware-wallet.general.close")))})}function ox(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),l._29(671088640,2,{input:0}),(n()(),l._9(2,0,null,null,15,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(3,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,ex)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,lx)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,rx)),l._8(13,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,ix)),l._8(16,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,3,0,e.dialogRef,l._32(t,3,1,l._22(t,4).transform("hardware-wallet.added.title")),e.currentState===e.states.Initial||e.currentState===e.states.Finished),n(t,7,0,e.currentState===e.states.Initial),n(t,10,0,e.currentState===e.states.ShowingResult),n(t,13,0,e.currentState===e.states.Finished),n(t,16,0,e.currentState===e.states.Finished||e.currentState===e.states.ShowingResult)},null)}var sx=l._5("app-hw-added-dialog",td,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-added-dialog",[],null,null,null,ox,tx)),l._8(1,180224,null,0,td,[da,ca,Sc,oc,ns,fa,jc],null,null)],null,null)},{},{},[]),ax=l._7({encapsulation:0,styles:[[".form-field[_ngcontent-%COMP%]{margin-bottom:0;margin-top:15px}"]],data:{}});function ux(n){return l._33(0,[(n()(),l._9(0,0,null,null,50,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(3,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(6,0,null,null,30,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,7).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,7).onReset()&&r),r},null,null)),l._8(7,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(9,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,24,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,21,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,18,"select",[["formControlName","words"],["id","words"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(n,t,e){var r=!0;return"change"===t&&(r=!1!==l._22(n,16).onChange(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,16).onTouched()&&r),r},null,null)),l._8(16,16384,null,0,_o,[l.G,l.l],null,null),l._28(1024,null,to,function(n){return[n]},[_o]),l._8(18,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(20,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,4,"option",[],null,null,null,null,null)),l._8(23,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(24,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(25,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,0,null,null,4,"option",[],null,null,null,null,null)),l._8(29,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(30,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(31,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(38,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(40,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(41,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(42,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(45,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.startOperation()&&l),l},w_,g_)),l._8(46,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(47,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.msgIcons.None,l._32(t,3,1,l._22(t,4).transform("hardware-wallet.generate-seed.text"))),n(t,7,0,e.form),n(t,18,0,"words"),n(t,23,0,12),n(t,24,0,12),n(t,29,0,24),n(t,30,0,24)},function(n,t){n(t,6,0,l._22(t,9).ngClassUntouched,l._22(t,9).ngClassTouched,l._22(t,9).ngClassPristine,l._22(t,9).ngClassDirty,l._22(t,9).ngClassValid,l._22(t,9).ngClassInvalid,l._22(t,9).ngClassPending),n(t,15,0,l._22(t,20).ngClassUntouched,l._22(t,20).ngClassTouched,l._22(t,20).ngClassPristine,l._22(t,20).ngClassDirty,l._22(t,20).ngClassValid,l._22(t,20).ngClassInvalid,l._22(t,20).ngClassPending),n(t,25,0,l._32(t,25,0,l._22(t,26).transform("wallet.new.12-words"))),n(t,31,0,l._32(t,31,0,l._22(t,32).transform("wallet.new.24-words"))),n(t,42,0,l._32(t,42,0,l._22(t,43).transform("hardware-wallet.general.cancel"))),n(t,47,0,l._32(t,47,0,l._22(t,48).transform("hardware-wallet.general.continue")))})}function cx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Spinner,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.generate-seed.configuring")))},null)}function dx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function hx(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function px(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),(n()(),l._9(1,0,null,null,15,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,ux)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,cx)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,dx)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,hx)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("hardware-wallet.options.configure-automatically")),e.currentState===e.states.Processing),n(t,6,0,e.currentState===e.states.Initial),n(t,9,0,e.currentState===e.states.Processing),n(t,12,0,e.currentState===e.states.ShowingResult),n(t,15,0,e.currentState!==e.states.Initial&&e.currentState!==e.states.Processing)},null)}var fx=l._5("app-hw-generate-seed-dialog",ed,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-generate-seed-dialog",[],null,null,null,px,ax)),l._8(1,180224,null,0,ed,[da,ca,oc,ns],null,null)],null,null)},{},{},[]),_x=l._7({encapsulation:0,styles:[[""]],data:{}});function mx(n){return l._33(0,[(n()(),l._9(0,0,null,null,18,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(3,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(6,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(9,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(10,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.requestBackup()&&l),l},w_,g_)),l._8(14,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(15,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,t.component.msgIcons.Warning,l._32(t,3,1,l._22(t,4).transform("hardware-wallet.create-backup.warning")))},function(n,t){n(t,10,0,l._32(t,10,0,l._22(t,11).transform("hardware-wallet.general.cancel"))),n(t,15,0,l._32(t,15,0,l._22(t,16).transform("hardware-wallet.general.continue")))})}function gx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Confirm,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.create-backup.instructions")))},null)}function yx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function bx(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function vx(n){return l._33(0,[(n()(),l._9(0,0,null,null,10,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,gx)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,yx)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,bx)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.currentState===e.states.Processing),n(t,6,0,e.currentState===e.states.ShowingResult),n(t,9,0,e.currentState!==e.states.Processing)},null)}function wx(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),(n()(),l._9(1,0,null,null,9,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,mx)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,vx)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("hardware-wallet.options.create-backup")),e.currentState===e.states.Processing),n(t,6,0,e.currentState===e.states.Initial),n(t,9,0,e.currentState!==e.states.Initial)},null)}var xx=l._5("app-hw-backup-dialog",ld,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-backup-dialog",[],null,null,null,wx,_x)),l._8(1,180224,null,0,ld,[da,ca,oc],null,null)],null,null)},{},{},[]),Mx=l._7({encapsulation:0,styles:[[".red-title[_ngcontent-%COMP%]{font-family:Skycoin;line-height:30px;font-size:14px;text-align:center;letter-spacing:.0769231em;color:#ff004e}.link[_ngcontent-%COMP%]{cursor:pointer;color:#0072ff}"]],data:{}});function kx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[["class","link"]],null,[[null,"click"]],function(n,t,e){var l=!0,r=n.component;return"click"===t&&(r.data.linkFunction(),l=!1!==r.closeModal(!1)&&l),l},null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform(e.data.linkText)))})}function Cx(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[["class","-check-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,4,"mat-checkbox",[["class","-check e2e-confirm-checkbox mat-checkbox"],["id","terms"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setAccept(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(4,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{id:[0,"id"],checked:[1,"checked"]},{change:"change"}),(n()(),l._31(5,0,["","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,4,0,"terms",t.component.accepted)},function(n,t){var e=t.component;n(t,2,0,l._22(t,4).id,l._22(t,4).indeterminate,l._22(t,4).checked,l._22(t,4).disabled,"before"==l._22(t,4).labelPosition),n(t,5,0,l._32(t,5,0,l._22(t,6).transform(e.data.checkboxText)))})}function Sx(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal(!1)&&l),l},w_,g_)),l._8(1,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(2,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){var e=t.component;n(t,2,0,l._32(t,2,0,l._22(t,3).transform(e.data.cancelButtonText)))})}function Ox(n){return l._33(0,[(n()(),l._9(0,0,null,null,24,"app-modal",[["class","modal"]],[[2,"red-title",null]],null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,5,"div",[["class","-body"]],null,null,null,null,null)),(n()(),l._31(5,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._4(16777216,null,null,1,null,kx)),l._8(8,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Cx)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._9(14,0,null,0,9,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Sx)),l._8(17,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(19,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal(!0)&&l),l},w_,g_)),l._8(20,49152,null,0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(21,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,e.dialogRef,l._32(t,1,1,l._22(t,2).transform(e.data.headerText)),e.disableDismiss),n(t,8,0,e.data.linkText&&e.data.linkFunction),n(t,12,0,e.data.checkboxText),n(t,17,0,e.data.cancelButtonText),n(t,20,0,e.data.checkboxText&&!e.accepted)},function(n,t){var e=t.component;n(t,0,0,e.data.redTitle),n(t,5,0,l._32(t,5,0,l._22(t,6).transform(e.data.text))),n(t,21,0,l._32(t,21,0,l._22(t,22).transform(e.data.confirmButtonText)))})}var Tx=l._5("app-confirmation",Nc,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-confirmation",[],null,null,null,Ox,Mx)),l._8(1,49152,null,0,Nc,[ca,da],null,null)],null,null)},{},{},[]),Lx=l._7({encapsulation:0,styles:[["mat-input-container[_ngcontent-%COMP%]{width:100%}.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{font-size:25px;letter-spacing:15px;text-align:center}.form-field[_ngcontent-%COMP%] .info[_ngcontent-%COMP%]{text-align:center}.form-field[_ngcontent-%COMP%] .info[_ngcontent-%COMP%] .link[_ngcontent-%COMP%]{color:#0072ff;cursor:pointer}.num-pad-row[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex}.num-pad-row[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;height:50px;border:1px solid #eff0f0;margin:2px}.num-pad-row[_ngcontent-%COMP%] button[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:#171a1d}"]],data:{}});function Px(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("hardware-wallet.enter-pin.instructions-tx")))})}function Dx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"span",[],null,null,null,null,null)),(n()(),l._31(1,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("hardware-wallet.enter-pin.instructions-change")))})}function Ax(n){return l._33(0,[l._29(402653184,1,{closeButton:0}),(n()(),l._9(1,0,null,null,116,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(5,0,null,0,28,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,6).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,6).onReset()&&r),r},null,null)),l._8(6,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(8,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,22,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,12,"div",[["class","info"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Px)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,Dx)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(19,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(21,0,null,null,2,"span",[["class","link"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.openHelp()&&l),l},null,null)),(n()(),l._31(22,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(26,0,null,null,5,"input",[["formControlName","pin"],["id","pin"],["readonly",""],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,27)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,27).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,27)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,27)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(27,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(29,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(31,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(35,0,null,0,73,"div",[["class","select-address-theme"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(37,0,null,null,19,"div",[["class","num-pad-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(39,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("7")&&l),l},i_,r_)),l._8(40,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(41,16384,null,0,Hs,[],null,null),(n()(),l._9(42,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(43,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(45,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("8")&&l),l},i_,r_)),l._8(46,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(47,16384,null,0,Hs,[],null,null),(n()(),l._9(48,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(49,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(51,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("9")&&l),l},i_,r_)),l._8(52,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(53,16384,null,0,Hs,[],null,null),(n()(),l._9(54,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(55,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(58,0,null,null,19,"div",[["class","num-pad-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(60,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("4")&&l),l},i_,r_)),l._8(61,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(62,16384,null,0,Hs,[],null,null),(n()(),l._9(63,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(64,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(66,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("5")&&l),l},i_,r_)),l._8(67,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(68,16384,null,0,Hs,[],null,null),(n()(),l._9(69,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(70,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(72,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("6")&&l),l},i_,r_)),l._8(73,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(74,16384,null,0,Hs,[],null,null),(n()(),l._9(75,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(76,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(79,0,null,null,19,"div",[["class","num-pad-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(81,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("1")&&l),l},i_,r_)),l._8(82,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(83,16384,null,0,Hs,[],null,null),(n()(),l._9(84,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(85,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(87,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("2")&&l),l},i_,r_)),l._8(88,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(89,16384,null,0,Hs,[],null,null),(n()(),l._9(90,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(91,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(93,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.addNumber("3")&&l),l},i_,r_)),l._8(94,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(95,16384,null,0,Hs,[],null,null),(n()(),l._9(96,0,null,0,1,"span",[],null,null,null,null,null)),(n()(),l._31(97,null,["",""])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(100,0,null,null,7,"div",[["class","num-pad-row"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(102,0,null,null,4,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.removeNumber()&&l),l},i_,r_)),l._8(103,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(104,16384,null,0,Hs,[],null,null),(n()(),l._9(105,0,null,0,1,"span",[["class","material-icons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["backspace"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(110,0,null,0,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(112,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.sendPin()&&l),l},w_,g_)),l._8(113,49152,null,0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(114,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform(e.title))),n(t,6,0,e.form),n(t,15,0,e.data.signingTx),n(t,18,0,e.data.changingPin&&e.data.changePinState===e.changePinStates.RequestingNewPin),n(t,29,0,"pin"),n(t,40,0,"primary"),n(t,46,0,"primary"),n(t,52,0,"primary"),n(t,61,0,"primary"),n(t,67,0,"primary"),n(t,73,0,"primary"),n(t,82,0,"primary"),n(t,88,0,"primary"),n(t,94,0,"primary"),n(t,103,0,"primary"),n(t,113,0,!e.form.valid)},function(n,t){var e=t.component;n(t,5,0,l._22(t,8).ngClassUntouched,l._22(t,8).ngClassTouched,l._22(t,8).ngClassPristine,l._22(t,8).ngClassDirty,l._22(t,8).ngClassValid,l._22(t,8).ngClassInvalid,l._22(t,8).ngClassPending),n(t,19,0,l._32(t,19,0,l._22(t,20).transform("hardware-wallet.enter-pin.instructions"))),n(t,22,0,l._32(t,22,0,l._22(t,23).transform("hardware-wallet.enter-pin.help"))),n(t,26,0,l._22(t,31).ngClassUntouched,l._22(t,31).ngClassTouched,l._22(t,31).ngClassPristine,l._22(t,31).ngClassDirty,l._22(t,31).ngClassValid,l._22(t,31).ngClassInvalid,l._22(t,31).ngClassPending),n(t,39,0,l._22(t,40).disabled||null),n(t,43,0,e.buttonsContent),n(t,45,0,l._22(t,46).disabled||null),n(t,49,0,e.buttonsContent),n(t,51,0,l._22(t,52).disabled||null),n(t,55,0,e.buttonsContent),n(t,60,0,l._22(t,61).disabled||null),n(t,64,0,e.buttonsContent),n(t,66,0,l._22(t,67).disabled||null),n(t,70,0,e.buttonsContent),n(t,72,0,l._22(t,73).disabled||null),n(t,76,0,e.buttonsContent),n(t,81,0,l._22(t,82).disabled||null),n(t,85,0,e.buttonsContent),n(t,87,0,l._22(t,88).disabled||null),n(t,91,0,e.buttonsContent),n(t,93,0,l._22(t,94).disabled||null),n(t,97,0,e.buttonsContent),n(t,102,0,l._22(t,103).disabled||null),n(t,114,0,l._32(t,114,0,l._22(t,115).transform("hardware-wallet.general.continue")))})}var Ex=l._5("app-hw-pin-dialog",bf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-pin-dialog",[],null,[["window","keyup"]],function(n,t,e){var r=!0;return"window:keyup"===t&&(r=!1!==l._22(n,1).keyEvent(e)&&r),r},Ax,Lx)),l._8(1,245760,null,0,bf,[da,ca,ns,fa,oc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),Yx=l._7({encapsulation:0,styles:[[""]],data:{}});function jx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Confirm,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.general.confirm")))},null)}function Ix(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function Rx(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function Hx(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),(n()(),l._9(1,0,null,null,12,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,jx)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Ix)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Rx)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform(e.changingExistingPin?"hardware-wallet.options.change-pin":"hardware-wallet.options.create-pin")),e.currentState===e.states.Initial),n(t,6,0,e.currentState===e.states.Initial),n(t,9,0,e.currentState===e.states.ShowingResult),n(t,12,0,e.currentState!==e.states.Initial)},null)}var Nx=l._5("app-hw-change-pin-dialog",rd,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-change-pin-dialog",[],null,null,null,Hx,Yx)),l._8(1,180224,null,0,rd,[da,ca,oc],null,null)],null,null)},{},{},[]),Fx=l._7({encapsulation:0,styles:[[""]],data:{}});function Bx(n){return l._33(0,[(n()(),l._9(0,0,null,null,15,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,2,"p",[],null,null,null,null,null)),(n()(),l._31(5,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(8,0,null,0,2,"p",[],null,null,null,null,null)),(n()(),l._31(9,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(12,0,null,0,2,"p",[],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){n(t,1,0,t.component.dialogRef,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.pin-help.title")))},function(n,t){n(t,5,0,l._32(t,5,0,l._22(t,6).transform("hardware-wallet.pin-help.part1"))),n(t,9,0,l._32(t,9,0,l._22(t,10).transform("hardware-wallet.pin-help.part2"))),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("hardware-wallet.pin-help.part3")))})}var Vx=l._5("app-hw-added-dialog",yf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-added-dialog",[],null,null,null,Bx,Fx)),l._8(1,49152,null,0,yf,[ca],null,null)],null,null)},{},{},[]),Wx=l._7({encapsulation:0,styles:[[".form-field[_ngcontent-%COMP%]{margin-bottom:0;margin-top:15px}.warning[_ngcontent-%COMP%]{margin-top:15px;color:#ff004e;text-align:center}"]],data:{}});function zx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"div",[["class","warning"]],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("hardware-wallet.restore-seed.warning")))})}function Ux(n){return l._33(0,[(n()(),l._9(0,0,null,null,53,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(3,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(6,0,null,null,30,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,7).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,7).onReset()&&r),r},null,null)),l._8(7,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(9,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,24,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,21,"div",[["class","-select"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,18,"select",[["formControlName","words"],["id","words"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(n,t,e){var r=!0;return"change"===t&&(r=!1!==l._22(n,16).onChange(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,16).onTouched()&&r),r},null,null)),l._8(16,16384,null,0,_o,[l.G,l.l],null,null),l._28(1024,null,to,function(n){return[n]},[_o]),l._8(18,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(20,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,4,"option",[],null,null,null,null,null)),l._8(23,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(24,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(25,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(28,0,null,null,4,"option",[],null,null,null,null,null)),l._8(29,147456,null,0,mo,[l.l,l.G,[2,_o]],{ngValue:[0,"ngValue"]},null),l._8(30,147456,null,0,bo,[l.l,l.G,[8,null]],{ngValue:[0,"ngValue"]},null),(n()(),l._31(31,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,zx)),l._8(39,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(41,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(43,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(44,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(45,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(48,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.startOperation()&&l),l},w_,g_)),l._8(49,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(50,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.msgIcons.None,l._32(t,3,1,l._22(t,4).transform(e.justCheckingSeed?"hardware-wallet.restore-seed.check-text":"hardware-wallet.restore-seed.text"))),n(t,7,0,e.form),n(t,18,0,"words"),n(t,23,0,12),n(t,24,0,12),n(t,29,0,24),n(t,30,0,24),n(t,39,0,!e.justCheckingSeed)},function(n,t){n(t,6,0,l._22(t,9).ngClassUntouched,l._22(t,9).ngClassTouched,l._22(t,9).ngClassPristine,l._22(t,9).ngClassDirty,l._22(t,9).ngClassValid,l._22(t,9).ngClassInvalid,l._22(t,9).ngClassPending),n(t,15,0,l._22(t,20).ngClassUntouched,l._22(t,20).ngClassTouched,l._22(t,20).ngClassPristine,l._22(t,20).ngClassDirty,l._22(t,20).ngClassValid,l._22(t,20).ngClassInvalid,l._22(t,20).ngClassPending),n(t,25,0,l._32(t,25,0,l._22(t,26).transform("wallet.new.12-words"))),n(t,31,0,l._32(t,31,0,l._22(t,32).transform("wallet.new.24-words"))),n(t,45,0,l._32(t,45,0,l._22(t,46).transform("hardware-wallet.general.cancel"))),n(t,50,0,l._32(t,50,0,l._22(t,51).transform("hardware-wallet.general.continue")))})}function Gx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.msgIcons.Confirm,l._32(t,1,1,l._22(t,2).transform(e.justCheckingSeed?"hardware-wallet.general.follow":"hardware-wallet.general.confirm-and-more")))},null)}function qx(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function Jx(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function Qx(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),(n()(),l._9(1,0,null,null,15,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Ux)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Gx)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,qx)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,Jx)),l._8(15,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform(e.justCheckingSeed?"hardware-wallet.options.confirm-seed":"hardware-wallet.options.restore-backup")),e.currentState===e.states.Processing),n(t,6,0,e.currentState===e.states.Initial),n(t,9,0,e.currentState===e.states.Processing),n(t,12,0,e.currentState===e.states.ShowingResult),n(t,15,0,e.currentState!==e.states.Initial&&e.currentState!==e.states.Processing)},null)}var Kx=l._5("app-hw-restore-seed-dialog",id,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-restore-seed-dialog",[],null,null,null,Qx,Wx)),l._8(1,180224,null,0,id,[da,ca,oc,ns],null,null)],null,null)},{},{},[]),Xx=l._7({encapsulation:0,styles:[[""]],data:{}});function Zx(n){return l._33(0,[l._29(402653184,1,{closeButton:0}),(n()(),l._9(1,0,null,null,8,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(5,0,null,0,3,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(6,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"],outputsList:[2,"outputsList"],lowerText:[3,"lowerText"]},null),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("hardware-wallet.create-tx.title")),!0),n(t,6,0,e.msgIcons.Confirm,l._32(t,6,1,l._22(t,7).transform("hardware-wallet.create-tx.upper-text")),e.data,l._32(t,6,3,l._22(t,8).transform("hardware-wallet.create-tx.lower-text")))},null)}var $x=l._5("app-hw-confirm-tx-dialog",vf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-confirm-tx-dialog",[],null,null,null,Zx,Xx)),l._8(1,180224,null,0,vf,[da,ca,oc],null,null)],null,null)},{},{},[]),nM=l._7({encapsulation:0,styles:[[""]],data:{}});function tM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"],lowerBigText:[2,"lowerBigText"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.msgIcons.Confirm,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.confirm-address.instructions")),e.data.address.address)},null)}function eM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function lM(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function rM(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),(n()(),l._9(1,0,null,null,12,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,tM)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,eM)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,lM)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("hardware-wallet.confirm-address.title")),e.currentState===e.states.Initial),n(t,6,0,e.currentState===e.states.Initial),n(t,9,0,e.currentState===e.states.ShowingResult),n(t,12,0,e.currentState!==e.states.Initial)},null)}var iM=l._5("app-hw-confirm-address-dialog",Ff,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-confirm-address-dialog",[],null,null,null,rM,nM)),l._8(1,180224,null,0,Ff,[da,ca,oc,Sc],null,null)],null,null)},{},{},[]),oM=l._7({encapsulation:0,styles:[[".options-container[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-ms-flex-wrap:wrap;flex-wrap:wrap}.options-container[_ngcontent-%COMP%] .button[_ngcontent-%COMP%]{width:118px;margin:20px;font-size:12px;line-height:unset;padding:0;color:unset;min-width:0}.options-container[_ngcontent-%COMP%] .button[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{width:64px;height:64px;margin:10px 0}.options-container[_ngcontent-%COMP%] .button[_ngcontent-%COMP%] .label[_ngcontent-%COMP%]{background-color:rgba(30,34,39,.05);padding:4px 10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}"]],data:{}});function sM(n){return l._33(0,[(n()(),l._9(0,0,null,null,8,"button",[["class","button mat-button"],["color","accent"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.closePopup(n.context.$implicit)&&l),l},i_,r_)),l._8(1,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(2,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,0,"img",[],[[8,"src",4]],null,null,null,null)),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(6,0,null,0,1,"div",[["class","label"]],null,null,null,null,null)),(n()(),l._31(7,null,["",""])),(n()(),l._31(-1,0,["\n "]))],function(n,t){n(t,1,0,"accent")},function(n,t){n(t,0,0,l._22(t,1).disabled||null),n(t,4,0,"assets/img/lang/"+t.context.$implicit.iconName),n(t,7,0,t.context.$implicit.name)})}function aM(n){return l._33(0,[(n()(),l._9(0,0,null,null,9,"app-modal",[["class","e2e-language-modal"]],null,null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,4,"div",[["class","options-container subtle-theme"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,sM)),l._8(7,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,e.dialogRef,l._32(t,1,1,l._22(t,2).transform("title.language")),e.disableDismiss),n(t,7,0,e.languages)},null)}var uM=l._5("app-select-language",Vc,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-select-language",[],null,null,null,aM,oM)),l._8(1,114688,null,0,Vc,[ca,Bc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),cM=l._7({encapsulation:0,styles:[["button[_ngcontent-%COMP%]{width:100%;text-align:left;padding:10px;border-bottom:1px solid #eff0f0;cursor:pointer}button[_ngcontent-%COMP%] .info[_ngcontent-%COMP%]{font-size:13px;line-height:22px;color:#171a1d}button[_ngcontent-%COMP%] .info[_ngcontent-%COMP%] div[_ngcontent-%COMP%]{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}button[_ngcontent-%COMP%] .info[_ngcontent-%COMP%] div[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{font-size:16px;width:16px;height:16px;position:relative;top:3px;margin:0 5px}button[_ngcontent-%COMP%] .info[_ngcontent-%COMP%] .grey[_ngcontent-%COMP%]{color:rgba(30,34,39,.5)}button[_ngcontent-%COMP%] .action[_ngcontent-%COMP%]{color:#0072ff}"]],data:{}});function dM(n){return l._33(0,[(n()(),l._9(0,0,null,null,26,"div",[["class","select-address-theme"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,23,"button",[["class","mat-button"],["color","primary"],["mat-button",""]],[[8,"disabled",0]],[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.select(n.context.$implicit)&&l),l},i_,r_)),l._8(3,180224,null,0,Bs,[l.l,Hl,Rr],{color:[0,"color"]},null),l._8(4,16384,null,0,Hs,[],null,null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(6,0,null,0,18,"div",[["class","info"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,6,"div",[],null,null,null,null,null)),(n()(),l._31(9,null,[""," "," "])),(n()(),l._9(10,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(11,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["play_arrow"])),(n()(),l._31(13,null,[" \u2248"," ",""])),l._25(0,If,[tn,qc,gf]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,2,"div",[["class","grey"]],null,null,null,null,null)),(n()(),l._31(17,null,["",": ",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,0,null,null,3,"div",[["class","grey"]],null,null,null,null,null)),(n()(),l._31(21,null,["",": ",""])),l._25(131072,De.i,[De.j,l.h]),l._27(23,1),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,3,0,"primary"),n(t,11,0)},function(n,t){var e=t.component;n(t,2,0,l._22(t,3).disabled||null),n(t,9,0,t.context.$implicit.fromAmount,e.getFromCoin(t.context.$implicit.pair)),n(t,13,0,l._32(t,13,0,l._22(t,14).transform(t.context.$implicit.toAmount,!0,"first")),e.getToCoin(t.context.$implicit.pair)),n(t,17,0,l._32(t,17,0,l._22(t,18).transform("exchange.history-window.address")),t.context.$implicit.address),n(t,21,0,l._32(t,21,0,l._22(t,22).transform("exchange.history-window.date")),l._32(t,21,1,n(t,23,0,l._22(t.parent,0),t.context.$implicit.timestamp)))})}function hM(n){return l._33(0,[l._25(0,ag,[]),(n()(),l._9(1,0,null,null,6,"app-modal",[],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,dM)),l._8(6,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("title.order-history"))),n(t,6,0,e.orders)},null)}var pM=l._5("app-exchange-history",ff,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-exchange-history",[],null,null,null,hM,cM)),l._8(1,114688,null,0,ff,[ca,qc,pf],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),fM=l._7({encapsulation:0,styles:[[""]],data:{}});function _M(n){return l._33(0,[(n()(),l._9(0,0,null,null,27,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(3,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(6,0,null,null,7,"div",[["class","-check-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(8,0,null,null,4,"mat-checkbox",[["class","-check mat-checkbox"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setConfirmed(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(10,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{checked:[0,"checked"]},{change:"change"}),(n()(),l._31(11,0,["","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(15,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(18,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(19,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.requestRemoval()&&l),l},w_,g_)),l._8(23,49152,null,0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(24,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.msgIcons.Warning,l._32(t,3,1,l._22(t,4).transform("hardware-wallet.remove-pin.warning"))),n(t,10,0,e.confirmed),n(t,23,0,!e.confirmed)},function(n,t){n(t,8,0,l._22(t,10).id,l._22(t,10).indeterminate,l._22(t,10).checked,l._22(t,10).disabled,"before"==l._22(t,10).labelPosition),n(t,11,0,l._32(t,11,0,l._22(t,12).transform("hardware-wallet.remove-pin.check"))),n(t,19,0,l._32(t,19,0,l._22(t,20).transform("hardware-wallet.general.cancel"))),n(t,24,0,l._32(t,24,0,l._22(t,25).transform("hardware-wallet.general.continue")))})}function mM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Confirm,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.general.confirm")))},null)}function gM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function yM(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function bM(n){return l._33(0,[(n()(),l._9(0,0,null,null,10,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,mM)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,gM)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,yM)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.currentState===e.states.Processing),n(t,6,0,e.currentState===e.states.ShowingResult),n(t,9,0,e.currentState!==e.states.Processing)},null)}function vM(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),(n()(),l._9(1,0,null,null,9,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,_M)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,bM)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("hardware-wallet.options.delete-pin")),e.currentState===e.states.Processing),n(t,6,0,e.currentState===e.states.Initial),n(t,9,0,e.currentState!==e.states.Initial)},null)}var wM=l._5("app-hw-remove-pin-dialog",od,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-remove-pin-dialog",[],null,null,null,vM,fM)),l._8(1,180224,null,0,od,[da,ca,oc],null,null)],null,null)},{},{},[]),xM=l._7({encapsulation:0,styles:[[""]],data:{}});function MM(n){return l._33(0,[(n()(),l._9(0,0,null,null,7,"div",[["class","-check-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,4,"mat-checkbox",[["class","-check mat-checkbox"],["type","checkbox"]],[[8,"id",0],[2,"mat-checkbox-indeterminate",null],[2,"mat-checkbox-checked",null],[2,"mat-checkbox-disabled",null],[2,"mat-checkbox-label-before",null]],[[null,"change"]],function(n,t,e){var l=!0;return"change"===t&&(l=!1!==n.component.setConfirmed(e)&&l),l},Ym,Em)),l._28(5120,null,to,function(n){return[n]},[ta]),l._8(4,4374528,null,0,ta,[l.l,l.h,Rr,[8,null],[2,Zs]],{checked:[0,"checked"]},{change:"change"}),(n()(),l._31(5,0,["","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],function(n,t){n(t,4,0,t.component.confirmed)},function(n,t){n(t,2,0,l._22(t,4).id,l._22(t,4).indeterminate,l._22(t,4).checked,l._22(t,4).disabled,"before"==l._22(t,4).labelPosition),n(t,5,0,l._32(t,5,0,l._22(t,6).transform("hardware-wallet.update-firmware.check")))})}function kM(n){return l._33(0,[(n()(),l._9(0,0,null,null,21,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(3,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,MM)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._9(9,0,null,null,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(12,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(13,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.startUpdating()&&l),l},w_,g_)),l._8(17,49152,[[2,4],["button",4]],0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(18,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.deviceHasFirmware?e.msgIcons.Warning:e.msgIcons.HardwareWallet,l._32(t,3,1,l._22(t,4).transform(e.text))),n(t,7,0,e.deviceHasFirmware),n(t,17,0,e.deviceHasFirmware&&!e.confirmed)},function(n,t){n(t,13,0,l._32(t,13,0,l._22(t,14).transform("hardware-wallet.general.cancel"))),n(t,18,0,l._32(t,18,0,l._22(t,19).transform("hardware-wallet.general.continue")))})}function CM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Spinner,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.update-firmware.title-connecting")))},null)}function SM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.Confirm,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.update-firmware.follow")))},null)}function OM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.result.icon,l._32(t,1,1,l._22(t,2).transform(e.result.text)))},null)}function TM(n){return l._33(0,[(n()(),l._9(0,0,null,null,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(3,49152,[[1,4],["closeButton",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(4,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "]))],null,function(n,t){n(t,4,0,l._32(t,4,0,l._22(t,5).transform("hardware-wallet.general.close")))})}function LM(n){return l._33(0,[(n()(),l._9(0,0,null,null,13,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,CM)),l._8(3,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,SM)),l._8(6,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,OM)),l._8(9,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n\n "])),(n()(),l._4(16777216,null,null,1,null,TM)),l._8(12,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "]))],function(n,t){var e=t.component;n(t,3,0,e.currentState===e.states.Connecting),n(t,6,0,e.currentState===e.states.Processing),n(t,9,0,e.currentState===e.states.ShowingResult),n(t,12,0,e.currentState!==e.states.Processing)},null)}function PM(n){return l._33(0,[l._29(671088640,1,{closeButton:0}),l._29(671088640,2,{button:0}),(n()(),l._9(2,0,null,null,9,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(3,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,kM)),l._8(7,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._4(16777216,null,0,1,null,LM)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n"]))],function(n,t){var e=t.component;n(t,3,0,e.dialogRef,l._32(t,3,1,l._22(t,4).transform(e.title)),e.currentState===e.states.Processing),n(t,7,0,e.currentState===e.states.Initial),n(t,10,0,e.currentState!==e.states.Initial)},null)}var DM=l._5("app-hw-update-firmware-dialog",sd,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-update-firmware-dialog",[],null,null,null,PM,xM)),l._8(1,180224,null,0,sd,[ca,oc,jc,De.j],null,null)],null,null)},{},{},[]),AM=l._7({encapsulation:0,styles:[[""]],data:{}});function EM(n){return l._33(0,[l._29(402653184,1,{closeButton:0}),(n()(),l._9(1,0,null,null,20,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(5,0,null,0,2,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(6,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n\n "])),(n()(),l._9(9,0,null,0,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(11,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closeModal()&&l),l},w_,g_)),l._8(12,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(13,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(16,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.update()&&l),l},w_,g_)),l._8(17,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(18,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("hardware-wallet.update-firmware-warning.title"))),n(t,6,0,e.msgIcons.Warning,l._32(t,6,1,l._22(t,7).transform("hardware-wallet.update-firmware-warning.text")))},function(n,t){n(t,13,0,l._32(t,13,0,l._22(t,14).transform("hardware-wallet.update-firmware-warning.cancel"))),n(t,18,0,l._32(t,18,0,l._22(t,19).transform("hardware-wallet.update-firmware-warning.update")))})}var YM=l._5("app-hw-update-alert-dialog",ad,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-hw-update-alert-dialog",[],null,null,null,EM,AM)),l._8(1,180224,null,0,ad,[ca,oc],null,null)],null,null)},{},{},[]),jM=l._7({encapsulation:0,styles:[["mat-input-container[_ngcontent-%COMP%]{width:100%}.-buttons[_ngcontent-%COMP%]{text-align:center}mat-icon[_ngcontent-%COMP%]{display:inline;font-size:14px;color:rgba(121,135,152,.5);vertical-align:text-bottom;padding-left:5px}"]],data:{}});function IM(n){return l._33(0,[l._29(402653184,1,{button:0}),(n()(),l._9(1,0,null,null,44,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(2,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"],disableDismiss:[2,"disableDismiss"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(5,0,null,0,26,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,6).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,6).onReset()&&r),r},null,null)),l._8(6,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(8,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(10,0,null,null,20,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,8,"label",[["for","note"]],null,null,null,null,null)),(n()(),l._31(13,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._9(15,16777216,null,null,4,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"longpress"],[null,"keydown"],[null,"touchend"]],function(n,t,e){var r=!0;return"longpress"===t&&(r=!1!==l._22(n,17).show()&&r),"keydown"===t&&(r=!1!==l._22(n,17)._handleKeydown(e)&&r),"touchend"===t&&(r=!1!==l._22(n,17).hide(1500)&&r),r},Hf,Rf)),l._8(16,638976,null,0,ou,[l.l,eu,[8,null]],null,null),l._8(17,147456,null,0,Iu,[Pi,l.l,Qr,l.R,l.B,Hl,Dr,Rr,Yu,[2,Dl]],{message:[0,"message"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["help"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(22,0,null,null,7,"input",[["formControlName","note"],["id","note"]],[[1,"maxlength",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0,i=n.component;return"input"===t&&(r=!1!==l._22(n,23)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,23).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,23)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,23)._compositionEnd(e.target.value)&&r),"keydown.enter"===t&&(r=!1!==i.changeNote()&&r),r},null,null)),l._8(23,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._8(24,540672,null,0,$o,[],{maxlength:[0,"maxlength"]},null),l._28(1024,null,Qi,function(n){return[n]},[$o]),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(27,671744,null,0,Xo,[[3,qi],[2,Qi],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(29,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(33,0,null,0,11,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(35,0,null,null,3,"app-button",[],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.closePopup()&&l),l},w_,g_)),l._8(36,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(37,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(40,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.changeNote()&&l),l},w_,g_)),l._8(41,49152,[[1,4],["button",4]],0,Lc,[],null,{action:"action"}),(n()(),l._31(42,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,2,0,e.dialogRef,l._32(t,2,1,l._22(t,3).transform("edit-note.title")),l._22(t,41)&&l._22(t,41).isLoading()),n(t,6,0,e.form),n(t,16,0),n(t,17,0,l._32(t,17,0,l._22(t,18).transform("send.personal-note-help"))),n(t,24,0,e.maxNoteChars),n(t,27,0,"note")},function(n,t){n(t,5,0,l._22(t,8).ngClassUntouched,l._22(t,8).ngClassTouched,l._22(t,8).ngClassPristine,l._22(t,8).ngClassDirty,l._22(t,8).ngClassValid,l._22(t,8).ngClassInvalid,l._22(t,8).ngClassPending),n(t,13,0,l._32(t,13,0,l._22(t,14).transform("send.personal-note-label"))),n(t,22,0,l._22(t,24).maxlength?l._22(t,24).maxlength:null,l._22(t,29).ngClassUntouched,l._22(t,29).ngClassTouched,l._22(t,29).ngClassPristine,l._22(t,29).ngClassDirty,l._22(t,29).ngClassValid,l._22(t,29).ngClassInvalid,l._22(t,29).ngClassPending),n(t,37,0,l._32(t,37,0,l._22(t,38).transform("edit-note.cancel-button"))),n(t,42,0,l._32(t,42,0,l._22(t,43).transform("edit-note.change-button")))})}var RM=l._5("app-change-note",am,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-change-note",[],null,null,null,IM,jM)),l._8(1,245760,null,0,am,[ca,da,ns,jc,ic],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),HM=l._7({encapsulation:2,styles:[".mat-autocomplete-panel{min-width:112px;max-width:280px;overflow:auto;-webkit-overflow-scrolling:touch;visibility:hidden;max-width:none;max-height:256px;position:relative}.mat-autocomplete-panel:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.mat-autocomplete-panel.mat-autocomplete-visible{visibility:visible}.mat-autocomplete-panel.mat-autocomplete-hidden{visibility:hidden}"],data:{}});function NM(n){return l._33(0,[(n()(),l._9(0,0,[[2,0],["panel",1]],null,2,"div",[["class","mat-autocomplete-panel"],["role","listbox"]],[[8,"id",0]],null,null,null,null)),l._8(1,278528,null,0,O,[l.u,l.v,l.l,l.G],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),l._21(null,0)],function(n,t){n(t,1,0,"mat-autocomplete-panel",t.component._classList)},function(n,t){n(t,0,0,t.component.id)})}function FM(n){return l._33(2,[l._29(402653184,1,{template:0}),l._29(671088640,2,{panel:0}),(n()(),l._4(0,[[1,2]],null,0,null,NM))],null,null)}var BM=l._7({encapsulation:0,styles:[[".form-container[_ngcontent-%COMP%]{margin-top:20px}.option[_ngcontent-%COMP%]{font-size:13px;height:42px}"]],data:{}});function VM(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"],upperBigText:[2,"upperBigText"]},null),l._25(131072,De.i,[De.j,l.h]),l._25(131072,De.i,[De.j,l.h])],function(n,t){n(t,1,0,t.component.msgIcons.None,l._32(t,1,1,l._22(t,2).transform("hardware-wallet.seed-word.info2")),l._32(t,1,2,l._22(t,3).transform("hardware-wallet.seed-word.info1")))},null)}function WM(n){return l._33(0,[(n()(),l._9(0,0,null,null,4,"app-hw-message",[],null,null,null,Vv,Cv)),l._8(1,49152,null,0,Rc,[],{icon:[0,"icon"],text:[1,"text"],upperBigText:[2,"upperBigText"]},null),l._25(131072,De.i,[De.j,l.h]),l._26(3,{number:0}),l._25(131072,De.i,[De.j,l.h])],function(n,t){var e=t.component;n(t,1,0,e.msgIcons.None,l._32(t,1,1,l._22(t,2).transform(e.data.restoringSoftwareWallet?"wallet.new.seed.recover-seed-help":"wallet.new.seed.new-seed-help")),l._32(t,1,2,l._22(t,4).transform("wallet.new.seed.enter-word",n(t,3,0,e.data.wordNumber))))},null)}function zM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"label",[["for","word"]],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){n(t,1,0,l._32(t,1,0,l._22(t,2).transform("hardware-wallet.seed-word.word")))})}function UM(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"mat-option",[["class","option mat-option"],["role","option"]],[[1,"tabindex",0],[2,"mat-selected",null],[2,"mat-option-multiple",null],[2,"mat-active",null],[8,"id",0],[1,"aria-selected",0],[1,"aria-disabled",0],[2,"mat-option-disabled",null]],[[null,"click"],[null,"keydown"]],function(n,t,e){var r=!0,i=n.component;return"click"===t&&(r=!1!==l._22(n,1)._selectViaInteraction()&&r),"keydown"===t&&(r=!1!==l._22(n,1)._handleKeydown(e)&&r),"click"===t&&(r=!1!==i.sendWord()&&r),r},wm,bm)),l._8(1,49152,[[1,4]],0,pr,[l.l,l.h,[2,hr],[2,cr]],{value:[0,"value"]},null),(n()(),l._31(2,0,["",""]))],function(n,t){n(t,1,0,t.context.$implicit)},function(n,t){n(t,0,0,l._22(t,1)._getTabIndex(),l._22(t,1).selected,l._22(t,1).multiple,l._22(t,1).active,l._22(t,1).id,l._22(t,1).selected.toString(),l._22(t,1).disabled.toString(),l._22(t,1).disabled),n(t,2,0,t.context.$implicit)})}function GM(n){return l._33(0,[(n()(),l._9(0,0,null,null,49,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,VM)),l._8(5,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,1,null,WM)),l._8(8,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(10,0,null,0,30,"div",[["class","form-container"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,11).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,11).onReset()&&r),r},null,null)),l._8(11,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(13,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,24,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,zM)),l._8(18,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(20,16777216,null,null,8,"input",[["aria-autocomplete","list"],["autocomplete","off"],["class","mat-input-element mat-form-field-autofill-control"],["formControlName","word"],["id","word"],["matInput",""],["role","combobox"]],[[1,"aria-activedescendant",0],[1,"aria-expanded",0],[1,"aria-owns",0],[2,"mat-input-server",null],[1,"id",0],[8,"placeholder",0],[8,"disabled",0],[8,"required",0],[8,"readOnly",0],[1,"aria-describedby",0],[1,"aria-invalid",0],[1,"aria-required",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown.enter"],[null,"focusin"],[null,"blur"],[null,"input"],[null,"keydown"],[null,"compositionstart"],[null,"compositionend"],[null,"focus"]],function(n,t,e){var r=!0,i=n.component;return"focusin"===t&&(r=!1!==l._22(n,22)._handleFocus()&&r),"blur"===t&&(r=!1!==l._22(n,22)._onTouched()&&r),"input"===t&&(r=!1!==l._22(n,22)._handleInput(e)&&r),"keydown"===t&&(r=!1!==l._22(n,22)._handleKeydown(e)&&r),"input"===t&&(r=!1!==l._22(n,23)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,23).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,23)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,23)._compositionEnd(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,27)._focusChanged(!1)&&r),"focus"===t&&(r=!1!==l._22(n,27)._focusChanged(!0)&&r),"input"===t&&(r=!1!==l._22(n,27)._onInput()&&r),"keydown.enter"===t&&(r=!1!==i.sendWord()&&r),r},null,null)),l._28(6144,null,Os,null,[pu]),l._8(22,147456,null,0,Is,[l.l,Pi,l.R,l.B,l.h,Ys,[2,Dl],[8,null],[2,sn]],{autocomplete:[0,"autocomplete"]},null),l._8(23,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n,t){return[n,t]},[Is,ro]),l._8(25,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(27,933888,null,0,pu,[l.l,Hl,[2,uo],[2,Wo],[2,qo],Kl,[8,null]],{id:[0,"id"]},null),l._8(28,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(30,0,null,null,8,"mat-autocomplete",[["class","mat-autocomplete"]],null,null,null,FM,HM)),l._8(31,1097728,[["auto",4]],2,Es,[l.h,l.l],null,null),l._29(603979776,1,{options:1}),l._29(603979776,2,{optionGroups:1}),(n()(),l._31(-1,0,["\n "])),(n()(),l._4(16777216,null,0,2,null,UM)),l._8(36,802816,null,0,L,[l.R,l.O,l.u],{ngForOf:[0,"ngForOf"]},null),l._25(131072,nn,[l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(42,0,null,0,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(44,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.sendWord()&&l),l},w_,g_)),l._8(45,49152,null,0,Lc,[],{disabled:[0,"disabled"]},{action:"action"}),(n()(),l._31(46,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,e.dialogRef,l._32(t,1,1,l._22(t,2).transform(e.data.isForHwWallet?"hardware-wallet.seed-word.title":"wallet.new.seed-label"))),n(t,5,0,e.data.isForHwWallet),n(t,8,0,!e.data.isForHwWallet),n(t,11,0,e.form),n(t,18,0,e.data.isForHwWallet),n(t,22,0,l._22(t,31)),n(t,25,0,"word"),n(t,27,0,"word"),n(t,36,0,l._32(t,36,0,l._22(t,37).transform(e.filteredOptions))),n(t,45,0,!e.form.valid)},function(n,t){n(t,10,0,l._22(t,13).ngClassUntouched,l._22(t,13).ngClassTouched,l._22(t,13).ngClassPristine,l._22(t,13).ngClassDirty,l._22(t,13).ngClassValid,l._22(t,13).ngClassInvalid,l._22(t,13).ngClassPending),n(t,20,1,[null==l._22(t,22).activeOption?null:l._22(t,22).activeOption.id,l._22(t,22).panelOpen.toString(),null==l._22(t,22).autocomplete?null:l._22(t,22).autocomplete.id,l._22(t,27)._isServer,l._22(t,27).id,l._22(t,27).placeholder,l._22(t,27).disabled,l._22(t,27).required,l._22(t,27).readonly,l._22(t,27)._ariaDescribedby||null,l._22(t,27).errorState,l._22(t,27).required.toString(),l._22(t,28).ngClassUntouched,l._22(t,28).ngClassTouched,l._22(t,28).ngClassPristine,l._22(t,28).ngClassDirty,l._22(t,28).ngClassValid,l._22(t,28).ngClassInvalid,l._22(t,28).ngClassPending]),n(t,46,0,l._32(t,46,0,l._22(t,47).transform("hardware-wallet.general.continue")))})}var qM=l._5("app-seed-word-dialog",Hc,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-seed-word-dialog",[],null,null,null,GM,BM)),l._8(1,245760,null,0,Hc,[da,ca,ns,Ac,jc,De.j,oc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),JM=l._7({encapsulation:0,styles:[[".form-container[_ngcontent-%COMP%]{margin-top:20px}"]],data:{}});function QM(n){return l._33(0,[(n()(),l._9(0,0,null,null,31,"app-modal",[["class","modal"]],null,null,null,wv,bv)),l._8(1,573440,null,0,yv,[],{dialog:[0,"dialog"],headline:[1,"headline"]},null),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(4,0,null,0,2,"div",[["class","-body"]],null,null,null,null,null)),(n()(),l._31(5,null,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(8,0,null,0,14,"div",[["class","form-container"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,t,e){var r=!0;return"submit"===t&&(r=!1!==l._22(n,9).onSubmit(e)&&r),"reset"===t&&(r=!1!==l._22(n,9).onReset()&&r),r},null,null)),l._8(9,540672,null,0,qo,[[8,null],[8,null]],{form:[0,"form"]},null),l._28(2048,null,qi,null,[qo]),l._8(11,16384,null,0,Yo,[qi],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(13,0,null,null,8,"div",[["class","form-field"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(15,0,null,null,5,"textarea",[["formControlName","data"],["id","data"],["rows","5"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(n,t,e){var r=!0;return"input"===t&&(r=!1!==l._22(n,16)._handleInput(e.target.value)&&r),"blur"===t&&(r=!1!==l._22(n,16).onTouched()&&r),"compositionstart"===t&&(r=!1!==l._22(n,16)._compositionStart()&&r),"compositionend"===t&&(r=!1!==l._22(n,16)._compositionEnd(e.target.value)&&r),r},null,null)),l._8(16,16384,null,0,ro,[l.G,l.l,[2,lo]],null,null),l._28(1024,null,to,function(n){return[n]},[ro]),l._8(18,671744,null,0,Xo,[[3,qi],[8,null],[8,null],[2,to]],{name:[0,"name"]},null),l._28(2048,null,uo,null,[Xo]),l._8(20,16384,null,0,Eo,[uo],null,null),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n "])),(n()(),l._9(24,0,null,0,6,"div",[["class","-buttons"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(26,0,null,null,3,"app-button",[["class","primary"]],null,[[null,"action"]],function(n,t,e){var l=!0;return"action"===t&&(l=!1!==n.component.processData()&&l),l},w_,g_)),l._8(27,49152,null,0,Lc,[],null,{action:"action"}),(n()(),l._31(28,0,["\n ","\n "])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,0,["\n"])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,1,0,e.dialogRef,l._32(t,1,1,l._22(t,2).transform("send.bulk-send.title"))),n(t,9,0,e.form),n(t,18,0,"data")},function(n,t){n(t,5,0,l._32(t,5,0,l._22(t,6).transform("send.bulk-send.indications"))),n(t,8,0,l._22(t,11).ngClassUntouched,l._22(t,11).ngClassTouched,l._22(t,11).ngClassPristine,l._22(t,11).ngClassDirty,l._22(t,11).ngClassValid,l._22(t,11).ngClassInvalid,l._22(t,11).ngClassPending),n(t,15,0,l._22(t,20).ngClassUntouched,l._22(t,20).ngClassTouched,l._22(t,20).ngClassPristine,l._22(t,20).ngClassDirty,l._22(t,20).ngClassValid,l._22(t,20).ngClassInvalid,l._22(t,20).ngClassPending),n(t,28,0,l._32(t,28,0,l._22(t,29).transform("send.bulk-send.process")))})}var KM=l._5("app-multiple-destinations-dialog",Hm,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-multiple-destinations-dialog",[],null,null,null,QM,JM)),l._8(1,245760,null,0,Hm,[ca,da,ns,jc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]),XM=l._7({encapsulation:0,styles:[[".main-container[_ngcontent-%COMP%]{position:fixed;bottom:0;width:100%;z-index:1000000;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.internal-container[_ngcontent-%COMP%]{color:#fff;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;min-width:40%;max-width:90%;display:-webkit-box;display:-ms-flexbox;display:flex;padding:10px;border-top-left-radius:5px;border-top-right-radius:5px}.red-background[_ngcontent-%COMP%]{background-color:rgba(255,0,0,.7)}.green-background[_ngcontent-%COMP%]{background-color:rgba(31,177,31,.7)}.yellow-background[_ngcontent-%COMP%]{background-color:rgba(255,94,0,.7)}.icon-container[_ngcontent-%COMP%]{margin-right:10px}.text-container[_ngcontent-%COMP%]{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;margin-right:10px}.text-container[_ngcontent-%COMP%] .title[_ngcontent-%COMP%]{font-size:15px;margin-top:-1px}.text-container[_ngcontent-%COMP%] .text[_ngcontent-%COMP%]{font-size:13px;margin-top:2px}.close-container[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{cursor:pointer}"]],data:{}});function ZM(n){return l._33(0,[(n()(),l._9(0,0,null,null,3,"div",[["class","icon-container"]],null,null,null,null,null)),(n()(),l._9(1,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,null,null,Hf,Rf)),l._8(2,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(3,0,["",""]))],function(n,t){n(t,2,0)},function(n,t){n(t,3,0,t.component.config.icon)})}function $M(n){return l._33(0,[(n()(),l._9(0,0,null,null,2,"div",[["class","title"]],null,null,null,null,null)),(n()(),l._31(1,null,["",""])),l._25(131072,De.i,[De.j,l.h])],null,function(n,t){var e=t.component;n(t,1,0,l._32(t,1,0,l._22(t,2).transform(e.config.title)))})}function nk(n){return l._33(0,[(n()(),l._9(0,0,null,null,22,"div",[["class","main-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(2,0,null,null,19,"div",[],[[8,"className",0]],null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,ZM)),l._8(5,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,8,"div",[["class","text-container"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._4(16777216,null,null,1,null,$M)),l._8(10,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(12,0,null,null,2,"div",[["class","text"]],null,null,null,null,null)),(n()(),l._31(13,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(17,0,null,null,3,"div",[["class","close-container"]],null,null,null,null,null)),(n()(),l._9(18,0,null,null,2,"mat-icon",[["class","mat-icon"],["role","img"]],null,[[null,"click"]],function(n,t,e){var l=!0;return"click"===t&&(l=!1!==n.component.hide()&&l),l},Hf,Rf)),l._8(19,638976,null,0,ou,[l.l,eu,[8,null]],null,null),(n()(),l._31(-1,0,["close"])),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"]))],function(n,t){var e=t.component;n(t,5,0,e.config.icon),n(t,10,0,e.config.title),n(t,19,0)},function(n,t){var e=t.component;n(t,2,0,"internal-container "+(e.config.color?e.config.color:"red-background")),n(t,13,0,l._32(t,13,0,l._22(t,14).transform(e.config.text)))})}function tk(n){return l._33(0,[(n()(),l._4(16777216,null,null,1,null,nk)),l._8(1,16384,null,0,D,[l.R,l.O],{ngIf:[0,"ngIf"]},null),(n()(),l._31(-1,null,["\n"]))],function(n,t){n(t,1,0,t.component.visible)},null)}var ek=l._7({encapsulation:0,styles:[[".size-alert[_ngcontent-%COMP%]{background-color:rgba(0,0,0,.85);position:fixed;top:0;left:0;width:100%;height:100%;z-index:10000;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center;color:#fff}.size-alert[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]{margin:0 40px;max-width:400px}mat-card[_ngcontent-%COMP%]{max-width:1000px;margin-top:80px;margin-right:auto;margin-left:auto}.logo[_ngcontent-%COMP%]{max-height:100%}.fill-remaining-space[_ngcontent-%COMP%]{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.sky-container[_ngcontent-%COMP%]{max-width:1000px;margin-top:20px;margin-right:auto;margin-left:auto}mat-toolbar[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{margin:0 20px}.search-field[_ngcontent-%COMP%]{border-radius:8px;border:none;background-color:#fff;padding:8px}.syncing[_ngcontent-%COMP%]{font-size:14px}.main-menu[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{margin-right:20px}#top-menu[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:#fbfbfb}#top-menu[_ngcontent-%COMP%] span#version[_ngcontent-%COMP%]{padding-top:12px}"]],data:{}});function lk(n){return l._33(0,[l._29(402653184,1,{msgBar:0}),(n()(),l._9(1,0,null,null,10,"div",[["class","size-alert d-md-none"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(3,0,null,null,7,"div",[],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(5,0,null,null,0,"img",[["src","assets/img/size-alert.png"]],null,null,null,null,null)),(n()(),l._31(-1,null,["\n "])),(n()(),l._9(7,0,null,null,2,"div",[],null,null,null,null,null)),(n()(),l._31(8,null,["",""])),l._25(131072,De.i,[De.j,l.h]),(n()(),l._31(-1,null,["\n "])),(n()(),l._31(-1,null,["\n"])),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(13,16777216,null,null,1,"router-outlet",[],null,null,null,null,null)),l._8(14,212992,null,0,bp,[yp,l.R,l.j,[8,null],l.h],null,null),(n()(),l._31(-1,null,["\n"])),(n()(),l._9(16,0,null,null,1,"app-msg-bar",[],null,null,null,tk,XM)),l._8(17,49152,[[1,4],["msgBar",4]],0,Yc,[],null,null)],function(n,t){n(t,14,0)},function(n,t){n(t,8,0,l._32(t,8,0,l._22(t,9).transform("errors.window-size")))})}var rk=l._5("app-root",wf,function(n){return l._33(0,[(n()(),l._9(0,0,null,null,1,"app-root",[],null,null,null,lk,ek)),l._8(1,114688,null,0,wf,[gf,Bc,Sc,oc,Xu,Zu,Ac,fa,jc],null,null)],function(n,t){n(t,1,0)},null)},{},{},[]);function ik(n){switch(n.length){case 0:return new us;case 1:return n[0];default:return new cs(n)}}function ok(n,t,e,l,r,i){void 0===r&&(r={}),void 0===i&&(i={});var o=[],s=[],a=-1,u=null;if(l.forEach(function(n){var e=n.offset,l=e==a,c=l&&u||{};Object.keys(n).forEach(function(e){var l=e,s=n[e];if("offset"!==e)switch(l=t.normalizePropertyName(l,o),s){case ds:s=r[e];break;case is:s=i[e];break;default:s=t.normalizeStyleValue(e,l,s,o)}c[l]=s}),l||s.push(c),u=c,a=e}),o.length)throw new Error("Unable to animate due to the following errors:\n - "+o.join("\n - "));return s}function sk(n,t,e,l){switch(t){case"start":n.onStart(function(){return l(e&&ak(e,"start",n.totalTime))});break;case"done":n.onDone(function(){return l(e&&ak(e,"done",n.totalTime))});break;case"destroy":n.onDestroy(function(){return l(e&&ak(e,"destroy",n.totalTime))})}}function ak(n,t,e){var l=uk(n.element,n.triggerName,n.fromState,n.toState,t||n.phaseName,void 0==e?n.totalTime:e),r=n._data;return null!=r&&(l._data=r),l}function uk(n,t,e,l,r,i){return void 0===r&&(r=""),void 0===i&&(i=0),{element:n,triggerName:t,fromState:e,toState:l,phaseName:r,totalTime:i}}function ck(n,t,e){var l;return n instanceof Map?(l=n.get(t))||n.set(t,l=e):(l=n[t])||(l=n[t]=e),l}function dk(n){var t=n.indexOf(":");return[n.substring(1,t),n.substr(t+1)]}var hk=function(n,t){return!1},pk=function(n,t){return!1},fk=function(n,t,e){return[]};if("undefined"!=typeof Element){if(hk=function(n,t){return n.contains(t)},Element.prototype.matches)pk=function(n,t){return n.matches(t)};else{var _k=Element.prototype,mk=_k.matchesSelector||_k.mozMatchesSelector||_k.msMatchesSelector||_k.oMatchesSelector||_k.webkitMatchesSelector;mk&&(pk=function(n,t){return mk.apply(n,[t])})}fk=function(n,t,e){var l=[];if(e)l.push.apply(l,n.querySelectorAll(t));else{var r=n.querySelector(t);r&&l.push(r)}return l}}var gk=null,yk=!1;function bk(){return"undefined"!=typeof document?document.body:null}var vk=pk,wk=hk,xk=fk,Mk=function(){function n(){}return n.prototype.validateStyleProperty=function(n){return function(n){gk||(gk=bk()||{},yk=!!gk.style&&"WebkitAppearance"in gk.style);var t=!0;return gk.style&&!function(n){return"ebkit"==n.substring(1,6)}(n)&&!(t=n in gk.style)&&yk&&(t="Webkit"+n.charAt(0).toUpperCase()+n.substr(1)in gk.style),t}(n)},n.prototype.matchesElement=function(n,t){return vk(n,t)},n.prototype.containsElement=function(n,t){return wk(n,t)},n.prototype.query=function(n,t,e){return xk(n,t,e)},n.prototype.computeStyle=function(n,t,e){return e||""},n.prototype.animate=function(n,t,e,l,r,i){return void 0===i&&(i=[]),new us},n}(),kk=function(){function n(){}return n.NOOP=new Mk,n}(),Ck=1e3;function Sk(n){if("number"==typeof n)return n;var t=n.match(/^(-?[\.\d]+)(m?s)/);return!t||t.length<2?0:Ok(parseFloat(t[1]),t[2])}function Ok(n,t){switch(t){case"s":return n*Ck;default:return n}}function Tk(n,t,e){return n.hasOwnProperty("duration")?n:function(n,t,e){var l,r=0,i="";if("string"==typeof n){var o=n.match(/^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i);if(null===o)return t.push('The provided timing value "'+n+'" is invalid.'),{duration:0,delay:0,easing:""};l=Ok(parseFloat(o[1]),o[2]);var s=o[3];null!=s&&(r=Ok(Math.floor(parseFloat(s)),o[4]));var a=o[5];a&&(i=a)}else l=n;if(!e){var u=!1,c=t.length;l<0&&(t.push("Duration values below 0 are not allowed for this animation step."),u=!0),r<0&&(t.push("Delay values below 0 are not allowed for this animation step."),u=!0),u&&t.splice(c,0,'The provided timing value "'+n+'" is invalid.')}return{duration:l,delay:r,easing:i}}(n,t,e)}function Lk(n,t){return void 0===t&&(t={}),Object.keys(n).forEach(function(e){t[e]=n[e]}),t}function Pk(n,t,e){if(void 0===e&&(e={}),t)for(var l in n)e[l]=n[l];else Lk(n,e);return e}function Dk(n,t){n.style&&Object.keys(t).forEach(function(e){var l=Nk(e);n.style[l]=t[e]})}function Ak(n,t){n.style&&Object.keys(t).forEach(function(t){var e=Nk(t);n.style[e]=""})}function Ek(n){return Array.isArray(n)?1==n.length?n[0]:os(n):n}var Yk=new RegExp("{{\\s*(.+?)\\s*}}","g");function jk(n){var t=[];if("string"==typeof n){for(var e=n.toString(),l=void 0;l=Yk.exec(e);)t.push(l[1]);Yk.lastIndex=0}return t}function Ik(n,t,e){var l=n.toString(),r=l.replace(Yk,function(n,l){var r=t[l];return t.hasOwnProperty(l)||(e.push("Please provide a value for the animation param "+l),r=""),r.toString()});return r==l?n:r}function Rk(n){for(var t=[],e=n.next();!e.done;)t.push(e.value),e=n.next();return t}var Hk=/-+([a-z0-9])/g;function Nk(n){return n.replace(Hk,function(){for(var n=[],t=0;t *";case":leave":return"* => void";case":increment":return function(n,t){return parseFloat(t)>parseFloat(n)};case":decrement":return function(n,t){return parseFloat(t) *"}}(n,e);if("function"==typeof l)return void t.push(l);n=l}var r=n.match(/^(\*|[-\w]+)\s*()\s*(\*|[-\w]+)$/);if(null==r||r.length<4)return e.push('The provided transition expression "'+n+'" is not supported'),t;var i=r[1],o=r[2],s=r[3];t.push(zk(i,s)),"<"!=o[0]||i==Bk&&s==Bk||t.push(zk(s,i))}(n,r,l)}):r.push(e),r),animation:i,queryCount:t.queryCount,depCount:t.depCount,options:Kk(n.options)}},n.prototype.visitSequence=function(n,t){var e=this;return{type:2,steps:n.steps.map(function(n){return Fk(e,n,t)}),options:Kk(n.options)}},n.prototype.visitGroup=function(n,t){var e=this,l=t.currentTime,r=0,i=n.steps.map(function(n){t.currentTime=l;var i=Fk(e,n,t);return r=Math.max(r,t.currentTime),i});return t.currentTime=r,{type:3,steps:i,options:Kk(n.options)}},n.prototype.visitAnimate=function(n,t){var e,l=function(n,t){var e=null;if(n.hasOwnProperty("duration"))e=n;else if("number"==typeof n)return Xk(Tk(n,t).duration,0,"");var l=n;if(l.split(/\s+/).some(function(n){return"{"==n.charAt(0)&&"{"==n.charAt(1)})){var r=Xk(0,0,"");return r.dynamic=!0,r.strValue=l,r}return Xk((e=e||Tk(l,t)).duration,e.delay,e.easing)}(n.timings,t.errors);t.currentAnimateTimings=l;var r=n.styles?n.styles:ss({});if(5==r.type)e=this.visitKeyframes(r,t);else{var i=n.styles,o=!1;if(!i){o=!0;var s={};l.easing&&(s.easing=l.easing),i=ss(s)}t.currentTime+=l.duration+l.delay;var a=this.visitStyle(i,t);a.isEmptyStep=o,e=a}return t.currentAnimateTimings=null,{type:4,timings:l,style:e,options:null}},n.prototype.visitStyle=function(n,t){var e=this._makeStyleAst(n,t);return this._validateStyleAst(e,t),e},n.prototype._makeStyleAst=function(n,t){var e=[];Array.isArray(n.styles)?n.styles.forEach(function(n){"string"==typeof n?n==is?e.push(n):t.errors.push("The provided style string value "+n+" is not allowed."):e.push(n)}):e.push(n.styles);var l=!1,r=null;return e.forEach(function(n){if(Qk(n)){var t=n,e=t.easing;if(e&&(r=e,delete t.easing),!l)for(var i in t)if(t[i].toString().indexOf("{{")>=0){l=!0;break}}}),{type:6,styles:e,easing:r,offset:n.offset,containsDynamicStyles:l,options:null}},n.prototype._validateStyleAst=function(n,t){var e=this,l=t.currentAnimateTimings,r=t.currentTime,i=t.currentTime;l&&i>0&&(i-=l.duration+l.delay),n.styles.forEach(function(n){"string"!=typeof n&&Object.keys(n).forEach(function(l){if(e._driver.validateStyleProperty(l)){var o,s,a,u=t.collectedStyles[t.currentQuerySelector],c=u[l],d=!0;c&&(i!=r&&i>=c.startTime&&r<=c.endTime&&(t.errors.push('The CSS property "'+l+'" that exists between the times of "'+c.startTime+'ms" and "'+c.endTime+'ms" is also being animated in a parallel animation between the times of "'+i+'ms" and "'+r+'ms"'),d=!1),i=c.startTime),d&&(u[l]={startTime:i,endTime:r}),t.options&&(o=t.errors,s=t.options.params||{},(a=jk(n[l])).length&&a.forEach(function(n){s.hasOwnProperty(n)||o.push("Unable to resolve the local animation param "+n+" in the given list of values")}))}else t.errors.push('The provided animation property "'+l+'" is not a supported CSS property for animations')})})},n.prototype.visitKeyframes=function(n,t){var e=this,l={type:5,styles:[],options:null};if(!t.currentAnimateTimings)return t.errors.push("keyframes() must be placed inside of a call to animate()"),l;var r=0,i=[],o=!1,s=!1,a=0,u=n.steps.map(function(n){var l=e._makeStyleAst(n,t),u=null!=l.offset?l.offset:function(n){if("string"==typeof n)return null;var t=null;if(Array.isArray(n))n.forEach(function(n){if(Qk(n)&&n.hasOwnProperty("offset")){var e=n;t=parseFloat(e.offset),delete e.offset}});else if(Qk(n)&&n.hasOwnProperty("offset")){var e=n;t=parseFloat(e.offset),delete e.offset}return t}(l.styles),c=0;return null!=u&&(r++,c=l.offset=u),s=s||c<0||c>1,o=o||c0&&r0?r==h?1:d*r:i[r],s=o*_;t.currentTime=p+f.delay+s,f.duration=s,e._validateStyleAst(n,t),n.offset=o,l.styles.push(n)}),l},n.prototype.visitReference=function(n,t){return{type:8,animation:Fk(this,Ek(n.animation),t),options:Kk(n.options)}},n.prototype.visitAnimateChild=function(n,t){return t.depCount++,{type:9,options:Kk(n.options)}},n.prototype.visitAnimateRef=function(n,t){return{type:10,animation:this.visitReference(n.animation,t),options:Kk(n.options)}},n.prototype.visitQuery=function(n,t){var e=t.currentQuerySelector,l=n.options||{};t.queryCount++,t.currentQuery=n;var r=function(n){var t=!!n.split(/\s*,\s*/).find(function(n){return":self"==n});return t&&(n=n.replace(Uk,"")),[n=n.replace(/@\*/g,".ng-trigger").replace(/@\w+/g,function(n){return".ng-trigger-"+n.substr(1)}).replace(/:animating/g,".ng-animating"),t]}(n.selector),i=r[0],o=r[1];t.currentQuerySelector=e.length?e+" "+i:i,ck(t.collectedStyles,t.currentQuerySelector,{});var s=Fk(this,Ek(n.animation),t);return t.currentQuery=null,t.currentQuerySelector=e,{type:11,selector:i,limit:l.limit||0,optional:!!l.optional,includeSelf:o,animation:s,originalSelector:n.selector,options:Kk(n.options)}},n.prototype.visitStagger=function(n,t){t.currentQuery||t.errors.push("stagger() can only be used inside of query()");var e="full"===n.timings?{duration:0,delay:0,easing:"full"}:Tk(n.timings,t.errors,!0);return{type:12,animation:Fk(this,Ek(n.animation),t),timings:e,options:null}},n}(),Jk=function(n){this.errors=n,this.queryCount=0,this.depCount=0,this.currentTransition=null,this.currentQuery=null,this.currentQuerySelector=null,this.currentAnimateTimings=null,this.currentTime=0,this.collectedStyles={},this.options=null};function Qk(n){return!Array.isArray(n)&&"object"==typeof n}function Kk(n){var t;return n?(n=Lk(n)).params&&(n.params=(t=n.params)?Lk(t):null):n={},n}function Xk(n,t,e){return{duration:n,delay:t,easing:e}}function Zk(n,t,e,l,r,i,o,s){return void 0===o&&(o=null),void 0===s&&(s=!1),{type:1,element:n,keyframes:t,preStyleProps:e,postStyleProps:l,duration:r,delay:i,totalTime:r+i,easing:o,subTimeline:s}}var $k=function(){function n(){this._map=new Map}return n.prototype.consume=function(n){var t=this._map.get(n);return t?this._map.delete(n):t=[],t},n.prototype.append=function(n,t){var e=this._map.get(n);e||this._map.set(n,e=[]),e.push.apply(e,t)},n.prototype.has=function(n){return this._map.has(n)},n.prototype.clear=function(){this._map.clear()},n}(),nC=new RegExp(":enter","g"),tC=new RegExp(":leave","g");function eC(n,t,e,l,r,i,o,s,a,u){return void 0===i&&(i={}),void 0===o&&(o={}),void 0===u&&(u=[]),(new lC).buildKeyframes(n,t,e,l,r,i,o,s,a,u)}var lC=function(){function n(){}return n.prototype.buildKeyframes=function(n,t,e,l,r,i,o,s,a,u){void 0===u&&(u=[]),a=a||new $k;var c=new iC(n,t,a,l,r,u,[]);c.options=s,c.currentTimeline.setStyles([i],null,c.errors,s),Fk(this,e,c);var d=c.timelines.filter(function(n){return n.containsAnimation()});if(d.length&&Object.keys(o).length){var h=d[d.length-1];h.allowOnlyTimelineStyles()||h.setStyles([o],null,c.errors,s)}return d.length?d.map(function(n){return n.buildKeyframes()}):[Zk(t,[],[],[],0,0,"",!1)]},n.prototype.visitTrigger=function(n,t){},n.prototype.visitState=function(n,t){},n.prototype.visitTransition=function(n,t){},n.prototype.visitAnimateChild=function(n,t){var e=t.subInstructions.consume(t.element);if(e){var l=t.createSubContext(n.options),r=t.currentTimeline.currentTime,i=this._visitSubInstructions(e,l,l.options);r!=i&&t.transformIntoNewTimeline(i)}t.previousNode=n},n.prototype.visitAnimateRef=function(n,t){var e=t.createSubContext(n.options);e.transformIntoNewTimeline(),this.visitReference(n.animation,e),t.transformIntoNewTimeline(e.currentTimeline.currentTime),t.previousNode=n},n.prototype._visitSubInstructions=function(n,t,e){var l=t.currentTimeline.currentTime,r=null!=e.duration?Sk(e.duration):null,i=null!=e.delay?Sk(e.delay):null;return 0!==r&&n.forEach(function(n){var e=t.appendInstructionToTimeline(n,r,i);l=Math.max(l,e.duration+e.delay)}),l},n.prototype.visitReference=function(n,t){t.updateOptions(n.options,!0),Fk(this,n.animation,t),t.previousNode=n},n.prototype.visitSequence=function(n,t){var e=this,l=t.subContextCount,r=t,i=n.options;if(i&&(i.params||i.delay)&&((r=t.createSubContext(i)).transformIntoNewTimeline(),null!=i.delay)){6==r.previousNode.type&&(r.currentTimeline.snapshotCurrentStyles(),r.previousNode=rC);var o=Sk(i.delay);r.delayNextStep(o)}n.steps.length&&(n.steps.forEach(function(n){return Fk(e,n,r)}),r.currentTimeline.applyStylesToKeyframe(),r.subContextCount>l&&r.transformIntoNewTimeline()),t.previousNode=n},n.prototype.visitGroup=function(n,t){var e=this,l=[],r=t.currentTimeline.currentTime,i=n.options&&n.options.delay?Sk(n.options.delay):0;n.steps.forEach(function(o){var s=t.createSubContext(n.options);i&&s.delayNextStep(i),Fk(e,o,s),r=Math.max(r,s.currentTimeline.currentTime),l.push(s.currentTimeline)}),l.forEach(function(n){return t.currentTimeline.mergeTimelineCollectedStyles(n)}),t.transformIntoNewTimeline(r),t.previousNode=n},n.prototype._visitTiming=function(n,t){if(n.dynamic){var e=n.strValue;return Tk(t.params?Ik(e,t.params,t.errors):e,t.errors)}return{duration:n.duration,delay:n.delay,easing:n.easing}},n.prototype.visitAnimate=function(n,t){var e=t.currentAnimateTimings=this._visitTiming(n.timings,t),l=t.currentTimeline;e.delay&&(t.incrementTime(e.delay),l.snapshotCurrentStyles());var r=n.style;5==r.type?this.visitKeyframes(r,t):(t.incrementTime(e.duration),this.visitStyle(r,t),l.applyStylesToKeyframe()),t.currentAnimateTimings=null,t.previousNode=n},n.prototype.visitStyle=function(n,t){var e=t.currentTimeline,l=t.currentAnimateTimings;!l&&e.getCurrentStyleProperties().length&&e.forwardFrame();var r=l&&l.easing||n.easing;n.isEmptyStep?e.applyEmptyStep(r):e.setStyles(n.styles,r,t.errors,t.options),t.previousNode=n},n.prototype.visitKeyframes=function(n,t){var e=t.currentAnimateTimings,l=t.currentTimeline.duration,r=e.duration,i=t.createSubContext().currentTimeline;i.easing=e.easing,n.styles.forEach(function(n){i.forwardTime((n.offset||0)*r),i.setStyles(n.styles,n.easing,t.errors,t.options),i.applyStylesToKeyframe()}),t.currentTimeline.mergeTimelineCollectedStyles(i),t.transformIntoNewTimeline(l+r),t.previousNode=n},n.prototype.visitQuery=function(n,t){var e=this,l=t.currentTimeline.currentTime,r=n.options||{},i=r.delay?Sk(r.delay):0;i&&(6===t.previousNode.type||0==l&&t.currentTimeline.getCurrentStyleProperties().length)&&(t.currentTimeline.snapshotCurrentStyles(),t.previousNode=rC);var o=l,s=t.invokeQuery(n.selector,n.originalSelector,n.limit,n.includeSelf,!!r.optional,t.errors);t.currentQueryTotal=s.length;var a=null;s.forEach(function(l,r){t.currentQueryIndex=r;var s=t.createSubContext(n.options,l);i&&s.delayNextStep(i),l===t.element&&(a=s.currentTimeline),Fk(e,n.animation,s),s.currentTimeline.applyStylesToKeyframe(),o=Math.max(o,s.currentTimeline.currentTime)}),t.currentQueryIndex=0,t.currentQueryTotal=0,t.transformIntoNewTimeline(o),a&&(t.currentTimeline.mergeTimelineCollectedStyles(a),t.currentTimeline.snapshotCurrentStyles()),t.previousNode=n},n.prototype.visitStagger=function(n,t){var e=t.parentContext,l=t.currentTimeline,r=n.timings,i=Math.abs(r.duration),o=i*(t.currentQueryTotal-1),s=i*t.currentQueryIndex;switch(r.duration<0?"reverse":r.easing){case"reverse":s=o-s;break;case"full":s=e.currentStaggerTime}var a=t.currentTimeline;s&&a.delayNextStep(s);var u=a.currentTime;Fk(this,n.animation,t),t.previousNode=n,e.currentStaggerTime=l.currentTime-u+(l.startTime-e.currentTimeline.startTime)},n}(),rC={},iC=function(){function n(n,t,e,l,r,i,o,s){this._driver=n,this.element=t,this.subInstructions=e,this._enterClassName=l,this._leaveClassName=r,this.errors=i,this.timelines=o,this.parentContext=null,this.currentAnimateTimings=null,this.previousNode=rC,this.subContextCount=0,this.options={},this.currentQueryIndex=0,this.currentQueryTotal=0,this.currentStaggerTime=0,this.currentTimeline=s||new oC(this._driver,t,0),o.push(this.currentTimeline)}return Object.defineProperty(n.prototype,"params",{get:function(){return this.options.params},enumerable:!0,configurable:!0}),n.prototype.updateOptions=function(n,t){var e=this;if(n){var l=n,r=this.options;null!=l.duration&&(r.duration=Sk(l.duration)),null!=l.delay&&(r.delay=Sk(l.delay));var i=l.params;if(i){var o=r.params;o||(o=this.options.params={}),Object.keys(i).forEach(function(n){t&&o.hasOwnProperty(n)||(o[n]=Ik(i[n],o,e.errors))})}}},n.prototype._copyOptions=function(){var n={};if(this.options){var t=this.options.params;if(t){var e=n.params={};Object.keys(t).forEach(function(n){e[n]=t[n]})}}return n},n.prototype.createSubContext=function(t,e,l){void 0===t&&(t=null);var r=e||this.element,i=new n(this._driver,r,this.subInstructions,this._enterClassName,this._leaveClassName,this.errors,this.timelines,this.currentTimeline.fork(r,l||0));return i.previousNode=this.previousNode,i.currentAnimateTimings=this.currentAnimateTimings,i.options=this._copyOptions(),i.updateOptions(t),i.currentQueryIndex=this.currentQueryIndex,i.currentQueryTotal=this.currentQueryTotal,i.parentContext=this,this.subContextCount++,i},n.prototype.transformIntoNewTimeline=function(n){return this.previousNode=rC,this.currentTimeline=this.currentTimeline.fork(this.element,n),this.timelines.push(this.currentTimeline),this.currentTimeline},n.prototype.appendInstructionToTimeline=function(n,t,e){var l={duration:null!=t?t:n.duration,delay:this.currentTimeline.currentTime+(null!=e?e:0)+n.delay,easing:""},r=new sC(this._driver,n.element,n.keyframes,n.preStyleProps,n.postStyleProps,l,n.stretchStartingKeyframe);return this.timelines.push(r),l},n.prototype.incrementTime=function(n){this.currentTimeline.forwardTime(this.currentTimeline.duration+n)},n.prototype.delayNextStep=function(n){n>0&&this.currentTimeline.delayNextStep(n)},n.prototype.invokeQuery=function(n,t,e,l,r,i){var o=[];if(l&&o.push(this.element),n.length>0){n=(n=n.replace(nC,"."+this._enterClassName)).replace(tC,"."+this._leaveClassName);var s=this._driver.query(this.element,n,1!=e);0!==e&&(s=e<0?s.slice(s.length+e,s.length):s.slice(0,e)),o.push.apply(o,s)}return r||0!=o.length||i.push('`query("'+t+'")` returned zero elements. (Use `query("'+t+'", { optional: true })` if you wish to allow this.)'),o},n}(),oC=function(){function n(n,t,e,l){this._driver=n,this.element=t,this.startTime=e,this._elementTimelineStylesLookup=l,this.duration=0,this._previousKeyframe={},this._currentKeyframe={},this._keyframes=new Map,this._styleSummary={},this._pendingStyles={},this._backFill={},this._currentEmptyStepKeyframe=null,this._elementTimelineStylesLookup||(this._elementTimelineStylesLookup=new Map),this._localTimelineStyles=Object.create(this._backFill,{}),this._globalTimelineStyles=this._elementTimelineStylesLookup.get(t),this._globalTimelineStyles||(this._globalTimelineStyles=this._localTimelineStyles,this._elementTimelineStylesLookup.set(t,this._localTimelineStyles)),this._loadKeyframe()}return n.prototype.containsAnimation=function(){switch(this._keyframes.size){case 0:return!1;case 1:return this.getCurrentStyleProperties().length>0;default:return!0}},n.prototype.getCurrentStyleProperties=function(){return Object.keys(this._currentKeyframe)},Object.defineProperty(n.prototype,"currentTime",{get:function(){return this.startTime+this.duration},enumerable:!0,configurable:!0}),n.prototype.delayNextStep=function(n){var t=1==this._keyframes.size&&Object.keys(this._pendingStyles).length;this.duration||t?(this.forwardTime(this.currentTime+n),t&&this.snapshotCurrentStyles()):this.startTime+=n},n.prototype.fork=function(t,e){return this.applyStylesToKeyframe(),new n(this._driver,t,e||this.currentTime,this._elementTimelineStylesLookup)},n.prototype._loadKeyframe=function(){this._currentKeyframe&&(this._previousKeyframe=this._currentKeyframe),this._currentKeyframe=this._keyframes.get(this.duration),this._currentKeyframe||(this._currentKeyframe=Object.create(this._backFill,{}),this._keyframes.set(this.duration,this._currentKeyframe))},n.prototype.forwardFrame=function(){this.duration+=1,this._loadKeyframe()},n.prototype.forwardTime=function(n){this.applyStylesToKeyframe(),this.duration=n,this._loadKeyframe()},n.prototype._updateStyle=function(n,t){this._localTimelineStyles[n]=t,this._globalTimelineStyles[n]=t,this._styleSummary[n]={time:this.currentTime,value:t}},n.prototype.allowOnlyTimelineStyles=function(){return this._currentEmptyStepKeyframe!==this._currentKeyframe},n.prototype.applyEmptyStep=function(n){var t=this;n&&(this._previousKeyframe.easing=n),Object.keys(this._globalTimelineStyles).forEach(function(n){t._backFill[n]=t._globalTimelineStyles[n]||is,t._currentKeyframe[n]=is}),this._currentEmptyStepKeyframe=this._currentKeyframe},n.prototype.setStyles=function(n,t,e,l){var r=this;t&&(this._previousKeyframe.easing=t);var i=l&&l.params||{},o=function(n,t){var e,l={};return n.forEach(function(n){"*"===n?(e=e||Object.keys(t)).forEach(function(n){l[n]=is}):Pk(n,!1,l)}),l}(n,this._globalTimelineStyles);Object.keys(o).forEach(function(n){var t=Ik(o[n],i,e);r._pendingStyles[n]=t,r._localTimelineStyles.hasOwnProperty(n)||(r._backFill[n]=r._globalTimelineStyles.hasOwnProperty(n)?r._globalTimelineStyles[n]:is),r._updateStyle(n,t)})},n.prototype.applyStylesToKeyframe=function(){var n=this,t=this._pendingStyles,e=Object.keys(t);0!=e.length&&(this._pendingStyles={},e.forEach(function(e){n._currentKeyframe[e]=t[e]}),Object.keys(this._localTimelineStyles).forEach(function(t){n._currentKeyframe.hasOwnProperty(t)||(n._currentKeyframe[t]=n._localTimelineStyles[t])}))},n.prototype.snapshotCurrentStyles=function(){var n=this;Object.keys(this._localTimelineStyles).forEach(function(t){var e=n._localTimelineStyles[t];n._pendingStyles[t]=e,n._updateStyle(t,e)})},n.prototype.getFinalKeyframe=function(){return this._keyframes.get(this.duration)},Object.defineProperty(n.prototype,"properties",{get:function(){var n=[];for(var t in this._currentKeyframe)n.push(t);return n},enumerable:!0,configurable:!0}),n.prototype.mergeTimelineCollectedStyles=function(n){var t=this;Object.keys(n._styleSummary).forEach(function(e){var l=t._styleSummary[e],r=n._styleSummary[e];(!l||r.time>l.time)&&t._updateStyle(e,r.value)})},n.prototype.buildKeyframes=function(){var n=this;this.applyStylesToKeyframe();var t=new Set,e=new Set,l=1===this._keyframes.size&&0===this.duration,r=[];this._keyframes.forEach(function(i,o){var s=Pk(i,!0);Object.keys(s).forEach(function(n){var l=s[n];l==ds?t.add(n):l==is&&e.add(n)}),l||(s.offset=o/n.duration),r.push(s)});var i=t.size?Rk(t.values()):[],o=e.size?Rk(e.values()):[];if(l){var s=r[0],a=Lk(s);s.offset=0,a.offset=1,r=[s,a]}return Zk(this.element,r,i,o,this.duration,this.startTime,this.easing,!1)},n}(),sC=function(n){function t(t,e,l,r,i,o,s){void 0===s&&(s=!1);var a=n.call(this,t,e,o.delay)||this;return a.element=e,a.keyframes=l,a.preStyleProps=r,a.postStyleProps=i,a._stretchStartingKeyframe=s,a.timings={duration:o.duration,delay:o.delay,easing:o.easing},a}return Object(i.__extends)(t,n),t.prototype.containsAnimation=function(){return this.keyframes.length>1},t.prototype.buildKeyframes=function(){var n=this.keyframes,t=this.timings,e=t.delay,l=t.duration,r=t.easing;if(this._stretchStartingKeyframe&&e){var i=[],o=l+e,s=e/o,a=Pk(n[0],!1);a.offset=0,i.push(a);var u=Pk(n[0],!1);u.offset=aC(s),i.push(u);for(var c=n.length-1,d=1;d<=c;d++){var h=Pk(n[d],!1);h.offset=aC((e+h.offset*l)/o),i.push(h)}l=o,e=0,r="",n=i}return Zk(this.element,n,this.preStyleProps,this.postStyleProps,l,e,r,!0)},t}(oC);function aC(n,t){void 0===t&&(t=3);var e=Math.pow(10,t-1);return Math.round(n*e)/e}var uC=function(){},cC=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return Object(i.__extends)(t,n),t.prototype.normalizePropertyName=function(n,t){return Nk(n)},t.prototype.normalizeStyleValue=function(n,t,e,l){var r="",i=e.toString().trim();if(dC[t]&&0!==e&&"0"!==e)if("number"==typeof e)r="px";else{var o=e.match(/^[+-]?[\d\.]+([a-z]*)$/);o&&0==o[1].length&&l.push("Please provide a CSS unit value for "+n+":"+e)}return i+r},t}(uC),dC=function(n){var t={};return"width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective".split(",").forEach(function(n){return t[n]=!0}),t}();function hC(n,t,e,l,r,i,o,s,a,u,c,d){return{type:0,element:n,triggerName:t,isRemovalTransition:r,fromState:e,fromStyles:i,toState:l,toStyles:o,timelines:s,queriedElements:a,preStyleProps:u,postStyleProps:c,errors:d}}var pC={},fC=function(){function n(n,t,e){this._triggerName=n,this.ast=t,this._stateStyles=e}return n.prototype.match=function(n,t){return function(n,t,e){return n.some(function(n){return n(t,e)})}(this.ast.matchers,n,t)},n.prototype.buildStyles=function(n,t,e){var l=this._stateStyles["*"],r=this._stateStyles[n],i=l?l.buildStyles(t,e):{};return r?r.buildStyles(t,e):i},n.prototype.build=function(n,t,e,l,r,o,s,a,u){var c=[],d=this.ast.options&&this.ast.options.params||pC,h=this.buildStyles(e,s&&s.params||pC,c),p=a&&a.params||pC,f=this.buildStyles(l,p,c),_=new Set,m=new Map,g=new Map,y="void"===l,b={params:Object(i.__assign)({},d,p)},v=eC(n,t,this.ast.animation,r,o,h,f,b,u,c);if(c.length)return hC(t,this._triggerName,e,l,y,h,f,[],[],m,g,c);v.forEach(function(n){var e=n.element,l=ck(m,e,{});n.preStyleProps.forEach(function(n){return l[n]=!0});var r=ck(g,e,{});n.postStyleProps.forEach(function(n){return r[n]=!0}),e!==t&&_.add(e)});var w=Rk(_.values());return hC(t,this._triggerName,e,l,y,h,f,v,w,m,g)},n}(),_C=function(){function n(n,t){this.styles=n,this.defaultParams=t}return n.prototype.buildStyles=function(n,t){var e={},l=Lk(this.defaultParams);return Object.keys(n).forEach(function(t){var e=n[t];null!=e&&(l[t]=e)}),this.styles.styles.forEach(function(n){if("string"!=typeof n){var r=n;Object.keys(r).forEach(function(n){var i=r[n];i.length>1&&(i=Ik(i,l,t)),e[n]=i})}}),e},n}(),mC=function(){function n(n,t){var e=this;this.name=n,this.ast=t,this.transitionFactories=[],this.states={},t.states.forEach(function(n){e.states[n.name]=new _C(n.style,n.options&&n.options.params||{})}),gC(this.states,"true","1"),gC(this.states,"false","0"),t.transitions.forEach(function(t){e.transitionFactories.push(new fC(n,t,e.states))}),this.fallbackTransition=new fC(n,{type:1,animation:{type:2,steps:[],options:null},matchers:[function(n,t){return!0}],options:null,queryCount:0,depCount:0},this.states)}return Object.defineProperty(n.prototype,"containsQueries",{get:function(){return this.ast.queryCount>0},enumerable:!0,configurable:!0}),n.prototype.matchTransition=function(n,t){return this.transitionFactories.find(function(e){return e.match(n,t)})||null},n.prototype.matchStyles=function(n,t,e){return this.fallbackTransition.buildStyles(n,t,e)},n}();function gC(n,t,e){n.hasOwnProperty(t)?n.hasOwnProperty(e)||(n[e]=n[t]):n.hasOwnProperty(e)&&(n[t]=n[e])}var yC=new $k,bC=function(){function n(n,t){this._driver=n,this._normalizer=t,this._animations={},this._playersById={},this.players=[]}return n.prototype.register=function(n,t){var e=[],l=Gk(this._driver,t,e);if(e.length)throw new Error("Unable to build the animation due to the following errors: "+e.join("\n"));this._animations[n]=l},n.prototype._buildPlayer=function(n,t,e){var l=n.element,r=ok(0,this._normalizer,0,n.keyframes,t,e);return this._driver.animate(l,r,n.duration,n.delay,n.easing,[])},n.prototype.create=function(n,t,e){var l=this;void 0===e&&(e={});var r,i=[],o=this._animations[n],s=new Map;if(o?(r=eC(this._driver,t,o,"ng-enter","ng-leave",{},{},e,yC,i)).forEach(function(n){var t=ck(s,n.element,{});n.postStyleProps.forEach(function(n){return t[n]=null})}):(i.push("The requested animation doesn't exist or has already been destroyed"),r=[]),i.length)throw new Error("Unable to create the animation due to the following errors: "+i.join("\n"));s.forEach(function(n,t){Object.keys(n).forEach(function(e){n[e]=l._driver.computeStyle(t,e,is)})});var a=ik(r.map(function(n){var t=s.get(n.element);return l._buildPlayer(n,{},t)}));return this._playersById[n]=a,a.onDestroy(function(){return l.destroy(n)}),this.players.push(a),a},n.prototype.destroy=function(n){var t=this._getPlayer(n);t.destroy(),delete this._playersById[n];var e=this.players.indexOf(t);e>=0&&this.players.splice(e,1)},n.prototype._getPlayer=function(n){var t=this._playersById[n];if(!t)throw new Error("Unable to find the timeline player referenced by "+n);return t},n.prototype.listen=function(n,t,e,l){var r=uk(t,"","","");return sk(this._getPlayer(n),e,r,l),function(){}},n.prototype.command=function(n,t,e,l){if("register"!=e)if("create"!=e){var r=this._getPlayer(n);switch(e){case"play":r.play();break;case"pause":r.pause();break;case"reset":r.reset();break;case"restart":r.restart();break;case"finish":r.finish();break;case"init":r.init();break;case"setPosition":r.setPosition(parseFloat(l[0]));break;case"destroy":this.destroy(n)}}else this.create(n,t,l[0]||{});else this.register(n,l[0])},n}(),vC=[],wC={namespaceId:"",setForRemoval:null,hasAnimation:!1,removedBeforeQueried:!1},xC={namespaceId:"",setForRemoval:null,hasAnimation:!1,removedBeforeQueried:!0},MC="__ng_removed",kC=function(){function n(n,t){void 0===t&&(t=""),this.namespaceId=t;var e=n&&n.hasOwnProperty("value");if(this.value=function(n){return null!=n?n:null}(e?n.value:n),e){var l=Lk(n);delete l.value,this.options=l}else this.options={};this.options.params||(this.options.params={})}return Object.defineProperty(n.prototype,"params",{get:function(){return this.options.params},enumerable:!0,configurable:!0}),n.prototype.absorbOptions=function(n){var t=n.params;if(t){var e=this.options.params;Object.keys(t).forEach(function(n){null==e[n]&&(e[n]=t[n])})}},n}(),CC=new kC("void"),SC=new kC("DELETED"),OC=function(){function n(n,t,e){this.id=n,this.hostElement=t,this._engine=e,this.players=[],this._triggers={},this._queue=[],this._elementListeners=new Map,this._hostClassName="ng-tns-"+n,jC(t,this._hostClassName)}return n.prototype.listen=function(n,t,e,l){var r,i=this;if(!this._triggers.hasOwnProperty(t))throw new Error('Unable to listen on the animation trigger event "'+e+'" because the animation trigger "'+t+"\" doesn't exist!");if(null==e||0==e.length)throw new Error('Unable to listen on the animation trigger "'+t+'" because the provided event is undefined!');if("start"!=(r=e)&&"done"!=r)throw new Error('The provided animation trigger event "'+e+'" for the animation trigger "'+t+'" is not supported!');var o=ck(this._elementListeners,n,[]),s={name:t,phase:e,callback:l};o.push(s);var a=ck(this._engine.statesByElement,n,{});return a.hasOwnProperty(t)||(jC(n,"ng-trigger"),jC(n,"ng-trigger-"+t),a[t]=CC),function(){i._engine.afterFlush(function(){var n=o.indexOf(s);n>=0&&o.splice(n,1),i._triggers[t]||delete a[t]})}},n.prototype.register=function(n,t){return!this._triggers[n]&&(this._triggers[n]=t,!0)},n.prototype._getTrigger=function(n){var t=this._triggers[n];if(!t)throw new Error('The provided animation trigger "'+n+'" has not been registered!');return t},n.prototype.trigger=function(n,t,e,l){var r=this;void 0===l&&(l=!0);var i=this._getTrigger(t),o=new LC(this.id,t,n),s=this._engine.statesByElement.get(n);s||(jC(n,"ng-trigger"),jC(n,"ng-trigger-"+t),this._engine.statesByElement.set(n,s={}));var a=s[t],u=new kC(e,this.id);if(!(e&&e.hasOwnProperty("value"))&&a&&u.absorbOptions(a.options),s[t]=u,a){if(a===SC)return o}else a=CC;if("void"===u.value||a.value!==u.value){var c=ck(this._engine.playersByElement,n,[]);c.forEach(function(n){n.namespaceId==r.id&&n.triggerName==t&&n.queued&&n.destroy()});var d=i.matchTransition(a.value,u.value),h=!1;if(!d){if(!l)return;d=i.fallbackTransition,h=!0}return this._engine.totalQueuedPlayers++,this._queue.push({element:n,triggerName:t,transition:d,fromState:a,toState:u,player:o,isFallbackTransition:h}),h||(jC(n,"ng-animate-queued"),o.onStart(function(){IC(n,"ng-animate-queued")})),o.onDone(function(){var t=r.players.indexOf(o);t>=0&&r.players.splice(t,1);var e=r._engine.playersByElement.get(n);if(e){var l=e.indexOf(o);l>=0&&e.splice(l,1)}}),this.players.push(o),c.push(o),o}if(!function(n,t){var e=Object.keys(n),l=Object.keys(t);if(e.length!=l.length)return!1;for(var r=0;r=0){for(var l=!1,r=e;r>=0;r--)if(this.driver.containsElement(this._namespaceList[r].hostElement,t)){this._namespaceList.splice(r+1,0,n),l=!0;break}l||this._namespaceList.splice(0,0,n)}else this._namespaceList.push(n);return this.namespacesByHostElement.set(t,n),n},n.prototype.register=function(n,t){var e=this._namespaceLookup[n];return e||(e=this.createNamespace(n,t)),e},n.prototype.registerTrigger=function(n,t,e){var l=this._namespaceLookup[n];l&&l.register(t,e)&&this.totalAnimations++},n.prototype.destroy=function(n,t){var e=this;if(n){var l=this._fetchNamespace(n);this.afterFlush(function(){e.namespacesByHostElement.delete(l.hostElement),delete e._namespaceLookup[n];var t=e._namespaceList.indexOf(l);t>=0&&e._namespaceList.splice(t,1)}),this.afterFlushAnimationsDone(function(){return l.destroy(t)})}},n.prototype._fetchNamespace=function(n){return this._namespaceLookup[n]},n.prototype.fetchNamespacesByElement=function(n){var t=new Set,e=this.statesByElement.get(n);if(e)for(var l=Object.keys(e),r=0;r=0;C--)this._namespaceList[C].drainQueuedTransitions(t).forEach(function(n){var t=n.player;M.push(t);var i=n.element;if(h&&e.driver.containsElement(h,i)){var o=w.get(i),d=_.get(i),p=e._buildInstruction(n,l,d,o);if(p.errors&&p.errors.length)k.push(p);else{if(n.isFallbackTransition)return t.onStart(function(){return Ak(i,p.fromStyles)}),t.onDestroy(function(){return Dk(i,p.toStyles)}),void r.push(t);p.timelines.forEach(function(n){return n.stretchStartingKeyframe=!0}),l.append(i,p.timelines),s.push({instruction:p,player:t,element:i}),p.queriedElements.forEach(function(n){return ck(a,n,[]).push(t)}),p.preStyleProps.forEach(function(n,t){var e=Object.keys(n);if(e.length){var l=u.get(t);l||u.set(t,l=new Set),e.forEach(function(n){return l.add(n)})}}),p.postStyleProps.forEach(function(n,t){var e=Object.keys(n),l=c.get(t);l||c.set(t,l=new Set),e.forEach(function(n){return l.add(n)})})}}else t.destroy()});if(k.length){var S=[];k.forEach(function(n){S.push("@"+n.triggerName+" has failed due to:\n"),n.errors.forEach(function(n){return S.push("- "+n+"\n")})}),M.forEach(function(n){return n.destroy()}),this.reportError(S)}var O=new Map,T=new Map;s.forEach(function(n){var t=n.element;l.has(t)&&(T.set(t,t),e._beforeAnimationBuild(n.player.namespaceId,n.instruction,O))}),r.forEach(function(n){var t=n.element;e._getPreviousPlayers(t,!1,n.namespaceId,n.triggerName,null).forEach(function(n){ck(O,t,[]).push(n),n.destroy()})});var L=g.filter(function(n){return HC(n,u,c)}),P=new Map;AC(P,this.driver,b,c,is).forEach(function(n){HC(n,u,c)&&L.push(n)});var D=new Map;f.forEach(function(n,t){AC(D,e.driver,new Set(n),u,ds)}),L.forEach(function(n){var t=P.get(n),e=D.get(n);P.set(n,Object(i.__assign)({},t,e))});var A=[],E=[],Y={};s.forEach(function(n){var t=n.element,i=n.player,s=n.instruction;if(l.has(t)){if(d.has(t))return i.onDestroy(function(){return Dk(t,s.toStyles)}),void r.push(i);var a=Y;if(T.size>1){for(var u=t,c=[];u=u.parentNode;){var h=T.get(u);if(h){a=h;break}c.push(u)}c.forEach(function(n){return T.set(n,a)})}var p=e._buildAnimation(i.namespaceId,s,O,o,D,P);if(i.setRealPlayer(p),a===Y)A.push(i);else{var f=e.playersByElement.get(a);f&&f.length&&(i.parentPlayer=ik(f)),r.push(i)}}else Ak(t,s.fromStyles),i.onDestroy(function(){return Dk(t,s.toStyles)}),E.push(i),d.has(t)&&r.push(i)}),E.forEach(function(n){var t=o.get(n.element);if(t&&t.length){var e=ik(t);n.setRealPlayer(e)}}),r.forEach(function(n){n.parentPlayer?n.syncPlayerEvents(n.parentPlayer):n.destroy()});for(var j=0;j0?this.driver.animate(n.element,t,n.duration,n.delay,n.easing,e):new us},n}(),LC=function(){function n(n,t,e){this.namespaceId=n,this.triggerName=t,this.element=e,this._player=new us,this._containsRealPlayer=!1,this._queuedCallbacks={},this.destroyed=!1,this.markedForDestroy=!1,this.queued=!0}return n.prototype.setRealPlayer=function(n){var t=this;this._containsRealPlayer||(this._player=n,Object.keys(this._queuedCallbacks).forEach(function(e){t._queuedCallbacks[e].forEach(function(t){return sk(n,e,void 0,t)})}),this._queuedCallbacks={},this._containsRealPlayer=!0,this.queued=!1)},n.prototype.getRealPlayer=function(){return this._player},n.prototype.syncPlayerEvents=function(n){var t=this,e=this._player;e.triggerCallback&&n.onStart(function(){return e.triggerCallback("start")}),n.onDone(function(){return t.finish()}),n.onDestroy(function(){return t.destroy()})},n.prototype._queueEvent=function(n,t){ck(this._queuedCallbacks,n,[]).push(t)},n.prototype.onDone=function(n){this.queued&&this._queueEvent("done",n),this._player.onDone(n)},n.prototype.onStart=function(n){this.queued&&this._queueEvent("start",n),this._player.onStart(n)},n.prototype.onDestroy=function(n){this.queued&&this._queueEvent("destroy",n),this._player.onDestroy(n)},n.prototype.init=function(){this._player.init()},n.prototype.hasStarted=function(){return!this.queued&&this._player.hasStarted()},n.prototype.play=function(){!this.queued&&this._player.play()},n.prototype.pause=function(){!this.queued&&this._player.pause()},n.prototype.restart=function(){!this.queued&&this._player.restart()},n.prototype.finish=function(){this._player.finish()},n.prototype.destroy=function(){this.destroyed=!0,this._player.destroy()},n.prototype.reset=function(){!this.queued&&this._player.reset()},n.prototype.setPosition=function(n){this.queued||this._player.setPosition(n)},n.prototype.getPosition=function(){return this.queued?0:this._player.getPosition()},Object.defineProperty(n.prototype,"totalTime",{get:function(){return this._player.totalTime},enumerable:!0,configurable:!0}),n.prototype.triggerCallback=function(n){var t=this._player;t.triggerCallback&&t.triggerCallback(n)},n}();function PC(n){return n&&1===n.nodeType}function DC(n,t){var e=n.style.display;return n.style.display=null!=t?t:"none",e}function AC(n,t,e,l,r){var i=[];e.forEach(function(n){return i.push(DC(n))});var o=[];l.forEach(function(e,l){var i={};e.forEach(function(n){var e=i[n]=t.computeStyle(l,n,r);e&&0!=e.length||(l[MC]=xC,o.push(l))}),n.set(l,i)});var s=0;return e.forEach(function(n){return DC(n,i[s++])}),o}function EC(n,t){var e=new Map;if(n.forEach(function(n){return e.set(n,[])}),0==t.length)return e;var l=new Set(t),r=new Map;return t.forEach(function(n){var t=function n(t){if(!t)return 1;var i=r.get(t);if(i)return i;var o=t.parentNode;return i=e.has(o)?o:l.has(o)?1:n(o),r.set(t,i),i}(n);1!==t&&e.get(t).push(n)}),e}var YC="$$classes";function jC(n,t){if(n.classList)n.classList.add(t);else{var e=n[YC];e||(e=n[YC]={}),e[t]=!0}}function IC(n,t){if(n.classList)n.classList.remove(t);else{var e=n[YC];e&&delete e[t]}}function RC(n,t,e){ik(e).onDone(function(){return n.processLeaveNode(t)})}function HC(n,t,e){var l=e.get(n);if(!l)return!1;var r=t.get(n);return r?l.forEach(function(n){return r.add(n)}):t.set(n,l),e.delete(n),!0}var NC=function(){function n(n,t){var e=this;this._driver=n,this._triggerCache={},this.onRemovalComplete=function(n,t){},this._transitionEngine=new TC(n,t),this._timelineEngine=new bC(n,t),this._transitionEngine.onRemovalComplete=function(n,t){return e.onRemovalComplete(n,t)}}return n.prototype.registerTrigger=function(n,t,e,l,r){var i=n+"-"+l,o=this._triggerCache[i];if(!o){var s=[],a=Gk(this._driver,r,s);if(s.length)throw new Error('The animation trigger "'+l+'" has failed to build due to the following errors:\n - '+s.join("\n - "));o=function(n,t){return new mC(n,t)}(l,a),this._triggerCache[i]=o}this._transitionEngine.registerTrigger(t,l,o)},n.prototype.register=function(n,t){this._transitionEngine.register(n,t)},n.prototype.destroy=function(n,t){this._transitionEngine.destroy(n,t)},n.prototype.onInsert=function(n,t,e,l){this._transitionEngine.insertNode(n,t,e,l)},n.prototype.onRemove=function(n,t,e){this._transitionEngine.removeNode(n,t,e)},n.prototype.disableAnimations=function(n,t){this._transitionEngine.markElementAsDisabled(n,t)},n.prototype.process=function(n,t,e,l){if("@"==e.charAt(0)){var r=dk(e);this._timelineEngine.command(r[0],t,r[1],l)}else this._transitionEngine.trigger(n,t,e,l)},n.prototype.listen=function(n,t,e,l,r){if("@"==e.charAt(0)){var i=dk(e);return this._timelineEngine.listen(i[0],t,i[1],r)}return this._transitionEngine.listen(n,t,e,l,r)},n.prototype.flush=function(n){void 0===n&&(n=-1),this._transitionEngine.flush(n)},Object.defineProperty(n.prototype,"players",{get:function(){return this._transitionEngine.players.concat(this._timelineEngine.players)},enumerable:!0,configurable:!0}),n.prototype.whenRenderingDone=function(){return this._transitionEngine.whenRenderingDone()},n}(),FC=function(n){function t(t,e){var r=n.call(this)||this;return r._nextAnimationId=0,r._renderer=t.createRenderer(e.body,{id:"0",encapsulation:l.S.None,styles:[],data:{animation:[]}}),r}return Object(i.__extends)(t,n),t.prototype.build=function(n){var t=this._nextAnimationId.toString();this._nextAnimationId++;var e=Array.isArray(n)?os(n):n;return WC(this._renderer,null,t,"register",[e]),new BC(t,this._renderer)},t}(rs),BC=function(n){function t(t,e){var l=n.call(this)||this;return l._id=t,l._renderer=e,l}return Object(i.__extends)(t,n),t.prototype.create=function(n,t){return new VC(this._id,n,t||{},this._renderer)},t}(function(){}),VC=function(){function n(n,t,e,l){this.id=n,this.element=t,this._renderer=l,this.parentPlayer=null,this._started=!1,this.totalTime=0,this._command("create",e)}return n.prototype._listen=function(n,t){return this._renderer.listen(this.element,"@@"+this.id+":"+n,t)},n.prototype._command=function(n){for(var t=[],e=1;e=0&&n=11?n:n+12:"sore"===t||"malam"===t?n+12:void 0},meridiem:function(n,t,e){return n<11?"pagi":n<15?"siang":n<19?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",ss:"%d detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}(e("PJh5"))},z3hR:function(n,t,e){!function(n){"use strict";function t(n,t,e,l){var r={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return t?r[e][0]:r[e][1]}function e(n){if(n=parseInt(n,10),isNaN(n))return!1;if(n<0)return!0;if(n<10)return 4<=n&&n<=7;if(n<100){var t=n%10;return e(0===t?n/10:t)}if(n<1e4){for(;n>=10;)n/=10;return e(n)}return e(n/=1e3)}n.defineLocale("lb",{months:"Januar_Februar_M\xe4erz_Abr\xebll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonndeg_M\xe9indeg_D\xebnschdeg_M\xebttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._M\xe9._D\xeb._M\xeb._Do._Fr._Sa.".split("_"),weekdaysMin:"So_M\xe9_D\xeb_M\xeb_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm [Auer]",LLLL:"dddd, D. MMMM YYYY H:mm [Auer]"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[G\xebschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:function(n){return e(n.substr(0,n.indexOf(" ")))?"a "+n:"an "+n},past:function(n){return e(n.substr(0,n.indexOf(" ")))?"viru "+n:"virun "+n},s:"e puer Sekonnen",ss:"%d Sekonnen",m:t,mm:"%d Minutten",h:t,hh:"%d Stonnen",d:t,dd:"%d Deeg",M:t,MM:"%d M\xe9int",y:t,yy:"%d Joer"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e("PJh5"))}},[0]); \ No newline at end of file diff --git a/src/gui/static/dist/polyfills.44742ea60435cec4c09d.bundle.js b/src/gui/static/dist/polyfills.44742ea60435cec4c09d.bundle.js new file mode 100644 index 0000000..876852c --- /dev/null +++ b/src/gui/static/dist/polyfills.44742ea60435cec4c09d.bundle.js @@ -0,0 +1 @@ +webpackJsonp([8],{"/whu":function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},"0Rih":function(t,e,n){"use strict";var r=n("OzIq"),o=n("Ds5P"),i=n("R3AP"),a=n("A16L"),c=n("1aA0"),u=n("vmSO"),s=n("9GpA"),f=n("UKM+"),l=n("zgIt"),p=n("qkyc"),h=n("yYvK"),v=n("kic5");t.exports=function(t,e,n,d,y,g){var _=r[t],k=_,m=y?"set":"add",b=k&&k.prototype,w={},T=function(t){var e=b[t];i(b,t,"delete"==t?function(t){return!(g&&!f(t))&&e.call(this,0===t?0:t)}:"has"==t?function(t){return!(g&&!f(t))&&e.call(this,0===t?0:t)}:"get"==t?function(t){return g&&!f(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof k&&(g||b.forEach&&!l(function(){(new k).entries().next()}))){var O=new k,D=O[m](g?{}:-0,1)!=O,E=l(function(){O.has(1)}),S=p(function(t){new k(t)}),P=!g&&l(function(){for(var t=new k,e=5;e--;)t[m](e,e);return!t.has(-0)});S||((k=e(function(e,n){s(e,k,t);var r=v(new _,e,k);return void 0!=n&&u(n,y,r[m],r),r})).prototype=b,b.constructor=k),(E||P)&&(T("delete"),T("has"),y&&T("get")),(P||D)&&T(m),g&&b.clear&&delete b.clear}else k=d.getConstructor(e,t,y,m),a(k.prototype,n),c.NEED=!0;return h(k,t),w[t]=k,o(o.G+o.W+o.F*(k!=_),w),g||d.setStrong(k,t,y),k}},1:function(t,e,n){t.exports=n("XS25")},"1aA0":function(t,e,n){var r=n("ulTY")("meta"),o=n("UKM+"),i=n("WBcL"),a=n("lDLk").f,c=0,u=Object.isExtensible||function(){return!0},s=!n("zgIt")(function(){return u(Object.preventExtensions({}))}),f=function(t){a(t,r,{value:{i:"O"+ ++c,w:{}}})},l=t.exports={KEY:r,NEED:!1,fastKey:function(t,e){if(!o(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!i(t,r)){if(!u(t))return"F";if(!e)return"E";f(t)}return t[r].i},getWeak:function(t,e){if(!i(t,r)){if(!u(t))return!0;if(!e)return!1;f(t)}return t[r].w},onFreeze:function(t){return s&&l.NEED&&u(t)&&!i(t,r)&&f(t),t}}},"2p1q":function(t,e,n){var r=n("lDLk"),o=n("fU25");t.exports=n("bUqO")?function(t,e,n){return r.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},"2tFN":function(t,e,n){n("CVR+"),n("vmSu"),n("4ZU1"),n("yx1U"),n("X7aK"),n("SPtU"),n("A52B"),n("PuTd"),n("dm+7"),n("JG34"),n("Rw4K"),n("9mGU"),n("bUY0"),n("mTp7"),t.exports=n("7gX0").Reflect},"3q4u":function(t,e,n){var r=n("wCso"),o=n("DIVP"),i=r.key,a=r.map,c=r.store;r.exp({deleteMetadata:function(t,e){var n=arguments.length<3?void 0:i(arguments[2]),r=a(o(e),n,!1);if(void 0===r||!r.delete(t))return!1;if(r.size)return!0;var u=c.get(e);return u.delete(n),!!u.size||c.delete(e)}})},"4ZU1":function(t,e,n){var r=n("lDLk"),o=n("Ds5P"),i=n("DIVP"),a=n("s4j0");o(o.S+o.F*n("zgIt")(function(){Reflect.defineProperty(r.f({},1,{value:1}),1,{value:2})}),"Reflect",{defineProperty:function(t,e,n){i(t),e=a(e,!0),i(n);try{return r.f(t,e,n),!0}catch(t){return!1}}})},"7gX0":function(t,e){var n=t.exports={version:"2.5.3"};"number"==typeof __e&&(__e=n)},"7ylX":function(t,e,n){var r=n("DIVP"),o=n("twxM"),i=n("QKXm"),a=n("mZON")("IE_PROTO"),c=function(){},u=function(){var t,e=n("jhxf")("iframe"),r=i.length;for(e.style.display="none",n("d075").appendChild(e),e.src="javascript:",(t=e.contentWindow.document).open(),t.write("'],s=0;o>s;s++){a.push("");for(var h=0;o>h;h++)a.push('');a.push("")}a.push("
"),r.innerHTML=a.join("");var u=r.childNodes[0],l=(e.width-u.offsetWidth)/2,f=(e.height-u.offsetHeight)/2;l>0&&f>0&&(u.style.margin=f+"px "+l+"px")},t.prototype.clear=function(){this._el.innerHTML=""},t}();(QRCode=function(t,e){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:s.H},"string"==typeof e&&(e={text:e}),e)for(var r in e)this._htOption[r]=e[r];"string"==typeof t&&(t=document.getElementById(t)),this._android=n(),this._el=t,this._oQRCode=null,this._oDrawing=new c(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)}).prototype.makeCode=function(t){this._oQRCode=new e(function(t,e){for(var r=1,o=function(t){var e=encodeURI(t).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return e.length+(e.length!=t?3:0)}(t),i=0,n=g.length;n>=i;i++){var a=0;switch(e){case s.L:a=g[i][0];break;case s.M:a=g[i][1];break;case s.Q:a=g[i][2];break;case s.H:a=g[i][3]}if(a>=o)break;r++}if(r>g.length)throw new Error("Too long data");return r}(t,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(t),this._oQRCode.make(),this._el.title=t,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=s}(); \ No newline at end of file diff --git a/src/gui/static/dist/styles.3072000db951801c187c.bundle.css b/src/gui/static/dist/styles.3072000db951801c187c.bundle.css new file mode 100644 index 0000000..d053976 --- /dev/null +++ b/src/gui/static/dist/styles.3072000db951801c187c.bundle.css @@ -0,0 +1,9 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fontawesome-webfont.674f50d287a8c48dc19b.eot?v=4.7.0);src:url(fontawesome-webfont.674f50d287a8c48dc19b.eot?#iefix&v=4.7.0) format('embedded-opentype'),url(fontawesome-webfont.af7ae505a9eed503f8b8.woff2?v=4.7.0) format('woff2'),url(fontawesome-webfont.fee66e712a8a08eef580.woff?v=4.7.0) format('woff'),url(fontawesome-webfont.b06871f281fee6b241d6.ttf?v=4.7.0) format('truetype'),url(fontawesome-webfont.912ec66d7572ff821749.svg?v=4.7.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:2s linear infinite fa-spin;animation:2s linear infinite fa-spin}.fa-pulse{-webkit-animation:1s steps(8) infinite fa-spin;animation:1s steps(8) infinite fa-spin}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:"\f2a3"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-address-card:before,.fa-vcard:before{content:"\f2bb"}.fa-address-card-o:before,.fa-vcard-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(MaterialIcons-Regular.e79bfd88537def476913.eot);src:local('Material Icons'),local('MaterialIcons-Regular'),url(MaterialIcons-Regular.570eb83859dc23dd0eec.woff2) format('woff2'),url(MaterialIcons-Regular.012cf6a10129e2275d79.woff) format('woff'),url(MaterialIcons-Regular.a37b0c01c0baf1888ca8.ttf) format('truetype')}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;-webkit-font-feature-settings:'liga';font-feature-settings:'liga'}.-table:last-of-type{margin-bottom:30px}.-table .-headers{color:rgba(30,34,39,.2);display:-webkit-box;display:-ms-flexbox;display:flex;font-size:12px;font-weight:700;height:50px;line-height:50px;margin:0 30px}.-table .-headers>div{padding:0 20px}.-table .-body{border-radius:15px;-webkit-box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);box-shadow:0 0 2px 2px rgba(0,0,0,.01),1px 1px 2px 2px rgba(0,0,0,.01);margin:0 30px}.-table .-body .-row{font-size:13px;padding:15px 0;background:#fafafa;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.-table .-body .-row:not(:last-child){border-bottom:1px solid #eff0f0}.-table .-body .-row:first-child{border-top-left-radius:15px;border-top-right-radius:15px}.-table .-body .-row:last-child{border-bottom-left-radius:15px;border-bottom-right-radius:15px}.-table .-body .-row>div{padding:0 20px}.-table .-width-70{width:70px;-ms-flex-negative:0;flex-shrink:0}.-table .-width-150{width:150px;-ms-flex-negative:0;flex-shrink:0}.-table .-width-200{width:200px;-ms-flex-negative:0;flex-shrink:0}.-table .-width-250{width:250px;-ms-flex-negative:0;flex-shrink:0}.modal .-body{line-height:20px;font-size:13px;color:#1e2227;opacity:.8}.modal .big-text{color:#000;font-weight:700;font-size:15px}.modal .-check-container{text-align:center;margin-top:25px}.modal .-check-container .-check label{font-family:Skycoin;line-height:normal;font-size:14px;color:#1e2227}.modal .-check-container .-check .mat-checkbox-checkmark-path{position:absolute;width:18px;height:8px;left:4.59px;top:9px;stroke:#0072ff!important}.modal .-check-container .-check .mat-checkbox-background,.modal .-check-container .-check .mat-checkbox-frame{top:0;left:0;right:0;bottom:0;position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;pointer-events:none;width:20px;height:20px;background:rgba(30,34,39,.05);border-radius:6px;border-color:transparent}.modal .-buttons{text-align:center}.modal app-button button{margin-top:28px}/*! + * Bootstrap Grid v4.0.0-beta.3 (https://getbootstrap.com) + * Copyright 2011-2017 The Bootstrap Authors + * Copyright 2011-2017 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */@-ms-viewport{width:device-width}html{-webkit-box-sizing:border-box;box-sizing:border-box;-ms-overflow-style:scrollbar;height:100%}*,::after,::before{-webkit-box-sizing:inherit;box-sizing:inherit}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-sm-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-sm-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-sm-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-sm-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-sm-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-sm-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-md-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-md-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-md-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-md-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-md-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-md-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-lg-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-lg-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-lg-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-lg-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-lg-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-lg-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-xl-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-xl-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-xl-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-xl-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-xl-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-xl-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}}.flex-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.flex-sm-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-sm-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.flex-md-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-md-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.flex-lg-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-lg-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.flex-xl-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-xl-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}.d-print-block{display:none!important}@media print{.d-print-block{display:block!important}}.d-print-inline{display:none!important}@media print{.d-print-inline{display:inline!important}}.d-print-inline-block{display:none!important}@media print{.d-print-inline-block{display:inline-block!important}.d-print-none{display:none!important}}.mat-elevation-z0{-webkit-box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12);box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.mat-elevation-z1{-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12)}.mat-elevation-z2{-webkit-box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-elevation-z3{-webkit-box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12);box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}.mat-elevation-z4{-webkit-box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.mat-elevation-z5{-webkit-box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12);box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12)}.mat-elevation-z6{-webkit-box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-elevation-z7{-webkit-box-shadow:0 4px 5px -2px rgba(0,0,0,.2),0 7px 10px 1px rgba(0,0,0,.14),0 2px 16px 1px rgba(0,0,0,.12);box-shadow:0 4px 5px -2px rgba(0,0,0,.2),0 7px 10px 1px rgba(0,0,0,.14),0 2px 16px 1px rgba(0,0,0,.12)}.mat-elevation-z8{-webkit-box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12);box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.mat-elevation-z9{-webkit-box-shadow:0 5px 6px -3px rgba(0,0,0,.2),0 9px 12px 1px rgba(0,0,0,.14),0 3px 16px 2px rgba(0,0,0,.12);box-shadow:0 5px 6px -3px rgba(0,0,0,.2),0 9px 12px 1px rgba(0,0,0,.14),0 3px 16px 2px rgba(0,0,0,.12)}.mat-elevation-z10{-webkit-box-shadow:0 6px 6px -3px rgba(0,0,0,.2),0 10px 14px 1px rgba(0,0,0,.14),0 4px 18px 3px rgba(0,0,0,.12);box-shadow:0 6px 6px -3px rgba(0,0,0,.2),0 10px 14px 1px rgba(0,0,0,.14),0 4px 18px 3px rgba(0,0,0,.12)}.mat-elevation-z11{-webkit-box-shadow:0 6px 7px -4px rgba(0,0,0,.2),0 11px 15px 1px rgba(0,0,0,.14),0 4px 20px 3px rgba(0,0,0,.12);box-shadow:0 6px 7px -4px rgba(0,0,0,.2),0 11px 15px 1px rgba(0,0,0,.14),0 4px 20px 3px rgba(0,0,0,.12)}.mat-elevation-z12{-webkit-box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12);box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-elevation-z13{-webkit-box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12);box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12)}.mat-elevation-z14{-webkit-box-shadow:0 7px 9px -4px rgba(0,0,0,.2),0 14px 21px 2px rgba(0,0,0,.14),0 5px 26px 4px rgba(0,0,0,.12);box-shadow:0 7px 9px -4px rgba(0,0,0,.2),0 14px 21px 2px rgba(0,0,0,.14),0 5px 26px 4px rgba(0,0,0,.12)}.mat-elevation-z15{-webkit-box-shadow:0 8px 9px -5px rgba(0,0,0,.2),0 15px 22px 2px rgba(0,0,0,.14),0 6px 28px 5px rgba(0,0,0,.12);box-shadow:0 8px 9px -5px rgba(0,0,0,.2),0 15px 22px 2px rgba(0,0,0,.14),0 6px 28px 5px rgba(0,0,0,.12)}.mat-elevation-z16{-webkit-box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.mat-elevation-z17{-webkit-box-shadow:0 8px 11px -5px rgba(0,0,0,.2),0 17px 26px 2px rgba(0,0,0,.14),0 6px 32px 5px rgba(0,0,0,.12);box-shadow:0 8px 11px -5px rgba(0,0,0,.2),0 17px 26px 2px rgba(0,0,0,.14),0 6px 32px 5px rgba(0,0,0,.12)}.mat-elevation-z18{-webkit-box-shadow:0 9px 11px -5px rgba(0,0,0,.2),0 18px 28px 2px rgba(0,0,0,.14),0 7px 34px 6px rgba(0,0,0,.12);box-shadow:0 9px 11px -5px rgba(0,0,0,.2),0 18px 28px 2px rgba(0,0,0,.14),0 7px 34px 6px rgba(0,0,0,.12)}.mat-elevation-z19{-webkit-box-shadow:0 9px 12px -6px rgba(0,0,0,.2),0 19px 29px 2px rgba(0,0,0,.14),0 7px 36px 6px rgba(0,0,0,.12);box-shadow:0 9px 12px -6px rgba(0,0,0,.2),0 19px 29px 2px rgba(0,0,0,.14),0 7px 36px 6px rgba(0,0,0,.12)}.mat-elevation-z20{-webkit-box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 20px 31px 3px rgba(0,0,0,.14),0 8px 38px 7px rgba(0,0,0,.12);box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 20px 31px 3px rgba(0,0,0,.14),0 8px 38px 7px rgba(0,0,0,.12)}.mat-elevation-z21{-webkit-box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 21px 33px 3px rgba(0,0,0,.14),0 8px 40px 7px rgba(0,0,0,.12);box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 21px 33px 3px rgba(0,0,0,.14),0 8px 40px 7px rgba(0,0,0,.12)}.mat-elevation-z22{-webkit-box-shadow:0 10px 14px -6px rgba(0,0,0,.2),0 22px 35px 3px rgba(0,0,0,.14),0 8px 42px 7px rgba(0,0,0,.12);box-shadow:0 10px 14px -6px rgba(0,0,0,.2),0 22px 35px 3px rgba(0,0,0,.14),0 8px 42px 7px rgba(0,0,0,.12)}.mat-elevation-z23{-webkit-box-shadow:0 11px 14px -7px rgba(0,0,0,.2),0 23px 36px 3px rgba(0,0,0,.14),0 9px 44px 8px rgba(0,0,0,.12);box-shadow:0 11px 14px -7px rgba(0,0,0,.2),0 23px 36px 3px rgba(0,0,0,.14),0 9px 44px 8px rgba(0,0,0,.12)}.mat-elevation-z24{-webkit-box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12)}.mat-h1,.mat-headline,.mat-typography h1{font:400 24px/32px Roboto,"Helvetica Neue",sans-serif;margin:0 0 16px}.mat-h2,.mat-title,.mat-typography h2{font:500 20px/32px Roboto,"Helvetica Neue",sans-serif;margin:0 0 16px}.mat-h3,.mat-subheading-2,.mat-typography h3{font:400 16px/28px Roboto,"Helvetica Neue",sans-serif;margin:0 0 16px}.mat-h4,.mat-subheading-1,.mat-typography h4{font:400 15px/24px Roboto,"Helvetica Neue",sans-serif;margin:0 0 16px}.mat-h5,.mat-typography h5{font-size:11.62px;font-weight:400;font-family:Roboto,"Helvetica Neue",sans-serif;line-height:20px;margin:0 0 12px}.mat-h6,.mat-typography h6{font-size:9.38px;font-weight:400;font-family:Roboto,"Helvetica Neue",sans-serif;line-height:20px;margin:0 0 12px}.mat-body-2,.mat-body-strong{font:500 14px/24px Roboto,"Helvetica Neue",sans-serif}.mat-body,.mat-body-1,.mat-typography{font:400 14px/20px Roboto,"Helvetica Neue",sans-serif}.mat-body p,.mat-body-1 p,.mat-typography p{margin:0 0 12px}.mat-caption,.mat-small{font:400 12px/20px Roboto,"Helvetica Neue",sans-serif}.mat-display-4,.mat-typography .mat-display-4{font:300 112px/112px Roboto,"Helvetica Neue",sans-serif;margin:0 0 56px;letter-spacing:-.05em}.mat-display-3,.mat-typography .mat-display-3{font:400 56px/56px Roboto,"Helvetica Neue",sans-serif;margin:0 0 64px;letter-spacing:-.02em}.mat-display-2,.mat-typography .mat-display-2{font:400 45px/48px Roboto,"Helvetica Neue",sans-serif;margin:0 0 64px;letter-spacing:-.005em}.mat-display-1,.mat-typography .mat-display-1{font:400 34px/40px Roboto,"Helvetica Neue",sans-serif;margin:0 0 64px}.mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px;font-weight:500}.mat-button-toggle,.mat-card{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-card-title{font-size:24px;font-weight:400}.mat-card-content,.mat-card-header .mat-card-title,.mat-card-subtitle{font-size:14px}.mat-checkbox{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-checkbox-layout .mat-checkbox-label{line-height:24px}.mat-chip{font-size:13px;line-height:18px}.mat-chip .mat-chip-remove.mat-icon{font-size:18px}.mat-table{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-header-cell{font-size:12px;font-weight:500}.mat-cell{font-size:14px}.mat-calendar{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-calendar-body{font-size:13px}.mat-calendar-body-label,.mat-calendar-period-button{font-size:14px;font-weight:500}.mat-calendar-table-header th{font-size:11px;font-weight:400}.mat-dialog-title{font:500 20px/32px Roboto,"Helvetica Neue",sans-serif}.mat-expansion-panel-header{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:15px;font-weight:400}.mat-expansion-panel-content{font:400 14px/20px Roboto,"Helvetica Neue",sans-serif}.mat-form-field{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:inherit;font-weight:400;line-height:1.125}.mat-form-field-wrapper{padding-bottom:1.25em}.mat-form-field-prefix .mat-icon,.mat-form-field-suffix .mat-icon{font-size:150%;line-height:1.125}.mat-form-field-prefix .mat-icon-button,.mat-form-field-suffix .mat-icon-button{height:1.5em;width:1.5em}.mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field-suffix .mat-icon-button .mat-icon{height:1.125em;line-height:1.125}.mat-form-field-infix{padding:.4375em 0;border-top:.84375em solid transparent}.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label,.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label{-webkit-transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px);transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px);-ms-transform:translateY(-1.28125em) scale(.75);width:133.33333333%}.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.00101px);transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.00101px);-ms-transform:translateY(-1.28124em) scale(.75);width:133.33334333%}.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{-webkit-transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.00102px);transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.00102px);-ms-transform:translateY(-1.28123em) scale(.75);width:133.33335333%}.mat-form-field-label-wrapper{top:-.84375em;padding-top:.84375em}.mat-form-field-label{top:1.28125em}.mat-form-field-underline{bottom:1.25em}.mat-form-field-subscript-wrapper{font-size:75%;margin-top:.54166667em;top:calc(100% - 1.66666667em)}.mat-grid-tile-footer,.mat-grid-tile-header{font-size:14px}.mat-grid-tile-footer .mat-line,.mat-grid-tile-header .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;-webkit-box-sizing:border-box;box-sizing:border-box}.mat-grid-tile-footer .mat-line:nth-child(n+2),.mat-grid-tile-header .mat-line:nth-child(n+2){font-size:12px}input.mat-input-element{margin-top:-.0625em}.mat-menu-item{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:16px;font-weight:400}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:12px}.mat-radio-button,.mat-select{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-select-trigger{height:1.125em}.mat-slide-toggle-content{font:400 14px/20px Roboto,"Helvetica Neue",sans-serif}.mat-slider-thumb-label-text{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:12px;font-weight:500}.mat-stepper-horizontal,.mat-stepper-vertical{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-step-label{font-size:14px;font-weight:400}.mat-step-label-selected{font-size:14px;font-weight:500}.mat-tab-group{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-tab-label,.mat-tab-link{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px;font-weight:500}.mat-toolbar,.mat-toolbar h1,.mat-toolbar h2,.mat-toolbar h3,.mat-toolbar h4,.mat-toolbar h5,.mat-toolbar h6{font:500 20px/32px Roboto,"Helvetica Neue",sans-serif;margin:0}.mat-tooltip{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:10px;padding-top:6px;padding-bottom:6px}.mat-list-item,.mat-list-option{font-family:Roboto,"Helvetica Neue",sans-serif}.mat-list .mat-list-item,.mat-nav-list .mat-list-item,.mat-selection-list .mat-list-item{font-size:16px}.mat-list .mat-list-item .mat-line,.mat-nav-list .mat-list-item .mat-line,.mat-selection-list .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;-webkit-box-sizing:border-box;box-sizing:border-box}.mat-list .mat-list-item .mat-line:nth-child(n+2),.mat-nav-list .mat-list-item .mat-line:nth-child(n+2),.mat-selection-list .mat-list-item .mat-line:nth-child(n+2){font-size:14px}.mat-list .mat-list-option,.mat-nav-list .mat-list-option,.mat-selection-list .mat-list-option{font-size:16px}.mat-list .mat-list-option .mat-line,.mat-nav-list .mat-list-option .mat-line,.mat-selection-list .mat-list-option .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;-webkit-box-sizing:border-box;box-sizing:border-box}.mat-list .mat-list-option .mat-line:nth-child(n+2),.mat-nav-list .mat-list-option .mat-line:nth-child(n+2),.mat-selection-list .mat-list-option .mat-line:nth-child(n+2){font-size:14px}.mat-list[dense] .mat-list-item,.mat-nav-list[dense] .mat-list-item,.mat-selection-list[dense] .mat-list-item{font-size:12px}.mat-list[dense] .mat-list-item .mat-line,.mat-nav-list[dense] .mat-list-item .mat-line,.mat-selection-list[dense] .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;-webkit-box-sizing:border-box;box-sizing:border-box}.mat-list[dense] .mat-list-item .mat-line:nth-child(n+2),.mat-list[dense] .mat-list-option,.mat-nav-list[dense] .mat-list-item .mat-line:nth-child(n+2),.mat-nav-list[dense] .mat-list-option,.mat-selection-list[dense] .mat-list-item .mat-line:nth-child(n+2),.mat-selection-list[dense] .mat-list-option{font-size:12px}.mat-list[dense] .mat-list-option .mat-line,.mat-nav-list[dense] .mat-list-option .mat-line,.mat-selection-list[dense] .mat-list-option .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;-webkit-box-sizing:border-box;box-sizing:border-box}.mat-list[dense] .mat-list-option .mat-line:nth-child(n+2),.mat-nav-list[dense] .mat-list-option .mat-line:nth-child(n+2),.mat-selection-list[dense] .mat-list-option .mat-line:nth-child(n+2){font-size:12px}.mat-list[dense] .mat-subheader,.mat-nav-list[dense] .mat-subheader,.mat-selection-list[dense] .mat-subheader{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:12px;font-weight:500}.mat-option{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:16px}.mat-optgroup-label{font:500 14px/24px Roboto,"Helvetica Neue",sans-serif}.mat-simple-snackbar{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px}.mat-simple-snackbar-action{line-height:1;font-family:inherit;font-size:inherit;font-weight:500}.mat-ripple{overflow:hidden}@media screen and (-ms-high-contrast:active){.mat-ripple{display:none}.mat-option-ripple{opacity:.5}}.mat-ripple.mat-ripple-unbounded{overflow:visible}.mat-ripple-element{position:absolute;border-radius:50%;pointer-events:none;-webkit-transition:opacity,-webkit-transform 0s cubic-bezier(0,0,.2,1);transition:opacity,-webkit-transform 0s cubic-bezier(0,0,.2,1);transition:opacity,transform 0s cubic-bezier(0,0,.2,1);transition:opacity,transform 0s cubic-bezier(0,0,.2,1),-webkit-transform 0s cubic-bezier(0,0,.2,1);-webkit-transform:scale(0);transform:scale(0)}.mat-option{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;position:relative;cursor:pointer;outline:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;max-width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:rgba(0,0,0,.87)}.mat-option[disabled]{cursor:default}[dir=rtl] .mat-option{text-align:right}.mat-option .mat-icon{margin-right:16px}[dir=rtl] .mat-option .mat-icon{margin-left:16px;margin-right:0}.mat-option[aria-disabled=true]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.mat-optgroup .mat-option:not(.mat-option-multiple){padding-left:32px}[dir=rtl] .mat-optgroup .mat-option:not(.mat-option-multiple){padding-left:16px;padding-right:32px}.mat-option-text{display:inline-block;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;overflow:hidden;text-overflow:ellipsis}.mat-option-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-option-pseudo-checkbox{margin-right:8px}[dir=rtl] .mat-option-pseudo-checkbox{margin-left:8px;margin-right:0}.mat-optgroup-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default;color:rgba(0,0,0,.54)}.mat-optgroup-label[disabled]{cursor:default}[dir=rtl] .mat-optgroup-label{text-align:right}.mat-optgroup-label .mat-icon{margin-right:16px}[dir=rtl] .mat-optgroup-label .mat-icon{margin-left:16px;margin-right:0}.cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.cdk-global-overlay-wrapper,.cdk-overlay-container{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-global-overlay-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;-webkit-box-sizing:border-box;box-sizing:border-box;z-index:1000}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;-webkit-transition:opacity .4s cubic-bezier(.25,.8,.25,1);transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.48}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.6)}.cdk-overlay-transparent-backdrop{background:0 0}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.mat-ripple-element{background-color:rgba(0,0,0,.1)}.mat-option:focus:not(.mat-option-disabled),.mat-option:hover:not(.mat-option-disabled){background:rgba(0,0,0,.04)}.mat-primary .mat-option.mat-selected:not(.mat-option-disabled){color:#0072ff}.mat-accent .mat-option.mat-selected:not(.mat-option-disabled){color:#ffc125}.mat-warn .mat-option.mat-selected:not(.mat-option-disabled){color:#f44336}.mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled){background:rgba(0,0,0,.04)}.mat-option.mat-active{background:rgba(0,0,0,.04);color:rgba(0,0,0,.87)}.mat-option.mat-option-disabled{color:rgba(0,0,0,.38)}.mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,.38)}.mat-pseudo-checkbox{color:rgba(0,0,0,.54)}.mat-pseudo-checkbox::after{color:#fafafa}.mat-accent .mat-pseudo-checkbox-checked,.mat-accent .mat-pseudo-checkbox-indeterminate,.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox-indeterminate{background:#ffc125}.mat-primary .mat-pseudo-checkbox-checked,.mat-primary .mat-pseudo-checkbox-indeterminate{background:#0072ff}.mat-warn .mat-pseudo-checkbox-checked,.mat-warn .mat-pseudo-checkbox-indeterminate{background:#f44336}.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.mat-app-background{background-color:#fafafa}.mat-theme-loaded-marker{display:none}.mat-autocomplete-panel{background:#fff;color:rgba(0,0,0,.87)}.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff}.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover):not(.mat-option-disabled){color:rgba(0,0,0,.87)}.mat-button,.mat-icon-button{background:0 0}.mat-button.mat-primary .mat-button-focus-overlay,.mat-icon-button.mat-primary .mat-button-focus-overlay{background-color:rgba(0,114,255,.12)}.mat-button.mat-accent .mat-button-focus-overlay,.mat-icon-button.mat-accent .mat-button-focus-overlay{background-color:rgba(255,193,37,.12)}.mat-button.mat-warn .mat-button-focus-overlay,.mat-icon-button.mat-warn .mat-button-focus-overlay{background-color:rgba(244,67,54,.12)}.mat-button[disabled] .mat-button-focus-overlay,.mat-icon-button[disabled] .mat-button-focus-overlay{background-color:transparent}.mat-button.mat-primary,.mat-icon-button.mat-primary{color:#0072ff}.mat-button.mat-accent,.mat-icon-button.mat-accent{color:#ffc125}.mat-button.mat-warn,.mat-icon-button.mat-warn{color:#f44336}.mat-button.mat-accent[disabled],.mat-button.mat-primary[disabled],.mat-button.mat-warn[disabled],.mat-button[disabled][disabled],.mat-icon-button.mat-accent[disabled],.mat-icon-button.mat-primary[disabled],.mat-icon-button.mat-warn[disabled],.mat-icon-button[disabled][disabled]{color:rgba(0,0,0,.38)}.mat-fab,.mat-mini-fab,.mat-raised-button{color:rgba(0,0,0,.87);background-color:#fff}.mat-fab.mat-accent,.mat-fab.mat-primary,.mat-fab.mat-warn,.mat-mini-fab.mat-accent,.mat-mini-fab.mat-primary,.mat-mini-fab.mat-warn,.mat-raised-button.mat-accent,.mat-raised-button.mat-primary,.mat-raised-button.mat-warn{color:#fff}.mat-fab.mat-accent[disabled],.mat-fab.mat-primary[disabled],.mat-fab.mat-warn[disabled],.mat-fab[disabled][disabled],.mat-mini-fab.mat-accent[disabled],.mat-mini-fab.mat-primary[disabled],.mat-mini-fab.mat-warn[disabled],.mat-mini-fab[disabled][disabled],.mat-raised-button.mat-accent[disabled],.mat-raised-button.mat-primary[disabled],.mat-raised-button.mat-warn[disabled],.mat-raised-button[disabled][disabled]{color:rgba(0,0,0,.38);background-color:rgba(0,0,0,.12)}.mat-fab.mat-primary,.mat-mini-fab.mat-primary,.mat-raised-button.mat-primary{background-color:#0072ff}.mat-fab.mat-accent,.mat-mini-fab.mat-accent,.mat-raised-button.mat-accent{background-color:#ffc125}.mat-fab.mat-warn,.mat-mini-fab.mat-warn,.mat-raised-button.mat-warn{background-color:#f44336}.mat-fab.mat-accent .mat-ripple-element,.mat-fab.mat-primary .mat-ripple-element,.mat-fab.mat-warn .mat-ripple-element,.mat-mini-fab.mat-accent .mat-ripple-element,.mat-mini-fab.mat-primary .mat-ripple-element,.mat-mini-fab.mat-warn .mat-ripple-element,.mat-raised-button.mat-accent .mat-ripple-element,.mat-raised-button.mat-primary .mat-ripple-element,.mat-raised-button.mat-warn .mat-ripple-element{background-color:rgba(255,255,255,.2)}.mat-button.mat-primary .mat-ripple-element{background-color:rgba(0,114,255,.1)}.mat-button.mat-accent .mat-ripple-element{background-color:rgba(255,193,37,.1)}.mat-button.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.1)}.mat-icon-button.mat-primary .mat-ripple-element{background-color:rgba(0,114,255,.2)}.mat-icon-button.mat-accent .mat-ripple-element{background-color:rgba(255,193,37,.2)}.mat-icon-button.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.2)}.mat-button-toggle{color:rgba(0,0,0,.38)}.mat-button-toggle.cdk-focused .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,.06)}.mat-button-toggle-checked{background-color:#e0e0e0;color:rgba(0,0,0,.54)}.mat-button-toggle-disabled{background-color:#eee;color:rgba(0,0,0,.38)}.mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.mat-card{background:#fff;color:rgba(0,0,0,.87)}.mat-card-subtitle{color:rgba(0,0,0,.54)}.mat-checkbox-frame{border-color:rgba(0,0,0,.54)}.mat-checkbox-checkmark{fill:#fafafa}.mat-checkbox-checkmark-path{stroke:#fafafa!important}.mat-checkbox-mixedmark{background-color:#fafafa}.mat-checkbox-checked.mat-primary .mat-checkbox-background,.mat-checkbox-indeterminate.mat-primary .mat-checkbox-background{background-color:#0072ff}.mat-checkbox-checked.mat-accent .mat-checkbox-background,.mat-checkbox-indeterminate.mat-accent .mat-checkbox-background{background-color:#ffc125}.mat-checkbox-checked.mat-warn .mat-checkbox-background,.mat-checkbox-indeterminate.mat-warn .mat-checkbox-background{background-color:#f44336}.mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.mat-checkbox-disabled .mat-checkbox-label{color:#b0b0b0}.mat-checkbox:not(.mat-checkbox-disabled).mat-primary .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(0,114,255,.26)}.mat-checkbox:not(.mat-checkbox-disabled).mat-accent .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(255,193,37,.26)}.mat-checkbox:not(.mat-checkbox-disabled).mat-warn .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.mat-chip:not(.mat-basic-chip){background-color:#e0e0e0;color:rgba(0,0,0,.87)}.mat-chip:not(.mat-basic-chip) .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.mat-chip:not(.mat-basic-chip) .mat-chip-remove:hover{opacity:.54}.mat-chip.mat-chip-selected.mat-primary{background-color:#0072ff;color:#fff}.mat-chip.mat-chip-selected.mat-primary .mat-chip-remove{color:#fff;opacity:.4}.mat-chip.mat-chip-selected.mat-primary .mat-chip-remove:hover{opacity:.54}.mat-chip.mat-chip-selected.mat-warn{background-color:#f44336;color:#fff}.mat-chip.mat-chip-selected.mat-warn .mat-chip-remove{color:#fff;opacity:.4}.mat-chip.mat-chip-selected.mat-warn .mat-chip-remove:hover{opacity:.54}.mat-chip.mat-chip-selected.mat-accent{background-color:#ffc125;color:#fff}.mat-chip.mat-chip-selected.mat-accent .mat-chip-remove{color:#fff;opacity:.4}.mat-chip.mat-chip-selected.mat-accent .mat-chip-remove:hover{opacity:.54}.mat-table{background:#fff}.mat-header-row,.mat-row{border-bottom-color:rgba(0,0,0,.12)}.mat-header-cell{color:rgba(0,0,0,.54)}.mat-cell{color:rgba(0,0,0,.87)}.mat-datepicker-content{background-color:#fff;color:rgba(0,0,0,.87)}.mat-calendar-arrow{border-top-color:rgba(0,0,0,.54)}.mat-calendar-next-button,.mat-calendar-previous-button{color:rgba(0,0,0,.54)}.mat-calendar-table-header{color:rgba(0,0,0,.38)}.mat-calendar-table-header-divider::after{background:rgba(0,0,0,.12)}.mat-calendar-body-label{color:rgba(0,0,0,.54)}.mat-calendar-body-cell-content{color:rgba(0,0,0,.87);border-color:transparent}.mat-calendar-body-disabled>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,.38)}.cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,.04)}.mat-calendar-body-selected{background-color:#0072ff;color:#fff}.mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(0,114,255,.4)}.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.38)}.mat-calendar-body-today.mat-calendar-body-selected{-webkit-box-shadow:inset 0 0 0 1px #fff;box-shadow:inset 0 0 0 1px #fff}.mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.18)}.mat-dialog-container,.mat-expansion-panel{background:#fff;color:rgba(0,0,0,.87)}.mat-action-row{border-top-color:rgba(0,0,0,.12)}.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-keyboard-focused,.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-program-focused,.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:rgba(0,0,0,.04)}.mat-expansion-panel-header-title{color:rgba(0,0,0,.87)}.mat-expansion-indicator::after,.mat-expansion-panel-header-description{color:rgba(0,0,0,.54)}.mat-expansion-panel-header[aria-disabled=true]{color:rgba(0,0,0,.38)}.mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description,.mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title{color:inherit}.mat-form-field-label,.mat-hint{color:rgba(0,0,0,.54)}.mat-focused .mat-form-field-label{color:#0072ff}.mat-focused .mat-form-field-label.mat-accent{color:#ffc125}.mat-focused .mat-form-field-label.mat-warn{color:#f44336}.mat-focused .mat-form-field-required-marker{color:#ffc125}.mat-form-field-underline{background-color:rgba(0,0,0,.42)}.mat-form-field-disabled .mat-form-field-underline{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.42)),color-stop(33%,rgba(0,0,0,.42)),color-stop(0,transparent));background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 1px;background-repeat:repeat-x}.mat-form-field-ripple{background-color:#0072ff}.mat-form-field-ripple.mat-accent{background-color:#ffc125}.mat-form-field-ripple.mat-warn{background-color:#f44336}.mat-form-field-invalid .mat-form-field-label,.mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker,.mat-form-field-invalid .mat-form-field-label.mat-accent{color:#f44336}.mat-form-field-invalid .mat-form-field-ripple{background-color:#f44336}.mat-error{color:#f44336}.mat-icon.mat-primary{color:#0072ff}.mat-icon.mat-accent{color:#ffc125}.mat-icon.mat-warn{color:#f44336}.mat-input-element:disabled{color:rgba(0,0,0,.38)}.mat-input-element{caret-color:#0072ff}.mat-input-element::-ms-input-placeholder{color:rgba(0,0,0,.42)}.mat-input-element::placeholder{color:rgba(0,0,0,.42)}.mat-input-element::-moz-placeholder{color:rgba(0,0,0,.42)}.mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,.42)}.mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,.42)}.mat-accent .mat-input-element{caret-color:#ffc125}.mat-form-field-invalid .mat-input-element,.mat-warn .mat-input-element{caret-color:#f44336}.mat-list .mat-list-item,.mat-list .mat-list-option,.mat-nav-list .mat-list-item,.mat-nav-list .mat-list-option,.mat-selection-list .mat-list-item,.mat-selection-list .mat-list-option{color:rgba(0,0,0,.87)}.mat-list .mat-subheader,.mat-nav-list .mat-subheader,.mat-selection-list .mat-subheader{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px;font-weight:500;color:rgba(0,0,0,.54)}.mat-list-item-disabled{background-color:#eee}.mat-divider{border-top-color:rgba(0,0,0,.12)}.mat-nav-list .mat-list-item{outline:0}.mat-nav-list .mat-list-item.mat-list-item-focus,.mat-nav-list .mat-list-item:hover{background:rgba(0,0,0,.04)}.mat-list-option{outline:0}.mat-list-option.mat-list-item-focus,.mat-list-option:hover{background:rgba(0,0,0,.04)}.mat-menu-panel{background:#fff}.mat-menu-item{background:0 0;color:rgba(0,0,0,.87)}.mat-menu-item[disabled]{color:rgba(0,0,0,.38)}.mat-menu-item .mat-icon:not([color]),.mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,.54)}.mat-menu-item-highlighted:not([disabled]),.mat-menu-item:focus:not([disabled]),.mat-menu-item:hover:not([disabled]){background:rgba(0,0,0,.04)}.mat-paginator{background:#fff}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,.54)}.mat-paginator-decrement,.mat-paginator-increment{border-top:2px solid rgba(0,0,0,.54);border-right:2px solid rgba(0,0,0,.54)}.mat-icon-button[disabled] .mat-paginator-decrement,.mat-icon-button[disabled] .mat-paginator-increment{border-color:rgba(0,0,0,.38)}.mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%2300c3ff%27%2F%3E%3C%2Fsvg%3E")}.mat-progress-bar-buffer{background-color:#00c3ff}.mat-progress-bar-fill::after{background-color:#0072ff}.mat-progress-bar.mat-accent .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23ffc125%27%2F%3E%3C%2Fsvg%3E")}.mat-progress-bar.mat-accent .mat-progress-bar-buffer,.mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#ffc125}.mat-progress-bar.mat-warn .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23ffcdd2%27%2F%3E%3C%2Fsvg%3E")}.mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#ffcdd2}.mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#f44336}.mat-progress-spinner circle,.mat-spinner circle{stroke:#0072ff}.mat-progress-spinner.mat-accent circle,.mat-spinner.mat-accent circle{stroke:#ffc125}.mat-progress-spinner.mat-warn circle,.mat-spinner.mat-warn circle{stroke:#f44336}.mat-radio-outer-circle{border-color:rgba(0,0,0,.54)}.mat-radio-disabled .mat-radio-outer-circle{border-color:rgba(0,0,0,.38)}.mat-radio-disabled .mat-radio-inner-circle,.mat-radio-disabled .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,0,0,.38)}.mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,.38)}.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#0072ff}.mat-radio-button.mat-primary .mat-radio-inner-circle{background-color:#0072ff}.mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,114,255,.26)}.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#ffc125}.mat-radio-button.mat-accent .mat-radio-inner-circle{background-color:#ffc125}.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element{background-color:rgba(255,193,37,.26)}.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#f44336}.mat-radio-button.mat-warn .mat-radio-inner-circle{background-color:#f44336}.mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.mat-select-content,.mat-select-panel-done-animating{background:#fff}.mat-select-value{color:rgba(0,0,0,.87)}.mat-select-placeholder{color:rgba(0,0,0,.42)}.mat-select-disabled .mat-select-value{color:rgba(0,0,0,.38)}.mat-select-arrow{color:rgba(0,0,0,.54)}.mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,.12)}.mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#0072ff}.mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#ffc125}.mat-form-field .mat-select.mat-select-invalid .mat-select-arrow,.mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#f44336}.mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,.38)}.mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,.87)}.mat-drawer{background-color:#fff;color:rgba(0,0,0,.87)}.mat-drawer.mat-drawer-push{background-color:#fff}.mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,.6)}.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#ffc125}.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(255,193,37,.5)}.mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle .mat-ripple-element{background-color:rgba(255,193,37,.12)}.mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#0072ff}.mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(0,114,255,.5)}.mat-slide-toggle.mat-primary:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle.mat-primary .mat-ripple-element{background-color:rgba(0,114,255,.12)}.mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#f44336}.mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(244,67,54,.5)}.mat-slide-toggle.mat-warn:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.12)}.mat-disabled .mat-slide-toggle-thumb{background-color:#bdbdbd}.mat-disabled .mat-slide-toggle-bar{background-color:rgba(0,0,0,.1)}.mat-slide-toggle-thumb{background-color:#fafafa}.mat-slide-toggle-bar{background-color:rgba(0,0,0,.38)}.mat-slider-track-background{background-color:rgba(0,0,0,.26)}.mat-primary .mat-slider-thumb,.mat-primary .mat-slider-thumb-label,.mat-primary .mat-slider-track-fill{background-color:#0072ff}.mat-primary .mat-slider-thumb-label-text{color:#fff}.mat-accent .mat-slider-thumb,.mat-accent .mat-slider-thumb-label,.mat-accent .mat-slider-track-fill{background-color:#ffc125}.mat-accent .mat-slider-thumb-label-text{color:#fff}.mat-warn .mat-slider-thumb,.mat-warn .mat-slider-thumb-label,.mat-warn .mat-slider-track-fill{background-color:#f44336}.mat-warn .mat-slider-thumb-label-text{color:#fff}.mat-slider-focus-ring{background-color:rgba(255,193,37,.2)}.cdk-focused .mat-slider-track-background,.mat-slider:hover .mat-slider-track-background{background-color:rgba(0,0,0,.38)}.mat-slider-disabled .mat-slider-thumb,.mat-slider-disabled .mat-slider-track-background,.mat-slider-disabled .mat-slider-track-fill,.mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,.12)}.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,.87)}.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,.26)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,.26);background-color:transparent}.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb{border-color:rgba(0,0,0,.38)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,.26)}.mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,.7)}.mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent);background-image:-moz-repeating-linear-gradient(.0001deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.mat-step-header.cdk-keyboard-focused,.mat-step-header.cdk-program-focused,.mat-step-header:hover{background-color:rgba(0,0,0,.04)}.mat-step-header .mat-step-label,.mat-step-header .mat-step-optional{color:rgba(0,0,0,.38)}.mat-step-header .mat-step-icon{background-color:#0072ff;color:#fff}.mat-step-header .mat-step-icon-not-touched{background-color:rgba(0,0,0,.38);color:#fff}.mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,.87)}.mat-stepper-horizontal,.mat-stepper-vertical{background-color:#fff}.mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,.12)}.mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,.12)}.mat-tab-header,.mat-tab-nav-bar{border-bottom:1px solid rgba(0,0,0,.12)}.mat-tab-group-inverted-header .mat-tab-header,.mat-tab-group-inverted-header .mat-tab-nav-bar{border-top:1px solid rgba(0,0,0,.12);border-bottom:none}.mat-tab-label,.mat-tab-link{color:rgba(0,0,0,.87)}.mat-tab-label.mat-tab-disabled,.mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.38)}.mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.38)}.mat-tab-group[class*=mat-background-] .mat-tab-header,.mat-tab-nav-bar[class*=mat-background-]{border-bottom:none;border-top:none}.mat-tab-group.mat-primary .mat-tab-label:focus,.mat-tab-group.mat-primary .mat-tab-link:focus,.mat-tab-nav-bar.mat-primary .mat-tab-label:focus,.mat-tab-nav-bar.mat-primary .mat-tab-link:focus{background-color:rgba(0,195,255,.3)}.mat-tab-group.mat-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary .mat-ink-bar{background-color:#0072ff}.mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-accent .mat-tab-label:focus,.mat-tab-group.mat-accent .mat-tab-link:focus,.mat-tab-nav-bar.mat-accent .mat-tab-label:focus,.mat-tab-nav-bar.mat-accent .mat-tab-link:focus{background-color:rgba(255,193,37,.3)}.mat-tab-group.mat-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:#ffc125}.mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-warn .mat-tab-label:focus,.mat-tab-group.mat-warn .mat-tab-link:focus,.mat-tab-nav-bar.mat-warn .mat-tab-label:focus,.mat-tab-nav-bar.mat-warn .mat-tab-link:focus{background-color:rgba(255,205,210,.3)}.mat-tab-group.mat-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#f44336}.mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label:focus,.mat-tab-group.mat-background-primary .mat-tab-link:focus,.mat-tab-nav-bar.mat-background-primary .mat-tab-label:focus,.mat-tab-nav-bar.mat-background-primary .mat-tab-link:focus{background-color:rgba(0,195,255,.3)}.mat-tab-group.mat-background-primary .mat-tab-header,.mat-tab-group.mat-background-primary .mat-tab-links,.mat-tab-nav-bar.mat-background-primary .mat-tab-header,.mat-tab-nav-bar.mat-background-primary .mat-tab-links{background-color:#0072ff}.mat-tab-group.mat-background-primary .mat-tab-label,.mat-tab-group.mat-background-primary .mat-tab-link,.mat-tab-nav-bar.mat-background-primary .mat-tab-label,.mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-primary .mat-ripple-element,.mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(255,255,255,.12)}.mat-tab-group.mat-background-accent .mat-tab-label:focus,.mat-tab-group.mat-background-accent .mat-tab-link:focus,.mat-tab-nav-bar.mat-background-accent .mat-tab-label:focus,.mat-tab-nav-bar.mat-background-accent .mat-tab-link:focus{background-color:rgba(255,193,37,.3)}.mat-tab-group.mat-background-accent .mat-tab-header,.mat-tab-group.mat-background-accent .mat-tab-links,.mat-tab-nav-bar.mat-background-accent .mat-tab-header,.mat-tab-nav-bar.mat-background-accent .mat-tab-links{background-color:#ffc125}.mat-tab-group.mat-background-accent .mat-tab-label,.mat-tab-group.mat-background-accent .mat-tab-link,.mat-tab-nav-bar.mat-background-accent .mat-tab-label,.mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:#fff}.mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-accent .mat-ripple-element,.mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(255,255,255,.12)}.mat-tab-group.mat-background-warn .mat-tab-label:focus,.mat-tab-group.mat-background-warn .mat-tab-link:focus,.mat-tab-nav-bar.mat-background-warn .mat-tab-label:focus,.mat-tab-nav-bar.mat-background-warn .mat-tab-link:focus{background-color:rgba(255,205,210,.3)}.mat-tab-group.mat-background-warn .mat-tab-header,.mat-tab-group.mat-background-warn .mat-tab-links,.mat-tab-nav-bar.mat-background-warn .mat-tab-header,.mat-tab-nav-bar.mat-background-warn .mat-tab-links{background-color:#f44336}.mat-tab-group.mat-background-warn .mat-tab-label,.mat-tab-group.mat-background-warn .mat-tab-link,.mat-tab-nav-bar.mat-background-warn .mat-tab-label,.mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-warn .mat-ripple-element,.mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,.12)}.mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,.87)}.mat-toolbar.mat-primary{background:#0072ff;color:#fff}.mat-toolbar.mat-accent{background:#ffc125;color:#fff}.mat-toolbar.mat-warn{background:#f44336;color:#fff}.mat-tooltip{background:rgba(97,97,97,.9)}.mat-snack-bar-container{background:#323232;color:#fff}.mat-simple-snackbar-action{color:#ffc125}.select-address-theme .mat-ripple-element{background-color:rgba(0,0,0,.1)}.select-address-theme .mat-option{color:rgba(0,0,0,.87)}.select-address-theme .mat-option:focus:not(.mat-option-disabled),.select-address-theme .mat-option:hover:not(.mat-option-disabled){background:rgba(0,0,0,.04)}.mat-primary .select-address-theme .mat-option.mat-selected:not(.mat-option-disabled){color:#ddd}.mat-accent .select-address-theme .mat-option.mat-selected:not(.mat-option-disabled){color:#ffc125}.mat-warn .select-address-theme .mat-option.mat-selected:not(.mat-option-disabled){color:#f44336}.select-address-theme .mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled){background:rgba(0,0,0,.04)}.select-address-theme .mat-option.mat-active{background:rgba(0,0,0,.04);color:rgba(0,0,0,.87)}.select-address-theme .mat-option.mat-option-disabled{color:rgba(0,0,0,.38)}.select-address-theme .mat-optgroup-label{color:rgba(0,0,0,.54)}.select-address-theme .mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,.38)}.select-address-theme .mat-pseudo-checkbox{color:rgba(0,0,0,.54)}.select-address-theme .mat-pseudo-checkbox::after{color:#fafafa}.select-address-theme .mat-accent .mat-pseudo-checkbox-checked,.select-address-theme .mat-accent .mat-pseudo-checkbox-indeterminate,.select-address-theme .mat-pseudo-checkbox-checked,.select-address-theme .mat-pseudo-checkbox-indeterminate{background:#ffc125}.select-address-theme .mat-primary .mat-pseudo-checkbox-checked,.select-address-theme .mat-primary .mat-pseudo-checkbox-indeterminate{background:#ddd}.select-address-theme .mat-warn .mat-pseudo-checkbox-checked,.select-address-theme .mat-warn .mat-pseudo-checkbox-indeterminate{background:#f44336}.select-address-theme .mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.select-address-theme .mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.select-address-theme .mat-app-background{background-color:#fafafa}.select-address-theme .mat-theme-loaded-marker{display:none}.select-address-theme .mat-autocomplete-panel{background:#fff;color:rgba(0,0,0,.87)}.select-address-theme .mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff}.select-address-theme .mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover):not(.mat-option-disabled){color:rgba(0,0,0,.87)}.select-address-theme .mat-button,.select-address-theme .mat-icon-button{background:0 0}.select-address-theme .mat-button.mat-primary .mat-button-focus-overlay,.select-address-theme .mat-icon-button.mat-primary .mat-button-focus-overlay{background-color:rgba(221,221,221,.12)}.select-address-theme .mat-button.mat-accent .mat-button-focus-overlay,.select-address-theme .mat-icon-button.mat-accent .mat-button-focus-overlay{background-color:rgba(255,193,37,.12)}.select-address-theme .mat-button.mat-warn .mat-button-focus-overlay,.select-address-theme .mat-icon-button.mat-warn .mat-button-focus-overlay{background-color:rgba(244,67,54,.12)}.select-address-theme .mat-button[disabled] .mat-button-focus-overlay,.select-address-theme .mat-icon-button[disabled] .mat-button-focus-overlay{background-color:transparent}.select-address-theme .mat-button.mat-primary,.select-address-theme .mat-icon-button.mat-primary{color:#ddd}.select-address-theme .mat-button.mat-accent,.select-address-theme .mat-icon-button.mat-accent{color:#ffc125}.select-address-theme .mat-button.mat-warn,.select-address-theme .mat-icon-button.mat-warn{color:#f44336}.select-address-theme .mat-button.mat-accent[disabled],.select-address-theme .mat-button.mat-primary[disabled],.select-address-theme .mat-button.mat-warn[disabled],.select-address-theme .mat-button[disabled][disabled],.select-address-theme .mat-icon-button.mat-accent[disabled],.select-address-theme .mat-icon-button.mat-primary[disabled],.select-address-theme .mat-icon-button.mat-warn[disabled],.select-address-theme .mat-icon-button[disabled][disabled]{color:rgba(0,0,0,.38)}.select-address-theme .mat-fab,.select-address-theme .mat-mini-fab,.select-address-theme .mat-raised-button{color:rgba(0,0,0,.87);background-color:#fff}.select-address-theme .mat-fab.mat-primary,.select-address-theme .mat-mini-fab.mat-primary,.select-address-theme .mat-raised-button.mat-primary{color:#ddd;background-color:#ddd}.select-address-theme .mat-fab.mat-accent,.select-address-theme .mat-fab.mat-warn,.select-address-theme .mat-mini-fab.mat-accent,.select-address-theme .mat-mini-fab.mat-warn,.select-address-theme .mat-raised-button.mat-accent,.select-address-theme .mat-raised-button.mat-warn{color:#fff}.select-address-theme .mat-fab.mat-accent[disabled],.select-address-theme .mat-fab.mat-primary[disabled],.select-address-theme .mat-fab.mat-warn[disabled],.select-address-theme .mat-fab[disabled][disabled],.select-address-theme .mat-mini-fab.mat-accent[disabled],.select-address-theme .mat-mini-fab.mat-primary[disabled],.select-address-theme .mat-mini-fab.mat-warn[disabled],.select-address-theme .mat-mini-fab[disabled][disabled],.select-address-theme .mat-raised-button.mat-accent[disabled],.select-address-theme .mat-raised-button.mat-primary[disabled],.select-address-theme .mat-raised-button.mat-warn[disabled],.select-address-theme .mat-raised-button[disabled][disabled]{color:rgba(0,0,0,.38);background-color:rgba(0,0,0,.12)}.select-address-theme .mat-fab.mat-accent,.select-address-theme .mat-mini-fab.mat-accent,.select-address-theme .mat-raised-button.mat-accent{background-color:#ffc125}.select-address-theme .mat-fab.mat-warn,.select-address-theme .mat-mini-fab.mat-warn,.select-address-theme .mat-raised-button.mat-warn{background-color:#f44336}.select-address-theme .mat-fab.mat-primary .mat-ripple-element,.select-address-theme .mat-mini-fab.mat-primary .mat-ripple-element,.select-address-theme .mat-raised-button.mat-primary .mat-ripple-element{background-color:rgba(221,221,221,.2)}.select-address-theme .mat-fab.mat-accent .mat-ripple-element,.select-address-theme .mat-fab.mat-warn .mat-ripple-element,.select-address-theme .mat-mini-fab.mat-accent .mat-ripple-element,.select-address-theme .mat-mini-fab.mat-warn .mat-ripple-element,.select-address-theme .mat-raised-button.mat-accent .mat-ripple-element,.select-address-theme .mat-raised-button.mat-warn .mat-ripple-element{background-color:rgba(255,255,255,.2)}.select-address-theme .mat-button.mat-primary .mat-ripple-element{background-color:rgba(221,221,221,.1)}.select-address-theme .mat-button.mat-accent .mat-ripple-element{background-color:rgba(255,193,37,.1)}.select-address-theme .mat-button.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.1)}.select-address-theme .mat-icon-button.mat-primary .mat-ripple-element{background-color:rgba(221,221,221,.2)}.select-address-theme .mat-icon-button.mat-accent .mat-ripple-element{background-color:rgba(255,193,37,.2)}.select-address-theme .mat-icon-button.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.2)}.select-address-theme .mat-button-toggle{color:rgba(0,0,0,.38)}.select-address-theme .mat-button-toggle.cdk-focused .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,.06)}.select-address-theme .mat-button-toggle-checked{background-color:#e0e0e0;color:rgba(0,0,0,.54)}.select-address-theme .mat-button-toggle-disabled{background-color:#eee;color:rgba(0,0,0,.38)}.select-address-theme .mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.select-address-theme .mat-card{background:#fff;color:rgba(0,0,0,.87)}.select-address-theme .mat-card-subtitle{color:rgba(0,0,0,.54)}.select-address-theme .mat-checkbox-frame{border-color:rgba(0,0,0,.54)}.select-address-theme .mat-checkbox-checkmark{fill:#fafafa}.select-address-theme .mat-checkbox-checkmark-path{stroke:#fafafa!important}.select-address-theme .mat-checkbox-mixedmark{background-color:#fafafa}.select-address-theme .mat-checkbox-checked.mat-primary .mat-checkbox-background,.select-address-theme .mat-checkbox-indeterminate.mat-primary .mat-checkbox-background{background-color:#ddd}.select-address-theme .mat-checkbox-checked.mat-accent .mat-checkbox-background,.select-address-theme .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background{background-color:#ffc125}.select-address-theme .mat-checkbox-checked.mat-warn .mat-checkbox-background,.select-address-theme .mat-checkbox-indeterminate.mat-warn .mat-checkbox-background{background-color:#f44336}.select-address-theme .mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.select-address-theme .mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.select-address-theme .mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.select-address-theme .mat-checkbox-disabled .mat-checkbox-label{color:#b0b0b0}.select-address-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-primary .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(221,221,221,.26)}.select-address-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-accent .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(255,193,37,.26)}.select-address-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-warn .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.select-address-theme .mat-chip:not(.mat-basic-chip){background-color:#e0e0e0;color:rgba(0,0,0,.87)}.select-address-theme .mat-chip:not(.mat-basic-chip) .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.select-address-theme .mat-chip:not(.mat-basic-chip) .mat-chip-remove:hover{opacity:.54}.select-address-theme .mat-chip.mat-chip-selected.mat-primary{background-color:#ddd;color:#ddd}.select-address-theme .mat-chip.mat-chip-selected.mat-primary .mat-chip-remove{color:#ddd;opacity:.4}.select-address-theme .mat-chip.mat-chip-selected.mat-primary .mat-chip-remove:hover{opacity:.54}.select-address-theme .mat-chip.mat-chip-selected.mat-warn{background-color:#f44336;color:#fff}.select-address-theme .mat-chip.mat-chip-selected.mat-warn .mat-chip-remove{color:#fff;opacity:.4}.select-address-theme .mat-chip.mat-chip-selected.mat-warn .mat-chip-remove:hover{opacity:.54}.select-address-theme .mat-chip.mat-chip-selected.mat-accent{background-color:#ffc125;color:#fff}.select-address-theme .mat-chip.mat-chip-selected.mat-accent .mat-chip-remove{color:#fff;opacity:.4}.select-address-theme .mat-chip.mat-chip-selected.mat-accent .mat-chip-remove:hover{opacity:.54}.select-address-theme .mat-table{background:#fff}.select-address-theme .mat-header-row,.select-address-theme .mat-row{border-bottom-color:rgba(0,0,0,.12)}.select-address-theme .mat-header-cell{color:rgba(0,0,0,.54)}.select-address-theme .mat-cell{color:rgba(0,0,0,.87)}.select-address-theme .mat-datepicker-content{background-color:#fff;color:rgba(0,0,0,.87)}.select-address-theme .mat-calendar-arrow{border-top-color:rgba(0,0,0,.54)}.select-address-theme .mat-calendar-next-button,.select-address-theme .mat-calendar-previous-button{color:rgba(0,0,0,.54)}.select-address-theme .mat-calendar-table-header{color:rgba(0,0,0,.38)}.select-address-theme .mat-calendar-table-header-divider::after{background:rgba(0,0,0,.12)}.select-address-theme .mat-calendar-body-label{color:rgba(0,0,0,.54)}.select-address-theme .mat-calendar-body-cell-content{color:rgba(0,0,0,.87);border-color:transparent}.mat-calendar-body-disabled>.select-address-theme .mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,.38)}.select-address-theme .cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.select-address-theme .cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.select-address-theme :not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,.04)}.select-address-theme .mat-calendar-body-selected{background-color:#ddd;color:#ddd}.select-address-theme .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(221,221,221,.4)}.select-address-theme .mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.38)}.select-address-theme .mat-calendar-body-today.mat-calendar-body-selected{-webkit-box-shadow:inset 0 0 0 1px #ddd;box-shadow:inset 0 0 0 1px #ddd}.select-address-theme .mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.18)}.select-address-theme .mat-dialog-container,.select-address-theme .mat-expansion-panel{background:#fff;color:rgba(0,0,0,.87)}.select-address-theme .mat-action-row{border-top-color:rgba(0,0,0,.12)}.select-address-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-keyboard-focused,.select-address-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-program-focused,.select-address-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:rgba(0,0,0,.04)}.select-address-theme .mat-expansion-panel-header-title{color:rgba(0,0,0,.87)}.select-address-theme .mat-expansion-indicator::after,.select-address-theme .mat-expansion-panel-header-description{color:rgba(0,0,0,.54)}.select-address-theme .mat-expansion-panel-header[aria-disabled=true]{color:rgba(0,0,0,.38)}.select-address-theme .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description,.select-address-theme .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title{color:inherit}.select-address-theme .mat-form-field-label,.select-address-theme .mat-hint{color:rgba(0,0,0,.54)}.select-address-theme .mat-focused .mat-form-field-label{color:#ddd}.select-address-theme .mat-focused .mat-form-field-label.mat-accent{color:#ffc125}.select-address-theme .mat-focused .mat-form-field-label.mat-warn{color:#f44336}.select-address-theme .mat-focused .mat-form-field-required-marker{color:#ffc125}.select-address-theme .mat-form-field-underline{background-color:rgba(0,0,0,.42)}.select-address-theme .mat-form-field-disabled .mat-form-field-underline{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.42)),color-stop(33%,rgba(0,0,0,.42)),color-stop(0,transparent));background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 1px;background-repeat:repeat-x}.select-address-theme .mat-form-field-ripple{background-color:#ddd}.select-address-theme .mat-form-field-ripple.mat-accent{background-color:#ffc125}.select-address-theme .mat-form-field-ripple.mat-warn{background-color:#f44336}.select-address-theme .mat-form-field-invalid .mat-form-field-label,.select-address-theme .mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker,.select-address-theme .mat-form-field-invalid .mat-form-field-label.mat-accent{color:#f44336}.select-address-theme .mat-form-field-invalid .mat-form-field-ripple{background-color:#f44336}.select-address-theme .mat-error{color:#f44336}.select-address-theme .mat-icon.mat-primary{color:#ddd}.select-address-theme .mat-icon.mat-accent{color:#ffc125}.select-address-theme .mat-icon.mat-warn{color:#f44336}.select-address-theme .mat-input-element:disabled{color:rgba(0,0,0,.38)}.select-address-theme .mat-input-element{caret-color:#ddd}.select-address-theme .mat-input-element::-ms-input-placeholder{color:rgba(0,0,0,.42)}.select-address-theme .mat-input-element::placeholder{color:rgba(0,0,0,.42)}.select-address-theme .mat-input-element::-moz-placeholder{color:rgba(0,0,0,.42)}.select-address-theme .mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,.42)}.select-address-theme .mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,.42)}.select-address-theme .mat-accent .mat-input-element{caret-color:#ffc125}.select-address-theme .mat-form-field-invalid .mat-input-element,.select-address-theme .mat-warn .mat-input-element{caret-color:#f44336}.select-address-theme .mat-list .mat-list-item,.select-address-theme .mat-list .mat-list-option,.select-address-theme .mat-nav-list .mat-list-item,.select-address-theme .mat-nav-list .mat-list-option,.select-address-theme .mat-selection-list .mat-list-item,.select-address-theme .mat-selection-list .mat-list-option{color:rgba(0,0,0,.87)}.select-address-theme .mat-list .mat-subheader,.select-address-theme .mat-nav-list .mat-subheader,.select-address-theme .mat-selection-list .mat-subheader{color:rgba(0,0,0,.54)}.select-address-theme .mat-list-item-disabled{background-color:#eee}.select-address-theme .mat-divider{border-top-color:rgba(0,0,0,.12)}.select-address-theme .mat-nav-list .mat-list-item{outline:0}.select-address-theme .mat-nav-list .mat-list-item.mat-list-item-focus,.select-address-theme .mat-nav-list .mat-list-item:hover{background:rgba(0,0,0,.04)}.select-address-theme .mat-list-option{outline:0}.select-address-theme .mat-list-option.mat-list-item-focus,.select-address-theme .mat-list-option:hover{background:rgba(0,0,0,.04)}.select-address-theme .mat-menu-panel{background:#fff}.select-address-theme .mat-menu-item{background:0 0;color:rgba(0,0,0,.87)}.select-address-theme .mat-menu-item[disabled]{color:rgba(0,0,0,.38)}.select-address-theme .mat-menu-item .mat-icon:not([color]),.select-address-theme .mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,.54)}.select-address-theme .mat-menu-item-highlighted:not([disabled]),.select-address-theme .mat-menu-item:focus:not([disabled]),.select-address-theme .mat-menu-item:hover:not([disabled]){background:rgba(0,0,0,.04)}.select-address-theme .mat-paginator{background:#fff}.select-address-theme .mat-paginator,.select-address-theme .mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,.54)}.select-address-theme .mat-paginator-decrement,.select-address-theme .mat-paginator-increment{border-top:2px solid rgba(0,0,0,.54);border-right:2px solid rgba(0,0,0,.54)}.select-address-theme .mat-icon-button[disabled] .mat-paginator-decrement,.select-address-theme .mat-icon-button[disabled] .mat-paginator-increment{border-color:rgba(0,0,0,.38)}.select-address-theme .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23dddddd%27%2F%3E%3C%2Fsvg%3E")}.select-address-theme .mat-progress-bar-buffer,.select-address-theme .mat-progress-bar-fill::after{background-color:#ddd}.select-address-theme .mat-progress-bar.mat-accent .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23ffc125%27%2F%3E%3C%2Fsvg%3E")}.select-address-theme .mat-progress-bar.mat-accent .mat-progress-bar-buffer,.select-address-theme .mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#ffc125}.select-address-theme .mat-progress-bar.mat-warn .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23ffcdd2%27%2F%3E%3C%2Fsvg%3E")}.select-address-theme .mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#ffcdd2}.select-address-theme .mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#f44336}.select-address-theme .mat-progress-spinner circle,.select-address-theme .mat-spinner circle{stroke:#ddd}.select-address-theme .mat-progress-spinner.mat-accent circle,.select-address-theme .mat-spinner.mat-accent circle{stroke:#ffc125}.select-address-theme .mat-progress-spinner.mat-warn circle,.select-address-theme .mat-spinner.mat-warn circle{stroke:#f44336}.select-address-theme .mat-radio-outer-circle{border-color:rgba(0,0,0,.54)}.select-address-theme .mat-radio-disabled .mat-radio-outer-circle{border-color:rgba(0,0,0,.38)}.select-address-theme .mat-radio-disabled .mat-radio-inner-circle,.select-address-theme .mat-radio-disabled .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,0,0,.38)}.select-address-theme .mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,.38)}.select-address-theme .mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#ddd}.select-address-theme .mat-radio-button.mat-primary .mat-radio-inner-circle{background-color:#ddd}.select-address-theme .mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element{background-color:rgba(221,221,221,.26)}.select-address-theme .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#ffc125}.select-address-theme .mat-radio-button.mat-accent .mat-radio-inner-circle{background-color:#ffc125}.select-address-theme .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element{background-color:rgba(255,193,37,.26)}.select-address-theme .mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#f44336}.select-address-theme .mat-radio-button.mat-warn .mat-radio-inner-circle{background-color:#f44336}.select-address-theme .mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.select-address-theme .mat-select-content,.select-address-theme .mat-select-panel-done-animating{background:#fff}.select-address-theme .mat-select-value{color:rgba(0,0,0,.87)}.select-address-theme .mat-select-placeholder{color:rgba(0,0,0,.42)}.select-address-theme .mat-select-disabled .mat-select-value{color:rgba(0,0,0,.38)}.select-address-theme .mat-select-arrow{color:rgba(0,0,0,.54)}.select-address-theme .mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,.12)}.select-address-theme .mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#ddd}.select-address-theme .mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#ffc125}.select-address-theme .mat-form-field .mat-select.mat-select-invalid .mat-select-arrow,.select-address-theme .mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#f44336}.select-address-theme .mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,.38)}.select-address-theme .mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,.87)}.select-address-theme .mat-drawer{background-color:#fff;color:rgba(0,0,0,.87)}.select-address-theme .mat-drawer.mat-drawer-push{background-color:#fff}.select-address-theme .mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,.6)}.select-address-theme .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#ffc125}.select-address-theme .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(255,193,37,.5)}.select-address-theme .mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.select-address-theme .mat-slide-toggle .mat-ripple-element{background-color:rgba(255,193,37,.12)}.select-address-theme .mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#ddd}.select-address-theme .mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(221,221,221,.5)}.select-address-theme .mat-slide-toggle.mat-primary:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.select-address-theme .mat-slide-toggle.mat-primary .mat-ripple-element{background-color:rgba(221,221,221,.12)}.select-address-theme .mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#f44336}.select-address-theme .mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(244,67,54,.5)}.select-address-theme .mat-slide-toggle.mat-warn:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.select-address-theme .mat-slide-toggle.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.12)}.select-address-theme .mat-disabled .mat-slide-toggle-thumb{background-color:#bdbdbd}.select-address-theme .mat-disabled .mat-slide-toggle-bar{background-color:rgba(0,0,0,.1)}.select-address-theme .mat-slide-toggle-thumb{background-color:#fafafa}.select-address-theme .mat-slide-toggle-bar{background-color:rgba(0,0,0,.38)}.select-address-theme .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.select-address-theme .mat-primary .mat-slider-thumb,.select-address-theme .mat-primary .mat-slider-thumb-label,.select-address-theme .mat-primary .mat-slider-track-fill{background-color:#ddd}.select-address-theme .mat-primary .mat-slider-thumb-label-text{color:#ddd}.select-address-theme .mat-accent .mat-slider-thumb,.select-address-theme .mat-accent .mat-slider-thumb-label,.select-address-theme .mat-accent .mat-slider-track-fill{background-color:#ffc125}.select-address-theme .mat-accent .mat-slider-thumb-label-text{color:#fff}.select-address-theme .mat-warn .mat-slider-thumb,.select-address-theme .mat-warn .mat-slider-thumb-label,.select-address-theme .mat-warn .mat-slider-track-fill{background-color:#f44336}.select-address-theme .mat-warn .mat-slider-thumb-label-text{color:#fff}.select-address-theme .mat-slider-focus-ring{background-color:rgba(255,193,37,.2)}.select-address-theme .cdk-focused .mat-slider-track-background,.select-address-theme .mat-slider:hover .mat-slider-track-background{background-color:rgba(0,0,0,.38)}.select-address-theme .mat-slider-disabled .mat-slider-thumb,.select-address-theme .mat-slider-disabled .mat-slider-track-background,.select-address-theme .mat-slider-disabled .mat-slider-track-fill,.select-address-theme .mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.select-address-theme .mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,.12)}.select-address-theme .mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.select-address-theme .mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,.87)}.select-address-theme .mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.select-address-theme .mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,.26)}.select-address-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,.26);background-color:transparent}.select-address-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb,.select-address-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb{border-color:rgba(0,0,0,.38)}.select-address-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb,.select-address-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,.26)}.select-address-theme .mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,.7)}.select-address-theme .mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent);background-image:-moz-repeating-linear-gradient(.0001deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.select-address-theme .mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.select-address-theme .mat-step-header.cdk-keyboard-focused,.select-address-theme .mat-step-header.cdk-program-focused,.select-address-theme .mat-step-header:hover{background-color:rgba(0,0,0,.04)}.select-address-theme .mat-step-header .mat-step-label,.select-address-theme .mat-step-header .mat-step-optional{color:rgba(0,0,0,.38)}.select-address-theme .mat-step-header .mat-step-icon{background-color:#ddd;color:#ddd}.select-address-theme .mat-step-header .mat-step-icon-not-touched{background-color:rgba(0,0,0,.38);color:#ddd}.select-address-theme .mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,.87)}.select-address-theme .mat-stepper-horizontal,.select-address-theme .mat-stepper-vertical{background-color:#fff}.select-address-theme .mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,.12)}.select-address-theme .mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,.12)}.select-address-theme .mat-tab-header,.select-address-theme .mat-tab-nav-bar{border-bottom:1px solid rgba(0,0,0,.12)}.select-address-theme .mat-tab-group-inverted-header .mat-tab-header,.select-address-theme .mat-tab-group-inverted-header .mat-tab-nav-bar{border-top:1px solid rgba(0,0,0,.12);border-bottom:none}.select-address-theme .mat-tab-label,.select-address-theme .mat-tab-link{color:rgba(0,0,0,.87)}.select-address-theme .mat-tab-label.mat-tab-disabled,.select-address-theme .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.38)}.select-address-theme .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.select-address-theme .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.38)}.select-address-theme .mat-tab-group[class*=mat-background-] .mat-tab-header,.select-address-theme .mat-tab-nav-bar[class*=mat-background-]{border-bottom:none;border-top:none}.select-address-theme .mat-tab-group.mat-primary .mat-tab-label:focus,.select-address-theme .mat-tab-group.mat-primary .mat-tab-link:focus,.select-address-theme .mat-tab-nav-bar.mat-primary .mat-tab-label:focus,.select-address-theme .mat-tab-nav-bar.mat-primary .mat-tab-link:focus{background-color:rgba(221,221,221,.3)}.select-address-theme .mat-tab-group.mat-primary .mat-ink-bar,.select-address-theme .mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.select-address-theme .mat-tab-nav-bar.mat-primary .mat-ink-bar,.select-address-theme .mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:#ddd}.select-address-theme .mat-tab-group.mat-accent .mat-tab-label:focus,.select-address-theme .mat-tab-group.mat-accent .mat-tab-link:focus,.select-address-theme .mat-tab-nav-bar.mat-accent .mat-tab-label:focus,.select-address-theme .mat-tab-nav-bar.mat-accent .mat-tab-link:focus{background-color:rgba(255,193,37,.3)}.select-address-theme .mat-tab-group.mat-accent .mat-ink-bar,.select-address-theme .mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:#ffc125}.select-address-theme .mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.select-address-theme .mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:#fff}.select-address-theme .mat-tab-group.mat-warn .mat-tab-label:focus,.select-address-theme .mat-tab-group.mat-warn .mat-tab-link:focus,.select-address-theme .mat-tab-nav-bar.mat-warn .mat-tab-label:focus,.select-address-theme .mat-tab-nav-bar.mat-warn .mat-tab-link:focus{background-color:rgba(255,205,210,.3)}.select-address-theme .mat-tab-group.mat-warn .mat-ink-bar,.select-address-theme .mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#f44336}.select-address-theme .mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.select-address-theme .mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-label:focus,.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-link:focus,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label:focus,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link:focus{background-color:rgba(221,221,221,.3)}.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-header,.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-links,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-links{background-color:#ddd}.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-label,.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-link,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:#ddd}.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(221,221,221,.4)}.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:#ddd}.select-address-theme .mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(221,221,221,.4)}.select-address-theme .mat-tab-group.mat-background-primary .mat-ripple-element,.select-address-theme .mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(221,221,221,.12)}.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-label:focus,.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-link:focus,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label:focus,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link:focus{background-color:rgba(255,193,37,.3)}.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-header,.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-links,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-links{background-color:#ffc125}.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-label,.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-link,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:#fff}.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:#fff}.select-address-theme .mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.select-address-theme .mat-tab-group.mat-background-accent .mat-ripple-element,.select-address-theme .mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(255,255,255,.12)}.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-label:focus,.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-link:focus,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label:focus,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link:focus{background-color:rgba(255,205,210,.3)}.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-header,.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-links,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-links{background-color:#f44336}.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-label,.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-link,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.select-address-theme .mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.select-address-theme .mat-tab-group.mat-background-warn .mat-ripple-element,.select-address-theme .mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,.12)}.select-address-theme .mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,.87)}.select-address-theme .mat-toolbar.mat-primary{background:#ddd;color:#ddd}.select-address-theme .mat-toolbar.mat-accent{background:#ffc125;color:#fff}.select-address-theme .mat-toolbar.mat-warn{background:#f44336;color:#fff}.select-address-theme .mat-tooltip{background:rgba(97,97,97,.9)}.select-address-theme .mat-snack-bar-container{background:#323232;color:#fff}.select-address-theme .mat-simple-snackbar-action{color:#ffc125}.subtle-theme .mat-ripple-element{background-color:rgba(0,0,0,.1)}.subtle-theme .mat-option{color:rgba(0,0,0,.87)}.subtle-theme .mat-option:focus:not(.mat-option-disabled),.subtle-theme .mat-option:hover:not(.mat-option-disabled){background:rgba(0,0,0,.04)}.mat-primary .subtle-theme .mat-option.mat-selected:not(.mat-option-disabled){color:#fff}.mat-accent .subtle-theme .mat-option.mat-selected:not(.mat-option-disabled){color:#ccc}.mat-warn .subtle-theme .mat-option.mat-selected:not(.mat-option-disabled){color:#f44336}.subtle-theme .mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled){background:rgba(0,0,0,.04)}.subtle-theme .mat-option.mat-active{background:rgba(0,0,0,.04);color:rgba(0,0,0,.87)}.subtle-theme .mat-option.mat-option-disabled{color:rgba(0,0,0,.38)}.subtle-theme .mat-optgroup-label{color:rgba(0,0,0,.54)}.subtle-theme .mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,.38)}.subtle-theme .mat-pseudo-checkbox{color:rgba(0,0,0,.54)}.subtle-theme .mat-pseudo-checkbox::after{color:#fafafa}.subtle-theme .mat-accent .mat-pseudo-checkbox-checked,.subtle-theme .mat-accent .mat-pseudo-checkbox-indeterminate,.subtle-theme .mat-pseudo-checkbox-checked,.subtle-theme .mat-pseudo-checkbox-indeterminate{background:#ccc}.subtle-theme .mat-primary .mat-pseudo-checkbox-checked,.subtle-theme .mat-primary .mat-pseudo-checkbox-indeterminate{background:#fff}.subtle-theme .mat-warn .mat-pseudo-checkbox-checked,.subtle-theme .mat-warn .mat-pseudo-checkbox-indeterminate{background:#f44336}.subtle-theme .mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.subtle-theme .mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.subtle-theme .mat-app-background{background-color:#fafafa}.subtle-theme .mat-theme-loaded-marker{display:none}.subtle-theme .mat-autocomplete-panel{background:#fff;color:rgba(0,0,0,.87)}.subtle-theme .mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff}.subtle-theme .mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover):not(.mat-option-disabled){color:rgba(0,0,0,.87)}.subtle-theme .mat-button,.subtle-theme .mat-icon-button{background:0 0}.subtle-theme .mat-button.mat-primary .mat-button-focus-overlay,.subtle-theme .mat-icon-button.mat-primary .mat-button-focus-overlay{background-color:rgba(255,255,255,.12)}.subtle-theme .mat-button.mat-accent .mat-button-focus-overlay,.subtle-theme .mat-icon-button.mat-accent .mat-button-focus-overlay{background-color:rgba(204,204,204,.12)}.subtle-theme .mat-button.mat-warn .mat-button-focus-overlay,.subtle-theme .mat-icon-button.mat-warn .mat-button-focus-overlay{background-color:rgba(244,67,54,.12)}.subtle-theme .mat-button[disabled] .mat-button-focus-overlay,.subtle-theme .mat-icon-button[disabled] .mat-button-focus-overlay{background-color:transparent}.subtle-theme .mat-button.mat-primary,.subtle-theme .mat-icon-button.mat-primary{color:#fff}.subtle-theme .mat-button.mat-accent,.subtle-theme .mat-icon-button.mat-accent{color:#ccc}.subtle-theme .mat-button.mat-warn,.subtle-theme .mat-icon-button.mat-warn{color:#f44336}.subtle-theme .mat-button.mat-accent[disabled],.subtle-theme .mat-button.mat-primary[disabled],.subtle-theme .mat-button.mat-warn[disabled],.subtle-theme .mat-button[disabled][disabled],.subtle-theme .mat-icon-button.mat-accent[disabled],.subtle-theme .mat-icon-button.mat-primary[disabled],.subtle-theme .mat-icon-button.mat-warn[disabled],.subtle-theme .mat-icon-button[disabled][disabled]{color:rgba(0,0,0,.38)}.subtle-theme .mat-fab,.subtle-theme .mat-mini-fab,.subtle-theme .mat-raised-button{color:rgba(0,0,0,.87);background-color:#fff}.subtle-theme .mat-fab.mat-primary,.subtle-theme .mat-mini-fab.mat-primary,.subtle-theme .mat-raised-button.mat-primary{color:#fff;background-color:#fff}.subtle-theme .mat-fab.mat-accent,.subtle-theme .mat-mini-fab.mat-accent,.subtle-theme .mat-raised-button.mat-accent{color:#ccc;background-color:#ccc}.subtle-theme .mat-fab.mat-warn,.subtle-theme .mat-mini-fab.mat-warn,.subtle-theme .mat-raised-button.mat-warn{color:#fff;background-color:#f44336}.subtle-theme .mat-fab.mat-accent[disabled],.subtle-theme .mat-fab.mat-primary[disabled],.subtle-theme .mat-fab.mat-warn[disabled],.subtle-theme .mat-fab[disabled][disabled],.subtle-theme .mat-mini-fab.mat-accent[disabled],.subtle-theme .mat-mini-fab.mat-primary[disabled],.subtle-theme .mat-mini-fab.mat-warn[disabled],.subtle-theme .mat-mini-fab[disabled][disabled],.subtle-theme .mat-raised-button.mat-accent[disabled],.subtle-theme .mat-raised-button.mat-primary[disabled],.subtle-theme .mat-raised-button.mat-warn[disabled],.subtle-theme .mat-raised-button[disabled][disabled]{color:rgba(0,0,0,.38);background-color:rgba(0,0,0,.12)}.subtle-theme .mat-fab.mat-primary .mat-ripple-element,.subtle-theme .mat-mini-fab.mat-primary .mat-ripple-element,.subtle-theme .mat-raised-button.mat-primary .mat-ripple-element{background-color:rgba(255,255,255,.2)}.subtle-theme .mat-fab.mat-accent .mat-ripple-element,.subtle-theme .mat-mini-fab.mat-accent .mat-ripple-element,.subtle-theme .mat-raised-button.mat-accent .mat-ripple-element{background-color:rgba(204,204,204,.2)}.subtle-theme .mat-fab.mat-warn .mat-ripple-element,.subtle-theme .mat-mini-fab.mat-warn .mat-ripple-element,.subtle-theme .mat-raised-button.mat-warn .mat-ripple-element{background-color:rgba(255,255,255,.2)}.subtle-theme .mat-button.mat-primary .mat-ripple-element{background-color:rgba(255,255,255,.1)}.subtle-theme .mat-button.mat-accent .mat-ripple-element{background-color:rgba(204,204,204,.1)}.subtle-theme .mat-button.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.1)}.subtle-theme .mat-icon-button.mat-primary .mat-ripple-element{background-color:rgba(255,255,255,.2)}.subtle-theme .mat-icon-button.mat-accent .mat-ripple-element{background-color:rgba(204,204,204,.2)}.subtle-theme .mat-icon-button.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.2)}.subtle-theme .mat-button-toggle{color:rgba(0,0,0,.38)}.subtle-theme .mat-button-toggle.cdk-focused .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,.06)}.subtle-theme .mat-button-toggle-checked{background-color:#e0e0e0;color:rgba(0,0,0,.54)}.subtle-theme .mat-button-toggle-disabled{background-color:#eee;color:rgba(0,0,0,.38)}.subtle-theme .mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.subtle-theme .mat-card{background:#fff;color:rgba(0,0,0,.87)}.subtle-theme .mat-card-subtitle{color:rgba(0,0,0,.54)}.subtle-theme .mat-checkbox-frame{border-color:rgba(0,0,0,.54)}.subtle-theme .mat-checkbox-checkmark{fill:#fafafa}.subtle-theme .mat-checkbox-checkmark-path{stroke:#fafafa!important}.subtle-theme .mat-checkbox-mixedmark{background-color:#fafafa}.subtle-theme .mat-checkbox-checked.mat-primary .mat-checkbox-background,.subtle-theme .mat-checkbox-indeterminate.mat-primary .mat-checkbox-background{background-color:#fff}.subtle-theme .mat-checkbox-checked.mat-accent .mat-checkbox-background,.subtle-theme .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background{background-color:#ccc}.subtle-theme .mat-checkbox-checked.mat-warn .mat-checkbox-background,.subtle-theme .mat-checkbox-indeterminate.mat-warn .mat-checkbox-background{background-color:#f44336}.subtle-theme .mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.subtle-theme .mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.subtle-theme .mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.subtle-theme .mat-checkbox-disabled .mat-checkbox-label{color:#b0b0b0}.subtle-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-primary .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(255,255,255,.26)}.subtle-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-accent .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(204,204,204,.26)}.subtle-theme .mat-checkbox:not(.mat-checkbox-disabled).mat-warn .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.subtle-theme .mat-chip:not(.mat-basic-chip){background-color:#e0e0e0;color:rgba(0,0,0,.87)}.subtle-theme .mat-chip:not(.mat-basic-chip) .mat-chip-remove{color:rgba(0,0,0,.87);opacity:.4}.subtle-theme .mat-chip:not(.mat-basic-chip) .mat-chip-remove:hover{opacity:.54}.subtle-theme .mat-chip.mat-chip-selected.mat-primary{background-color:#fff;color:#fff}.subtle-theme .mat-chip.mat-chip-selected.mat-primary .mat-chip-remove{color:#fff;opacity:.4}.subtle-theme .mat-chip.mat-chip-selected.mat-primary .mat-chip-remove:hover{opacity:.54}.subtle-theme .mat-chip.mat-chip-selected.mat-warn{background-color:#f44336;color:#fff}.subtle-theme .mat-chip.mat-chip-selected.mat-warn .mat-chip-remove{color:#fff;opacity:.4}.subtle-theme .mat-chip.mat-chip-selected.mat-warn .mat-chip-remove:hover{opacity:.54}.subtle-theme .mat-chip.mat-chip-selected.mat-accent{background-color:#ccc;color:#ccc}.subtle-theme .mat-chip.mat-chip-selected.mat-accent .mat-chip-remove{color:#ccc;opacity:.4}.subtle-theme .mat-chip.mat-chip-selected.mat-accent .mat-chip-remove:hover{opacity:.54}.subtle-theme .mat-table{background:#fff}.subtle-theme .mat-header-row,.subtle-theme .mat-row{border-bottom-color:rgba(0,0,0,.12)}.subtle-theme .mat-header-cell{color:rgba(0,0,0,.54)}.subtle-theme .mat-cell{color:rgba(0,0,0,.87)}.subtle-theme .mat-datepicker-content{background-color:#fff;color:rgba(0,0,0,.87)}.subtle-theme .mat-calendar-arrow{border-top-color:rgba(0,0,0,.54)}.subtle-theme .mat-calendar-next-button,.subtle-theme .mat-calendar-previous-button{color:rgba(0,0,0,.54)}.subtle-theme .mat-calendar-table-header{color:rgba(0,0,0,.38)}.subtle-theme .mat-calendar-table-header-divider::after{background:rgba(0,0,0,.12)}.subtle-theme .mat-calendar-body-label{color:rgba(0,0,0,.54)}.subtle-theme .mat-calendar-body-cell-content{color:rgba(0,0,0,.87);border-color:transparent}.mat-calendar-body-disabled>.subtle-theme .mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,.38)}.subtle-theme .cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.subtle-theme .cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.subtle-theme :not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,.04)}.subtle-theme .mat-calendar-body-selected{background-color:#fff;color:#fff}.subtle-theme .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(255,255,255,.4)}.subtle-theme .mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.38)}.subtle-theme .mat-calendar-body-today.mat-calendar-body-selected{-webkit-box-shadow:inset 0 0 0 1px #fff;box-shadow:inset 0 0 0 1px #fff}.subtle-theme .mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.18)}.subtle-theme .mat-dialog-container,.subtle-theme .mat-expansion-panel{background:#fff;color:rgba(0,0,0,.87)}.subtle-theme .mat-action-row{border-top-color:rgba(0,0,0,.12)}.subtle-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-keyboard-focused,.subtle-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-program-focused,.subtle-theme .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:rgba(0,0,0,.04)}.subtle-theme .mat-expansion-panel-header-title{color:rgba(0,0,0,.87)}.subtle-theme .mat-expansion-indicator::after,.subtle-theme .mat-expansion-panel-header-description{color:rgba(0,0,0,.54)}.subtle-theme .mat-expansion-panel-header[aria-disabled=true]{color:rgba(0,0,0,.38)}.subtle-theme .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description,.subtle-theme .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title{color:inherit}.subtle-theme .mat-form-field-label,.subtle-theme .mat-hint{color:rgba(0,0,0,.54)}.subtle-theme .mat-focused .mat-form-field-label{color:#fff}.subtle-theme .mat-focused .mat-form-field-label.mat-accent{color:#ccc}.subtle-theme .mat-focused .mat-form-field-label.mat-warn{color:#f44336}.subtle-theme .mat-focused .mat-form-field-required-marker{color:#ccc}.subtle-theme .mat-form-field-underline{background-color:rgba(0,0,0,.42)}.subtle-theme .mat-form-field-disabled .mat-form-field-underline{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.42)),color-stop(33%,rgba(0,0,0,.42)),color-stop(0,transparent));background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 1px;background-repeat:repeat-x}.subtle-theme .mat-form-field-ripple{background-color:#fff}.subtle-theme .mat-form-field-ripple.mat-accent{background-color:#ccc}.subtle-theme .mat-form-field-ripple.mat-warn{background-color:#f44336}.subtle-theme .mat-form-field-invalid .mat-form-field-label,.subtle-theme .mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker,.subtle-theme .mat-form-field-invalid .mat-form-field-label.mat-accent{color:#f44336}.subtle-theme .mat-form-field-invalid .mat-form-field-ripple{background-color:#f44336}.subtle-theme .mat-error{color:#f44336}.subtle-theme .mat-icon.mat-primary{color:#fff}.subtle-theme .mat-icon.mat-accent{color:#ccc}.subtle-theme .mat-icon.mat-warn{color:#f44336}.subtle-theme .mat-input-element:disabled{color:rgba(0,0,0,.38)}.subtle-theme .mat-input-element{caret-color:#fff}.subtle-theme .mat-input-element::-ms-input-placeholder{color:rgba(0,0,0,.42)}.subtle-theme .mat-input-element::placeholder{color:rgba(0,0,0,.42)}.subtle-theme .mat-input-element::-moz-placeholder{color:rgba(0,0,0,.42)}.subtle-theme .mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,.42)}.subtle-theme .mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,.42)}.subtle-theme .mat-accent .mat-input-element{caret-color:#ccc}.subtle-theme .mat-form-field-invalid .mat-input-element,.subtle-theme .mat-warn .mat-input-element{caret-color:#f44336}.subtle-theme .mat-list .mat-list-item,.subtle-theme .mat-list .mat-list-option,.subtle-theme .mat-nav-list .mat-list-item,.subtle-theme .mat-nav-list .mat-list-option,.subtle-theme .mat-selection-list .mat-list-item,.subtle-theme .mat-selection-list .mat-list-option{color:rgba(0,0,0,.87)}.subtle-theme .mat-list .mat-subheader,.subtle-theme .mat-nav-list .mat-subheader,.subtle-theme .mat-selection-list .mat-subheader{color:rgba(0,0,0,.54)}.subtle-theme .mat-list-item-disabled{background-color:#eee}.subtle-theme .mat-divider{border-top-color:rgba(0,0,0,.12)}.subtle-theme .mat-nav-list .mat-list-item{outline:0}.subtle-theme .mat-nav-list .mat-list-item.mat-list-item-focus,.subtle-theme .mat-nav-list .mat-list-item:hover{background:rgba(0,0,0,.04)}.subtle-theme .mat-list-option{outline:0}.subtle-theme .mat-list-option.mat-list-item-focus,.subtle-theme .mat-list-option:hover{background:rgba(0,0,0,.04)}.subtle-theme .mat-menu-panel{background:#fff}.subtle-theme .mat-menu-item{background:0 0;color:rgba(0,0,0,.87)}.subtle-theme .mat-menu-item[disabled]{color:rgba(0,0,0,.38)}.subtle-theme .mat-menu-item .mat-icon:not([color]),.subtle-theme .mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,.54)}.subtle-theme .mat-menu-item-highlighted:not([disabled]),.subtle-theme .mat-menu-item:focus:not([disabled]),.subtle-theme .mat-menu-item:hover:not([disabled]){background:rgba(0,0,0,.04)}.subtle-theme .mat-paginator{background:#fff}.subtle-theme .mat-paginator,.subtle-theme .mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,.54)}.subtle-theme .mat-paginator-decrement,.subtle-theme .mat-paginator-increment{border-top:2px solid rgba(0,0,0,.54);border-right:2px solid rgba(0,0,0,.54)}.subtle-theme .mat-icon-button[disabled] .mat-paginator-decrement,.subtle-theme .mat-icon-button[disabled] .mat-paginator-increment{border-color:rgba(0,0,0,.38)}.subtle-theme .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27white%27%2F%3E%3C%2Fsvg%3E")}.subtle-theme .mat-progress-bar-buffer,.subtle-theme .mat-progress-bar-fill::after{background-color:#fff}.subtle-theme .mat-progress-bar.mat-accent .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23cccccc%27%2F%3E%3C%2Fsvg%3E")}.subtle-theme .mat-progress-bar.mat-accent .mat-progress-bar-buffer,.subtle-theme .mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#ccc}.subtle-theme .mat-progress-bar.mat-warn .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23ffcdd2%27%2F%3E%3C%2Fsvg%3E")}.subtle-theme .mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#ffcdd2}.subtle-theme .mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#f44336}.subtle-theme .mat-progress-spinner circle,.subtle-theme .mat-spinner circle{stroke:#fff}.subtle-theme .mat-progress-spinner.mat-accent circle,.subtle-theme .mat-spinner.mat-accent circle{stroke:#ccc}.subtle-theme .mat-progress-spinner.mat-warn circle,.subtle-theme .mat-spinner.mat-warn circle{stroke:#f44336}.subtle-theme .mat-radio-outer-circle{border-color:rgba(0,0,0,.54)}.subtle-theme .mat-radio-disabled .mat-radio-outer-circle{border-color:rgba(0,0,0,.38)}.subtle-theme .mat-radio-disabled .mat-radio-inner-circle,.subtle-theme .mat-radio-disabled .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,0,0,.38)}.subtle-theme .mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,.38)}.subtle-theme .mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#fff}.subtle-theme .mat-radio-button.mat-primary .mat-radio-inner-circle{background-color:#fff}.subtle-theme .mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element{background-color:rgba(255,255,255,.26)}.subtle-theme .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#ccc}.subtle-theme .mat-radio-button.mat-accent .mat-radio-inner-circle{background-color:#ccc}.subtle-theme .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element{background-color:rgba(204,204,204,.26)}.subtle-theme .mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#f44336}.subtle-theme .mat-radio-button.mat-warn .mat-radio-inner-circle{background-color:#f44336}.subtle-theme .mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.subtle-theme .mat-select-content,.subtle-theme .mat-select-panel-done-animating{background:#fff}.subtle-theme .mat-select-value{color:rgba(0,0,0,.87)}.subtle-theme .mat-select-placeholder{color:rgba(0,0,0,.42)}.subtle-theme .mat-select-disabled .mat-select-value{color:rgba(0,0,0,.38)}.subtle-theme .mat-select-arrow{color:rgba(0,0,0,.54)}.subtle-theme .mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,.12)}.subtle-theme .mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#fff}.subtle-theme .mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#ccc}.subtle-theme .mat-form-field .mat-select.mat-select-invalid .mat-select-arrow,.subtle-theme .mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#f44336}.subtle-theme .mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,.38)}.subtle-theme .mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,.87)}.subtle-theme .mat-drawer{background-color:#fff;color:rgba(0,0,0,.87)}.subtle-theme .mat-drawer.mat-drawer-push{background-color:#fff}.subtle-theme .mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,.6)}.subtle-theme .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#ccc}.subtle-theme .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(204,204,204,.5)}.subtle-theme .mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.subtle-theme .mat-slide-toggle .mat-ripple-element{background-color:rgba(204,204,204,.12)}.subtle-theme .mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#fff}.subtle-theme .mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(255,255,255,.5)}.subtle-theme .mat-slide-toggle.mat-primary:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.subtle-theme .mat-slide-toggle.mat-primary .mat-ripple-element{background-color:rgba(255,255,255,.12)}.subtle-theme .mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#f44336}.subtle-theme .mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(244,67,54,.5)}.subtle-theme .mat-slide-toggle.mat-warn:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.subtle-theme .mat-slide-toggle.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.12)}.subtle-theme .mat-disabled .mat-slide-toggle-thumb{background-color:#bdbdbd}.subtle-theme .mat-disabled .mat-slide-toggle-bar{background-color:rgba(0,0,0,.1)}.subtle-theme .mat-slide-toggle-thumb{background-color:#fafafa}.subtle-theme .mat-slide-toggle-bar{background-color:rgba(0,0,0,.38)}.subtle-theme .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.subtle-theme .mat-primary .mat-slider-thumb,.subtle-theme .mat-primary .mat-slider-thumb-label,.subtle-theme .mat-primary .mat-slider-track-fill{background-color:#fff}.subtle-theme .mat-primary .mat-slider-thumb-label-text{color:#fff}.subtle-theme .mat-accent .mat-slider-thumb,.subtle-theme .mat-accent .mat-slider-thumb-label,.subtle-theme .mat-accent .mat-slider-track-fill{background-color:#ccc}.subtle-theme .mat-accent .mat-slider-thumb-label-text{color:#ccc}.subtle-theme .mat-warn .mat-slider-thumb,.subtle-theme .mat-warn .mat-slider-thumb-label,.subtle-theme .mat-warn .mat-slider-track-fill{background-color:#f44336}.subtle-theme .mat-warn .mat-slider-thumb-label-text{color:#fff}.subtle-theme .mat-slider-focus-ring{background-color:rgba(204,204,204,.2)}.subtle-theme .cdk-focused .mat-slider-track-background,.subtle-theme .mat-slider:hover .mat-slider-track-background{background-color:rgba(0,0,0,.38)}.subtle-theme .mat-slider-disabled .mat-slider-thumb,.subtle-theme .mat-slider-disabled .mat-slider-track-background,.subtle-theme .mat-slider-disabled .mat-slider-track-fill,.subtle-theme .mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.subtle-theme .mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,.12)}.subtle-theme .mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.subtle-theme .mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,.87)}.subtle-theme .mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.subtle-theme .mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,.26)}.subtle-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,.26);background-color:transparent}.subtle-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb,.subtle-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb{border-color:rgba(0,0,0,.38)}.subtle-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb,.subtle-theme .mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,.26)}.subtle-theme .mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,.7)}.subtle-theme .mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent);background-image:-moz-repeating-linear-gradient(.0001deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.subtle-theme .mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.subtle-theme .mat-step-header.cdk-keyboard-focused,.subtle-theme .mat-step-header.cdk-program-focused,.subtle-theme .mat-step-header:hover{background-color:rgba(0,0,0,.04)}.subtle-theme .mat-step-header .mat-step-label,.subtle-theme .mat-step-header .mat-step-optional{color:rgba(0,0,0,.38)}.subtle-theme .mat-step-header .mat-step-icon{background-color:#fff;color:#fff}.subtle-theme .mat-step-header .mat-step-icon-not-touched{background-color:rgba(0,0,0,.38);color:#fff}.subtle-theme .mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,.87)}.subtle-theme .mat-stepper-horizontal,.subtle-theme .mat-stepper-vertical{background-color:#fff}.subtle-theme .mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,.12)}.subtle-theme .mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,.12)}.subtle-theme .mat-tab-header,.subtle-theme .mat-tab-nav-bar{border-bottom:1px solid rgba(0,0,0,.12)}.subtle-theme .mat-tab-group-inverted-header .mat-tab-header,.subtle-theme .mat-tab-group-inverted-header .mat-tab-nav-bar{border-top:1px solid rgba(0,0,0,.12);border-bottom:none}.subtle-theme .mat-tab-label,.subtle-theme .mat-tab-link{color:rgba(0,0,0,.87)}.subtle-theme .mat-tab-label.mat-tab-disabled,.subtle-theme .mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.38)}.subtle-theme .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.subtle-theme .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.38)}.subtle-theme .mat-tab-group[class*=mat-background-] .mat-tab-header,.subtle-theme .mat-tab-nav-bar[class*=mat-background-]{border-bottom:none;border-top:none}.subtle-theme .mat-tab-group.mat-primary .mat-tab-label:focus,.subtle-theme .mat-tab-group.mat-primary .mat-tab-link:focus,.subtle-theme .mat-tab-nav-bar.mat-primary .mat-tab-label:focus,.subtle-theme .mat-tab-nav-bar.mat-primary .mat-tab-link:focus{background-color:rgba(255,255,255,.3)}.subtle-theme .mat-tab-group.mat-primary .mat-ink-bar,.subtle-theme .mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.subtle-theme .mat-tab-nav-bar.mat-primary .mat-ink-bar,.subtle-theme .mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:#fff}.subtle-theme .mat-tab-group.mat-accent .mat-tab-label:focus,.subtle-theme .mat-tab-group.mat-accent .mat-tab-link:focus,.subtle-theme .mat-tab-nav-bar.mat-accent .mat-tab-label:focus,.subtle-theme .mat-tab-nav-bar.mat-accent .mat-tab-link:focus{background-color:rgba(204,204,204,.3)}.subtle-theme .mat-tab-group.mat-accent .mat-ink-bar,.subtle-theme .mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.subtle-theme .mat-tab-nav-bar.mat-accent .mat-ink-bar,.subtle-theme .mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:#ccc}.subtle-theme .mat-tab-group.mat-warn .mat-tab-label:focus,.subtle-theme .mat-tab-group.mat-warn .mat-tab-link:focus,.subtle-theme .mat-tab-nav-bar.mat-warn .mat-tab-label:focus,.subtle-theme .mat-tab-nav-bar.mat-warn .mat-tab-link:focus{background-color:rgba(255,205,210,.3)}.subtle-theme .mat-tab-group.mat-warn .mat-ink-bar,.subtle-theme .mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#f44336}.subtle-theme .mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.subtle-theme .mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-label:focus,.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-link:focus,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label:focus,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link:focus{background-color:rgba(255,255,255,.3)}.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-header,.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-links,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-links{background-color:#fff}.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-label,.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-link,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:#fff}.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:#fff}.subtle-theme .mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.subtle-theme .mat-tab-group.mat-background-primary .mat-ripple-element,.subtle-theme .mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(255,255,255,.12)}.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-label:focus,.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-link:focus,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label:focus,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link:focus{background-color:rgba(204,204,204,.3)}.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-header,.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-links,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-links{background-color:#ccc}.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-label,.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-link,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:#ccc}.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(204,204,204,.4)}.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:#ccc}.subtle-theme .mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(204,204,204,.4)}.subtle-theme .mat-tab-group.mat-background-accent .mat-ripple-element,.subtle-theme .mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(204,204,204,.12)}.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-label:focus,.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-link:focus,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label:focus,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link:focus{background-color:rgba(255,205,210,.3)}.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-header,.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-links,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-links{background-color:#f44336}.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-label,.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-link,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.subtle-theme .mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.subtle-theme .mat-tab-group.mat-background-warn .mat-ripple-element,.subtle-theme .mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,.12)}.subtle-theme .mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,.87)}.subtle-theme .mat-toolbar.mat-primary{background:#fff;color:#fff}.subtle-theme .mat-toolbar.mat-accent{background:#ccc;color:#ccc}.subtle-theme .mat-toolbar.mat-warn{background:#f44336;color:#fff}.subtle-theme .mat-tooltip{background:rgba(97,97,97,.9)}.subtle-theme .mat-snack-bar-container{background:#323232;color:#fff}.subtle-theme .mat-simple-snackbar-action{color:#ccc}@font-face{font-family:Skycoin;font-style:normal;font-weight:300;src:url(Skycoin-Light.770b27ec05c2f97a1a27.woff2) format("woff2"),url(Skycoin-Light.4be01e4a68be8bf590da.woff) format("woff")}@font-face{font-family:Skycoin;font-style:italic;font-weight:300;src:url(Skycoin-LightItalic.d10a437db5d8e2a52b4a.woff2) format("woff2"),url(Skycoin-LightItalic.39e68da05bf8b4a77aa2.woff) format("woff")}@font-face{font-family:Skycoin;font-style:normal;font-weight:400;src:url(Skycoin-Regular.21b4caaaedc00594e7bd.woff2) format("woff2"),url(Skycoin-Regular.98d953e74f174cf013b4.woff) format("woff")}@font-face{font-family:Skycoin;font-style:italic;font-weight:400;src:url(Skycoin-RegularItalic.9eabbc2e01a7e17bb57d.woff2) format("woff2"),url(Skycoin-RegularItalic.9947360f79b09132fd21.woff) format("woff")}@font-face{font-family:Skycoin;font-style:normal;font-weight:700;src:url(Skycoin-Bold.6ccafc6fabc0cc8a971a.woff2) format("woff2"),url(Skycoin-Bold.42363955889f2f20c527.woff) format("woff")}@font-face{font-family:Skycoin;font-style:italic;font-weight:700;src:url(Skycoin-BoldItalic.c414dad20c4e3020221c.woff2) format("woff2"),url(Skycoin-BoldItalic.923dce74069362d168fe.woff) format("woff")}a,body,button,div,h1,h2,h3,h4,h5,h6,mat-option.mat-option,mat-panel-description,mat-panel-title,option,p,select,span{font-family:Skycoin,sans-serif}body{background-color:#f7f7f7;margin:0;padding:0;height:100%}header{background:url(header.e11f7c6852766b9319d6.png) center center/cover,linear-gradient(-155deg,#686e96 0,#373b5c 100%);width:100%;height:300px}mat-dialog-container{border-radius:5px!important}.mat-dialog-container{padding:0!important}.header-container{max-width:848px;text-align:center;padding-top:40px;margin-right:auto;margin-left:auto}.header-container h1{font-size:3em;color:#fff}.button-line{margin-top:40px;text-align:right}.datatable-row-group{cursor:pointer}button.active{background-color:rgba(0,0,0,.12)}mat-spinner.in-button .mat-spinner path{stroke:#000;opacity:.3}mat-spinner.in-button{display:inline-block;margin-left:10px}mat-spinner.in-button.small,mat-spinner.in-button.small svg{height:18px!important;width:18px!important}mat-spinner.in-text{display:inline-block;height:12px!important;width:12px!important;margin:0 0 0 7px!important}mat-spinner.in-text svg{height:12px!important;width:12px!important}mat-spinner.in-text svg circle{stroke:#0072ff}snack-bar-container{background-color:rgba(255,0,0,.8)!important}mat-panel-title{width:60%;display:block;-webkit-box-flex:0!important;-ms-flex-positive:0!important;flex-grow:0!important}.sky-container{min-width:100%;min-height:100%}.sky-container.sky-container-grey{background-color:#f7f7f7}.-flex-fill,.flex-fill{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.form-field{margin-bottom:20px}.form-field label{color:#1e2227;display:block;font-size:13px;line-height:20px;margin-bottom:2px}.form-field input{border:2px solid rgba(0,0,0,.05);border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;line-height:20px;padding:10px;width:100%}.form-field .-input-addon{display:-webkit-box;display:-ms-flexbox;display:flex}.form-field .-input-addon input{border-top-right-radius:0;border-bottom-right-radius:0}.form-field .-input-addon span{border:2px;border-radius:0 6px 6px 0;background:#f1f1f1;padding:0 10px;line-height:44px;color:rgba(30,34,39,.5);font-size:14px;-ms-flex-negative:0;flex-shrink:0}.form-field select{background-color:#fff;border:2px solid rgba(0,0,0,.05);border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;line-height:20px;padding:10px;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-field textarea{border:2px solid rgba(0,0,0,.05);border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;line-height:20px;padding:10px;width:100%}.primary button.enabled,.primary-gradient-background{background:#0072ff;background:-webkit-gradient(linear,left top,right bottom,from(#0072ff),to(#00c3ff));background:linear-gradient(to bottom right,#0072ff,#00c3ff)}.primary button.enabled span,.primary-gradient-background span{color:#fff}.primary-color{color:#0072ff}.secondary-color{color:#ffc125}.no-opacity{opacity:1!important}.light-opacity{opacity:.2}.rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}mat-spinner.in-button svg{height:24px!important;width:24px!important}.empty-row{padding:0 1.2rem!important;line-height:50px!important}.alert-box{color:#ff004e;font-size:12px;padding:15px;line-height:1.5;background-color:#ffdede;display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:20px}.alert-box .title{font-size:20px}.alert-box mat-icon{margin-top:5px;margin-right:10px;-webkit-animation:1s linear infinite alert-blinking;animation:1s linear infinite alert-blinking}.alert-box mat-checkbox{margin-top:10px;display:inline-block}@-webkit-keyframes alert-blinking{50%{opacity:.2}}@keyframes alert-blinking{50%{opacity:.2}}.onboarding-container{width:100%;height:100%;overflow-x:hidden;background:#0072ff;background:-webkit-gradient(linear,left top,right bottom,from(#0072ff),to(#00c3ff));background:linear-gradient(to bottom right,#0072ff,#00c3ff)}.onboarding-container .row-container{max-width:450px;width:80%;margin:0 auto}.onboarding-container label{color:#fff}.onboarding-container input{border:2px solid rgba(0,0,0,.05);border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;line-height:20px;padding:10px;width:100%}.onboarding-container select{background-color:#fff;border:2px solid rgba(0,0,0,.05);border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;line-height:20px;padding:10px;width:100%;-webkit-appearance:none}.onboarding-container textarea{border:2px solid rgba(0,0,0,.05);border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;line-height:20px;padding:10px;width:100%}.dark button.enabled{background-color:#171a1d!important}.dark button.enabled span{color:#fff}.ghost button.enabled{background-color:rgba(0,0,0,0)!important}.ghost button.enabled span{color:#000}.-select{position:relative}.-select::after{content:'';display:block;position:absolute;top:0;right:0;background:url(/assets/img/chevron-right-grey.png) 0 0/32px 32px no-repeat;width:32px;height:32px;margin:6px;pointer-events:none;-webkit-transform:rotate(90deg);transform:rotate(90deg)}.mat-menu-panel{border-radius:5px!important;background-color:#fefefe}.mat-menu-panel .mat-menu-item{font-family:Skycoin;line-height:50px}.mat-menu-panel.compact .mat-menu-item{font-size:13px;height:35px;line-height:35px}.qr-code-button{opacity:.6;cursor:pointer}.qr-code-button:hover{opacity:1}.mat-dialog-content{max-height:90vh!important}@media (max-height:600px){.mat-dialog-content{max-height:80vh!important}}.mouse-disabled{pointer-events:none}.coin-selector-container{display:inline-block;margin-left:5px;margin-bottom:5px}.coins-value-label{font-size:10px;margin-top:1px;padding:3px 10px;background-color:#f7f7f7;border-radius:4px}.coins-value-label span{opacity:.5}.coins-value-label .link{color:#0072ff;cursor:pointer;display:inline-block;font-size:11px;margin-bottom:3px;margin-top:-5px}.coins-value-label .centerd-link{width:100%;text-align:center}.red{color:#ff004e}.element-disabled{pointer-events:none;opacity:.5} \ No newline at end of file diff --git a/src/gui/static/e2e-proxy.config.js b/src/gui/static/e2e-proxy.config.js new file mode 100644 index 0000000..2c7ad44 --- /dev/null +++ b/src/gui/static/e2e-proxy.config.js @@ -0,0 +1,14 @@ +const PROXY_CONFIG = { + "/api/*": { + "target": "http://127.0.0.1:46420", + "secure": false, + "logLevel": "debug", + "bypass": function (req) { + req.headers["host"] = '127.0.0.1:46420'; + req.headers["referer"] = 'http://127.0.0.1:46420'; + req.headers["origin"] = 'http://127.0.0.1:46420'; + } + } +}; + +module.exports = PROXY_CONFIG; diff --git a/src/gui/static/e2e/onboarding.e2e-spec.ts b/src/gui/static/e2e/onboarding.e2e-spec.ts new file mode 100644 index 0000000..b8d6308 --- /dev/null +++ b/src/gui/static/e2e/onboarding.e2e-spec.ts @@ -0,0 +1,48 @@ +import { OnboardingCreatePage } from './onboarding.po'; + +describe('Onboarding', () => { + const page = new OnboardingCreatePage(); + + it('should display title', () => { + page.navigateTo(); + expect(page.getHeaderText()).toEqual('Create Wallet'); + }); + + it('should select language', () => { + expect(page.selectLanguage()).toEqual(true); + }); + + it('should load wallet', () => { + expect(page.loadWallet()).toEqual(true); + }); + + it('should create wallet', () => { + expect(page.createWallet()).toEqual(true); + }); + + it('should show safeguard', () => { + expect(page.getSafeguardIsShown()).toEqual(true); + }); + + it('should hide accepted safeguard', () => { + expect(page.acceptSafeguard()).toEqual(false); + }); + + it('should be able to go back from wallet encryption', () => { + expect(page.goBack()).toEqual('Create Wallet'); + page.createWallet(false); + page.acceptSafeguard(); + }); + + it('should encrypt wallet by default', () => { + expect(page.getEncryptWalletCheckbox().isSelected()).toBeTruthy(); + }); + + it('should be able to continue without encryption', () => { + expect(page.canContinueWithoutEncryption()).toEqual(true); + }); + + it('should encrypt wallet', () => { + expect(page.encryptWallet()).toEqual(true); + }); +}); diff --git a/src/gui/static/e2e/onboarding.po.ts b/src/gui/static/e2e/onboarding.po.ts new file mode 100644 index 0000000..fc1c6cc --- /dev/null +++ b/src/gui/static/e2e/onboarding.po.ts @@ -0,0 +1,124 @@ +import { browser, by, element, protractor } from 'protractor'; + +export class OnboardingCreatePage { + navigateTo() { + return browser.get('/#/wizard'); + } + + getHeaderText() { + return element(by.css('.-header span')).getText(); + } + + selectLanguage() { + browser.sleep(1000); + + return element(by.css('.e2e-language-modal')).isPresent().then(languageSelectionIsShown => { + if (!languageSelectionIsShown) { + return true; + } + + return element.all(by.css('.e2e-language-modal .button')).first().click().then(() => { + const el = element(by.css('.e2e-language-modal')); + + return browser.wait(protractor.ExpectedConditions.invisibilityOf(el), 5000).then(() => true); + }); + }); + } + + getSafeguardIsShown() { + return element(by.css('app-confirmation')).isPresent(); + } + + acceptSafeguard() { + return element.all(by.css('app-modal .mat-checkbox-label')).first().click().then(() => { + return element(by.buttonText('Continue')).click().then(() => { + return this.getSafeguardIsShown(); + }); + }); + } + + createWallet(goToManualSeedMode = true) { + element(by.buttonText('New')).click(); + + if (goToManualSeedMode) { + element(by.css('.seed-type-button >div')).click(); + element(by.css('.e2e-confirm-checkbox')).click(); + element(by.buttonText('Continue')).click(); + } + + const label = element(by.css('[formcontrolname="label"]')); + const seed = element(by.css('[formcontrolname="seed"]')); + const confirm = element(by.css('[formcontrolname="confirm_seed"]')); + const btnCreate = element(by.buttonText('Create')); + + label.clear(); + label.sendKeys('Test onboarding wallet'); + seed.clear(); + seed.sendKeys('test test'); + confirm.clear(); + confirm.sendKeys('test test'); + + browser.sleep(1000); + const seedValidationCheckBox = element(by.css('.-check')); + seedValidationCheckBox.click(); + + return btnCreate.isEnabled().then(status => { + if (status) { + btnCreate.click(); + } + + return status; + }); + } + + loadWallet() { + element(by.buttonText('Load')).click(); + + element(by.css('.seed-type-button >div')).click(); + element(by.buttonText('Continue')).click(); + + const label = element(by.css('[formcontrolname="label"]')); + const seed = element(by.css('[formcontrolname="seed"]')); + const btnLoad = element(by.buttonText('Create')); + + label.clear(); + label.sendKeys('Test wallet'); + seed.clear(); + seed.sendKeys('test test'); + + browser.sleep(1000); + const seedValidationCheckBox = element(by.css('.-check')); + seedValidationCheckBox.click(); + + return btnLoad.isEnabled(); + } + + goBack() { + return element(by.buttonText('Back')).click().then(() => { + return this.getHeaderText(); + }); + } + + getEncryptWalletCheckbox() { + return element(by.css('.mat-checkbox-input')); + } + + canContinueWithoutEncryption() { + return element(by.css('.mat-checkbox-label')).click().then(() => { + return element(by.buttonText('Finish')).isEnabled(); + }); + } + + encryptWallet() { + const password = element(by.css('[formcontrolname="password"]')); + const confirm = element(by.css('[formcontrolname="confirm"]')); + const button = element(by.buttonText('Finish')); + + return element(by.css('.mat-checkbox-label')).click().then(() => { + password.sendKeys('password'); + confirm.sendKeys('password'); + + return button.isEnabled(); + }); + } +} diff --git a/src/gui/static/e2e/send.e2e-spec.ts b/src/gui/static/e2e/send.e2e-spec.ts new file mode 100644 index 0000000..8881f14 --- /dev/null +++ b/src/gui/static/e2e/send.e2e-spec.ts @@ -0,0 +1,38 @@ +import { SendPage } from './send.po'; + +describe('Send', () => { + const page = new SendPage(); + + it('should display title', () => { + page.navigateTo(); + expect(page.getHeaderText()).toEqual('Send'); + }); + + it('should have wallets', () => { + expect(page.getWalletsCount()).toBeGreaterThan(0); + }); + + it('should have coins in wallets', () => { + expect(page.getWalletsWithCoins().then(w => w.length)).toBeGreaterThan(0); + }); + + it('should have wallets enabled', () => { + expect(page.getValidWallets().then(w => w.length)).toBeGreaterThan(0); + }); + + it('should select valid wallet', () => { + expect(page.selectValidWallet()).toBeTruthy(); + }); + + it('should not be able to send with wrong amount', () => { + expect(page.fillFormWithCoins('615701')).toBeFalsy(); + expect(page.fillFormWithCoins('0')).toBeFalsy(); + expect(page.fillFormWithCoins('-1')).toBeFalsy(); + expect(page.fillFormWithCoins('a')).toBeFalsy(); + }); + + it('should be able to send with correct amount', () => { + expect(page.fillFormWithCoins('615700')).toBeTruthy(); + expect(page.fillFormWithCoins('1')).toBeTruthy(); + }); +}); diff --git a/src/gui/static/e2e/send.po.ts b/src/gui/static/e2e/send.po.ts new file mode 100644 index 0000000..0437c48 --- /dev/null +++ b/src/gui/static/e2e/send.po.ts @@ -0,0 +1,68 @@ +import { browser, by, element } from 'protractor'; + +export class SendPage { + navigateTo() { + return browser.get('/#/send'); + } + + getHeaderText() { + return element(by.css('.title')).getText(); + } + + getWalletsCount() { + return element.all(by.css('#wallet option')).count(); + } + + getWalletsWithCoins() { + return element.all(by.tagName('#wallet option')) + .filter((opt) => { + return opt.getText().then((v) => { + return this.getCoinsFromOptionString(v) > 0; + }); + }); + } + + getValidWallets() { + return element.all(by.tagName('#wallet option')) + .filter((opt) => { + return opt.getText().then((v) => { + return opt.getAttribute('disabled').then(status => { + return status === null && this.getCoinsFromOptionString(v) > 0; + }); + }); + }); + } + + selectValidWallet() { + return this.getValidWallets().then(wallets => { + return wallets[0].click().then(() => { + return true; + }); + }); + } + + fillFormWithCoins(coins: string) { + const dest = element(by.css('[formcontrolname="address"]')); + const amount = element(by.css('[formcontrolname="coins"]')); + const btnSend = element(by.buttonText('Send')); + + dest.clear(); + amount.clear(); + + return dest.sendKeys('2e1erPpaxNVC37PkEv3n8PESNw2DNr5aJNy').then(() => { + return this.getValidWallets().then(wallets => { + return wallets[0].click().then(() => { + return amount.sendKeys(coins).then(() => { + return btnSend.isEnabled(); + }); + }); + }); + }); + } + + private getCoinsFromOptionString(option: string) { + const value = option.slice(option.indexOf('-') + 1, option.indexOf(' SKY')); + + return parseFloat(value); + } +} diff --git a/src/gui/static/e2e/transactions.e2e-spec.ts b/src/gui/static/e2e/transactions.e2e-spec.ts new file mode 100644 index 0000000..8ce7732 --- /dev/null +++ b/src/gui/static/e2e/transactions.e2e-spec.ts @@ -0,0 +1,22 @@ +import { TransactionsPage } from './transactions.po'; + +describe('Transactions', () => { + const page = new TransactionsPage(); + + it('should display title', () => { + page.navigateTo(); + expect(page.getHeaderText()).toEqual('History'); + }); + + it('should contain transactions', () => { + expect(page.getTransactionsCount()).toBeGreaterThan(0); + }); + + it('should show transaction detail modal', () => { + expect(page.showTransactionsModal()).toBeTruthy(); + }); + + it('should hide transaction detail modal', () => { + expect(page.hideTransactionModal()).toBeFalsy(); + }); +}); diff --git a/src/gui/static/e2e/transactions.po.ts b/src/gui/static/e2e/transactions.po.ts new file mode 100644 index 0000000..c0faa27 --- /dev/null +++ b/src/gui/static/e2e/transactions.po.ts @@ -0,0 +1,37 @@ +import { browser, by, element, protractor } from 'protractor'; + +export class TransactionsPage { + navigateTo() { + return browser.get('/#/transactions'); + } + + getHeaderText() { + return element(by.css('.title')).getText(); + } + + getTransactions() { + return element.all(by.css('.-transaction')); + } + + getTransactionsCount() { + return this.getTransactions().count(); + } + + getTransactionDetailIsShow() { + return element(by.css('app-transaction-detail')).isPresent(); + } + + showTransactionsModal() { + return this.getTransactions().first().click().then(() => { + return this.getTransactionDetailIsShow(); + }); + } + + hideTransactionModal() { + const el = element(by.css('app-transaction-detail .-header img')); + + return browser.wait(protractor.ExpectedConditions.visibilityOf(el), 5000).then(() => el.click().then(() => { + return this.getTransactionDetailIsShow(); + })); + } +} diff --git a/src/gui/static/e2e/tsconfig.e2e.json b/src/gui/static/e2e/tsconfig.e2e.json new file mode 100644 index 0000000..01edfb1 --- /dev/null +++ b/src/gui/static/e2e/tsconfig.e2e.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "../out-tsc/e2e", + "module": "commonjs", + "target": "es5", + "types": [ + "jasmine", + "jasminewd2", + "node" + ] + } +} diff --git a/src/gui/static/e2e/wallets.e2e-spec.ts b/src/gui/static/e2e/wallets.e2e-spec.ts new file mode 100644 index 0000000..57e84be --- /dev/null +++ b/src/gui/static/e2e/wallets.e2e-spec.ts @@ -0,0 +1,90 @@ +import { WalletsPage } from './wallets.po'; + +describe('Wallets', () => { + const page = new WalletsPage(); + + it('should display title', () => { + page.navigateTo(); + expect(page.getHeaderText()).toEqual('Wallets'); + }); + + it('should show create wallet', () => { + expect(page.showAddWallet()).toEqual(true); + expect(page.getWalletModalTitle()).toEqual('Create Wallet'); + }); + + it('should validate create wallet, seed mismatch', () => { + expect(page.fillWalletForm('Test', 'seed', 'seed2')).toEqual(false); + }); + + it('should validate create wallet, empty label', () => { + expect(page.fillWalletForm('', 'seed', 'seed', false)).toEqual(false); + }); + + it('should create wallet', () => { + expect(page.fillWalletForm('Test create wallet', 'test create wallet', 'test create wallet', false)).toEqual(true); + page.waitForWalletToBeCreated(); + }); + + it('should show load wallet', () => { + expect(page.showLoadWallet()).toEqual(true); + expect(page.getWalletModalTitle()).toEqual('Load Wallet'); + }); + + it('should validate load wallet, seed', () => { + expect(page.fillWalletForm('Test', '', null)).toEqual(false); + }); + + it('should validate load wallet, empty label', () => { + expect(page.fillWalletForm('', 'seed', null, false)).toEqual(false); + }); + + it('should load wallet', () => { + expect(page.fillWalletForm('Test load wallet', 'test load wallet', null, false)).toEqual(true); + page.waitForWalletToBeCreated(); + }); + + it('should expand wallet', () => { + expect(page.expandWallet()).toEqual(true); + }); + + it('should show wallet QR modal', () => { + expect(page.showQrDialog()).toEqual(true); + }); + + it('should hide wallet QR modal', () => { + expect(page.hideQrDialog()).toEqual(false); + }); + + it('should add address to wallet', () => { + expect(page.addAddress()).toEqual(true); + }); + + it('should hide empty address', () => { + expect(page.getCountOfEmptyAddresses('.-hide-empty')).toEqual(0); + }); + + it('should show empty address', () => { + expect(page.getCountOfEmptyAddresses('.-show-empty')).toBeGreaterThan(0); + }); + + it('should show change wallet name modal', () => { + expect(page.showChangeWalletName()).toEqual(true); + }); + + it('should change wallet name', () => { + expect(page.changeWalletName()).toEqual(true); + }); + + it('should encrypt wallet', () => { + expect(page.canEncrypt()).toEqual(true); + }); + + it('should decrypt wallet', () => { + expect(page.canDecrypt()).toEqual(true); + }); + + it('should display price information', () => { + expect(page.showPriceInformation()).toEqual(true); + }); +}); diff --git a/src/gui/static/e2e/wallets.po.ts b/src/gui/static/e2e/wallets.po.ts new file mode 100644 index 0000000..5e41a98 --- /dev/null +++ b/src/gui/static/e2e/wallets.po.ts @@ -0,0 +1,258 @@ +import { browser, by, element, protractor } from 'protractor'; + +export class WalletsPage { + navigateTo() { + return browser.get('/#/wallets'); + } + + getHeaderText() { + return element(by.css('.title')).getText(); + } + + showAddWallet() { + const btnAdd = element(by.buttonText('New Wallet')); + + return btnAdd.click().then(() => { + return element(by.css('app-create-wallet')).isPresent(); + }); + } + + showLoadWallet() { + const btnLoad = element(by.buttonText('Load Wallet')); + + return btnLoad.click().then(() => { + return element(by.css('app-create-wallet')).isPresent(); + }); + } + + getWalletModalTitle() { + return element(by.css('app-create-wallet .-header')).getText(); + } + + fillWalletForm(label: string, seed: string, confirm: string|null, goToManualSeedMode = true) { + + if (goToManualSeedMode) { + element(by.css('.seed-type-button >div')).click(); + if (confirm !== null) { + element(by.css('.e2e-confirm-checkbox')).click(); + } + element(by.buttonText('Continue')).click(); + } + + return element.all(by.css('[formcontrolname="type"]')).then(test => { + + if (test.length === 0) { + element(by.css('app-arrow-link')).click(); + } + + const type = element(by.css('[formcontrolname="type"]')); + const labelEl = element(by.css('[formcontrolname="label"]')); + const seedEl = element(by.css('[formcontrolname="seed"]')); + const btn = element(by.buttonText(confirm ? 'Create' : 'Load')); + const encrypt = element(by.css('.mat-checkbox-label')); + + encrypt.click(); + labelEl.clear(); + seedEl.clear(); + labelEl.sendKeys(label); + seedEl.sendKeys(seed); + + if (confirm) { + const confirmEl = element(by.css('[formcontrolname="confirm_seed"]')); + confirmEl.clear(); + confirmEl.sendKeys(confirm); + } + + if (label !== '' && (seed === confirm || (!confirm && seed !== ''))) { + const seedValidationCheckBox = element(by.css('.alert-box .mat-checkbox-inner-container')); + seedValidationCheckBox.click(); + } + + type.click(); + + return element.all(by.tagName('option')).then(options => { + options[0].click(); + + return btn.isEnabled().then(status => { + if (status) { + btn.click(); + } + + return this.getSafeguardIsShown().then(safeguardIsShown => { + if (safeguardIsShown) { + return this.acceptSafeguard().then(() => { + return status; + }); + } else { + return status; + } + }); + }); + }); + }); + } + + expandWallet() { + return this.getWalletWithName('Test create wallet').click().then(() => { + return element(by.css('app-wallet-detail')).isPresent(); + }); + } + + showQrDialog() { + return browser.sleep(1000).then(() => element(by.css('app-qr-code-button')).click().then(() => { + return element(by.css('app-qr-code')).isPresent(); + })); + } + + hideQrDialog() { + return browser.sleep(1000).then(() => element(by.css('app-modal .-header img')).click().then(() => { + return element(by.css('app-qr-code')).isPresent(); + })); + } + + addAddress() { + return element.all(by.css('.-record')).count().then(originalCount => { + return element(by.css('.-options')).click().then(() => { + return browser.sleep(2000).then(() => { + return element(by.css('.e2e-add')).click().then(() => { + return browser.sleep(2000).then(() => { + return element(by.buttonText('Create')).click().then(() => { + return browser.sleep(2000).then(() => { + return element.all(by.css('.-record')).count().then(newCount => { + return newCount > originalCount; + }); + }); + }); + }); + }); + }); + }); + }); + } + + getCountOfEmptyAddresses(clickSelector: string) { + return element(by.css(clickSelector)).click().then(() => { + return element.all(by.css('.-record > div:nth-child(3)')).filter((address) => { + return address.getText().then(value => { + return value === '0'; + }); + }).count(); + }); + } + + showChangeWalletName() { + return element(by.css('.-options')).click().then(() => { + return element(by.css('.e2e-rename')).click().then(() => { + return element(by.css('app-change-name')).isPresent(); + }); + }); + } + + changeWalletName() { + const label = element(by.css('[formcontrolname="label"]')); + const btn = element(by.buttonText('Rename')); + + return label.clear().then(() => { + return label.sendKeys('New Wallet Name').then(() => { + return btn.click().then(() => { + return browser.sleep(1000).then(() => { + return element(by.css('body')).sendKeys(protractor.Key.ESCAPE).then(() => { + return this.getWalletWithName('New Wallet Name').isPresent(); + }); + }); + }); + }); + }); + } + + canEncrypt() { + return element(by.css('.-options')).click().then(() => { + return element(by.css('.e2e-encrypt')).click().then(() => { + const p1 = element(by.css('[formcontrolname="password"]')); + const p2 = element(by.css('[formcontrolname="confirm_password"]')); + const btn = element(by.buttonText('Proceed')); + + p1.sendKeys('password'); + p2.sendKeys('password'); + + return btn.click().then(() => { + return browser.wait( + protractor.ExpectedConditions.stalenessOf(element(by.css('app-password-dialog'))), + 30000, + 'Can not encrypt wallet', + ).then(() => { + return element(by.css('.e2e-decrypt')).isPresent().then(response => { + return element(by.css('body')).sendKeys(protractor.Key.ESCAPE).then(() => { + return response; + }); + }); + }); + }); + }); + }); + } + + canDecrypt() { + return element(by.css('.-options')).click().then(() => { + return element(by.css('.e2e-decrypt')).click().then(() => { + const p1 = element(by.css('[formcontrolname="password"]')); + const btn = element(by.buttonText('Proceed')); + + p1.clear(); + p1.sendKeys('password'); + + return btn.click().then(() => { + return browser.wait( + protractor.ExpectedConditions.stalenessOf(element(by.css('app-password-dialog'))), + 30000, + 'Can not decrypt wallet', + ).then(() => { + return element(by.css('.e2e-encrypt')).isPresent().then(response => { + return element(by.css('body')).sendKeys(protractor.Key.ESCAPE).then(() => { + return response; + }); + }); + }); + }); + }); + }); + } + + showPriceInformation() { + return element(by.css('.balance p.dollars')).getText().then(text => { + return this.checkHeaderPriceFormat(text); + }); + } + + getSafeguardIsShown() { + return element(by.css('app-confirmation')).isPresent(); + } + + acceptSafeguard() { + return element.all(by.css('.e2e-confirm-checkbox')).first().click().then(() => { + return element(by.buttonText('Continue')).click().then(() => { + return this.getSafeguardIsShown(); + }); + }); + } + + waitForWalletToBeCreated() { + browser.wait( + protractor.ExpectedConditions.stalenessOf(element(by.css('app-create-wallet'))), + 10000, + 'Wallet was not created', + ); + } + + private getWalletWithName(name: string) { + return element.all(by.css('.e2e-wallets.ng-star-inserted')) + .filter(wallet => wallet.element(by.css('.-label .text-truncate')).getText().then(text => text === name)) + .first(); + } + + private checkHeaderPriceFormat(price: string) { + const reg = /^\$[0-9,]+.[0-9]{2}\s\(\$[0-9,]+.[0-9]{2}\)$/; + + return !!price.match(reg); + } +} diff --git a/src/gui/static/karma.conf.js b/src/gui/static/karma.conf.js new file mode 100644 index 0000000..cff5110 --- /dev/null +++ b/src/gui/static/karma.conf.js @@ -0,0 +1,34 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/0.13/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + files: [ + { pattern: 'test-fixtures/*.json', included: false } + ], + client:{ + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ], + fixWebpackSourcePaths: true + }, + + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }); +}; diff --git a/src/gui/static/package-lock.json b/src/gui/static/package-lock.json new file mode 100644 index 0000000..ea3caab --- /dev/null +++ b/src/gui/static/package-lock.json @@ -0,0 +1,18185 @@ +{ + "name": "desktopwallet", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@angular-devkit/architect": { + "version": "0.1000.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1000.5.tgz", + "integrity": "sha512-BhNqB7fmmrDQwxoJ3zdw5FslFD+nYGgMTiC48ERVYJVuN3BK6xtt2OGA7vho3eJ13OE5cPGUi8crQDRROgxxQg==", + "dev": true, + "requires": { + "@angular-devkit/core": "10.0.5", + "rxjs": "6.5.5" + }, + "dependencies": { + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + } + } + }, + "@angular-devkit/build-angular": { + "version": "0.1000.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.1000.5.tgz", + "integrity": "sha512-YOlYdOksFsirCV7l2S0T/k9phRtT5eR+Pk3uWHXGfrkCBzFlAHw1EqOlJLOOSuN+stGHHYnKES2WUVJRJXLlCQ==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.1000.5", + "@angular-devkit/build-optimizer": "0.1000.5", + "@angular-devkit/build-webpack": "0.1000.5", + "@angular-devkit/core": "10.0.5", + "@babel/core": "7.9.6", + "@babel/generator": "7.9.6", + "@babel/plugin-transform-runtime": "7.9.6", + "@babel/preset-env": "7.9.6", + "@babel/runtime": "7.9.6", + "@babel/template": "7.8.6", + "@jsdevtools/coverage-istanbul-loader": "3.0.3", + "@ngtools/webpack": "10.0.5", + "ajv": "6.12.3", + "autoprefixer": "9.8.0", + "babel-loader": "8.1.0", + "browserslist": "^4.9.1", + "cacache": "15.0.3", + "caniuse-lite": "^1.0.30001032", + "circular-dependency-plugin": "5.2.0", + "copy-webpack-plugin": "6.0.3", + "core-js": "3.6.4", + "css-loader": "3.5.3", + "cssnano": "4.1.10", + "file-loader": "6.0.0", + "find-cache-dir": "3.3.1", + "glob": "7.1.6", + "jest-worker": "26.0.0", + "karma-source-map-support": "1.4.0", + "less-loader": "6.1.0", + "license-webpack-plugin": "2.2.0", + "loader-utils": "2.0.0", + "mini-css-extract-plugin": "0.9.0", + "minimatch": "3.0.4", + "open": "7.0.4", + "parse5": "4.0.0", + "pnp-webpack-plugin": "1.6.4", + "postcss": "7.0.31", + "postcss-import": "12.0.1", + "postcss-loader": "3.0.0", + "raw-loader": "4.0.1", + "regenerator-runtime": "0.13.5", + "resolve-url-loader": "3.1.1", + "rimraf": "3.0.2", + "rollup": "2.10.9", + "rxjs": "6.5.5", + "sass": "1.26.5", + "sass-loader": "8.0.2", + "semver": "7.3.2", + "source-map": "0.7.3", + "source-map-loader": "1.0.0", + "source-map-support": "0.5.19", + "speed-measure-webpack-plugin": "1.3.3", + "style-loader": "1.2.1", + "stylus": "0.54.7", + "stylus-loader": "3.0.2", + "terser": "4.7.0", + "terser-webpack-plugin": "3.0.1", + "tree-kill": "1.2.2", + "webpack": "4.43.0", + "webpack-dev-middleware": "3.7.2", + "webpack-dev-server": "3.11.0", + "webpack-merge": "4.2.2", + "webpack-sources": "1.4.3", + "webpack-subresource-integrity": "1.4.1", + "worker-plugin": "4.0.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/runtime": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", + "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "core-js": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + } + } + }, + "@angular-devkit/build-optimizer": { + "version": "0.1000.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1000.5.tgz", + "integrity": "sha512-H6jTF7TOYq909HR6M3Bu8lScqrG1qznK2XMefK3m1I1jBJ+WO4bL7hrhTp/CIY3d+47txep+XqhitDWD/6ikpg==", + "dev": true, + "requires": { + "loader-utils": "2.0.0", + "source-map": "0.7.3", + "tslib": "2.0.0", + "webpack-sources": "1.4.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", + "dev": true + } + } + }, + "@angular-devkit/build-webpack": { + "version": "0.1000.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1000.5.tgz", + "integrity": "sha512-233EbW+6IKJEV20IG9Qzlz8MdDedzoTheB+lx9tTPn21m0ph2vmpTsNOsmMWwvdBBgXbv3pW3SMbJiqDCh7u4w==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.1000.5", + "@angular-devkit/core": "10.0.5", + "rxjs": "6.5.5" + }, + "dependencies": { + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + } + } + }, + "@angular-devkit/core": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-10.0.5.tgz", + "integrity": "sha512-ZaF1EYniIo+yRLvvaKnLrjYCdKeg2U3YtbA932M2AIfjgfFv/9mnAbH4jmZsBZhCstxZPz+ItwJesdR20h4Z1Q==", + "dev": true, + "requires": { + "ajv": "6.12.3", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.5.5", + "source-map": "0.7.3" + }, + "dependencies": { + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "@angular-devkit/schematics": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-10.0.5.tgz", + "integrity": "sha512-UeeV8O0IydxCKj2oejygs80oIAQXPYrJHo0PQ/fa0RH6rtV3wZwirdy+yqq/BDGhtV/5VQSVCvu6uyAtGGMgNg==", + "dev": true, + "requires": { + "@angular-devkit/core": "10.0.5", + "ora": "4.0.4", + "rxjs": "6.5.5" + }, + "dependencies": { + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + } + } + }, + "@angular/animations": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-10.0.7.tgz", + "integrity": "sha512-lTF7wuhx16fc3WahmqcYE3Q6sHB5sUQZ6m4dKg38wuf49Hr9x8uQpOMypnOAp9qfKG06ZZ2arRs53JeHpzkMPw==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, + "@angular/cdk": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-10.1.1.tgz", + "integrity": "sha512-Gt9TmqSVxPTmuNkApEuvva25U60WW152r9+vL7ViFgG+297RE7tzUU8ffBwMXZMdtXnrhLKqLv6ZaBhihMM2Kw==", + "requires": { + "parse5": "^5.0.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true + } + } + }, + "@angular/cli": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-10.0.5.tgz", + "integrity": "sha512-Qsa90IGPApJS9HL6Ih7Z8S8mIdriWYEintsT9cfI0WMVYyjvSNZQBf1SvnNU3IEboV4RFnpfXJNmQz1Q4KsRFQ==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.1000.5", + "@angular-devkit/core": "10.0.5", + "@angular-devkit/schematics": "10.0.5", + "@schematics/angular": "10.0.5", + "@schematics/update": "0.1000.5", + "@yarnpkg/lockfile": "1.1.0", + "ansi-colors": "4.1.1", + "debug": "4.1.1", + "ini": "1.3.5", + "inquirer": "7.1.0", + "npm-package-arg": "8.0.1", + "npm-pick-manifest": "6.1.0", + "open": "7.0.4", + "pacote": "9.5.12", + "read-package-tree": "5.3.1", + "rimraf": "3.0.2", + "semver": "7.3.2", + "symbol-observable": "1.2.0", + "universal-analytics": "0.4.20", + "uuid": "8.1.0" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "uuid": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz", + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==", + "dev": true + } + } + }, + "@angular/common": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-10.0.7.tgz", + "integrity": "sha512-CPjmbjylbMG0eFLWz7TCaxONDcwuldcvEheEwaBGS3RloHVsa+ry/8r6/7YilQkscdNPUazhX8pIzzrxIf9cBQ==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, + "@angular/compiler": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-10.0.7.tgz", + "integrity": "sha512-ut4aq7G0OwpRM2jhWjqN7RR02z9ybwFlP8j+2cr+6wwxZLUB+Gwe+O8iuz6h98O7F9yZx8Lbr5bQ07xbiHgdag==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, + "@angular/compiler-cli": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-10.0.7.tgz", + "integrity": "sha512-bfz/18ktAtc6Es7YaH23paT6Sajitt/0VLuUw0lqhmchV+Xa2c3BEYyOX2AGycEX4mNg7XJoZxOUgJs/9/u4wA==", + "dev": true, + "requires": { + "canonical-path": "1.0.0", + "chokidar": "^3.0.0", + "convert-source-map": "^1.5.1", + "dependency-graph": "^0.7.2", + "fs-extra": "4.0.2", + "magic-string": "^0.25.0", + "minimist": "^1.2.0", + "reflect-metadata": "^0.1.2", + "semver": "^6.3.0", + "source-map": "^0.6.1", + "sourcemap-codec": "^1.4.8", + "tslib": "^2.0.0", + "yargs": "15.3.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chokidar": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz", + "integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", + "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", + "dev": true + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.0.tgz", + "integrity": "sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.0" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "@angular/core": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-10.0.7.tgz", + "integrity": "sha512-h8R/2TCIFkagrFl6zmPN34gS5ZtQ1soYDI8dDeLj0+oQ+qH8HncoRgzYl+1+agFvUeYQ2pkwc5i635j/LwC++Q==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, + "@angular/forms": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-10.0.7.tgz", + "integrity": "sha512-xSGPhidaUWLop3j9zPy4ZeO+/rwnusNWvwrDNey4W68lS068AExRXqf3yTuzobqBGdV2swDJaRabzgD7NS8yag==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, + "@angular/language-service": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-10.0.7.tgz", + "integrity": "sha512-iD1It0GjQyn+1KKVh0IMTtrRw/HI0cXq69KYju2LXckngzSK0GXg+yvPP4sizwSBhJW2xeepV8qGkpGo9M+Wyw==", + "dev": true + }, + "@angular/material": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-10.1.1.tgz", + "integrity": "sha512-D9VXwW2ieDUvkQD1VVEX6bxIdCaK6uA6jHpMU2ZLTIQ/EzNRDRwmJbr4rqPhxtHmLMXF+66EBXEjgyV7l91h5g==", + "requires": { + "tslib": "^2.0.0" + } + }, + "@angular/platform-browser": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-10.0.7.tgz", + "integrity": "sha512-iACZDApTWTID+Dgpv9ztAlmP4OBIyCnqfmSrVWIpN30O/2pgalYS4hKS+jFXXjqG3IXrG6IpOAbFT9UubOWXKg==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, + "@angular/platform-browser-dynamic": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.0.7.tgz", + "integrity": "sha512-ESn1hssKmgFbSSU8tI3KcP6QFEMKaxTvoKElkwULhAnCNkeXAhZaIkTdeqaa/vkO8s9nRbRwqcLuhw/mIQJbpQ==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, + "@angular/router": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-10.0.7.tgz", + "integrity": "sha512-uZAUTSQNuDvpkWGqF2qTkqr+btrNwg9USRB08lzhkWH351Myt1S/7ECVYOWNek6b/NmlAA+e3Kcyb94uDwMEew==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/compat-data": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", + "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/core": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", + "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.6", + "@babel/parser": "^7.9.6", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", + "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", + "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.4", + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", + "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-regex": "^7.10.4", + "regexpu-core": "^4.7.0" + } + }, + "@babel/helper-define-map": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", + "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz", + "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==", + "dev": true, + "requires": { + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/helper-hoist-variables": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", + "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", + "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-module-transforms": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", + "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz", + "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-wrap-function": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", + "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", + "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", + "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", + "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", + "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", + "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", + "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", + "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.10.4" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", + "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", + "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", + "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", + "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", + "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", + "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", + "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.5.tgz", + "integrity": "sha512-6Ycw3hjpQti0qssQcA6AMSFDHeNJ++R6dIMnpRqUjFeBBTmTDPa8zgF90OVfTvAo11mXZTlVUViY1g8ffrURLg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", + "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-define-map": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", + "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", + "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", + "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", + "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", + "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", + "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", + "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-literals": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", + "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", + "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", + "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", + "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", + "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", + "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", + "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", + "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", + "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", + "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", + "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", + "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", + "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.6.tgz", + "integrity": "sha512-qcmiECD0mYOjOIt8YHNsAP1SxPooC/rDmfmiSK9BNY72EitdSc7l44WTEklaWuFtbOEBjNhWWyph/kOImbNJ4w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "resolve": "^1.8.1", + "semver": "^5.5.1" + }, + "dependencies": { + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", + "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", + "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", + "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-regex": "^7.10.4" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", + "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", + "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", + "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/preset-env": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.6.tgz", + "integrity": "sha512-0gQJ9RTzO0heXOhzftog+a/WyOuqMrAIugVYxMYf83gh1CQaQDjMtsOpqOwXyDL/5JcWsrCm8l4ju8QC97O7EQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.9.6", + "@babel/helper-compilation-targets": "^7.9.6", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-numeric-separator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.9.6", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.9.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.8.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.9.5", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.9.5", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.9.0", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.9.6", + "@babel/plugin-transform-modules-commonjs": "^7.9.6", + "@babel/plugin-transform-modules-systemjs": "^7.9.6", + "@babel/plugin-transform-modules-umd": "^7.9.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.9.5", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.9.6", + "browserslist": "^4.11.1", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", + "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/types": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jsdevtools/coverage-istanbul-loader": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.3.tgz", + "integrity": "sha512-TAdNkeGB5Fe4Og+ZkAr1Kvn9by2sfL44IAHFtxlh1BA1XJ5cLpO9iSNki5opWESv3l3vSHsZ9BNKuqFKbEbFaA==", + "dev": true, + "requires": { + "convert-source-map": "^1.7.0", + "istanbul-lib-instrument": "^4.0.1", + "loader-utils": "^1.4.0", + "merge-source-map": "^1.1.0", + "schema-utils": "^2.6.4" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "@ngtools/webpack": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-10.0.5.tgz", + "integrity": "sha512-jMHfLXFzmgRlZbHgS71BEIKDyHbkfKrJL1sWEs3Ylox+TEIYzJiGfnem5ZGpr8wplz8HMMJ+xngtABePvc3/0w==", + "dev": true, + "requires": { + "@angular-devkit/core": "10.0.5", + "enhanced-resolve": "4.1.1", + "rxjs": "6.5.5", + "webpack-sources": "1.4.3" + }, + "dependencies": { + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + } + } + }, + "@ngx-translate/core": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-10.0.2.tgz", + "integrity": "sha512-7nM3DrJaqKswwtJlbu2kuKNl+hE8Isr18sKsKvGGpSxQk+G0gO0reDlx2PhUNus7TJTkA1C59vU/JoN8hIvZ4g==", + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@npmcli/move-file": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", + "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "@schematics/angular": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-10.0.5.tgz", + "integrity": "sha512-zg8QxgW3uLva/MSKMRYfV7dzj00SUki4nxYN4j1rw42VlwNPnFrPtzFVEilL6N7wFgoHP/6cZRgm4bfXYvLBvg==", + "dev": true, + "requires": { + "@angular-devkit/core": "10.0.5", + "@angular-devkit/schematics": "10.0.5" + } + }, + "@schematics/update": { + "version": "0.1000.5", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.1000.5.tgz", + "integrity": "sha512-xodvq3X4B90u8myMEp9ESPnD2aC4YtNXj1FOcJ+BnguRA7q9rq9EL9Xqdef8sx3PObbSiKC0OFLyxgw76WuC3Q==", + "dev": true, + "requires": { + "@angular-devkit/core": "10.0.5", + "@angular-devkit/schematics": "10.0.5", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "npm-package-arg": "^8.0.0", + "pacote": "9.5.12", + "rxjs": "6.5.5", + "semver": "7.3.2", + "semver-intersect": "1.4.0" + }, + "dependencies": { + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/jasmine": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.3.16.tgz", + "integrity": "sha512-Nveep4zKGby8uIvG2AEUyYOwZS8uVeHK9TgbuWYSawUDDdIgfhCKz28QzamTo//Jk7Ztt9PO3f+vzlB6a4GV1Q==", + "dev": true + }, + "@types/jasminewd2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.3.tgz", + "integrity": "sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==", + "dev": true, + "requires": { + "@types/jasmine": "*" + } + }, + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.12.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.47.tgz", + "integrity": "sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A==", + "dev": true + }, + "@types/q": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", + "dev": true + }, + "@types/selenium-webdriver": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.17.tgz", + "integrity": "sha512-tGomyEuzSC1H28y2zlW6XPCaDaXFaD6soTdb4GNdmte2qfHtrKqhy0ZFs4r/1hpazCfEZqeTSRLvSasmEx89uw==", + "dev": true + }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "@types/webpack-sources": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.8.tgz", + "integrity": "sha512-JHB2/xZlXOjzjBB6fMOpH1eQAfsrpqVVIbneE0Rok16WXwFaznaI5vfg75U5WgGJm7V9W1c4xeRQDjX/zwvghA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abab": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", + "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "dependencies": { + "mime-db": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "dev": true, + "requires": { + "mime-db": "1.42.0" + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + } + } + }, + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "adjust-sourcemap-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz", + "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==", + "dev": true, + "requires": { + "assert": "1.4.1", + "camelcase": "5.0.0", + "loader-utils": "1.2.3", + "object-path": "0.11.4", + "regex-parser": "2.2.10" + }, + "dependencies": { + "camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + } + } + }, + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "agentkeepalive": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "dev": true, + "requires": { + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "dependencies": { + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + } + } + }, + "ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "dev": true + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", + "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001061", + "chalk": "^2.4.2", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.30", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + } + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "base-x": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", + "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "~2.0.0" + } + }, + "blocking-proxy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", + "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "bn.js": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "bootstrap": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.0.0-beta.3.tgz", + "integrity": "sha512-/Qe1Q2d1muLEZRX2iCteMQHZBBAm6ZIjJ9FcBYK/xLr05+HvDtBOVBN+Cz7mCNZuy0zr+y5artZHM05W7mIz6g==" + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "browserify-sign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", + "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.2", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz", + "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001093", + "electron-to-chromium": "^1.3.488", + "escalade": "^3.0.1", + "node-releases": "^1.1.58" + } + }, + "browserstack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.6.0.tgz", + "integrity": "sha512-HJDJ0TSlmkwnt9RZ+v5gFpa1XZTBYTj0ywvLwJ3241J7vMw2jAsGNVhKHtmCOyg+VxeLZyaibO9UL71AsUeDIw==", + "dev": true, + "requires": { + "https-proxy-agent": "^2.2.1" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cacache": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.3.tgz", + "integrity": "sha512-bc3jKYjqv7k4pWh7I/ixIjfcjPul4V4jme/WbjvwGS5LzoPL/GzXr4C5EgPNLO/QEZl9Oi61iGitYEdwcrwLCQ==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "move-file": "^2.0.0", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.0", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "tar": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", + "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001109", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001109.tgz", + "integrity": "sha512-4JIXRodHzdS3HdK8nSgIqXYLExOvG+D2/EenSvcub2Kp3QEADjo2v2oUn5g0n0D+UNwG9BtwKOyGcSq2qvQXvQ==", + "dev": true + }, + "canonical-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", + "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", + "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", + "dev": true, + "requires": { + "ansi-styles": "^3.1.0", + "escape-string-regexp": "^1.0.5", + "supports-color": "^4.0.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-dependency-plugin": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz", + "integrity": "sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz", + "integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA==", + "dev": true + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "dependencies": { + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "codelyzer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.0.tgz", + "integrity": "sha512-edJIQCIcxD9DhVSyBEdJ38AbLikm515Wl91t5RDGNT88uA6uQdTm4phTWfn9JhzAI8kXNUcfYyAE90lJElpGtA==", + "dev": true, + "requires": { + "@angular/compiler": "9.0.0", + "@angular/core": "9.0.0", + "app-root-path": "^3.0.0", + "aria-query": "^3.0.0", + "axobject-query": "2.0.2", + "css-selector-tokenizer": "^0.7.1", + "cssauron": "^1.4.0", + "damerau-levenshtein": "^1.0.4", + "rxjs": "^6.5.3", + "semver-dsl": "^1.0.1", + "source-map": "^0.5.7", + "sprintf-js": "^1.1.2", + "tslib": "^1.10.0", + "zone.js": "~0.10.3" + }, + "dependencies": { + "@angular/compiler": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.0.tgz", + "integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==", + "dev": true + }, + "@angular/core": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.0.tgz", + "integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==", + "dev": true + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "^1.1.1" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", + "dev": true, + "requires": { + "arity-n": "^1.0.4" + } + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-webpack-plugin": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.0.3.tgz", + "integrity": "sha512-q5m6Vz4elsuyVEIUXr7wJdIdePWTubsqVbEMvf1WQnHGv0Q+9yPRu7MtYFPt+GBOXRav9lvIINifTQ1vSCs+eA==", + "dev": true, + "requires": { + "cacache": "^15.0.4", + "fast-glob": "^3.2.4", + "find-cache-dir": "^3.3.1", + "glob-parent": "^5.1.1", + "globby": "^11.0.1", + "loader-utils": "^2.0.0", + "normalize-path": "^3.0.0", + "p-limit": "^3.0.1", + "schema-utils": "^2.7.0", + "serialize-javascript": "^4.0.0", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "cacache": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", + "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.0", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "tar": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", + "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + }, + "core-js-compat": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-loader": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.3.tgz", + "integrity": "sha512-UEr9NH5Lmi7+dguAm+/JSPovNjYbm2k3TK58EiwQHzOHH5Jfq1Y+XoP2bQO6TMn7PptMd0opxxedAWcaSTRKHw==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.27", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.0.3", + "schema-utils": "^2.6.6", + "semver": "^6.3.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", + "dev": true, + "requires": { + "css": "^2.0.0" + } + }, + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-what": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", + "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", + "dev": true + }, + "cssauron": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", + "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", + "dev": true, + "requires": { + "through": "X.X.X" + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "cssnano": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", + "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.7", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", + "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "dev": true, + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.2", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true + }, + "csso": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", + "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", + "dev": true, + "requires": { + "css-tree": "1.0.0-alpha.39" + }, + "dependencies": { + "css-tree": { + "version": "1.0.0-alpha.39", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", + "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "dev": true, + "requires": { + "mdn-data": "2.0.6", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", + "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "^1.0.1" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "date-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", + "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + } + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + } + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "dependency-graph": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", + "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.516", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.516.tgz", + "integrity": "sha512-WDM5AAQdOrvLqSX8g3Zd5AujBXfMxf96oeZkff0U2HF5op3tjShE+on2yay3r1UD4M9I3p0iHpAS4+yV8U8A9A==", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", + "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "0.3.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "^7.1.2" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "engine.io-client": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz", + "integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==", + "dev": true, + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, + "err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escalade": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz", + "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "dev": true + }, + "events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "dev": true + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-loader": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.0.0.tgz", + "integrity": "sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.5" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "follow-redirects": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", + "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", + "dev": true, + "requires": { + "debug": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + } + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.10.tgz", + "integrity": "sha512-Dw5DScF/8AWhWzWRbnQrFJfeR/TOJZjRr9Du9kfmd8t234ICcVeDBlauFl/jVcE5ZewhlPoCFvIqp0SE3kAVxA==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "requires": { + "globule": "^1.0.0" + } + }, + "genfun": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", + "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + } + } + }, + "globule": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", + "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "^1.0.2" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==" + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "dev": true + }, + "html-entities": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + }, + "http-proxy": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", + "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", + "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "requires": { + "import-from": "^2.1.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=" + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "^2.0.0" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-svg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "dev": true, + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isbinaryfile": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", + "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "dev": true, + "requires": { + "exit": "^0.1.2", + "glob": "^7.0.6", + "jasmine-core": "~2.8.0" + }, + "dependencies": { + "jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", + "dev": true + } + } + }, + "jasmine-core": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", + "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", + "dev": true + }, + "jasmine-spec-reporter": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-5.0.2.tgz", + "integrity": "sha512-6gP1LbVgJ+d7PKksQBc2H0oDGNRQI3gKUsWlswKaQ2fif9X5gzhQcgM5+kiJGCQVurOG09jqNhk7payggyp5+g==", + "dev": true, + "requires": { + "colors": "1.4.0" + } + }, + "jasminewd2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", + "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", + "dev": true + }, + "jest-worker": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", + "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-base64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", + "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "jszip": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz", + "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==", + "dev": true, + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "karma": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/karma/-/karma-5.0.9.tgz", + "integrity": "sha512-dUA5z7Lo7G4FRSe1ZAXqOINEEWxmCjDBbfRBmU/wYlSMwxUQJP/tEEP90yJt3Uqo03s9rCgVnxtlfq+uDhxSPg==", + "dev": true, + "requires": { + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.0.0", + "colors": "^1.4.0", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "flatted": "^2.0.2", + "glob": "^7.1.6", + "graceful-fs": "^4.2.4", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.6", + "lodash": "^4.17.15", + "log4js": "^6.2.1", + "mime": "^2.4.5", + "minimatch": "^3.0.4", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^2.3.0", + "source-map": "^0.6.1", + "tmp": "0.2.1", + "ua-parser-js": "0.7.21", + "yargs": "^15.3.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chokidar": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz", + "integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "dev": true + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "karma-chrome-launcher": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", + "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", + "dev": true, + "requires": { + "which": "^1.2.1" + } + }, + "karma-cli": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/karma-cli/-/karma-cli-2.0.0.tgz", + "integrity": "sha512-1Kb28UILg1ZsfqQmeELbPzuEb5C6GZJfVIk0qOr8LNYQuYWmAaqP16WpbpKEjhejDrDYyYOwwJXSZO6u7q5Pvw==", + "dev": true, + "requires": { + "resolve": "^1.3.3" + } + }, + "karma-coverage-istanbul-reporter": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz", + "integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^3.0.2", + "minimatch": "^3.0.4" + } + }, + "karma-jasmine": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-3.3.1.tgz", + "integrity": "sha512-Nxh7eX9mOQMyK0VSsMxdod+bcqrR/ikrmEiWj5M6fwuQ7oI+YEF1FckaDsWfs6TIpULm9f0fTKMjF7XcrvWyqQ==", + "dev": true, + "requires": { + "jasmine-core": "^3.5.0" + } + }, + "karma-jasmine-html-reporter": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.4.tgz", + "integrity": "sha512-PtilRLno5O6wH3lDihRnz0Ba8oSn0YUJqKjjux1peoYGwo0AQqrWRbdWk/RLzcGlb+onTyXAnHl6M+Hu3UxG/Q==", + "dev": true + }, + "karma-read-json": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/karma-read-json/-/karma-read-json-1.1.0.tgz", + "integrity": "sha1-4M40XFrmOKNqWgXcGmoELczaseQ=", + "dev": true + }, + "karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "requires": { + "source-map-support": "^0.5.5" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "less": { + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz", + "integrity": "sha512-+1V2PCMFkL+OIj2/HrtrvZw0BC0sYLMICJfbQjuj/K8CEnlrFX6R5cKKgzzttsZDHyxQNL1jqMREjKN3ja/E3Q==", + "dev": true, + "requires": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "native-request": "^1.0.5", + "source-map": "~0.6.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "less-loader": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-6.1.0.tgz", + "integrity": "sha512-/jLzOwLyqJ7Kt3xg5sHHkXtOyShWwFj410K9Si9WO+/h8rmYxxkSR0A3/hFEntWudE20zZnWMtpMYnLzqTVdUA==", + "dev": true, + "requires": { + "clone": "^2.1.2", + "less": "^3.11.1", + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.6" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, + "license-webpack-plugin": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.2.0.tgz", + "integrity": "sha512-XPsdL/0brSHf+7dXIlRqotnCQ58RX2au6otkOg4U3dm8uH+Ka/fW4iukEs95uXm+qKe/SBs+s1Ll/aQddKG+tg==", + "dev": true, + "requires": { + "@types/webpack-sources": "^0.1.5", + "webpack-sources": "^1.2.0" + } + }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "requires": { + "immediate": "~3.0.5" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "log4js": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", + "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", + "dev": true, + "requires": { + "date-format": "^3.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.1", + "rfdc": "^1.1.4", + "streamroller": "^2.2.4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "loglevel": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", + "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "make-fetch-happen": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", + "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", + "dev": true, + "requires": { + "agentkeepalive": "^3.4.1", + "cacache": "^12.0.0", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^4.0.0", + "ssri": "^6.0.0" + }, + "dependencies": { + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mini-css-extract-plugin": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", + "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "moment": { + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.21.0.tgz", + "integrity": "sha512-TCZ36BjURTeFTM/CwRcViQlfkMvL1/vFISuNLO5GkcVm1+QHfbSiNqZuWeMFjj1/3+uAjXswgRk30j1kkLYJBQ==" + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "move-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/move-file/-/move-file-2.0.0.tgz", + "integrity": "sha512-cdkdhNCgbP5dvS4tlGxZbD+nloio9GIimP57EjqFhwLcMjnU+XJKAZzlmg/TN/AK1LuNAdTSvm3CPPP4Xkv0iQ==", + "dev": true, + "requires": { + "path-exists": "^4.0.0" + }, + "dependencies": { + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "native-request": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.0.7.tgz", + "integrity": "sha512-9nRjinI9bmz+S7dgNtf4A70+/vPhnd+2krGpy4SUlADuOuSa24IDkNaZ+R/QT1wQ6S8jBdi6wE7fLekFZNfUpQ==", + "dev": true, + "optional": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-fetch-npm": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz", + "integrity": "sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==", + "dev": true, + "requires": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node-forge": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "dev": true + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + } + } + }, + "node-releases": { + "version": "1.1.60", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", + "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==", + "dev": true + }, + "node-sass": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz", + "integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==", + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.11", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "^2.2.4", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true + }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-install-checks": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz", + "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==", + "dev": true, + "requires": { + "semver": "^7.1.1" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "npm-package-arg": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.0.1.tgz", + "integrity": "sha512-/h5Fm6a/exByzFSTm7jAyHbgOqErl9qSNJDQF32Si/ZzgwT2TERVxRxn3Jurw1wflgyVVAxnFR4fRHPM7y1ClQ==", + "dev": true, + "requires": { + "hosted-git-info": "^3.0.2", + "semver": "^7.0.0", + "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.5.tgz", + "integrity": "sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-pick-manifest": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.0.tgz", + "integrity": "sha512-ygs4k6f54ZxJXrzT0x34NybRlLeZ4+6nECAIbr2i0foTnijtS1TJiyzpqtuUAJOps/hO0tNDr8fRV5g+BtRlTw==", + "dev": true, + "requires": { + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.0.0", + "semver": "^7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "npm-registry-fetch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.5.tgz", + "integrity": "sha512-yQ0/U4fYpCCqmueB2g8sc+89ckQ3eXpmU4+Yi2j5o/r0WkKvE2+Y0tK3DEILAtn2UaQTkjTHxIXe2/CSdit+/Q==", + "dev": true, + "requires": { + "JSONStream": "^1.3.4", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "npm-package-arg": "^6.1.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "npm-package-arg": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "dev": true, + "requires": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, + "object-is": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", + "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.1.tgz", + "integrity": "sha512-ZpZpjcJeugQfWsfyQlshVoowIIQ1qBGSVll4rfDq6JJVO//fesjoX808hXWfBjY+ROZgpKDI5TRSRBSoJiZ8eg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/open/-/open-7.0.4.tgz", + "integrity": "sha512-brSA+/yq+b08Hsr4c8fsEW2CRzk1BmfN3SAK/5VCHQ9bdoZJ4qa/+AfR0xHjlbbZUyPkUHs1b8x1RqdyZdkVqQ==", + "dev": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + }, + "dependencies": { + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + } + } + }, + "ora": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.4.tgz", + "integrity": "sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pacote": { + "version": "9.5.12", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.12.tgz", + "integrity": "sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cacache": "^12.0.2", + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-normalize-package-bin": "^1.0.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^3.0.0", + "npm-registry-fetch": "^4.0.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.10", + "unique-filename": "^1.1.1", + "which": "^1.3.1" + }, + "dependencies": { + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "npm-package-arg": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "dev": true, + "requires": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-pick-manifest": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", + "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "npm-package-arg": "^6.0.0", + "semver": "^5.4.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pnp-webpack-plugin": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", + "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "dev": true, + "requires": { + "ts-pnp": "^1.1.6" + } + }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.31.tgz", + "integrity": "sha512-a937VDHE1ftkjk+8/7nj/mrjtmkn69xxzJgRETXdAUU+IgOYPQNJF17haGWbeDxSyk++HA14UA98FurvPyBJOA==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-calc": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", + "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", + "dev": true, + "requires": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-import": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", + "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-load-config": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + } + }, + "postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + } + }, + "postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "dev": true, + "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + } + }, + "postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dev": true, + "requires": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "dependencies": { + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + } + } + }, + "postcss-svgo": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", + "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "dev": true, + "requires": { + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "promise-retry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "dev": true, + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "dev": true + } + } + }, + "protoduck": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", + "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", + "dev": true, + "requires": { + "genfun": "^5.0.0" + } + }, + "protractor": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz", + "integrity": "sha512-UqkFjivi4GcvUQYzqGYNe0mLzfn5jiLmO8w9nMhQoJRLhy2grJonpga2IWhI6yJO30LibWXJJtA4MOIZD2GgZw==", + "dev": true, + "requires": { + "@types/q": "^0.0.32", + "@types/selenium-webdriver": "^3.0.0", + "blocking-proxy": "^1.0.0", + "browserstack": "^1.5.1", + "chalk": "^1.1.3", + "glob": "^7.0.3", + "jasmine": "2.8.0", + "jasminewd2": "^2.1.0", + "q": "1.4.1", + "saucelabs": "^1.5.0", + "selenium-webdriver": "3.6.0", + "source-map-support": "~0.4.0", + "webdriver-js-extender": "2.1.0", + "webdriver-manager": "^12.1.7", + "yargs": "^15.3.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "webdriver-manager": { + "version": "12.1.7", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.7.tgz", + "integrity": "sha512-XINj6b8CYuUYC93SG3xPkxlyUc3IJbD6Vvo75CVGuG9uzsefDzWQrhz0Lq8vbPxtb4d63CZdYophF8k8Or/YiA==", + "dev": true, + "requires": { + "adm-zip": "^0.4.9", + "chalk": "^1.1.1", + "del": "^2.2.0", + "glob": "^7.0.3", + "ini": "^1.3.4", + "minimist": "^1.2.0", + "q": "^1.4.1", + "request": "^2.87.0", + "rimraf": "^2.5.2", + "semver": "^5.3.0", + "xml2js": "^0.4.17" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", + "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + } + } + }, + "raw-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.1.tgz", + "integrity": "sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.5" + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "requires": { + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-package-json": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.1.tgz", + "integrity": "sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "json-parse-better-errors": "^1.0.1", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "read-package-tree": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", + "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", + "dev": true, + "requires": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "dependencies": { + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", + "dev": true + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.0.tgz", + "integrity": "sha512-qArkXsjJq7H+T86WrIFV0Fnu/tNOkZ4cgXmjkzAu3b/58D5mFIO8JH/y77t7C9q0OdDRdh9s7Ue5GasYssxtXw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + } + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regex-parser": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", + "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==", + "dev": true + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "resolve-url-loader": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz", + "integrity": "sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ==", + "dev": true, + "requires": { + "adjust-sourcemap-loader": "2.0.0", + "camelcase": "5.3.1", + "compose-function": "3.0.3", + "convert-source-map": "1.7.0", + "es6-iterator": "2.0.3", + "loader-utils": "1.2.3", + "postcss": "7.0.21", + "rework": "1.0.1", + "rework-visit": "1.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "postcss": { + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rework": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", + "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", + "dev": true, + "requires": { + "convert-source-map": "^0.3.3", + "css": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", + "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=", + "dev": true + } + } + }, + "rework-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", + "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=", + "dev": true + }, + "rfdc": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", + "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", + "dev": true + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "^7.0.5" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rollup": { + "version": "2.10.9", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.10.9.tgz", + "integrity": "sha512-dY/EbjiWC17ZCUSyk14hkxATAMAShkMsD43XmZGWjLrgFj15M3Dw2kEkA9ns64BiLFm9PKN6vTQw8neHwK74eg==", + "dev": true, + "requires": { + "fsevents": "~2.1.2" + }, + "dependencies": { + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + } + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + } + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass": { + "version": "1.26.5", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.5.tgz", + "integrity": "sha512-FG2swzaZUiX53YzZSjSakzvGtlds0lcbF+URuU9mxOv7WBh7NhXEVDa4kPKN4hN6fC2TkOTOKqiqp6d53N9X5Q==", + "dev": true, + "requires": { + "chokidar": ">=2.0.0 <4.0.0" + } + }, + "sass-graph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^7.0.0" + } + }, + "sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "saucelabs": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", + "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", + "dev": true, + "requires": { + "https-proxy-agent": "^2.2.1" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selenium-webdriver": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", + "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", + "dev": true, + "requires": { + "jszip": "^3.1.3", + "rimraf": "^2.5.4", + "tmp": "0.0.30", + "xml2js": "^0.4.17" + }, + "dependencies": { + "tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + } + } + }, + "selfsigned": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", + "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "dev": true, + "requires": { + "node-forge": "0.9.0" + } + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "semver-dsl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", + "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "semver-intersect": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.4.0.tgz", + "integrity": "sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ==", + "dev": true, + "requires": { + "semver": "^5.0.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + } + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "smart-buffer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "socket.io": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", + "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "dev": true, + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.4.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.3.0", + "socket.io-parser": "~3.4.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==", + "dev": true + }, + "socket.io-client": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + } + } + }, + "socket.io-parser": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", + "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "sockjs": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + } + }, + "sockjs-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "dev": true, + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "socks": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", + "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", + "dev": true, + "requires": { + "ip": "1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", + "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", + "dev": true, + "requires": { + "agent-base": "~4.2.1", + "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + } + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-1.0.0.tgz", + "integrity": "sha512-ZayyQCSCrQazN50aCvuS84lJT4xc1ZAcykH5blHaBdVveSwjiFK8UGMPvao0ho54DTb0Jf7m57uRRG/YYUZ2Fg==", + "dev": true, + "requires": { + "data-urls": "^2.0.0", + "iconv-lite": "^0.5.1", + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.6", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "speed-measure-webpack-plugin": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.3.tgz", + "integrity": "sha512-2ljD4Ch/rz2zG3HsLsnPfp23osuPBS0qPuz9sGpkNXTN1Ic4M+W9xB8l8rS8ob2cO4b1L+WTJw/0AJwWYVgcxQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "ssri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", + "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "requires": { + "readable-stream": "^2.0.1" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "streamroller": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", + "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", + "dev": true, + "requires": { + "date-format": "^2.1.0", + "debug": "^4.1.1", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "^4.0.1" + } + }, + "style-loader": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.2.1.tgz", + "integrity": "sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.6" + } + }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "stylus": { + "version": "0.54.7", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", + "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", + "dev": true, + "requires": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.3", + "mkdirp": "~0.5.x", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.0.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "stylus-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", + "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", + "dev": true, + "requires": { + "loader-utils": "^1.0.2", + "lodash.clonedeep": "^4.5.0", + "when": "~3.6.x" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "terser": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz", + "integrity": "sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "terser-webpack-plugin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.0.1.tgz", + "integrity": "sha512-eFDtq8qPUEa9hXcUzTwKXTnugIVtlqc1Z/ZVhG8LmRT3lgRY13+pQTnFLY2N7ATB6TKCHuW/IGjoAnZz9wOIqw==", + "dev": true, + "requires": { + "cacache": "^15.0.3", + "find-cache-dir": "^3.3.1", + "jest-worker": "^26.0.0", + "p-limit": "^2.3.0", + "schema-utils": "^2.6.6", + "serialize-javascript": "^3.0.0", + "source-map": "^0.6.1", + "terser": "^4.6.13", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + }, + "dependencies": { + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + } + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "requires": { + "glob": "^7.1.2" + } + }, + "ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "ts-pnp": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", + "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", + "dev": true + }, + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "dependencies": { + "mime-db": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "dev": true, + "requires": { + "mime-db": "1.42.0" + } + } + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.21", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", + "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universal-analytics": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.20.tgz", + "integrity": "sha512-gE91dtMvNkjO+kWsPstHRtSwHXz0l2axqptGYp5ceg4MsuurloM0PU3pdOfpb5zBXUvyjT4PwhWK2m39uczZuw==", + "dev": true, + "requires": { + "debug": "^3.0.0", + "request": "^2.88.0", + "uuid": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util-promisify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz", + "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "watchpack": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", + "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "dev": true, + "requires": { + "chokidar": "^3.4.1", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true, + "optional": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz", + "integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + } + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webdriver-js-extender": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", + "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", + "dev": true, + "requires": { + "@types/selenium-webdriver": "^3.0.0", + "selenium-webdriver": "^3.0.1" + } + }, + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + }, + "webpack": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", + "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.1", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "terser-webpack-plugin": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", + "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^3.1.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "dev": true + } + } + }, + "webpack-dev-server": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.20", + "sockjs-client": "1.4.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "webpack-subresource-integrity": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.4.1.tgz", + "integrity": "sha512-XMLFInbGbB1HV7K4vHWANzc1CN0t/c4bBvnlvGxGwV45yE/S/feAXIm8dJsCkzqWtSKnmaEgTp/meyeThxG4Iw==", + "dev": true, + "requires": { + "webpack-sources": "^1.3.0" + } + }, + "websocket-driver": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "dev": true, + "requires": { + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^5.0.0" + } + }, + "when": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", + "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "worker-plugin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/worker-plugin/-/worker-plugin-4.0.3.tgz", + "integrity": "sha512-7hFDYWiKcE3yHZvemsoM9lZis/PzurHAEX1ej8PLCu818Rt6QqUAiDdxHPCKZctzmhqzPpcFSgvMCiPbtooqAg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "dev": true + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dev": true, + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + } + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "requires": { + "camelcase": "^3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + } + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true + }, + "zone.js": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", + "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==" + } + } +} diff --git a/src/gui/static/package.json b/src/gui/static/package.json new file mode 100644 index 0000000..ae360db --- /dev/null +++ b/src/gui/static/package.json @@ -0,0 +1,61 @@ +{ + "name": "desktopwallet", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build --prod", + "build-travis": "ng build --prod --output-path=$BUILD_UI_TRAVIS_DIR", + "test": "ng test --watch=false", + "lint": "ng lint", + "e2e": "ng e2e desktopwallet-e2e" + }, + "private": true, + "dependencies": { + "@angular/animations": "^10.0.7", + "@angular/cdk": "^10.1.1", + "@angular/common": "^10.0.7", + "@angular/compiler": "^10.0.7", + "@angular/core": "^10.0.7", + "@angular/forms": "^10.0.7", + "@angular/material": "^10.1.1", + "@angular/platform-browser": "^10.0.7", + "@angular/platform-browser-dynamic": "^10.0.7", + "@angular/router": "^10.0.7", + "@ngx-translate/core": "^10.0.2", + "base-x": "3.0.5", + "bignumber.js": "^7.2.1", + "bootstrap": "^4.0.0-beta.2", + "core-js": "^2.5.4", + "font-awesome": "^4.7.0", + "moment": "^2.21.0", + "node-sass": "4.12.0", + "rxjs": "^6.5.3", + "tslib": "^2.0.0", + "zone.js": "~0.10.3" + }, + "devDependencies": { + "@angular-devkit/build-angular": "~0.1000.5", + "@angular/cli": "^10.0.5", + "@angular/compiler-cli": "^10.0.7", + "@angular/language-service": "^10.0.7", + "@types/jasmine": "~3.3.8", + "@types/jasminewd2": "~2.0.3", + "@types/node": "^12.11.1", + "codelyzer": "^6.0.0", + "jasmine-core": "~3.5.0", + "jasmine-spec-reporter": "~5.0.0", + "karma": "~5.0.0", + "karma-chrome-launcher": "~3.1.0", + "karma-cli": "~2.0.0", + "karma-coverage-istanbul-reporter": "~3.0.2", + "karma-jasmine": "~3.3.0", + "karma-jasmine-html-reporter": "^1.5.0", + "karma-read-json": "^1.1.0", + "protractor": "~7.0.0", + "ts-node": "~7.0.0", + "tslint": "~6.1.0", + "typescript": "~3.9.7" + } +} diff --git a/src/gui/static/protractor.conf.js b/src/gui/static/protractor.conf.js new file mode 100644 index 0000000..98b7152 --- /dev/null +++ b/src/gui/static/protractor.conf.js @@ -0,0 +1,31 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 60000, + specs: [ + './e2e/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome', + chromeOptions: { + args: ['--no-sandbox', '--headless', '--disable-gpu', 'window-size=1920,1080'] + } + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 60000, + print: function() {} + }, + onPrepare() { + require('ts-node').register({ + project: 'e2e/tsconfig.e2e.json' + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; diff --git a/src/gui/static/proxy.config.js b/src/gui/static/proxy.config.js new file mode 100644 index 0000000..8b2915b --- /dev/null +++ b/src/gui/static/proxy.config.js @@ -0,0 +1,46 @@ +const PROXY_CONFIG = { + "/swaplab": { + "target": "https://swaplab.cc", + "logLevel": "debug", + "changeOrigin": true, + pathRewrite: {'^/swaplab' : ''} + }, + "/api": { + "target": "http://127.0.0.1:6420", + "secure": false, + "logLevel": "debug", + "bypass": function (req) { + req.headers["host"] = '127.0.0.1:6420'; + req.headers["referer"] = 'http://127.0.0.1:6420'; + req.headers["origin"] = 'http://127.0.0.1:6420'; + } + }, + "/local-btc": { + "target": "http://127.0.0.1:18443/", + "logLevel": "debug", + "changeOrigin": true, + pathRewrite: {'^/local-btc' : ''} + }, + "/local-eth": { + "target": "http://127.0.0.1:8545/", + "logLevel": "debug", + "changeOrigin": true, + pathRewrite: {'^/local-eth' : ''} + }, + "/local-blockbook": { + "target": "http://127.0.0.1:9130/", + "logLevel": "debug", + "changeOrigin": true, + pathRewrite: {'^/local-blockbook' : ''} + }, + "/teller/*": { + "target": "http://127.0.0.1:7071", + "pathRewrite": { + "^/teller" : "api/" + }, + "secure": true, + "logLevel": "debug" + } +}; + +module.exports = PROXY_CONFIG; diff --git a/src/gui/static/src/app/app-routing.module.ts b/src/gui/static/src/app/app-routing.module.ts new file mode 100644 index 0000000..51dd46d --- /dev/null +++ b/src/gui/static/src/app/app-routing.module.ts @@ -0,0 +1,95 @@ +import { NgModule } from '@angular/core'; +import { WalletsComponent } from './components/pages/wallets/wallets.component'; +import { SendCoinsComponent } from './components/pages/send-coins/send-coins.component'; +import { RouterModule } from '@angular/router'; +import { PendingTransactionsComponent } from './components/pages/settings/pending-transactions/pending-transactions.component'; +import { OutputsComponent } from './components/pages/settings/outputs/outputs.component'; +import { BlockchainComponent } from './components/pages/settings/blockchain/blockchain.component'; +import { BackupComponent } from './components/pages/settings/backup/backup.component'; +import { NetworkComponent } from './components/pages/settings/network/network.component'; +import { BuyComponent } from './components/pages/buy/buy.component'; +import { TransactionListComponent } from './components/pages/transaction-list/transaction-list.component'; +import { WizardGuardService } from './services/wizard-guard.service'; +import { OnboardingComponent } from './components/pages/onboarding/onboarding.component'; +import { ResetPasswordComponent } from './components/pages/reset-password/reset-password.component'; +import { ExchangeComponent } from './components/pages/exchange/exchange.component'; +import { AddressHistoryComponent } from './components/pages/address-history/address-history.component'; + + +const ROUTES = [ + { + path: '', + redirectTo: 'wallets', + pathMatch: 'full', + }, + { + path: 'wallets', + component: WalletsComponent, + canActivate: [WizardGuardService], + }, + { + path: 'send', + component: SendCoinsComponent, + canActivate: [WizardGuardService], + }, + { + path: 'transactions', + component: TransactionListComponent, + canActivate: [WizardGuardService], + }, + { + path: 'addresses', + component: AddressHistoryComponent, + canActivate: [WizardGuardService], + }, + { + path: 'buy', + component: BuyComponent, + canActivate: [WizardGuardService], + }, + { + path: 'exchange', + component: ExchangeComponent, + canActivate: [WizardGuardService], + }, + { + path: 'settings', + children: [ + { + path: 'backup', + component: BackupComponent, + }, + { + path: 'blockchain', + component: BlockchainComponent, + }, + { + path: 'network', + component: NetworkComponent, + }, + { + path: 'outputs', + component: OutputsComponent, + }, + { + path: 'pending-transactions', + component: PendingTransactionsComponent, + }, + ], + canActivate: [WizardGuardService], + }, + { + path: 'wizard', + component: OnboardingComponent, + }, + { + path: 'reset/:id', + component: ResetPasswordComponent, + }, +]; + +@NgModule({ + imports: [RouterModule.forRoot(ROUTES, { useHash: true })], + exports: [RouterModule], +}) +export class AppRoutingModule { } diff --git a/src/gui/static/src/app/app-translation.module.ts b/src/gui/static/src/app/app-translation.module.ts new file mode 100644 index 0000000..67e0bf4 --- /dev/null +++ b/src/gui/static/src/app/app-translation.module.ts @@ -0,0 +1,21 @@ +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { from, Observable } from 'rxjs'; +import { NgModule } from '@angular/core'; + +// Loads the translation files, with cache busting. +export class TranslationModuleLoader implements TranslateLoader { + getTranslation(lang: string): Observable { + return from(import(`../assets/i18n/${lang}.json`)); + } +} + +@NgModule({ + imports: [TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslationModuleLoader, + }, + })], + exports: [TranslateModule], +}) +export class AppTranslationModule { } diff --git a/src/gui/static/src/app/app.component.html b/src/gui/static/src/app/app.component.html new file mode 100644 index 0000000..5f10d9d --- /dev/null +++ b/src/gui/static/src/app/app.component.html @@ -0,0 +1,15 @@ +
+
+ +
{{ 'errors.window-size' | translate }}
+
+
+ +
+ + \ No newline at end of file diff --git a/src/gui/static/src/app/app.component.scss b/src/gui/static/src/app/app.component.scss new file mode 100644 index 0000000..85edadf --- /dev/null +++ b/src/gui/static/src/app/app.component.scss @@ -0,0 +1,19 @@ +.size-alert { + background-color: rgba(0, 0, 0, 0.85); + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 10000; + display: inline-flex; + align-items: center; + justify-content: center; + text-align: center; + color: white; + + > div { + margin: 0px 40px; + max-width: 400px; + } +} diff --git a/src/gui/static/src/app/app.component.ts b/src/gui/static/src/app/app.component.ts new file mode 100644 index 0000000..1f09e12 --- /dev/null +++ b/src/gui/static/src/app/app.component.ts @@ -0,0 +1,101 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; + +import { HwWalletService } from './services/hw-wallet.service'; +import { HwPinDialogComponent } from './components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component'; +import { Bip39WordListService } from './services/bip39-word-list.service'; +import { HwConfirmTxDialogComponent } from './components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component'; +import { HwWalletPinService } from './services/hw-wallet-pin.service'; +import { HwWalletSeedWordService } from './services/hw-wallet-seed-word.service'; +import { LanguageService } from './services/language.service'; +import { MsgBarComponent } from './components/layout/msg-bar/msg-bar.component'; +import { MsgBarService } from './services/msg-bar.service'; +import { SeedWordDialogComponent } from './components/layout/seed-word-dialog/seed-word-dialog.component'; +import { SelectLanguageComponent } from './components/layout/select-language/select-language.component'; +import { CoinService } from './services/coin.service'; +import { AppUpdateService } from './services/app-update.service'; +import { NodeService } from './services/node.service'; +import { BlockchainService } from './services/blockchain.service'; +import { NetworkService } from './services/network.service'; +import { OperatorService } from './services/operators.service'; +import { FiberOperatorsGenerator } from './services/coin-specific/fiber/fiber-operators-generator'; +import { BtcOperatorsGenerator } from './services/coin-specific/btc/btc-operators-generator'; +import { EthOperatorsGenerator } from './services/coin-specific/eth/eth-operators-generator'; + +/** + * Main component for the app. + */ +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], +}) +export class AppComponent implements OnInit { + // Single MsgBarComponent instance used on the app. + @ViewChild('msgBar') msgBar: MsgBarComponent; + + // If the app content must be shown. Used when the coin is changed, to remove the content + // for a short moment to force the pages to be deleted and created again. + showContent = false; + + constructor( + private languageService: LanguageService, + private dialog: MatDialog, + private msgBarService: MsgBarService, + nodeService: NodeService, + hwWalletService: HwWalletService, + hwWalletPinService: HwWalletPinService, + hwWalletSeedWordService: HwWalletSeedWordService, + bip38WordList: Bip39WordListService, + coinService: CoinService, + appUpdateService: AppUpdateService, + blockchainService: BlockchainService, + networkService: NetworkService, + operatorService: OperatorService, + ) { + coinService.initialize(); + operatorService.initialize(new FiberOperatorsGenerator(), new BtcOperatorsGenerator(), new EthOperatorsGenerator()); + + // When the coin is changed, remove the content for 3 frames, which forces the pages to be + // recreated and gives time for the system vars to be resetted. + coinService.currentCoin.subscribe(() => { + this.showContent = false; + setTimeout(() => { + setTimeout(() => { + setTimeout(() => { + this.showContent = true; + }); + }); + }); + }); + + // Asign modal window classes to some services, to avoid circular references. + hwWalletPinService.requestPinComponent = HwPinDialogComponent; + hwWalletSeedWordService.requestWordComponent = SeedWordDialogComponent; + hwWalletService.signTransactionConfirmationComponent = HwConfirmTxDialogComponent; + + bip38WordList.initialize(); + appUpdateService.initialize(); + nodeService.initialize(); + blockchainService.initialize(); + networkService.initialize(); + } + + ngOnInit() { + this.languageService.initialize(); + + // If the user has not selected the language for the first time, show the + // language selection modal window. + const subscription = this.languageService.savedSelectedLanguageLoaded.subscribe(savedSelectedLanguageLoaded => { + if (!savedSelectedLanguageLoaded) { + SelectLanguageComponent.openDialog(this.dialog, true); + } + + subscription.unsubscribe(); + }); + + setTimeout(() => { + this.msgBarService.msgBarComponent = this.msgBar; + }); + } +} diff --git a/src/gui/static/src/app/app.config.ts b/src/gui/static/src/app/app.config.ts new file mode 100644 index 0000000..3efaf7a --- /dev/null +++ b/src/gui/static/src/app/app.config.ts @@ -0,0 +1,143 @@ +import { SkycoinCoin } from './coins/skycoin.coin'; +import { TestCoin } from './coins/test.coin'; +import { BtcCoin } from './coins/btc.coin'; +import { EthCoin } from './coins/eth.coin'; + +export const AppConfig = { + + // General settings. + //////////////////////////////// + + /** + * If the wallet will allow to work with bip44 wallets. + */ + bip44Enabled: true, + /** + * If the wallet will allow to work with xpub wallets. + */ + xPubEnabled: true, + /** + * If true, the option for buying coins via the OTC service will be enabled. + */ + otcEnabled: false, + /** + * How many coins the hw wallet can have. + */ + maxHardwareWalletAddresses: 1, + /** + * Max gap of unused addresses a wallet can have between 2 used addresses before the user is + * alerted about potential problems that could appear for restoring all addresses when loading + * the wallet again using the seed. + */ + maxAddressesGap: 20, + /** + * Normal size for some modal windows. + */ + mediumModalWidth: '566px', + + // History settings for coins using Blockbook. + //////////////////////////////// + + /** + * Max number of transactions per address to retrieve when building the transaction history and + * the user has few addresses, for performance reasons. Must not be more than 250. + */ + maxTxPerAddressIfFewAddresses: 50, + /** + * Max number of transactions per address to retrieve when building the transaction history and + * the user has many addresses, for performance reasons. Must not be more than 250. + */ + maxTxPerAddressIfManyAddresses: 25, + /** + * Value wich will multiply maxTxPerAddressIfFewAddresses and maxTxPerAddressIfManyAddresses + * to get the max number of transactions per address to retrieve if the user asks for + * more transactions. + */ + maxTxPerAddressMultiplier: 3, + /** + * Absolute max number of transactions per address that can be requested when building the + * transaction history. Must be less than 1000 and more than + * maxTxPerAddressIfFewAddresses * maxTxPerAddressMultiplier. + */ + maxTxPerAddressAllowedByBackend: 300, + /** + * Max number of addresses considered as "few" while building the transaction history. + */ + fewAddressesLimit: 7, + + // Hw wallet firmware. + //////////////////////////////// + + /** + * URL for checking the number of the most recent version of the Skywallet firmware. + */ + urlForHwWalletVersionChecking: 'https://version.skycoin.com/skywallet/version.txt', + /** + * First part of the URL for donwnloading the lastest firmware for the Skywallet. The number of + * the lastest version and '.bin' is added at the end of the value by the code. + */ + hwWalletDownloadUrlAndPrefix: 'https://downloads.skycoin.com/skywallet/skywallet-firmware-v', + /** + * URL were the user can download the lastest version of the hw wallet daemon. + */ + hwWalletDaemonDownloadUrl: 'https://www.skycoin.com/downloads/', + + // Wallet update. + //////////////////////////////// + + /** + * URL for checking the number of the most recent version of the wallet software. + */ + urlForVersionChecking: 'https://version.skycoin.com/skycoin/version.txt', + /** + * URL were the user can download the lastest version of the wallet software. + */ + walletDownloadUrl: 'https://www.skycoin.com/downloads/', + + // Coins. + //////////////////////////////// + + /** + * Array with the coins that will be available in the app. + */ + coins: [ + new SkycoinCoin(), + new TestCoin(), + new BtcCoin(), + new EthCoin(), + ], + + /** + * Name of the default coin. + */ + defaultCoinName: 'Skycoin', + + // Translations. + //////////////////////////////// + + /** + * Array with the available translations. For more info check the readme file in the + * folder with the translation files. + */ + languages: [{ + code: 'en', + name: 'English', + iconName: 'en.png', + }, + { + code: 'zh', + name: '中文', + iconName: 'zh.png', + }, + { + code: 'es', + name: 'Español', + iconName: 'es.png', + }, + ], + + /** + * Default language used by the software. + */ + defaultLanguage: 'en', +}; diff --git a/src/gui/static/src/app/app.datatypes.ts b/src/gui/static/src/app/app.datatypes.ts new file mode 100644 index 0000000..c9ef711 --- /dev/null +++ b/src/gui/static/src/app/app.datatypes.ts @@ -0,0 +1,15 @@ +/** + * Internal Objects + */ +export class PurchaseOrder { + coin_type: string; + filename: string; + deposit_address: string; + recipient_address: string; + status?: string; +} + +export class TellerConfig { + enabled: boolean; + sky_btc_exchange_rate: number; +} diff --git a/src/gui/static/src/app/app.module.ts b/src/gui/static/src/app/app.module.ts new file mode 100644 index 0000000..4915a63 --- /dev/null +++ b/src/gui/static/src/app/app.module.ts @@ -0,0 +1,301 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { AppComponent } from './app.component'; +import { WalletsComponent } from './components/pages/wallets/wallets.component'; +import { CreateWalletComponent } from './components/pages/wallets/create-wallet/create-wallet.component'; +import { ReactiveFormsModule } from '@angular/forms'; +import { SendCoinsComponent } from './components/pages/send-coins/send-coins.component'; +import { DateFromNowPipe } from './pipes/date-from-now.pipe'; +import { BlockchainService } from './services/blockchain.service'; +import { DateTimePipe } from './pipes/date-time.pipe'; +import { PendingTransactionsComponent } from './components/pages/settings/pending-transactions/pending-transactions.component'; +import { OutputsComponent } from './components/pages/settings/outputs/outputs.component'; +import { BlockchainComponent } from './components/pages/settings/blockchain/blockchain.component'; +import { BackupComponent } from './components/pages/settings/backup/backup.component'; +import { NetworkComponent } from './components/pages/settings/network/network.component'; +import { NetworkService } from './services/network.service'; +import { ChangeNameComponent } from './components/pages/wallets/change-name/change-name.component'; +import { ButtonComponent } from './components/layout/button/button.component'; +import { QrCodeComponent } from './components/layout/qr-code/qr-code.component'; +import { BuyComponent } from './components/pages/buy/buy.component'; +import { AddDepositAddressComponent } from './components/pages/buy/add-deposit-address/add-deposit-address.component'; +import { PurchaseService } from './services/purchase.service'; +import { TellerStatusPipe } from './pipes/teller-status.pipe'; +import { HeaderComponent } from './components/layout/header/header.component'; +import { TopBarComponent } from './components/layout/header/top-bar/top-bar.component'; +import { PriceService } from './services/price.service'; +import { TransactionListComponent } from './components/pages/transaction-list/transaction-list.component'; +import { TransactionDetailComponent } from './components/pages/transaction-list/transaction-detail/transaction-detail.component'; +import { NavBarComponent } from './components/layout/header/nav-bar/nav-bar.component'; +import { WalletDetailComponent } from './components/pages/wallets/wallet-detail/wallet-detail.component'; +import { ModalComponent } from './components/layout/modal/modal.component'; +import { PasswordDialogComponent } from './components/layout/password-dialog/password-dialog.component'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatListModule } from '@angular/material/list'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatProgressSpinnerModule, MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS } from '@angular/material/progress-spinner'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatSliderModule } from '@angular/material/slider'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { HttpClientModule } from '@angular/common/http'; +import { WizardGuardService } from './services/wizard-guard.service'; +import { OnboardingCreateWalletComponent } from './components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component'; +import { OnboardingEncryptWalletComponent } from './components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component'; +import { DoubleButtonComponent } from './components/layout/double-button/double-button.component'; +import { SeedModalComponent } from './components/pages/settings/backup/seed-modal/seed-modal.component'; +import { OnboardingComponent } from './components/pages/onboarding/onboarding.component'; +import { DontsavepasswordDirective } from './directives/dontsavepassword.directive'; +import { SendVerifyComponent } from './components/pages/send-coins/send-preview/send-preview.component'; +import { TransactionInfoComponent } from './components/pages/send-coins/send-preview/transaction-info/transaction-info.component'; +import { SendCoinsFormComponent } from './components/pages/send-coins/send-coins-form/send-coins-form.component'; +import { NavBarSwitchService } from './services/nav-bar-switch.service'; +import { LoadingContentComponent } from './components/layout/loading-content/loading-content.component'; +import { NumberOfAddressesComponent } from './components/pages/wallets/number-of-addresses/number-of-addresses'; +import { SelectAddressComponent } from './components/layout/select-address/select-address.component'; +import { CreateWalletFormComponent } from './components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component'; +import { ResetPasswordComponent } from './components/pages/reset-password/reset-password.component'; +import { ExchangeComponent } from './components/pages/exchange/exchange.component'; +import { ExchangeService } from './services/exchange.service'; +import { ExchangeCreateComponent } from './components/pages/exchange/exchange-create/exchange-create.component'; +import { ExchangeStatusComponent } from './components/pages/exchange/exchange-status/exchange-status.component'; +import { HwWalletService } from './services/hw-wallet.service'; +import { HwOptionsDialogComponent } from './components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component'; +import { HwWipeDialogComponent } from './components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component'; +import { HwAddedDialogComponent } from './components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component'; +import { HwGenerateSeedDialogComponent } from './components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component'; +import { HwBackupDialogComponent } from './components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component'; +import { ConfirmationComponent } from './components/layout/confirmation/confirmation.component'; +import { HwMessageComponent } from './components/layout/hardware-wallet/hw-message/hw-message.component'; +import { HwPinDialogComponent } from './components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component'; +import { HwChangePinDialogComponent } from './components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component'; +import { HwPinHelpDialogComponent } from './components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component'; +import { HwRestoreSeedDialogComponent } from './components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component'; +import { Bip39WordListService } from './services/bip39-word-list.service'; +import { HwDialogBaseComponent } from './components/layout/hardware-wallet/hw-dialog-base.component'; +import { HwConfirmTxDialogComponent } from './components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component'; +import { HwConfirmAddressDialogComponent } from './components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component'; +import { HwWalletDaemonService } from './services/hw-wallet-daemon.service'; +import { HwWalletPinService } from './services/hw-wallet-pin.service'; +import { HwWalletSeedWordService } from './services/hw-wallet-seed-word.service'; +import { LanguageService } from './services/language.service'; +import { SelectLanguageComponent } from './components/layout/select-language/select-language.component'; +import { ExchangeHistoryComponent } from './components/pages/exchange/exchange-history/exchange-history.component'; +import { StorageService } from './services/storage.service'; +import { CommonTextPipe } from './pipes/common-text.pipe'; +import { AmountPipe } from './pipes/amount.pipe'; +import { DecimalPipe } from '@angular/common'; +import { HwRemovePinDialogComponent } from './components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component'; +import { HwUpdateFirmwareDialogComponent } from './components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component'; +import { HwUpdateAlertDialogComponent } from './components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component'; +import { ChangeNoteComponent } from './components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component'; +import { MsgBarComponent } from './components/layout/msg-bar/msg-bar.component'; +import { MsgBarService } from './services/msg-bar.service'; +import { SeedWordDialogComponent } from './components/layout/seed-word-dialog/seed-word-dialog.component'; +import { MultipleDestinationsDialogComponent } from './components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component'; +import { FormSourceSelectionComponent } from './components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component'; +import { FormDestinationComponent } from './components/pages/send-coins/form-parts/form-destination/form-destination.component'; +import { CopyRawTxComponent } from './components/pages/send-coins/offline-dialogs/implementations/copy-raw-tx.component'; +import { SignRawTxComponent } from './components/pages/send-coins/offline-dialogs/implementations/sign-raw-tx.component'; +import { BroadcastRawTxComponent } from './components/pages/send-coins/offline-dialogs/implementations/broadcast-raw-tx.component'; +import { OfflineDialogsBaseComponent } from './components/pages/send-coins/offline-dialogs/offline-dialogs-base.component'; +import { ArrowLinkComponent } from './components/layout/arrow-link/arrow-link.component'; +import { QrCodeButtonComponent } from './components/layout/qr-code-button/qr-code-button.component'; +import { WalletsAndAddressesService } from './services/wallet-operations/wallets-and-addresses.service'; +import { SoftwareWalletService } from './services/wallet-operations/software-wallet.service'; +import { HardwareWalletService } from './services/wallet-operations/hardware-wallet.service'; +import { BalanceAndOutputsService } from './services/wallet-operations/balance-and-outputs.service'; +import { SpendingService } from './services/wallet-operations/spending.service'; +import { HistoryService } from './services/wallet-operations/history.service'; +import { AppRoutingModule } from './app-routing.module'; +import { AppTranslationModule } from './app-translation.module'; +import { WalletOptionsComponent } from './components/pages/wallets/wallet-options/wallet-options.component'; +import { AddressHistoryComponent } from './components/pages/address-history/address-history.component'; +import { GetNextAddressComponent } from './components/layout/get-next-address/get-next-address.component'; +import { CoinService } from './services/coin.service'; +import { AppUpdateService } from './services/app-update.service'; +import { NodeService } from './services/node.service'; +import { SelectCoinOverlayComponent } from './components/layout/select-coin-overlay/select-coin-overlay.component'; +import { FiberApiService } from './services/api/fiber-api.service'; +import { WalletUtilsService } from './services/wallet-operations/wallet-utils.service'; +import { OperatorService } from './services/operators.service'; +import { BtcApiService } from './services/api/btc-api.service'; +import { EthApiService } from './services/api/eth-api.service'; +import { BlockbookApiService } from './services/api/blockbook-api.service'; +import { SelectCoinComponent } from './components/layout/select-coin/select-coin.component'; +import { MainColorFormElementDirective } from './directives/styling/main-color-form-element.directive'; +import { ColorImageDirective } from './directives/styling/image-color.directive'; +import { ThemeColorTextDirective } from './directives/styling/theme-color-text.directive'; +import { AssistedSeedFieldComponent } from './components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component'; +import { SelectConfirmationsComponent } from './components/pages/settings/blockchain/select-confirmations/select-confirmations.component'; +import { FormFieldErrorDirective } from './directives/form-field-error.directive'; + + +@NgModule({ + declarations: [ + AddDepositAddressComponent, + AppComponent, + BackupComponent, + BlockchainComponent, + BuyComponent, + ButtonComponent, + ChangeNameComponent, + CreateWalletComponent, + DateFromNowPipe, + DateTimePipe, + HeaderComponent, + NetworkComponent, + OutputsComponent, + PendingTransactionsComponent, + QrCodeComponent, + SendCoinsComponent, + TellerStatusPipe, + TopBarComponent, + TransactionDetailComponent, + TransactionListComponent, + WalletsComponent, + NavBarComponent, + WalletDetailComponent, + ModalComponent, + OnboardingCreateWalletComponent, + OnboardingEncryptWalletComponent, + DoubleButtonComponent, + PasswordDialogComponent, + SeedModalComponent, + OnboardingComponent, + DontsavepasswordDirective, + SendVerifyComponent, + TransactionInfoComponent, + SendCoinsFormComponent, + LoadingContentComponent, + NumberOfAddressesComponent, + SelectAddressComponent, + CreateWalletFormComponent, + ResetPasswordComponent, + ExchangeComponent, + ExchangeCreateComponent, + ExchangeStatusComponent, + HwOptionsDialogComponent, + HwWipeDialogComponent, + HwAddedDialogComponent, + HwGenerateSeedDialogComponent, + HwBackupDialogComponent, + ConfirmationComponent, + HwMessageComponent, + HwPinDialogComponent, + HwChangePinDialogComponent, + HwPinHelpDialogComponent, + HwRestoreSeedDialogComponent, + HwDialogBaseComponent, + HwConfirmTxDialogComponent, + HwConfirmAddressDialogComponent, + SelectLanguageComponent, + ExchangeHistoryComponent, + CommonTextPipe, + AmountPipe, + HwRemovePinDialogComponent, + HwUpdateFirmwareDialogComponent, + HwUpdateAlertDialogComponent, + ChangeNoteComponent, + MsgBarComponent, + SeedWordDialogComponent, + MultipleDestinationsDialogComponent, + FormSourceSelectionComponent, + FormDestinationComponent, + CopyRawTxComponent, + SignRawTxComponent, + BroadcastRawTxComponent, + OfflineDialogsBaseComponent, + ArrowLinkComponent, + WalletOptionsComponent, + QrCodeButtonComponent, + AddressHistoryComponent, + GetNextAddressComponent, + SelectCoinOverlayComponent, + SelectCoinComponent, + MainColorFormElementDirective, + ColorImageDirective, + ThemeColorTextDirective, + AssistedSeedFieldComponent, + SelectConfirmationsComponent, + FormFieldErrorDirective, + ], + imports: [ + AppTranslationModule, + AppRoutingModule, + BrowserModule, + HttpClientModule, + MatButtonModule, + MatCardModule, + MatDialogModule, + MatExpansionModule, + MatGridListModule, + MatIconModule, + MatInputModule, + MatListModule, + MatMenuModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatSelectModule, + MatTabsModule, + MatToolbarModule, + MatTooltipModule, + MatCheckboxModule, + MatSliderModule, + MatAutocompleteModule, + NoopAnimationsModule, + ReactiveFormsModule, + ], + providers: [ + FiberApiService, + BlockchainService, + ExchangeService, + NavBarSwitchService, + NetworkService, + PriceService, + PurchaseService, + WizardGuardService, + HwWalletService, + Bip39WordListService, + HwWalletDaemonService, + HwWalletPinService, + HwWalletSeedWordService, + LanguageService, + StorageService, + MsgBarService, + DecimalPipe, + WalletsAndAddressesService, + SoftwareWalletService, + HardwareWalletService, + BalanceAndOutputsService, + SpendingService, + HistoryService, + CoinService, + AppUpdateService, + NodeService, + WalletUtilsService, + OperatorService, + BtcApiService, + EthApiService, + BlockbookApiService, + { + provide: MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS, + useValue: { + _forceAnimations: true, + }, + }, + ], + bootstrap: [AppComponent], +}) +export class AppModule { } diff --git a/src/gui/static/src/app/app.theme.scss b/src/gui/static/src/app/app.theme.scss new file mode 100644 index 0000000..a823f8e --- /dev/null +++ b/src/gui/static/src/app/app.theme.scss @@ -0,0 +1,83 @@ +@import '~@angular/material/theming'; +// Plus imports for other components in your app. + +// Include the common styles for Angular Material. We include this here so that you only +// have to load a single css file for Angular Material in your app. +// Be sure that you only ever include this mixin once! +@include mat-core(); + +// Define the palettes for your theme using the Material Design palettes available in palette.scss +// (imported above). For each palette, you can optionally specify a default, lighter, and darker +// hue. + +$mat-skycoin-primary: ( + 100: white, + 500: white, + contrast: ( + 100: white, + 500: white, + ) +); + +$mat-skycoin-accent: ( + 500: white, + contrast: ( + 500: white + ) +); + +$candy-app-primary: mat-palette($mat-skycoin-primary, 500, 100, 500); +$candy-app-accent: mat-palette($mat-skycoin-accent, 500, 500, 500); + +// The warn palette is optional (defaults to red). +$candy-app-warn: mat-palette($mat-red); + +// Create the theme object (a Sass map containing all of the palettes). +$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn); + +// Include theme styles for core and each component used in your app. +// Alternatively, you can import and @include the theme mixins for each component +// that you are using. +@include angular-material-theme($candy-app-theme); + +$mat-light-button-primary: ( + 100: #777, + 500: #777, + contrast: ( + 100: #777, + 500: #777, + ) +); + +$light-button-primary: mat-palette($mat-light-button-primary); +$light-button-theme: mat-light-theme($light-button-primary, $candy-app-accent); + +.light-button-theme { + @include angular-material-theme($light-button-theme); +} + +$mat-very-light-button-primary: ( + 100: white, + 500: white, + contrast: ( + 100: white, + 500: white, + ) +); + +$mat-very-light-button-accent: ( + 100: #cccccc, + 500: #cccccc, + contrast: ( + 100: #cccccc, + 500: #cccccc, + ) +); + +$very-light-button-primary: mat-palette($mat-very-light-button-primary); +$very-light-button-accent: mat-palette($mat-very-light-button-accent); +$very-light-button-theme: mat-light-theme($very-light-button-primary, $very-light-button-accent); + +.very-light-button-theme { + @include angular-material-theme($very-light-button-theme); +} diff --git a/src/gui/static/src/app/coins/btc.coin.ts b/src/gui/static/src/app/coins/btc.coin.ts new file mode 100644 index 0000000..733529b --- /dev/null +++ b/src/gui/static/src/app/coins/btc.coin.ts @@ -0,0 +1,35 @@ +import { Coin } from './coin'; +import { CoinTypes } from './settings/coin-types'; +import { BtcCoinConfig } from './coin-type-configs/btc.coin-config'; +import { SkywalletSupportedCoinTypes } from './settings/skywallet-supported-coin-types'; +import { CoinStyleBase } from './settings/coin-style-base'; + +export class BtcCoin extends Coin { + coinType = CoinTypes.BTC; + devOnly = true; + isLocal = false; + nodeUrl = '/local-btc'; + indexerUrl = '/local-blockbook'; + coinName = 'Bitcoin'; + coinSymbol = 'BTC'; + feePaymentCoinUnit = 'sats'; + uriSpecificatioPrefix = 'bitcoin'; + priceTickerId = 'btc-bitcoin'; + assetsFolderName = 'bitcoin'; + normalConfirmationsNeeded = 3; + skywalletCoinType = SkywalletSupportedCoinTypes.BTC; + config = new BtcCoinConfig(); + styleConfig = new CoinStyleBase(); + + constructor() { + super(); + + this.styleConfig.mainColor = '#ff7600'; + this.styleConfig.gradientDark = '#ff7600'; + this.styleConfig.gradientLight = '#ff9900'; + this.styleConfig.onboardingGradientDark = '#ff6a00'; + this.styleConfig.onboardingGradientLight = '#ff8d00'; + + this.styleConfig.mainColorImagesFilter = 'invert(55%) sepia(72%) saturate(3833%) hue-rotate(1deg) brightness(103%) contrast(104%)'; + } +} diff --git a/src/gui/static/src/app/coins/coin-type-configs/btc.coin-config.ts b/src/gui/static/src/app/coins/coin-type-configs/btc.coin-config.ts new file mode 100644 index 0000000..c347bbc --- /dev/null +++ b/src/gui/static/src/app/coins/coin-type-configs/btc.coin-config.ts @@ -0,0 +1,36 @@ +import BigNumber from 'bignumber.js'; + +/** + * Configuration for all coins with the CoinTypes.BTC type. It includes default values for + * each property. + */ +export class BtcCoinConfig { + /** + * Max number of decimals in which each coin can be divided. + */ + decimals = 8; + /** + * How many coins the miners get per block before the first halving. + */ + initialMiningReward = 50; + /** + * Numbers of blocks which must be mined for a halving to occur. + */ + halvingBlocks = 210000; + /** + * How old, in minutes, the last block known by the node can be before the app starts + * considering the blockchain to be out of sync. + */ + outOfSyncMinutes = 90; + /** + * Max amount of coins that will be created + */ + totalSupply = 21000000; + /** + * Minimum fee (in sats per byte) the node accepts. In Bitcoin Core it is the value of the + * -minrelaytxfee param multiplied by 100,000. IMPORTANT: as the code may calculate a size + * different than the one the node will take into account, it is recommended to use a value + * greater than the one set in the node. + */ + minFee = new BigNumber(1.5); +} diff --git a/src/gui/static/src/app/coins/coin-type-configs/eth.coin-config.ts b/src/gui/static/src/app/coins/coin-type-configs/eth.coin-config.ts new file mode 100644 index 0000000..32166a2 --- /dev/null +++ b/src/gui/static/src/app/coins/coin-type-configs/eth.coin-config.ts @@ -0,0 +1,24 @@ +import BigNumber from 'bignumber.js'; + +/** + * Configuration for all coins with the CoinTypes.ETH type. It includes default values for + * each property. + */ +export class EthCoinConfig { + /** + * Max number of decimals in which each coin can be divided. + */ + decimals = 18; + /** + * ID of the blockchain. + */ + chainId = '1'; + /** + * Minimum fee (in Gwei per gas) the node accepts. + */ + minFee = new BigNumber(0.001); + + constructor(chainId: string) { + this.chainId = chainId; + } +} diff --git a/src/gui/static/src/app/coins/coin.ts b/src/gui/static/src/app/coins/coin.ts new file mode 100644 index 0000000..1e326db --- /dev/null +++ b/src/gui/static/src/app/coins/coin.ts @@ -0,0 +1,126 @@ +import { CoinTypes } from './settings/coin-types'; +import { SkywalletSupportedCoinTypes } from './settings/skywallet-supported-coin-types'; +import { CoinTypeFeatures } from './features/coin-type-features'; +import { FiberFeatures } from './features/fiber-features'; +import { BtcFeatures } from './features/btc-features'; +import { EthFeatures } from './features/eth-features'; +import { CoinStyleBase } from './settings/coin-style-base'; + +/** + * Base class with the properties of the coins this wallet can work with. + */ +export abstract class Coin { + /** + * The type of the coin. + */ + abstract coinType: CoinTypes; + /** + * If true, the coin will not be available in production builds. + */ + abstract devOnly: boolean; + /** + * Set to true if the local node is the one which must manage the software wallets. A max of + * one coin can be managed by the local node. + */ + abstract isLocal: boolean; + /** + * URL of the remote node which must be used for this coin. Only if isLocal is false. + */ + nodeUrl: string; + /** + * URL of the Blockbook instance which must be used for this coin, if it is applicable. + */ + indexerUrl: string; + /** + * Name of the coin. Must be unique, as it is used as ID. + */ + abstract coinName: string; + /** + * Small name of the coin, like SKY for Skycoin. + */ + abstract coinSymbol: string; + /** + * Name of the unit in which the transaction fees are paid. For Bitcoin it would be "sats", + * and "gwei" for Ethereum. Only if the fees are paid in coins and not hours. + */ + feePaymentCoinUnit: string; + /** + * Name of the coin hours, if the coin uses them. + */ + hoursName: string; + /** + * Singular form of the name of the coin hours, if the coin uses them. + */ + hoursNameSingular: string; + /** + * This wallet uses the Skycoin URI Specification and BIP-21 when creating QR codes and + * requesting coins. This variable defines the prefix that will be used for creating QR codes + * and URLs. IT MUST BE UNIQUE FOR EACH COIN. + */ + abstract uriSpecificatioPrefix: string; + /** + * ID of the coin on the coin price service. If null, the wallet will not show the USD price. + */ + priceTickerId: string; + /** + * URL for accessing the blockchain explorer. + */ + explorerUrl: string; + /** + * Name of the folder with the assets for the coin. The folder must be inside src/assets/coins. + */ + abstract assetsFolderName: string; + /** + * If the assets folder includes a "gradient.png" file to be used as an overlay in the header. + */ + headerHasGradient = true; + /** + * How many confirmations a transaction must normally have to be considered final, without + * taking into account the selections made by the user. Must be at least 1. + */ + abstract normalConfirmationsNeeded: number; + /** + * The type identifying how the Skywallet should work with this coin. If not set, the + * compatibility with the Skywallet is deactivated. + */ + skywalletCoinType: SkywalletSupportedCoinTypes; + /** + * Configuration for the coin. Take into account that this param must have an object + * corresponding to the selected coin type. For example, if coinType === CoinTypes.BTC, then + * this property must have an instance of BtcCoinConfig. + */ + config: any; + /** + * Styling configuration for the coin. + */ + abstract styleConfig: CoinStyleBase; + + + /*************************************************** + * + * The following properties don't have to be added in subclasses when creating a new coin. + * + ***************************************************/ + + /** + * How many confirmations a transaction must have to be considered final, as selected by + * the user. + */ + confirmationsNeeded: number; + + /** + * Returns an object indicating which features of the app or general properties are compatible + * and/or valid for all the coins with the type this coin has. + */ + get coinTypeFeatures(): CoinTypeFeatures { + if (this.coinType === CoinTypes.Fiber) { + return new FiberFeatures(); + } else if (this.coinType === CoinTypes.BTC) { + return new BtcFeatures(); + } else if (this.coinType === CoinTypes.ETH) { + return new EthFeatures(); + } + + return null; + } +} diff --git a/src/gui/static/src/app/coins/eth.coin.ts b/src/gui/static/src/app/coins/eth.coin.ts new file mode 100644 index 0000000..89c63c0 --- /dev/null +++ b/src/gui/static/src/app/coins/eth.coin.ts @@ -0,0 +1,21 @@ +import { Coin } from './coin'; +import { CoinTypes } from './settings/coin-types'; +import { EthCoinConfig } from './coin-type-configs/eth.coin-config'; +import { CoinStyleBase } from './settings/coin-style-base'; + +export class EthCoin extends Coin { + coinType = CoinTypes.ETH; + devOnly = true; + isLocal = false; + nodeUrl = '/local-eth'; + indexerUrl = '/local-blockbook'; + coinName = 'Ethereum'; + coinSymbol = 'ETH'; + feePaymentCoinUnit = 'gwei'; + uriSpecificatioPrefix = 'ethereum'; + priceTickerId = 'eth-ethereum'; + assetsFolderName = 'ethereum'; + normalConfirmationsNeeded = 30; + config = new EthCoinConfig('32576'); + styleConfig = new CoinStyleBase(); +} diff --git a/src/gui/static/src/app/coins/features/btc-features.ts b/src/gui/static/src/app/coins/features/btc-features.ts new file mode 100644 index 0000000..acb838d --- /dev/null +++ b/src/gui/static/src/app/coins/features/btc-features.ts @@ -0,0 +1,14 @@ +import { CoinTypeFeatures } from './coin-type-features'; + +export class BtcFeatures implements CoinTypeFeatures { + softwareWallets = false; + legacySoftwareWallets = false; + bip44SoftwareWallets = false; + xPubSoftwareWallets = false; + outputs = true; + networkingStats = false; + blockchainSyncProgress = false; + showAllPendingTransactions = false; + coinHours = false; + limitedSendingOptions = false; +} diff --git a/src/gui/static/src/app/coins/features/coin-type-features.ts b/src/gui/static/src/app/coins/features/coin-type-features.ts new file mode 100644 index 0000000..a77dc15 --- /dev/null +++ b/src/gui/static/src/app/coins/features/coin-type-features.ts @@ -0,0 +1,48 @@ +/** + * Indicates which features of the app or general properties are compatible and/or valid for all + * the coins of a specific type. + */ +export interface CoinTypeFeatures { + /** + * If the app can manage any type of software wallets for the coin type. + */ + softwareWallets: boolean; + /** + * If the app can manage legacy software wallets for the coin type. + */ + legacySoftwareWallets: boolean; + /** + * If the app can manage bip44 software wallets for the coin type. + */ + bip44SoftwareWallets: boolean; + /** + * If the app can manage xpub software wallets for the coin type. + */ + xPubSoftwareWallets: boolean; + /** + * If the coin type uses outputs for managing the balances. + */ + outputs: boolean; + /** + * If the app can show network stats for the coin type. + */ + networkingStats: boolean; + /** + * If the app can show information about the progress while the backend is synchronizing. + */ + blockchainSyncProgress: boolean; + /** + * If the app can show all the pending transactions and not only the ones related to + * the user wallets. + */ + showAllPendingTransactions: boolean; + /** + * If the coin type generates coin hours. + */ + coinHours: boolean; + /** + * If the coin only allows to send transactions to a single destination and does not allow + * to select the change address. + */ + limitedSendingOptions: boolean; +} diff --git a/src/gui/static/src/app/coins/features/eth-features.ts b/src/gui/static/src/app/coins/features/eth-features.ts new file mode 100644 index 0000000..b07b803 --- /dev/null +++ b/src/gui/static/src/app/coins/features/eth-features.ts @@ -0,0 +1,14 @@ +import { CoinTypeFeatures } from './coin-type-features'; + +export class EthFeatures implements CoinTypeFeatures { + softwareWallets = false; + legacySoftwareWallets = false; + bip44SoftwareWallets = false; + xPubSoftwareWallets = false; + outputs = false; + networkingStats = false; + blockchainSyncProgress = true; + showAllPendingTransactions = false; + coinHours = false; + limitedSendingOptions = true; +} diff --git a/src/gui/static/src/app/coins/features/fiber-features.ts b/src/gui/static/src/app/coins/features/fiber-features.ts new file mode 100644 index 0000000..8081822 --- /dev/null +++ b/src/gui/static/src/app/coins/features/fiber-features.ts @@ -0,0 +1,14 @@ +import { CoinTypeFeatures } from './coin-type-features'; + +export class FiberFeatures implements CoinTypeFeatures { + softwareWallets = true; + legacySoftwareWallets = true; + bip44SoftwareWallets = true; + xPubSoftwareWallets = true; + outputs = true; + networkingStats = true; + blockchainSyncProgress = true; + showAllPendingTransactions = true; + coinHours = true; + limitedSendingOptions = false; +} diff --git a/src/gui/static/src/app/coins/settings/coin-style-base.ts b/src/gui/static/src/app/coins/settings/coin-style-base.ts new file mode 100644 index 0000000..9e3f5ff --- /dev/null +++ b/src/gui/static/src/app/coins/settings/coin-style-base.ts @@ -0,0 +1,31 @@ +/** + * Base class with the configurations for customizing the colors of some UI elements when a + * specific coin is selected. Each property must be set to a valid css color value. + */ +export class CoinStyleBase { + // Main color, used for links and some other UI elements. Blue for Skycoin. + mainColor = '#0072ff'; + // Secondary color, used in some icons. Yellow for Skycoin. + secondaryColor = '#ffc125'; + + // Filters used to make the base black icons have the main and secondary colors of the coin. + // Must have valid values for the "filter" css property, without the ";" at the end. + // You can use utilities like https://codepen.io/sosuke/pen/Pjoqqp to get the correct filter. + mainColorImagesFilter = 'invert(26%) sepia(98%) saturate(3197%) hue-rotate(206deg) brightness(105%) contrast(104%)'; + secondaryColorImagesFilter = 'invert(84%) sepia(24%) saturate(2995%) hue-rotate(338deg) brightness(106%) contrast(101%)'; + + // Colors for the app gradients, used as background on the wizard and some buttons. + gradientDark = '#0072ff'; + gradientLight = '#00C3ff'; + onboardingGradientDark = '#0072ff'; + onboardingGradientLight = '#00C3ff'; + + // Color of the texts shown on the app header. + headerTextColor = '#fff'; + // Color for the small background shown behind the available hours and synchronization + // progress indicator, in the app header. + headerHoursBackgroundColor = 'rgba(255, 255, 255, 0.3)'; + // Color for texts with the available hours and synchronization progress indicator, in + // the app header. + headerHoursTextColor = '#000'; +} diff --git a/src/gui/static/src/app/coins/settings/coin-types.ts b/src/gui/static/src/app/coins/settings/coin-types.ts new file mode 100644 index 0000000..a2ab137 --- /dev/null +++ b/src/gui/static/src/app/coins/settings/coin-types.ts @@ -0,0 +1,17 @@ +/** + * Enums the coin types which are compatible with this app. + */ +export enum CoinTypes { + /** + * Coins based on the core Skycoin blockchain technology. + */ + Fiber = 'Fiber', + /** + * Bitcoin-like coins. + */ + BTC = 'BTC', + /** + * Ethereum-like coins. + */ + ETH = 'ETH', +} diff --git a/src/gui/static/src/app/coins/settings/skywallet-supported-coin-types.ts b/src/gui/static/src/app/coins/settings/skywallet-supported-coin-types.ts new file mode 100644 index 0000000..b243542 --- /dev/null +++ b/src/gui/static/src/app/coins/settings/skywallet-supported-coin-types.ts @@ -0,0 +1,13 @@ +/** + * Enums the coin types which are compatible with the Skywallet. + */ +export enum SkywalletSupportedCoinTypes { + /** + * Coins based on the core Skycoin blockchain technology. + */ + SKY = 'SKY', + /** + * Bitcoin-like coins. + */ + BTC = 'BTC', +} diff --git a/src/gui/static/src/app/coins/skycoin.coin.ts b/src/gui/static/src/app/coins/skycoin.coin.ts new file mode 100644 index 0000000..620535a --- /dev/null +++ b/src/gui/static/src/app/coins/skycoin.coin.ts @@ -0,0 +1,23 @@ +import { Coin } from './coin'; +import { environment } from '../../environments/environment'; +import { CoinTypes } from './settings/coin-types'; +import { SkywalletSupportedCoinTypes } from './settings/skywallet-supported-coin-types'; +import { CoinStyleBase } from './settings/coin-style-base'; + +export class SkycoinCoin extends Coin { + coinType = CoinTypes.Fiber; + devOnly = false; + isLocal = true; + nodeUrl = environment.nodeUrl; + coinName = 'Skycoin'; + coinSymbol = 'SKY'; + hoursName = 'Coin Hours'; + hoursNameSingular = 'Coin Hour'; + uriSpecificatioPrefix = 'skycoin'; + priceTickerId = 'sky-skycoin'; + explorerUrl = 'https://explorer.skycoin.com'; + assetsFolderName = 'skycoin'; + normalConfirmationsNeeded = 1; + skywalletCoinType = SkywalletSupportedCoinTypes.SKY; + styleConfig = new CoinStyleBase(); +} diff --git a/src/gui/static/src/app/coins/test.coin.ts b/src/gui/static/src/app/coins/test.coin.ts new file mode 100644 index 0000000..ad28ceb --- /dev/null +++ b/src/gui/static/src/app/coins/test.coin.ts @@ -0,0 +1,23 @@ +import { Coin } from './coin'; +import { environment } from '../../environments/environment'; +import { CoinTypes } from './settings/coin-types'; +import { SkywalletSupportedCoinTypes } from './settings/skywallet-supported-coin-types'; +import { CoinStyleBase } from './settings/coin-style-base'; + +export class TestCoin extends Coin { + coinType = CoinTypes.Fiber; + devOnly = true; + isLocal = false; + nodeUrl = environment.nodeUrl; + coinName = 'Testcoin'; + coinSymbol = 'TST'; + hoursName = 'Test Hours'; + hoursNameSingular = 'Test Hour'; + uriSpecificatioPrefix = 'testcoin'; + priceTickerId = 'btc-bitcoin'; + explorerUrl = 'https://explorer.testcoin.net'; + assetsFolderName = 'testcoin'; + normalConfirmationsNeeded = 1; + skywalletCoinType = SkywalletSupportedCoinTypes.SKY; + styleConfig = new CoinStyleBase(); +} diff --git a/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.html b/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.html new file mode 100644 index 0000000..fd33cbc --- /dev/null +++ b/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.html @@ -0,0 +1,9 @@ + + {{ text | translate }} + {{ pointForward ? 'keyboard_arrow_right' : (pointDown ? 'keyboard_arrow_down' : 'keyboard_arrow_up') }} + + + + {{ text | translate }} + {{ pointForward ? 'keyboard_arrow_right' : (pointDown ? 'keyboard_arrow_down' : 'keyboard_arrow_up') }} + diff --git a/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.scss b/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.scss new file mode 100644 index 0000000..35d247c --- /dev/null +++ b/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.scss @@ -0,0 +1,16 @@ +@import '../../../../theme/variables'; + +.white-text { + color: $white !important; +} + +span { + padding-left: 5px; + + mat-icon { + padding: 0; + display: inline; + vertical-align: middle; + font-size: 13px; + } +} diff --git a/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.ts b/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.ts new file mode 100644 index 0000000..e45ab14 --- /dev/null +++ b/src/gui/static/src/app/components/layout/arrow-link/arrow-link.component.ts @@ -0,0 +1,30 @@ +import { Component, Input, Output, EventEmitter, OnDestroy } from '@angular/core'; + +/** + * Shows a link-like text with an arrow at the right. Used for showing more options or a list. + */ +@Component({ + selector: 'app-arrow-link', + templateUrl: 'arrow-link.component.html', + styleUrls: ['arrow-link.component.scss'], +}) +export class ArrowLinkComponent implements OnDestroy { + // Removes the padding at the left. + @Input() noPadding = false; + // Makes the arrow at the right to point up (false) or down (true). + @Input() pointDown = true; + // If true, the arrow will always point forward. + @Input() pointForward = false; + // If the link must be white. + @Input() whiteText: boolean; + @Input() text = ''; + @Output() pressed = new EventEmitter(); + + onClick(event) { + this.pressed.emit(event); + } + + ngOnDestroy() { + this.pressed.complete(); + } +} diff --git a/src/gui/static/src/app/components/layout/button/button.component.html b/src/gui/static/src/app/components/layout/button/button.component.html new file mode 100644 index 0000000..84ec58e --- /dev/null +++ b/src/gui/static/src/app/components/layout/button/button.component.html @@ -0,0 +1,18 @@ +
+ +
diff --git a/src/gui/static/src/app/components/layout/button/button.component.scss b/src/gui/static/src/app/components/layout/button/button.component.scss new file mode 100644 index 0000000..e91faba --- /dev/null +++ b/src/gui/static/src/app/components/layout/button/button.component.scss @@ -0,0 +1,65 @@ +@import '../../../../theme/variables'; + +$button-height: 50px; + +// Class also used by the parents. +.internal-container { + display: inline; +} + +button { + border-radius: 1000px; + height: $button-height; + margin: 20px 10px 0; + width: 170px; + overflow: hidden; +} + +/* Default button color. */ +button.enabled { + background-color: $grey-very-light; + box-shadow: none; + color: $black; +} + +/* 2 lines max. Content centered. */ +.content-container { + display: flex; + align-items: center; + max-height: 100%; + justify-content: center; + + .content { + flex-grow: 0; + overflow: hidden; + white-space: normal; + line-height: $font-size-standard-plus * 1.3; + font-size: $font-size-standard-plus; + max-height: min(($font-size-standard-plus * 1.3) * 2, $button-height); + word-break: break-word; + } + + mat-icon { + flex-shrink: 0; + margin-left: 10px; + opacity: 0.3; + line-height: 20px; + } + + mat-spinner { + flex-shrink: 0; + margin-left: 10px; + height: 18px !important; + width: 18px !important; + + ::ng-deep svg { + height: 18px !important; + width: 18px !important; + } + } + + .white-spinner ::ng-deep circle { + stroke: white; + opacity: 0.5; + } +} diff --git a/src/gui/static/src/app/components/layout/button/button.component.ts b/src/gui/static/src/app/components/layout/button/button.component.ts new file mode 100644 index 0000000..b49bbca --- /dev/null +++ b/src/gui/static/src/app/components/layout/button/button.component.ts @@ -0,0 +1,142 @@ +import { Component, EventEmitter, Input, Output, ViewChild, OnDestroy, Renderer2, AfterViewInit } from '@angular/core'; +import { SubscriptionLike } from 'rxjs'; + +import { CoinService } from '../../../services/coin.service'; +import { MatButton } from '@angular/material/button'; + +enum ButtonStates { + Normal = 'Normal', + Loading = 'Loading', + Success = 'Success', +} + +/** + * Normal rounded button used in most parts of the app. + */ +@Component({ + selector: 'app-button', + templateUrl: 'button.component.html', + styleUrls: ['button.component.scss'], +}) +export class ButtonComponent implements AfterViewInit, OnDestroy { + // If true, the button is shown with the main gradiend as background. + private useMainGradientInternal = false; + @Input() set useMainGradient(val: boolean) { + this.useMainGradientInternal = val; + this.updateStyle(); + } + get useMainGradient(): boolean { + return this.useMainGradientInternal; + } + + // Disables the button. + private disabledInternal = false; + @Input() set disabled(val: boolean) { + this.disabledInternal = val; + this.updateStyle(); + } + get disabled(): boolean { + return this.disabledInternal; + } + + // If true, the button will send click events even when disabled. + @Input() forceEmitEvents = false; + // Click event. + @Output() action = new EventEmitter(); + @ViewChild('button') button: MatButton; + + state = ButtonStates.Normal; + buttonStates = ButtonStates; + + // Colors of the main gradient than can be used as background. + private gradientColor1 = ''; + private gradientColor2 = ''; + private subscription: SubscriptionLike; + + constructor( + coinService: CoinService, + private renderer: Renderer2, + ) { + // Get the main colors. + this.subscription = coinService.currentCoin.subscribe(coin => { + this.gradientColor1 = coin.styleConfig.gradientDark; + this.gradientColor2 = coin.styleConfig.gradientLight; + this.updateStyle(); + }); + } + + ngAfterViewInit() { + this.updateStyle(); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + this.action.complete(); + } + + onClick() { + if (!this.disabled || this.forceEmitEvents) { + this.action.emit(); + } + } + + /** + * Focuses the button. + */ + focus() { + this.button.focus(); + } + + /** + * Shows the loading animation. The button does not send click events while the + * animation is active. + */ + setLoading() { + this.state = ButtonStates.Loading; + } + + /** + * Shows the success icon. + */ + setSuccess() { + this.state = ButtonStates.Success; + setTimeout(() => this.state = ButtonStates.Normal, 3000); + } + + setDisabled() { + this.disabled = true; + } + + setEnabled() { + this.disabled = false; + } + + isLoading(): boolean { + return this.state === ButtonStates.Loading; + } + + /** + * Removes the icons and animations, but does not affects the enabled/disabled status. + * @returns The currents instance is returned to make it easier to concatenate function calls. + */ + resetState() { + this.state = ButtonStates.Normal; + + return this; + } + + // Updates the style color. + private updateStyle() { + if (this.button) { + if (this.useMainGradientInternal && !this.disabled) { + // Show the main gradient as background. + this.renderer.setStyle(this.button._elementRef.nativeElement, 'background', 'linear-gradient(to bottom right, ' + this.gradientColor1 + ', ' + this.gradientColor2 + ')'); + this.renderer.setStyle(this.button._elementRef.nativeElement, 'color', 'white'); + } else { + // Show the standard background. + this.renderer.setStyle(this.button._elementRef.nativeElement, 'background', null); + this.renderer.setStyle(this.button._elementRef.nativeElement, 'color', null); + } + } + } +} diff --git a/src/gui/static/src/app/components/layout/confirmation/confirmation.component.html b/src/gui/static/src/app/components/layout/confirmation/confirmation.component.html new file mode 100644 index 0000000..eb98c07 --- /dev/null +++ b/src/gui/static/src/app/components/layout/confirmation/confirmation.component.html @@ -0,0 +1,23 @@ + + {{ data.text | translate }} + {{ data.linkText | translate }} + +
+ {{ data.checkboxText | translate }} + +
+ +
+ + {{ data.cancelButtonText | translate }} + + + {{ data.confirmButtonText | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/confirmation/confirmation.component.scss b/src/gui/static/src/app/components/layout/confirmation/confirmation.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/confirmation/confirmation.component.ts b/src/gui/static/src/app/components/layout/confirmation/confirmation.component.ts new file mode 100644 index 0000000..7fe0466 --- /dev/null +++ b/src/gui/static/src/app/components/layout/confirmation/confirmation.component.ts @@ -0,0 +1,127 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +/** + * Predefined button combinations for ConfirmationComponent. + */ +export enum DefaultConfirmationButtons { + YesNo = 'YesNo', + ContinueCancel = 'ContinueCancel', + Close = 'Close', +} + +/** + * Settings for ConfirmationComponent. + */ +export interface ConfirmationParams { + /** + * Main text the modal window will show. + */ + text: string; + /** + * Custom title for the modal window. + */ + headerText?: string; + /** + * If set, the modal window will show a check box the user will have to acept before being able + * to press the confirmation button. + */ + checkboxText?: string; + /** + * Default buttons combination the modal window will show. If set, you will not be able to set + * custom texts for the buttons. + */ + defaultButtons?: DefaultConfirmationButtons; + /** + * Text for the confirmation button. If unset, the button is not shown. + */ + confirmButtonText?: string; + /** + * Text for the cancel button. If unset, the button is not shown. + */ + cancelButtonText?: string; + /** + * If true, the title of the modal window will be red. + */ + redTitle?: boolean; + /** + * If true, the user will be forced to close the modal window using the confirm or cancel button. + */ + disableDismiss?: boolean; + /** + * If set, the modal window will show the link under the main text. + */ + linkText?: string; + /** + * Function that will be called when the user clicks the link. + */ + linkFunction?(): void; +} + +/** + * Modal window used to ask the user to confirm an operation. If the user confirms the operation, + * the modal window is closed and "true" is returned in the "afterClosed" event. + */ +@Component({ + selector: 'app-confirmation', + templateUrl: './confirmation.component.html', + styleUrls: ['./confirmation.component.scss'], +}) +export class ConfirmationComponent { + // If the user checked the checkbox. + accepted = false; + disableDismiss = false; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, confirmationParams: ConfirmationParams): MatDialogRef { + const config = new MatDialogConfig(); + config.data = confirmationParams; + config.autoFocus = false; + config.width = '450px'; + + return dialog.open(ConfirmationComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: ConfirmationParams, + ) { + // Default header. + if (!data.headerText) { + data.headerText = 'confirmation.default-title'; + } + + // Use a default buttons combination, if requested. + if (data.defaultButtons) { + data.confirmButtonText = null; + data.cancelButtonText = null; + + if (data.defaultButtons === DefaultConfirmationButtons.Close) { + data.confirmButtonText = 'common.close-button'; + } + + if (data.defaultButtons === DefaultConfirmationButtons.YesNo) { + data.confirmButtonText = 'confirmation.yes-button'; + data.cancelButtonText = 'confirmation.no-button'; + } + + if (data.defaultButtons === DefaultConfirmationButtons.ContinueCancel) { + data.confirmButtonText = 'common.continue-button'; + data.cancelButtonText = 'common.cancel-button'; + } + } + + this.disableDismiss = !!data.disableDismiss; + } + + closeModal(isConfirmed: boolean) { + this.dialogRef.close(isConfirmed); + } + + // Used by the checkbox. + setAccept(event) { + this.accepted = event.checked ? true : false; + } +} diff --git a/src/gui/static/src/app/components/layout/double-button/double-button.component.html b/src/gui/static/src/app/components/layout/double-button/double-button.component.html new file mode 100644 index 0000000..83b30b2 --- /dev/null +++ b/src/gui/static/src/app/components/layout/double-button/double-button.component.html @@ -0,0 +1,14 @@ +
+ {{ leftButtonText }} + {{ rightButtonText }} +
diff --git a/src/gui/static/src/app/components/layout/double-button/double-button.component.scss b/src/gui/static/src/app/components/layout/double-button/double-button.component.scss new file mode 100644 index 0000000..1a12033 --- /dev/null +++ b/src/gui/static/src/app/components/layout/double-button/double-button.component.scss @@ -0,0 +1,81 @@ +@import '../../../../theme/variables'; + +.-small-button ::ng-deep button { + width: unset; + height: unset; + padding: 0 10px 0 10px; + min-width: 100px; + margin: unset; + box-shadow: unset; + background-color: transparent !important; + line-height: 1 !important; + min-height: 26px; + + span { + color: $black; + line-height: unset !important; + } + + .content-container { + .content { + font-size: $font-size-standard; + } + } +} + +.-small-button ::ng-deep button.enabled { + background-color: $black !important; + span { + color: $white; + } +} + +.-buttons-container { + width: fit-content; + padding: 5px; + background: $wizard-double-button-background; + border-radius: 100px; + margin: 0px auto; + font-size: 1px; +} + +.light { + &.-buttons-container { + background: $internal-double-button-background; + } + + .-small-button ::ng-deep button.enabled { + background-color: $white !important; + + span { + color: $black; + } + } +} + +@media (max-width: $max-sm-width) { + .-buttons-container.navbar.light { + border-radius: 20px; + + app-button ::ng-deep .internal-container { + display: block; + } + } +} + +.small { + &.-buttons-container { + padding: 2px; + } + + .-small-button ::ng-deep button { + min-width: 70px; + min-height: 16px; + + .content-container { + .content { + font-size: $font-size-micro; + } + } + } +} diff --git a/src/gui/static/src/app/components/layout/double-button/double-button.component.ts b/src/gui/static/src/app/components/layout/double-button/double-button.component.ts new file mode 100644 index 0000000..5029f99 --- /dev/null +++ b/src/gui/static/src/app/components/layout/double-button/double-button.component.ts @@ -0,0 +1,55 @@ +import { Component, EventEmitter, Input, Output, ViewEncapsulation, OnDestroy } from '@angular/core'; + +/** + * Identifies the active button of a DoubleButtonComponent. + */ +export enum DoubleButtonActive { + RightButton = 'RightButton', + LeftButton = 'LeftButton', +} + +/** + * Bar with 2 buttons, one active and other inactive. Used to select between two options. + */ +@Component({ + selector: 'app-double-button', + templateUrl: './double-button.component.html', + styleUrls: ['./double-button.component.scss'], + encapsulation: ViewEncapsulation.Emulated, +}) +export class DoubleButtonComponent implements OnDestroy { + @Input() rightButtonText: string; + @Input() leftButtonText: string; + @Input() activeButton: DoubleButtonActive; + // Allows to add classes to the component. + @Input() className = ''; + // If true, when the user clicks one of the buttons the newly selected button will not + // be selected automatically. Instead, the control will just send the event indicating the + // click and the "activeButton" property will have to be changed for the clicked button to + // be selected. + @Input() changeActiveButtonManually = false; + @Output() onStateChange = new EventEmitter(); + ButtonStates = DoubleButtonActive; + + ngOnDestroy() { + this.onStateChange.complete(); + } + + onRightButtonClicked() { + if (this.activeButton === DoubleButtonActive.LeftButton) { + if (!this.changeActiveButtonManually) { + this.activeButton = DoubleButtonActive.RightButton; + } + this.onStateChange.emit(DoubleButtonActive.RightButton); + } + } + + onLeftButtonClicked() { + if (this.activeButton === DoubleButtonActive.RightButton) { + if (!this.changeActiveButtonManually) { + this.activeButton = DoubleButtonActive.LeftButton; + } + this.onStateChange.emit(DoubleButtonActive.LeftButton); + } + } +} diff --git a/src/gui/static/src/app/components/layout/get-next-address/get-next-address.component.html b/src/gui/static/src/app/components/layout/get-next-address/get-next-address.component.html new file mode 100644 index 0000000..b96cffb --- /dev/null +++ b/src/gui/static/src/app/components/layout/get-next-address/get-next-address.component.html @@ -0,0 +1,3 @@ + + + diff --git a/src/gui/static/src/app/components/layout/get-next-address/get-next-address.component.scss b/src/gui/static/src/app/components/layout/get-next-address/get-next-address.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/get-next-address/get-next-address.component.ts b/src/gui/static/src/app/components/layout/get-next-address/get-next-address.component.ts new file mode 100644 index 0000000..d640a4f --- /dev/null +++ b/src/gui/static/src/app/components/layout/get-next-address/get-next-address.component.ts @@ -0,0 +1,133 @@ +import { Component, Inject, OnDestroy } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { SubscriptionLike, Observable } from 'rxjs'; + +import { AppConfig } from '../../../app.config'; +import { WalletBase, WalletTypes } from '../../../services/wallet-operations/wallet-objects'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; +import { PasswordSubmitEvent, PasswordDialogParams, PasswordDialogComponent } from '../password-dialog/password-dialog.component'; +import { processServiceError } from '../../../utils/errors'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { OperationError } from '../../../utils/operation-error'; +import { LastAddress } from '../../../services/coin-specific/wallets-and-addresses-operator'; + +/** + * Modal window used for getting the next external address of a wallet. + * After getting the address, the modal window is closed and the address string + * is returned in the "afterClosed" event. Does not work for deterministic addresses. + */ +@Component({ + selector: 'app-get-next-address', + templateUrl: './get-next-address.component.html', + styleUrls: ['./get-next-address.component.scss'], +}) +export class GetNextAddressComponent implements OnDestroy { + private passwordDialogRef: MatDialogRef; + private operationCompleted = false; + private operationSubscription: SubscriptionLike; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, wallet: WalletBase): MatDialogRef { + const config = new MatDialogConfig(); + config.data = wallet; + config.autoFocus = false; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(GetNextAddressComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: WalletBase, + private walletsAndAddressesService: WalletsAndAddressesService, + private dialog: MatDialog, + private msgBarService: MsgBarService, + ) { + if (data.walletType === WalletTypes.Deterministic) { + this.dialogRef.close(); + } else { + this.loadWalletAddress(); + } + } + + ngOnDestroy() { + this.removeOperationSubscription(); + } + + /** + * Loads the next address of the wallet. If the last address of the wallet has already + * been used, it automatically asks for the password and creates a new address. + * @param passwordSubmitEvent Event of the modal window used for asking the user for + * the password. Should not be provided, it is used internally. + * @param avoidCreating If true, the function will not try to create a new address if the + * last one has already been used. Should not be provided, it is used internally. + */ + private loadWalletAddress(passwordSubmitEvent?: PasswordSubmitEvent, avoidCreating?: boolean) { + this.removeOperationSubscription(); + + const password = passwordSubmitEvent ? passwordSubmitEvent.password : null; + + let operation: Observable; + if (!avoidCreating) { + operation = this.walletsAndAddressesService.getNextAddressAndUpdateWallet(this.data, password); + } else { + operation = this.walletsAndAddressesService.getLastAddressAndUpdateWallet(this.data, true); + } + + // Get the address. + this.operationSubscription = operation.subscribe(response => { + // The service returns null if the wallet is encrypted, a new address must be created and + // no password was provided, so the password must be requested. + if (!response && this.data.encrypted && !passwordSubmitEvent) { + const params: PasswordDialogParams = { + wallet: this.data, + description: 'get-address.password-info', + }; + this.passwordDialogRef = PasswordDialogComponent.openDialog(this.dialog, params); + + this.passwordDialogRef.afterClosed().subscribe(() => { + // If the user closes the window without providing the password, skip the new + // address creation part. + if (!this.operationCompleted) { + this.loadWalletAddress(null, true); + } + }); + + this.passwordDialogRef.componentInstance.passwordSubmit.subscribe(eventData => { + // Repeat the operation, this time with the password. + this.loadWalletAddress(eventData); + }); + + return; + } + + // Close the password modal window, if any. + if (passwordSubmitEvent) { + passwordSubmitEvent.close(); + } + + // Return the address. + this.dialogRef.close(response.lastAddress); + + if (response.alreadyUsed) { + this.msgBarService.showWarning('get-address.used-address-warning'); + } + }, (err: OperationError) => { + if (passwordSubmitEvent) { + passwordSubmitEvent.error(err); + } else { + err = processServiceError(err); + this.msgBarService.showError(err); + this.dialogRef.close(); + } + }); + } + + private removeOperationSubscription() { + if (this.operationSubscription) { + this.operationSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.html new file mode 100644 index 0000000..4b5fe1a --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.html @@ -0,0 +1,48 @@ + + + + + + + + +
+ +
{{ 'hardware-wallet.added.added1' | translate }}
+
+
+ +
+
+
{{ 'hardware-wallet.added.characters-warning' | translate }}
+ +
{{ 'hardware-wallet.added.added2' | translate }}
+
+ +
+ + {{ (currentState === states.Finished ? 'common.continue-button' : 'common.close-button') | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.scss new file mode 100644 index 0000000..62b0af0 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.scss @@ -0,0 +1,11 @@ +@import '../../../../../theme/_variables.scss'; + +.upper-text { + margin-top: 10px; + margin-bottom: 10px; +} + +.warning { + margin: -20px 0 20px; + color: $grey; +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.ts new file mode 100644 index 0000000..8ed7beb --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-added-dialog/hw-added-dialog.component.ts @@ -0,0 +1,128 @@ +import { Component, Inject, OnDestroy, ViewChild, ElementRef } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog'; +import { FormGroup, FormBuilder } from '@angular/forms'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { ChildHwDialogParams } from '../hw-options-dialog/hw-options-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; +import { ChangeNameComponent, ChangeNameData } from '../../../pages/wallets/change-name/change-name.component'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { OperationError } from '../../../../utils/operation-error'; +import { processServiceError } from '../../../../utils/errors'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; +import { WalletBase } from '../../../../services/wallet-operations/wallet-objects'; +import { HardwareWalletService } from '../../../../services/wallet-operations/hardware-wallet.service'; +import { CreateWalletArgs } from '../../../../services/coin-specific/wallets-and-addresses-operator'; + +/** + * Modal window used to add a new device to the wallet list. This modal window was created + * for being oppenend by the hw wallet options modal window. + */ +@Component({ + selector: 'app-hw-added-dialog', + templateUrl: './hw-added-dialog.component.html', + styleUrls: ['./hw-added-dialog.component.scss'], +}) +export class HwAddedDialogComponent extends HwDialogBaseComponent implements OnDestroy { + @ViewChild('input') input: ElementRef; + wallet: WalletBase; + form: FormGroup; + maxHwWalletLabelLength = HwWalletService.maxLabelLength; + + // Vars with the validation error messages. + inputErrorMsg = ''; + + // Saves the initial label of the device, to know if the user tried to change it. + private initialLabel: string; + + constructor( + @Inject(MAT_DIALOG_DATA) private data: ChildHwDialogParams, + public dialogRef: MatDialogRef, + hwWalletService: HwWalletService, + private formBuilder: FormBuilder, + private dialog: MatDialog, + private msgBarService: MsgBarService, + private walletsAndAddressesService: WalletsAndAddressesService, + private hardwareWalletService: HardwareWalletService, + ) { + super(hwWalletService, dialogRef); + + const args: CreateWalletArgs = { + isHardwareWallet: true, + }; + + // Add the device to the wallets list. + this.operationSubscription = this.walletsAndAddressesService.createWallet(args).subscribe(wallet => { + // Update the security warnings. + this.operationSubscription = this.hardwareWalletService.getFeaturesAndUpdateData(wallet).subscribe(() => { + this.wallet = wallet; + this.initialLabel = wallet.label; + + this.form = this.formBuilder.group({ + label: [wallet.label], + }); + + this.form.setValidators(this.validateForm.bind(this)); + + this.currentState = this.states.Finished; + + // Request the data and state of the hw wallet options modal window to be refreshed. + this.data.requestOptionsComponentRefresh(); + + setTimeout(() => this.input.nativeElement.focus()); + }, err => this.processError(err)); + }, err => this.processError(err)); + } + + private processError(err: OperationError) { + err = processServiceError(err); + this.processHwOperationError(err); + + // Make the hw wallet options modal window show the error msg. + this.data.requestOptionsComponentRefresh(err.translatableErrorMsg); + } + + ngOnDestroy() { + super.ngOnDestroy(); + this.msgBarService.hide(); + } + + saveNameAndCloseModal() { + if (this.form.value.label === this.initialLabel) { + // If no change was made to the label, just close the window. + this.closeModal(); + } else { + this.msgBarService.hide(); + + // Open the appropiate component to change the device label. + const data = new ChangeNameData(); + data.wallet = this.wallet; + data.newName = this.form.value.label; + ChangeNameComponent.openDialog(this.dialog, data, true).afterClosed().subscribe(result => { + if (result && !result.errorMsg) { + this.closeModal(); + } else if (result && result.errorMsg) { + this.msgBarService.showError(result.errorMsg); + } + }); + } + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.inputErrorMsg = ''; + + let valid = true; + + if (!this.form.get('label').value) { + valid = false; + if (this.form.get('label').touched) { + this.inputErrorMsg = 'hardware-wallet.added.added-error-info'; + } + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component.html new file mode 100644 index 0000000..aa1a40c --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component.html @@ -0,0 +1,39 @@ + + +
+ + +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'common.continue-button' | translate }} + +
+
+ +
+ + + + + + + +
+ + {{ 'common.close-button' | translate }} + +
+
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component.ts new file mode 100644 index 0000000..a846dd1 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-backup-dialog/hw-backup-dialog.component.ts @@ -0,0 +1,41 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { ChildHwDialogParams } from '../hw-options-dialog/hw-options-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; + +/** + * Allows to create a backup of the seed of the device. This modal window was created for being + * oppenend by the hw wallet options modal window. + */ +@Component({ + selector: 'app-hw-backup-dialog', + templateUrl: './hw-backup-dialog.component.html', + styleUrls: ['./hw-backup-dialog.component.scss'], +}) +export class HwBackupDialogComponent extends HwDialogBaseComponent { + constructor( + @Inject(MAT_DIALOG_DATA) public data: ChildHwDialogParams, + public dialogRef: MatDialogRef, + private hwWalletService: HwWalletService, + ) { + super(hwWalletService, dialogRef); + } + + requestBackup() { + this.currentState = this.states.Processing; + + this.operationSubscription = this.hwWalletService.backup().subscribe( + () => { + this.showResult({ + text: 'hardware-wallet.general.completed', + icon: this.msgIcons.Success, + }); + // Request the hw wallet options modal window to refresh the security warnings. + this.data.requestOptionsComponentRefresh(null, true); + }, + err => this.processHwOperationError(err), + ); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component.html new file mode 100644 index 0000000..c0a3ca3 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component.html @@ -0,0 +1,23 @@ + + + + + + + + +
+ + {{ 'common.close-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component.ts new file mode 100644 index 0000000..6df8513 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-change-pin-dialog/hw-change-pin-dialog.component.ts @@ -0,0 +1,49 @@ +import { mergeMap } from 'rxjs/operators'; +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { ChildHwDialogParams } from '../hw-options-dialog/hw-options-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; + +/** + * Allows to add a PIN code to the device or change the one it has. This modal window was + * created for being oppenend by the hw wallet options modal window. + */ +@Component({ + selector: 'app-hw-change-pin-dialog', + templateUrl: './hw-change-pin-dialog.component.html', + styleUrls: ['./hw-change-pin-dialog.component.scss'], +}) +export class HwChangePinDialogComponent extends HwDialogBaseComponent { + // If true, the device already has a PIN code and the operation is for changing it. If + // false, the device does not have a PIN code and the operation is for creating one. + changingExistingPin: boolean; + + constructor( + @Inject(MAT_DIALOG_DATA) public data: ChildHwDialogParams, + public dialogRef: MatDialogRef, + private hwWalletService: HwWalletService, + ) { + super(hwWalletService, dialogRef); + + this.changingExistingPin = data.walletHasPin; + + this.operationSubscription = this.hwWalletService.getFeatures().pipe(mergeMap(features => { + // Update the title, just in case, as it should not be needed. + this.changingExistingPin = features.rawResponse.pin_protection; + + return this.hwWalletService.changePin(features.rawResponse.pin_protection); + })).subscribe( + () => { + this.showResult({ + text: 'hardware-wallet.general.completed', + icon: this.msgIcons.Success, + }); + // Request the hw wallet options modal window to refresh the security warnings. + this.data.requestOptionsComponentRefresh(null, true); + }, + err => this.processHwOperationError(err), + ); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component.html new file mode 100644 index 0000000..ec38b0f --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component.html @@ -0,0 +1,21 @@ + + + + + + + + +
+ + {{ 'common.close-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component.ts new file mode 100644 index 0000000..c994863 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component.ts @@ -0,0 +1,69 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialogConfig, MatDialog } from '@angular/material/dialog'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; +import { HardwareWalletService } from '../../../../services/wallet-operations/hardware-wallet.service'; +import { WalletBase } from '../../../../services/wallet-operations/wallet-objects'; + +/** + * Settings for HwConfirmAddressDialogComponent. + */ +export class AddressConfirmationParams { + /** + * Wallet which contains the address to sonfirm. + */ + wallet: WalletBase; + /** + * Index of the address inside the wallet. + */ + addressIndex: number; + /** + * If true, the UI will show the complete confirmation text after the user confirms the address. + * If false, a short text will be shown. The complete text should be displayed only the first + * time the user confirms the address. + */ + showCompleteConfirmation: boolean; +} + +/** + * Allows the user to confirm the desktop and hw wallets show the same address. + */ +@Component({ + selector: 'app-hw-confirm-address-dialog', + templateUrl: './hw-confirm-address-dialog.component.html', + styleUrls: ['./hw-confirm-address-dialog.component.scss'], +}) +export class HwConfirmAddressDialogComponent extends HwDialogBaseComponent { + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, confirmationParams: AddressConfirmationParams): MatDialogRef { + const config = new MatDialogConfig(); + config.width = '566px'; + config.autoFocus = false; + config.data = confirmationParams; + + return dialog.open(HwConfirmAddressDialogComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public data: AddressConfirmationParams, + public dialogRef: MatDialogRef, + private hardwareWalletService: HardwareWalletService, + hwWalletService: HwWalletService, + ) { + super(hwWalletService, dialogRef); + + // Ask for confirmation and update the address and the wallet if the user confirms. + this.operationSubscription = this.hardwareWalletService.confirmAddress(data.wallet, data.addressIndex).subscribe( + () => { + this.showResult({ + text: data.showCompleteConfirmation ? 'hardware-wallet.confirm-address.confirmation' : 'hardware-wallet.confirm-address.short-confirmation', + icon: this.msgIcons.Success, + }); + }, + err => this.processHwOperationError(err), + ); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component.html new file mode 100644 index 0000000..e1ff26c --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component.html @@ -0,0 +1,9 @@ + + + + diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component.ts new file mode 100644 index 0000000..f54755f --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-confirm-tx-dialog/hw-confirm-tx-dialog.component.ts @@ -0,0 +1,35 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialogConfig, MatDialog } from '@angular/material/dialog'; + +import { HwWalletService, HwWalletTxRecipientData } from '../../../../services/hw-wallet.service'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; + +/** + * Allow the user to confirm a transaction before sending it. + */ +@Component({ + selector: 'app-hw-confirm-tx-dialog', + templateUrl: './hw-confirm-tx-dialog.component.html', + styleUrls: ['./hw-confirm-tx-dialog.component.scss'], +}) +export class HwConfirmTxDialogComponent extends HwDialogBaseComponent { + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, recipientData: HwWalletTxRecipientData[]): MatDialogRef { + const config = new MatDialogConfig(); + config.data = recipientData; + config.autoFocus = false; + config.width = '600px'; + + return dialog.open(HwConfirmTxDialogComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public data: HwWalletTxRecipientData[], + public dialogRef: MatDialogRef, + hwWalletService: HwWalletService, + ) { + super(hwWalletService, dialogRef); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-dialog-base.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-dialog-base.component.ts new file mode 100644 index 0000000..70ee783 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-dialog-base.component.ts @@ -0,0 +1,156 @@ +import { Component, OnDestroy, ViewChild } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; + +import { MessageIcons } from './hw-message/hw-message.component'; +import { HwWalletService } from '../../../services/hw-wallet.service'; +import { ButtonComponent } from '../button/button.component'; +import { processServiceError } from '../../../utils/errors'; +import { AppConfig } from '../../../app.config'; +import { OperationError, HWOperationResults } from '../../../utils/operation-error'; + +/** + * Data to show on the UI to inform the user about the result of an operation. + */ +export class ResultData { + /** + * Text to show. + */ + text: String; + /** + * Link to show after the text. Must be a valid URL. + */ + link?: String; + /** + * Icon to show. + */ + icon: MessageIcons; +} + +/** + * Different states in which an implementation of HwDialogBaseComponent can be. Each + * implementation is responsible for using each state as appropiate, but the + * ShowingResult state should be used for displaying in the UI the result of the + * requested oepration. + */ +export enum States { + Connecting, + Initial, + Processing, + ShowingResult, + Finished, + Other, +} + +/** + * Base class for the modal windows related to the hw wallet. It includes code for simplifying + * several actions which are common for the hw wallet modal windows, like managing states, + * operations with the close button, closing the window if the device is disconnected and more. + * The type expected by this class is just the class implementing it. + */ +@Component({ + template: '', +}) +export class HwDialogBaseComponent implements OnDestroy { + // Reference to the close button. For it to work the implementation must have "#closeButton" + // added to the close button tag. + @ViewChild('closeButton') closeButton: ButtonComponent; + + // If true, the modal window will be automatically closed if the device is disconnected. + closeIfHwDisconnected = true; + + // Allows to access from the HTML files the icons the msg areas can show. + msgIcons = MessageIcons; + // Current state of the window. Must be interpreted by the implementation. + currentState: States = States.Initial; + // Allows to access from the HTML files the states in which the window can be. + states = States; + // Result to show on the UI when the state indicates a result must be shown. + result: ResultData; + + // Add operation subscriptions to this var to close them automatically when closing the window. + protected operationSubscription: SubscriptionLike; + private hwConnectionSubscription: SubscriptionLike; + + constructor( + private _hwWalletService: HwWalletService, + public _dialogRef: MatDialogRef, + ) { + // Inform connection events and close the window if needed. + this.hwConnectionSubscription = this._hwWalletService.walletConnectedAsyncEvent.subscribe(connected => { + this.hwConnectionChanged(connected); + if (!connected && this.closeIfHwDisconnected) { + this.closeModal(); + } + }); + } + + ngOnDestroy() { + if (this.operationSubscription && !this.operationSubscription.closed) { + this.operationSubscription.unsubscribe(); + } + this.hwConnectionSubscription.unsubscribe(); + } + + closeModal() { + this._dialogRef.close(); + } + + /** + * Called every time the connection state of the device changes. + * @param connected If the device is connected (true) or not (false). + */ + hwConnectionChanged(connected: boolean) { + + } + + /** + * Process the result of an operation which finished in an error. It closes the modal window if + * appropiate or prepares the error for being displayed on the UI. + * @param result Result obtained after finishing the operation. + */ + protected processHwOperationError(result: OperationError) { + if (result) { + result = processServiceError(result); + + if (result.type === HWOperationResults.Disconnected && this.closeIfHwDisconnected) { + this.closeModal(); + } else { + // Prepares the error for being displayed on the UI. + this.showResult({ + text: result.translatableErrorMsg, + icon: MessageIcons.Error, + }); + } + } + } + + /** + * Process and saves a result to be shown on the UI and also changes the state of the modal + * window to the one indicationg a result must be shown to the user. + * @param result Result to process. + * @param focusButton If true, the close button of the modal window is focused. + */ + protected showResult(result: ResultData, focusButton = true) { + if (result) { + // If there was an error connecting with the daemon or its version, the link to download + // the daemon is added to the elements which will be displayed. + if (result.text === 'hardware-wallet.errors.daemon-connection' || result.text.indexOf('Problem connecting to the Skywallet Daemon') !== -1) { + result.text = 'hardware-wallet.errors.daemon-connection'; + result.link = AppConfig.hwWalletDaemonDownloadUrl; + } else if (result.text === 'hardware-wallet.errors.outdated-daemon') { + result.text = 'hardware-wallet.errors.outdated-daemon'; + result.link = AppConfig.hwWalletDaemonDownloadUrl; + } + + this.currentState = States.ShowingResult; + this.result = result; + + setTimeout(() => { + if (this.closeButton && focusButton) { + this.closeButton.focus(); + } + }); + } + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component.html new file mode 100644 index 0000000..055c13a --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component.html @@ -0,0 +1,47 @@ + + +
+ + + + +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'common.continue-button' | translate }} + +
+
+ + + + + + + + +
+ + {{ 'common.close-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component.ts new file mode 100644 index 0000000..ccd780f --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-generate-seed-dialog/hw-generate-seed-dialog.component.ts @@ -0,0 +1,46 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { ChildHwDialogParams } from '../hw-options-dialog/hw-options-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; + +/** + * Allows to make a seedless device create a new random seed and use it. This modal window was + * created for being oppenend by the hw wallet options modal window. + */ +@Component({ + selector: 'app-hw-generate-seed-dialog', + templateUrl: './hw-generate-seed-dialog.component.html', + styleUrls: ['./hw-generate-seed-dialog.component.scss'], +}) +export class HwGenerateSeedDialogComponent extends HwDialogBaseComponent { + form: FormGroup; + + constructor( + @Inject(MAT_DIALOG_DATA) public data: ChildHwDialogParams, + public dialogRef: MatDialogRef, + private hwWalletService: HwWalletService, + formBuilder: FormBuilder, + ) { + super(hwWalletService, dialogRef); + + this.form = formBuilder.group({ + words: [24, Validators.required], + }); + } + + startOperation() { + this.currentState = this.states.Processing; + + this.operationSubscription = this.hwWalletService.generateMnemonic(this.form.controls['words'].value).subscribe( + () => { + // Request the data and state of the hw wallet options modal window to be refreshed. + this.data.requestOptionsComponentRefresh(); + this.closeModal(); + }, + err => this.processHwOperationError(err), + ); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.html new file mode 100644 index 0000000..7a18419 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.html @@ -0,0 +1,37 @@ +
+ +
+ + done + error_outline + usb + memory + error + touch_app +
+ +
+
+ {{ upperBigText }} +
+ {{ text }} + {{ linkText }} + {{ linkText }} +
+
+ • {{ output.coins | amount }} + + {{ 'hardware-wallet.create-tx.separator-for-coins-and-hours' | translate }} {{ output.hours | amount:false }} + + {{ 'hardware-wallet.create-tx.separator-to-destination' | translate }} {{ output.address }} +
+
+ {{ lowerText }} +
+ {{ lowerBigText }} +
+
+ {{ lowerLightText }} +
+
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.scss new file mode 100644 index 0000000..654a2e4 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.scss @@ -0,0 +1,56 @@ +@import '../../../../../theme/variables'; + +.content { + display: flex; + + .icon-container { + margin-right: 20px; + + mat-spinner { + display: inline-block; + + height: 36px !important; + width: 36px !important; + + ::ng-deep svg { + height: 36px !important; + width: 36px !important; + } + + ::ng-deep circle { + stroke: $grey-light; + } + } + + i { + font-size: 40px; + } + } + + .text-container { + flex-grow: 1; + align-self: center; + + .list { + padding: 10px 0; + + .list-element { + word-break: break-all; + margin: 10px 0; + font-size: $font-size-standard-minus; + color: #000000; + font-weight: bold; + } + } + } + + .-blinking { + animation: alert-blinking 1s linear infinite; + } +} + +.big-text { + color: $black; + font-weight: bold; + font-size: $font-size-big; +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.ts new file mode 100644 index 0000000..4613628 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-message/hw-message.component.ts @@ -0,0 +1,62 @@ +import { Component, Input, Output, EventEmitter, OnDestroy } from '@angular/core'; + +import { HwWalletTxRecipientData } from '../../../../services/hw-wallet.service'; + +/** + * Icons HwMessageComponent can show. + */ +export enum MessageIcons { + None, + Spinner, + Success, + Error, + Usb, + HardwareWallet, + Warning, + Confirm, +} + +/** + * Generic control for showing messages. It includes an area for an icon on the left side + * and various text with different format. All properties are optional. + */ +@Component({ + selector: 'app-hw-message', + templateUrl: './hw-message.component.html', + styleUrls: ['./hw-message.component.scss'], +}) +export class HwMessageComponent implements OnDestroy { + // Icon to show at the left. + @Input() icon: MessageIcons = MessageIcons.None; + // Text to show. + @Input() text: string; + // Link to show after the main text. + @Input() linkText: string; + // URL for the link. If no URL is set, the linkClicked event is dispatched when the user + // clicks the link. + @Input() linkIsUrl = false; + // Outputs to show as a list. It is used to show the list of coins going out during a + // transaction, so the user can check it before confirming the tx. It is shown under + // the main text. + @Input() outputsList: HwWalletTxRecipientData[]; + // Text shown after the main text, the link and the outputs list. + @Input() lowerText: string; + // Big text shown at the top of the main text. Can be used as a title. + @Input() upperBigText: string; + // Big text shown below the main text. + @Input() lowerBigText: string; + // Light text shown at the bottom of the component. + @Input() lowerLightText: string; + // Event dispatched when the user clicks the link if no URL for it was provided. + @Output() linkClicked = new EventEmitter(); + + icons = MessageIcons; + + ngOnDestroy() { + this.linkClicked.complete(); + } + + activateLink() { + this.linkClicked.emit(); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.html new file mode 100644 index 0000000..6bda894 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.html @@ -0,0 +1,98 @@ + + + + + + + +
+ + + + +
+ error +
+
{{ (securityWarnings.length > 1 ? 'hardware-wallet.options.security-warnings-title' : 'hardware-wallet.options.security-warning-title') | translate}}
+ +
{{ securityWarnings.length > 1 ? ((i + 1) + ')') : '' }} {{ warning | translate}}
+
+
+
+
+ +
{{ 'hardware-wallet.options.options' | translate }}
+
+ +
+ + +
+
+ + + + + +
+
+
+ +
+ + {{ 'common.loading' | translate }} +
+ +
+ + {{ 'common.close-button' | translate }} + +
+ +
+ + {{ 'common.close-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.scss new file mode 100644 index 0000000..9d70d4d --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.scss @@ -0,0 +1,69 @@ +@import '../../../../../theme/variables'; + +.alert-box { + margin-top: 25px; +} + +.options-label { + margin-top: 25px; + margin-bottom: 10px; + font-weight: bold; +} + +.option-buttons-container { + margin: 0 -10px; + + button { + width: 100%; + text-align: left; + padding: 10px 10px; + border-bottom: 1px solid $grey-very-light; + + &:first-child { + border-top: 1px solid $grey-very-light; + } + + .label { + font-size: $font-size-standard; + line-height: 1.7; + color: $black; + } + } +} + +.-blinking { + animation: alert-blinking 1s linear infinite; +} + +.loading-indicator { + width: 100px; + height: 40px; + left: calc(50% - 50px); + top: calc(50% - 20px); + position: absolute; + display: flex; + justify-content: center; + align-items: center; + + mat-spinner { + margin-left: 7px; + margin-right: 12px; + height: 18px !important; + width: 18px !important; + + ::ng-deep svg { + height: 18px !important; + width: 18px !important; + + circle { + stroke: $grey-light; + } + } + } +} + +.disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.ts new file mode 100644 index 0000000..b95590f --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component.ts @@ -0,0 +1,447 @@ +import { Component, OnDestroy, Inject } from '@angular/core'; +import { MatDialogRef, MatDialogConfig, MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { SubscriptionLike, Observable, of } from 'rxjs'; +import { map, first, tap, mergeMap } from 'rxjs/operators'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { HwWipeDialogComponent } from '../hw-wipe-dialog/hw-wipe-dialog.component'; +import { HwAddedDialogComponent } from '../hw-added-dialog/hw-added-dialog.component'; +import { HwGenerateSeedDialogComponent } from '../hw-generate-seed-dialog/hw-generate-seed-dialog.component'; +import { HwBackupDialogComponent } from '../hw-backup-dialog/hw-backup-dialog.component'; +import { HwChangePinDialogComponent } from '../hw-change-pin-dialog/hw-change-pin-dialog.component'; +import { HwRestoreSeedDialogComponent } from '../hw-restore-seed-dialog/hw-restore-seed-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; +import { HwRemovePinDialogComponent } from '../hw-remove-pin-dialog/hw-remove-pin-dialog.component'; +import { HwUpdateFirmwareDialogComponent } from '../hw-update-firmware-dialog/hw-update-firmware-dialog.component'; +import { HwUpdateAlertDialogComponent } from '../hw-update-alert-dialog/hw-update-alert-dialog.component'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { AppConfig } from '../../../../app.config'; +import { OperationError, HWOperationResults } from '../../../../utils/operation-error'; +import { processServiceError } from '../../../../utils/errors'; +import { HardwareWalletService, HwFeaturesResponse, HwSecurityWarnings } from '../../../../services/wallet-operations/hardware-wallet.service'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; +import { WalletBase } from '../../../../services/wallet-operations/wallet-objects'; +import { CoinService } from '../../../../services/coin.service'; + +/** + * Params sent to the modal windows openned by HwOptionsDialogComponent. + */ +export interface ChildHwDialogParams { + /** + * Wallet object representing the connected device. It will be null if the connected device + * have not been added to the wallet list. + */ + wallet: WalletBase; + /** + * If the connected device has PIN code protection activated. + */ + walletHasPin: boolean; + /** + * Function for asking the hw wallet options modal window to recheck the connected device, + * due to changes made to it, and refresh the data. + * @param error If a valid string is provided, instead of rechecking the connected device + * the hw wallet options modal window will just hide the options and show the provided + * error msg. + * @param recheckSecurityOnly If true, instead of completelly recheck the connected device, + * the hw wallet options modal window will just update the security warnings. + */ + requestOptionsComponentRefresh(error?: string, recheckSecurityOnly?: boolean): void; +} + +/** + * Shows basic info and general configuration options for the connected hw wallet. If the + * onboarding option is set to true, it will just try to find a known hw wallet connected + * (if an unknown one is connected it will try to add it to the wallet list first and then + * try to detect it again) and, after finding one, it will just close itself, return "true" + * iin the "afterClosed" event and make a service wait to open it again after navigating + * to the wallet list. This behavior allows the user to just add a wallet while on the wizard. + */ +@Component({ + selector: 'app-hw-options-dialog', + templateUrl: './hw-options-dialog.component.html', + styleUrls: ['./hw-options-dialog.component.scss'], +}) +export class HwOptionsDialogComponent extends HwDialogBaseComponent implements OnDestroy { + closeIfHwDisconnected = false; + + // If true, indicates that the connected device does not have a seed. + newWalletConnected = false; + // If true, the window state was set to "other" (which is used to show an error related to + // the PIN code) because the user entered a wrong PIN. If false, it was because the user + // did not enter the PIN code. + otherStateBecauseWrongPin = false; + // Version of the firmware of the connected device. + firmwareVersion = ''; + + // Wallet object corresponding to the current device, if it has been already added to the + // wallet list. + wallet: WalletBase; + + // Security warning texts to show on the UI. + securityWarnings: string[] = []; + // Vars for knowing which security warnings were found. + firmwareVersionNotVerified: boolean; + outdatedFirmware: boolean; + needsBackup: boolean; + needsPin: boolean; + // Indicates if the security warning are being updated. The Security warnings are used as + // a way to know the state of the device and show the appropiate options. + refreshingWarnings = false; + + private dialogSubscription: SubscriptionLike; + + // If true, the last openned modal window requested, after closing it, this window to refesh + // all its data. + private completeRecheckRequested = false; + // If true, the last openned modal window requested, after closing it, this window to refesh + // the security warnings. + private recheckSecurityOnlyRequested = false; + // If true, the last openned modal window requested, after closing it, this window to show + // a custom error msg. + private showErrorRequested = false; + // Custom error msg the last openned modal window requested to be shown. + private customErrorMsg = ''; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + * @param onboarding Set to true if the window is being openned from the wizard. + */ + public static openDialog(dialog: MatDialog, onboarding: boolean): MatDialogRef { + const config = new MatDialogConfig(); + config.data = onboarding; + config.autoFocus = false; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(HwOptionsDialogComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) private onboarding: boolean, + public dialogRef: MatDialogRef, + private hwWalletService: HwWalletService, + private dialog: MatDialog, + private msgBarService: MsgBarService, + private hardwareWalletService: HardwareWalletService, + private walletsAndAddressesService: WalletsAndAddressesService, + private coinService: CoinService, + ) { + super(hwWalletService, dialogRef); + + this.checkWallet(true); + } + + ngOnDestroy() { + super.ngOnDestroy(); + this.removeDialogSubscription(); + this.removeOperationSubscription(); + this.msgBarService.hide(); + } + + hwConnectionChanged(connected: boolean) { + // If the device was connected or disconnected, recheck it. + this.checkWallet(true); + } + + update() { + this.openUpdateDialog(); + } + + generateMnemonic() { + this.openDialog(HwGenerateSeedDialogComponent); + } + + restoreMnemonic() { + this.openDialog(HwRestoreSeedDialogComponent); + } + + changePin() { + this.openDialog(HwChangePinDialogComponent); + } + + removePin() { + this.openDialog(HwRemovePinDialogComponent); + } + + backup() { + this.openDialog(HwBackupDialogComponent); + } + + wipe() { + this.openDialog(HwWipeDialogComponent); + } + + confirmSeed() { + this.openDialog(HwRestoreSeedDialogComponent); + } + + /** + * Opens a modal window for making a specific operation related to the hw wallet. + * @param dialogType Class of the modal window to open. + */ + private openDialog(dialogType) { + this.customErrorMsg = ''; + + this.removeDialogSubscription(); + const config = new MatDialogConfig(); + config.width = '450px'; + config.autoFocus = false; + + // Data for the modal window. + config.data = { + // Include the current wallet, if there is one. + wallet: this.wallet, + walletHasPin: !this.needsPin, + requestOptionsComponentRefresh: ((error: string = null, recheckSecurityOnly: boolean = false) => { + if (!error) { + // Set the data to be updated after closing the window, as requested. + if (!recheckSecurityOnly) { + this.completeRecheckRequested = true; + } else { + this.recheckSecurityOnlyRequested = true; + } + } else { + // Set a custom error to be shown after closing the window. + this.showErrorRequested = true; + this.customErrorMsg = error; + } + }), + }; + + // Open the modal window. + this.dialogSubscription = this.dialog.open(dialogType, config).afterClosed().subscribe(() => { + // Refresh the data or show an error, if previously requested. + if (this.completeRecheckRequested) { + this.checkWallet(); + } else if (this.recheckSecurityOnlyRequested) { + this.updateSecurityWarningsAndData().subscribe(); + } else if (this.showErrorRequested) { + this.showError(); + } + this.completeRecheckRequested = false; + this.recheckSecurityOnlyRequested = false; + this.showErrorRequested = false; + }); + } + + private removeDialogSubscription() { + if (this.dialogSubscription) { + this.dialogSubscription.unsubscribe(); + } + } + + /** + * Updates the list of security warnings related to the connected device. Also updates and + * saves the changes of the wallet object which represents the connected device, if there is + * already one. + * @returns The observable for performing the operation. + */ + private updateSecurityWarningsAndData(): Observable { + return of(1).pipe( + tap(() => this.refreshingWarnings = true), + mergeMap(() => this.hardwareWalletService.getFeaturesAndUpdateData(this.wallet)), + map((response: HwFeaturesResponse) => { + this.refreshingWarnings = false; + this.securityWarnings = []; + + // Build a list with the texts of all warnings and set variables to known which + // warnings were found. + + if (response.securityWarnings.includes(HwSecurityWarnings.FirmwareVersionNotVerified)) { + this.firmwareVersionNotVerified = true; + this.securityWarnings.push('hardware-wallet.options.unchecked-version-warning'); + } else { + this.firmwareVersionNotVerified = false; + } + + if (response.securityWarnings.includes(HwSecurityWarnings.OutdatedFirmware)) { + this.outdatedFirmware = true; + this.securityWarnings.push('hardware-wallet.options.outdated-version-warning'); + } else { + this.outdatedFirmware = false; + } + + // If there is no wallet, the device does not have a seed, so the warning is not relevant. + if (this.wallet && response.securityWarnings.includes(HwSecurityWarnings.NeedsBackup)) { + this.needsBackup = true; + this.securityWarnings.push('hardware-wallet.options.backup-warning'); + } else { + this.needsBackup = false; + } + + // If there is no wallet, the device does not have a seed, so the warning is not relevant. + if (this.wallet && response.securityWarnings.includes(HwSecurityWarnings.NeedsPin)) { + this.needsPin = true; + this.securityWarnings.push('hardware-wallet.options.pin-warning'); + } else { + this.needsPin = false; + } + + // Inform if the name of the wallet on the wallet list was updated to match the one + // shown on the device. + if (response.walletNameUpdated) { + this.msgBarService.showWarning('hardware-wallet.general.name-updated'); + } + + this.firmwareVersion = response.features.fw_major + '.' + response.features.fw_minor + '.' + response.features.fw_patch; + + return response; + }), + ); + } + + /** + * Makes the initial steps for Checking if there is a connected hw wallet and its features. + * @param suggestToUpdate If a modal window sugesting the user to update the firmware should + * be shown if a more recent version of the firmware is detected. + */ + private checkWallet(suggestToUpdate = false) { + this.wallet = null; + // Show the loading animation. + this.showResult({ + text: 'hardware-wallet.options.connecting', + icon: this.msgIcons.Spinner, + }, false); + + this.removeOperationSubscription(); + + this.operationSubscription = this.hwWalletService.getDeviceConnected().subscribe(connected => { + if (!connected) { + // Show the no device connected msg. + this.showResult({ + text: 'hardware-wallet.options.disconnected', + icon: this.msgIcons.Usb, + }); + } else { + // Try to check if the device is in bootloader mode, in which case the firmware update + // modal window is openned. No previous operation is cancelled because that may cause + // problems if the device is in bootloader mode. If the operation fails, it is asumed + // that it was because the device has a pending operation and it is not in + // bootloader mode. + this.operationSubscription = this.hwWalletService.getFeatures(false).subscribe(result => { + if (result.rawResponse.bootloader_mode) { + this.openUpdateDialog(); + } else { + this.continueCheckingWallet(suggestToUpdate); + } + }, () => this.continueCheckingWallet(suggestToUpdate)); + } + }, (err: OperationError) => { + this.processHwOperationError(err); + }); + } + + /** + * Checks if the connected device has a seed, updates its security warnings, verifies if + * it was already added to the wallet list and any other operation nedded for showing the + * appropiate info and options for the device. + * @param suggestToUpdate If a modal window sugesting the user to update the firmware should + * be shown if a more recent version of the firmware is detected. + */ + private continueCheckingWallet(suggestToUpdate: boolean) { + // Get the first address of the device, to use it for identification. + this.operationSubscription = this.hwWalletService.getAddresses(1, 0, this.coinService.currentCoinInmediate.skywalletCoinType).subscribe( + response => { + // If the first address was obteined, get all the saved wallets of the current coin. + this.operationSubscription = this.walletsAndAddressesService.currentWallets.pipe(first()).subscribe(wallets => { + // Check if there is already a saved hw wallet with the obtained first address. + const alreadySaved = wallets.some(wallet => { + const found = wallet.addresses[0].compareAddress(response.rawResponse[0]) && wallet.isHardware; + if (found) { + this.wallet = wallet; + } + + return found; + }); + + if (alreadySaved) { + // Update the security warnings. + this.operationSubscription = this.updateSecurityWarningsAndData().subscribe(result => { + if (suggestToUpdate && result.securityWarnings.find(warning => warning === HwSecurityWarnings.OutdatedFirmware)) { + this.openUpdateWarning(); + } + + if (!this.onboarding) { + // Show the options. + this.currentState = this.states.Finished; + this.newWalletConnected = false; + } else { + // Close the modal window and request to open it again after navigating to the + // wallet list. + this.hwWalletService.showOptionsWhenPossible = true; + this.dialogRef.close(true); + } + }, err => this.processHwOperationError(err)); + } else { + // Open the appropiate component for adding the device to the wallet list. + this.openDialog(HwAddedDialogComponent); + } + }); + }, + (err: OperationError) => { + err = processServiceError(err); + + if (err.type === HWOperationResults.WithoutSeed) { + // If trying to get the first address failed because the device does not have a seed, + // the options for a new device are shown. + this.operationSubscription = this.updateSecurityWarningsAndData().subscribe(result => { + this.currentState = this.states.Finished; + this.newWalletConnected = true; + + if (suggestToUpdate && result.securityWarnings.find(warning => warning === HwSecurityWarnings.OutdatedFirmware)) { + this.openUpdateWarning(); + } + }, error => this.processHwOperationError(error)); + } else if (err.type === HWOperationResults.FailedOrRefused) { + // Show an error due to a problem with the PIN and allow the user to wipe + // the device if needed. + this.currentState = this.states.Other; + this.otherStateBecauseWrongPin = false; + } else if (err.type === HWOperationResults.WrongPin) { + // Show an error due to a problem with the PIN and allow the user to wipe + // the device if needed. + this.currentState = this.states.Other; + this.otherStateBecauseWrongPin = true; + } else { + this.processHwOperationError(err); + } + }, + ); + } + + private removeOperationSubscription() { + if (this.operationSubscription) { + this.operationSubscription.unsubscribe(); + } + } + + /** + * Opens a warning modal window asking the user to update the firmware. + */ + private openUpdateWarning() { + HwUpdateAlertDialogComponent.openDialog(this.dialog).afterClosed().subscribe(update => { + if (update) { + this.openUpdateDialog(); + } + }); + } + + /** + * Opens the firmware update modal window and closes this one. + */ + private openUpdateDialog() { + HwUpdateFirmwareDialogComponent.openDialog(this.dialog); + this.closeModal(); + } + + /** + * Shows the custom error msg saved on customErrorMsg, or a generic one, if no custom + * msg was saved. + */ + private showError() { + this.showResult({ + text: this.customErrorMsg ? this.customErrorMsg : 'hardware-wallet.errors.generic-error', + icon: this.msgIcons.Error, + }); + this.customErrorMsg = ''; + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.html new file mode 100644 index 0000000..c2dceff --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.html @@ -0,0 +1,52 @@ + + + +
+
+
+ + {{ 'hardware-wallet.enter-pin.instructions-tx' | translate }} + + + {{ 'hardware-wallet.enter-pin.instructions-change' | translate }} + + + {{ 'hardware-wallet.enter-pin.instructions-generic' | translate }} + + {{ 'hardware-wallet.enter-pin.help' | translate }} +
+ +
+
+ + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+ + +
+ + {{ 'common.continue-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.scss new file mode 100644 index 0000000..5eb6c5e --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.scss @@ -0,0 +1,30 @@ +@import '../../../../../theme/variables'; + +mat-form-field { + width: 100%; +} + +.form-field { + input { + font-size: 25px; + line-height: 1; + letter-spacing: 15px; + text-align: center; + margin-top: 5px; + } +} + +.num-pad-row { + display: flex; + + button { + flex-grow: 1; + height: 50px; + border: $grey-very-light solid 1px; + margin: 2px; + + span { + color: $black; + } + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.ts new file mode 100644 index 0000000..7dcb525 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component.ts @@ -0,0 +1,126 @@ +import { Component, OnInit, HostListener, Inject } from '@angular/core'; +import { FormBuilder, Validators, FormGroup } from '@angular/forms'; +import { MatDialogRef, MatDialog, MatDialogConfig, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { HwPinHelpDialogComponent } from '../hw-pin-help-dialog/hw-pin-help-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; +import { ChangePinStates } from '../../../../services/hw-wallet-pin.service'; + +/** + * Settings for HwPinDialogComponent. + */ +export interface HwPinDialogParams { + /** + * If the PIN code is being requested for signing a tx. Ignored if changingPin is true. + */ + signingTx: boolean; + /** + * If the PIN code is being requested for setting or changing the PIN on the device. + */ + changingPin: boolean; + /** + * State of the PIN changing operation if changingPin is true. + */ + changePinState: ChangePinStates; +} + +/** + * Allows the user to enter the PIN code. If the user completes the operation, the modal window + * is closed and the positions selected by the user on the PIN matrix are returned in the + * "afterClosed" event. + */ +@Component({ + selector: 'app-hw-pin-dialog', + templateUrl: './hw-pin-dialog.component.html', + styleUrls: ['./hw-pin-dialog.component.scss'], +}) +export class HwPinDialogComponent extends HwDialogBaseComponent implements OnInit { + form: FormGroup; + changePinStates = ChangePinStates; + buttonsContent = '•'; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, params: HwPinDialogParams): MatDialogRef { + const config = new MatDialogConfig(); + config.data = params; + config.autoFocus = false; + config.width = '350px'; + + return dialog.open(HwPinDialogComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public data: HwPinDialogParams, + public dialogRef: MatDialogRef, + private formBuilder: FormBuilder, + private dialog: MatDialog, + hwWalletService: HwWalletService, + ) { + super(hwWalletService, dialogRef); + } + + ngOnInit() { + this.form = this.formBuilder.group({ + pin: ['', Validators.compose([Validators.required, Validators.minLength(4)])], + }); + } + + get title(): string { + if (!this.data.changingPin) { + return 'hardware-wallet.enter-pin.title'; + } else if (this.data.changePinState === ChangePinStates.RequestingNewPin) { + return 'hardware-wallet.enter-pin.title-change-new'; + } else if (this.data.changePinState === ChangePinStates.ConfirmingNewPin) { + return 'hardware-wallet.enter-pin.title-change-confirm'; + } else { + return 'hardware-wallet.enter-pin.title-change-current'; + } + } + + openHelp() { + HwPinHelpDialogComponent.openDialog(this.dialog); + } + + /** + * Allow to enter the PIN using the numeric keys to emulate the PIN matrix. + */ + @HostListener('window:keyup', ['$event']) + keyEvent(event: KeyboardEvent) { + const key = parseInt(event.key, 10); + if (key > 0 && key < 10) { + this.addNumber(key.toString()); + } else if (event.keyCode === 8) { + this.removeNumber(); + } else if (event.keyCode === 13) { + this.sendPin(); + } + } + + /** + * Add a new number to the PIN. + * @param number Position of the number of the new number on the matrix. + */ + addNumber(number: string) { + const currentValue: string = this.form.value.pin; + if (currentValue.length < 8) { + this.form.get('pin').setValue(currentValue + number); + } + } + + /** + * Removes the last number from the PIN. + */ + removeNumber() { + const currentValue: string = this.form.value.pin; + this.form.get('pin').setValue(currentValue.substring(0, currentValue.length - 1)); + } + + sendPin() { + if (this.form.valid) { + this.dialogRef.close(this.form.value.pin); + } + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component.html new file mode 100644 index 0000000..0e8bcd6 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component.html @@ -0,0 +1,5 @@ + +

{{ 'hardware-wallet.pin-help.part1' | translate }}

+

{{ 'hardware-wallet.pin-help.part2' | translate }}

+

{{ 'hardware-wallet.pin-help.part3' | translate }}

+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component.ts new file mode 100644 index 0000000..897f8f8 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-pin-help-dialog/hw-pin-help-dialog.component.ts @@ -0,0 +1,27 @@ +import { Component } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +/** + * Shows instructions about how to use the PIN matrix. + */ +@Component({ + selector: 'app-hw-added-dialog', + templateUrl: './hw-pin-help-dialog.component.html', + styleUrls: ['./hw-pin-help-dialog.component.scss'], +}) +export class HwPinHelpDialogComponent { + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = false; + config.width = '450px'; + + return dialog.open(HwPinHelpDialogComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + ) { } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component.html new file mode 100644 index 0000000..1aa86e0 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component.html @@ -0,0 +1,48 @@ + + +
+ + +
+ {{ 'common.generic-confirmation-check' | translate }} + +
+ +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'common.continue-button' | translate }} + +
+
+ +
+ + + + + + + +
+ + {{ 'common.close-button' | translate }} + +
+
+
\ No newline at end of file diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component.ts new file mode 100644 index 0000000..ebb6785 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-remove-pin-dialog/hw-remove-pin-dialog.component.ts @@ -0,0 +1,49 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { ChildHwDialogParams } from '../hw-options-dialog/hw-options-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; + +/** + * Allows to remove the PIN code protection from a device. This modal window was created for + * being oppenend by the hw wallet options modal window. + */ +@Component({ + selector: 'app-hw-remove-pin-dialog', + templateUrl: './hw-remove-pin-dialog.component.html', + styleUrls: ['./hw-remove-pin-dialog.component.scss'], +}) +export class HwRemovePinDialogComponent extends HwDialogBaseComponent { + // If the user has confirmed the operation with the checkbox. + confirmed = false; + + constructor( + @Inject(MAT_DIALOG_DATA) public data: ChildHwDialogParams, + public dialogRef: MatDialogRef, + private hwWalletService: HwWalletService, + ) { + super(hwWalletService, dialogRef); + } + + setConfirmed(event) { + this.confirmed = event.checked; + } + + // Starts the operation. + requestRemoval() { + this.currentState = this.states.Processing; + + this.operationSubscription = this.hwWalletService.removePin().subscribe( + () => { + this.showResult({ + text: 'hardware-wallet.general.completed', + icon: this.msgIcons.Success, + }); + // Request the hw wallet options modal window to refresh the security warnings. + this.data.requestOptionsComponentRefresh(null, true); + }, + err => this.processHwOperationError(err), + ); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.html new file mode 100644 index 0000000..14dcfb5 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.html @@ -0,0 +1,53 @@ + + + +
+ + + + +
{{ 'hardware-wallet.restore-seed.warning' | translate }}
+ +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'common.continue-button' | translate }} + +
+
+ + + + + + + + +
+ + {{ 'common.close-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.scss new file mode 100644 index 0000000..e15658c --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.scss @@ -0,0 +1,7 @@ +@import '../../../../../theme/variables'; + +.warning { + margin-top: 15px; + color: $red; + text-align: center; +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.ts new file mode 100644 index 0000000..2acf25a --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-restore-seed-dialog/hw-restore-seed-dialog.component.ts @@ -0,0 +1,59 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { ChildHwDialogParams } from '../hw-options-dialog/hw-options-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; + +/** + * Allows to load a seed on a seedless device or to let the user to enter a seed to check + * if it is equal to the one on the device (if a wallet object is included in the params). This + * modal window was created for being oppenend by the hw wallet options modal window. + */ +@Component({ + selector: 'app-hw-restore-seed-dialog', + templateUrl: './hw-restore-seed-dialog.component.html', + styleUrls: ['./hw-restore-seed-dialog.component.scss'], +}) +export class HwRestoreSeedDialogComponent extends HwDialogBaseComponent { + form: FormGroup; + // If true, the seed entered by the user will not be loaded on the device, the operation will + // just compare it to the one on the device. + justCheckingSeed: boolean; + + constructor( + @Inject(MAT_DIALOG_DATA) public data: ChildHwDialogParams, + public dialogRef: MatDialogRef, + private hwWalletService: HwWalletService, + formBuilder: FormBuilder, + ) { + super(hwWalletService, dialogRef); + + this.form = formBuilder.group({ + words: [24, Validators.required], + }); + + this.justCheckingSeed = !!this.data.wallet; + } + + startOperation() { + this.currentState = this.states.Processing; + + this.operationSubscription = this.hwWalletService.recoverMnemonic(this.form.controls['words'].value, this.justCheckingSeed).subscribe( + () => { + if (!this.justCheckingSeed) { + // Request the data and state of the hw wallet options modal window to be refreshed. + this.data.requestOptionsComponentRefresh(); + this.closeModal(); + } else { + this.showResult({ + text: 'hardware-wallet.restore-seed.correct-seed', + icon: this.msgIcons.Success, + }); + } + }, + err => this.processHwOperationError(err), + ); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component.html new file mode 100644 index 0000000..cd6c6b6 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component.html @@ -0,0 +1,15 @@ + + + +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'hardware-wallet.update-firmware-warning.update' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component.ts new file mode 100644 index 0000000..2d0808f --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-alert-dialog/hw-update-alert-dialog.component.ts @@ -0,0 +1,39 @@ +import { Component } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; + +/** + * Modal window for alerting the user that there is a firmware update available. If the user + * selects to install the update, the modal window is closed and "true" is returned in the + * "afterClosed" event. + */ +@Component({ + selector: 'app-hw-update-alert-dialog', + templateUrl: './hw-update-alert-dialog.component.html', + styleUrls: ['./hw-update-alert-dialog.component.scss'], +}) +export class HwUpdateAlertDialogComponent extends HwDialogBaseComponent { + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = false; + config.width = '450px'; + + return dialog.open(HwUpdateAlertDialogComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + hwWalletService: HwWalletService, + ) { + super(hwWalletService, dialogRef); + } + + update() { + this._dialogRef.close(true); + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component.html new file mode 100644 index 0000000..206bc13 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component.html @@ -0,0 +1,54 @@ + + +
+ + +
+ {{ 'common.generic-confirmation-check' | translate }} + +
+ +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'common.continue-button' | translate }} + +
+
+ +
+ + + + + + + + + + +
+ + {{ 'common.close-button' | translate }} + +
+
+
\ No newline at end of file diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component.ts new file mode 100644 index 0000000..6a0de0a --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-update-firmware-dialog/hw-update-firmware-dialog.component.ts @@ -0,0 +1,175 @@ +import { Component, OnDestroy } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { SubscriptionLike, of } from 'rxjs'; +import { mergeMap, delay } from 'rxjs/operators'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { OperationError, HWOperationResults } from '../../../../utils/operation-error'; +import { processServiceError } from '../../../../utils/errors'; + +/** + * Allows to download and install the firmware of the hw wallet. + */ +@Component({ + selector: 'app-hw-update-firmware-dialog', + templateUrl: './hw-update-firmware-dialog.component.html', + styleUrls: ['./hw-update-firmware-dialog.component.scss'], +}) +export class HwUpdateFirmwareDialogComponent extends HwDialogBaseComponent implements OnDestroy { + closeIfHwDisconnected = false; + + currentState = this.states.Connecting; + // If the user has confirmed the operation with the checkbox. + confirmed = false; + + deviceInBootloaderMode = false; + deviceHasFirmware = true; + + private checkDeviceSubscription: SubscriptionLike; + + // The texts shown on the modal window depend on the features of the connected device. + + get title(): string { + if (this.currentState === this.states.Connecting) { + return 'hardware-wallet.update-firmware.title-connecting'; + } else if (this.deviceHasFirmware) { + return 'hardware-wallet.update-firmware.title-update'; + } + + return 'hardware-wallet.update-firmware.title-install'; + } + + get text(): string { + if (!this.deviceHasFirmware) { + return 'hardware-wallet.update-firmware.text-no-firmware'; + } + + if (this.deviceInBootloaderMode) { + return 'hardware-wallet.update-firmware.text-bootloader'; + } + + return 'hardware-wallet.update-firmware.text-not-bootloader'; + } + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = false; + config.width = '450px'; + + return dialog.open(HwUpdateFirmwareDialogComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + private hwWalletService: HwWalletService, + private msgBarService: MsgBarService, + ) { + super(hwWalletService, dialogRef); + this.checkDevice(false); + } + + ngOnDestroy() { + super.ngOnDestroy(); + this.msgBarService.hide(); + this.closeCheckDeviceSubscription(); + } + + setConfirmed(event) { + this.confirmed = event.checked; + } + + // Downloads and installs the lastest firmware. + startUpdating() { + this.msgBarService.hide(); + this.showResult({ + text: 'hardware-wallet.update-firmware.text-downloading', + icon: this.msgIcons.Spinner, + }); + + // Temporarily stop checking the device features. + this.closeCheckDeviceSubscription(); + + this.operationSubscription = this.hwWalletService.updateFirmware(() => this.currentState = this.states.Processing).subscribe( + () => { + // Show the success msg. + this.showResult({ + text: 'hardware-wallet.update-firmware.finished', + icon: this.msgIcons.Success, + }); + }, + (err: OperationError) => { + err = processServiceError(err); + + // Show the result. + if (err.type === HWOperationResults.Success) { + this.showResult({ + text: 'hardware-wallet.update-firmware.finished', + icon: this.msgIcons.Success, + }); + } else if (err.type === HWOperationResults.Timeout) { + this.showResult({ + text: 'hardware-wallet.update-firmware.timeout', + icon: this.msgIcons.Error, + }); + } else { + // If there was a simple error, return to the initial state. + setTimeout(() => { + this.msgBarService.showError(err); + }); + + this.checkDevice(false); + + this.currentState = this.states.Initial; + } + }, + ); + } + + /** + * Checks if the device is connected and gets its features. + * @param delayOperation If there must be a small delay before making the operation. + */ + private checkDevice(delayOperation = true) { + this.closeCheckDeviceSubscription(); + + // The call to get the features asks no to cancel the current operation before getting + // the data because the cancel operation does not work well in bootloader mode. + this.checkDeviceSubscription = of(0).pipe(delay(delayOperation ? 1000 : 0), mergeMap(() => this.hwWalletService.getFeatures(false))).subscribe(response => { + this.deviceInBootloaderMode = response.rawResponse.bootloader_mode; + if (this.deviceInBootloaderMode) { + this.deviceHasFirmware = response.rawResponse.firmware_present; + } else { + this.deviceHasFirmware = true; + } + + if (this.currentState === this.states.Connecting) { + this.currentState = this.states.Initial; + } + + // Repeat the operation periodically. + this.checkDevice(); + }, () => { + // Asume the device is not connected. + this.deviceInBootloaderMode = false; + this.deviceHasFirmware = true; + + if (this.currentState === this.states.Connecting) { + this.currentState = this.states.Initial; + } + + // Repeat the operation periodically. + this.checkDevice(); + }); + } + + private closeCheckDeviceSubscription() { + if (this.checkDeviceSubscription) { + this.checkDeviceSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component.html b/src/gui/static/src/app/components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component.html new file mode 100644 index 0000000..f9dbae4 --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component.html @@ -0,0 +1,48 @@ + + +
+ + +
+ {{ 'hardware-wallet.wipe.confirm-delete-check' | translate }} + +
+ +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'common.continue-button' | translate }} + +
+
+ +
+ + + + + + + +
+ + {{ 'common.close-button' | translate }} + +
+
+
diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component.scss b/src/gui/static/src/app/components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component.ts b/src/gui/static/src/app/components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component.ts new file mode 100644 index 0000000..0db148a --- /dev/null +++ b/src/gui/static/src/app/components/layout/hardware-wallet/hw-wipe-dialog/hw-wipe-dialog.component.ts @@ -0,0 +1,66 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { ChildHwDialogParams } from '../hw-options-dialog/hw-options-dialog.component'; +import { HwDialogBaseComponent } from '../hw-dialog-base.component'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; + +/** + * Allows to wipe the device and to remove the wallet from the list. This modal window was + * created for being oppenend by the hw wallet options modal window. + */ +@Component({ + selector: 'app-hw-wipe-dialog', + templateUrl: './hw-wipe-dialog.component.html', + styleUrls: ['./hw-wipe-dialog.component.scss'], +}) +export class HwWipeDialogComponent extends HwDialogBaseComponent { + showDeleteFromList = true; + deleteFromList = true; + + constructor( + @Inject(MAT_DIALOG_DATA) public data: ChildHwDialogParams, + public dialogRef: MatDialogRef, + private hwWalletService: HwWalletService, + private walletsAndAddressesService: WalletsAndAddressesService, + ) { + super(hwWalletService, dialogRef); + + // If no wallet was send as part of the data, the option for removing the wallet from + // the wallet list is not shown and no wallet is removed, as there is no way to know which + // wallet to remove. This is for wiping unknown devices, mainly ones blocked with a PIN code. + if (!data.wallet) { + this.showDeleteFromList = false; + this.deleteFromList = false; + } + } + + // Changes the option which indicates if the wallet must be removed from the wallet list. + setDeleteFromList(event) { + this.deleteFromList = event.checked; + } + + // Wipes the device. + requestWipe() { + this.currentState = this.states.Processing; + + this.operationSubscription = this.hwWalletService.wipe().subscribe( + () => { + this.showResult({ + text: 'hardware-wallet.general.completed', + icon: this.msgIcons.Success, + }); + + // Request the data and state of the hw wallet options modal window to be refreshed. + this.data.requestOptionsComponentRefresh(); + + // Remove the wallet from the list, if requested. + if (this.deleteFromList) { + this.walletsAndAddressesService.deleteWallet(this.data.wallet.id); + } + }, + err => this.processHwOperationError(err), + ); + } +} diff --git a/src/gui/static/src/app/components/layout/header/header.component.html b/src/gui/static/src/app/components/layout/header/header.component.html new file mode 100644 index 0000000..7792b80 --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/header.component.html @@ -0,0 +1,79 @@ +
+ +
+ +
+ +
+
+

{{ 'common.loading' | translate }}

+

{{ synchronizationPercentage | percent:'1.2-2' }}

+

{{ 'header.syncing-blocks' | translate }}

+

{{ coins | amount:true:'first' }} {{ coins | amount:true:'last' }}

+

+ + {{ (coins * price) | currency:'USD':'symbol':'1.2-2' }} + - + ({{ price | currency:'USD':'symbol':'1.2-2' }}) + + {{ 'common.loading' | translate }} +

+
+
+ +
+

{{ 'common.loading' | translate }}

+

{{ 'header.syncing-blocks' | translate }} {{ '(' + currentBlock + '/' + highestBlock + ')' }}

+

{{ hours | amount:false }}

+
+ +
+

+ {{ 'header.syncing-blocks' | translate }} + + {{ '(' + currentBlock + '/' + highestBlock + ')' }} + +

+
+
+
+
+ + + +
+
+ {{ 'header.warnings.update-part1' | translate }} + v{{ appUpdateService.lastestVersion }} + {{ 'header.warnings.update-part3' | translate }} +
+
+
+
{{ 'header.warnings.csrf' | translate }}
+
+
+
{{ 'header.warnings.no-connections' | translate }}
+
+
+
+ {{ 'header.warnings.pending-txs-part1' | translate }} + {{ 'header.warnings.pending-txs-part2' | translate }} + {{ 'header.warnings.pending-txs-part2' | translate }} + {{ 'header.warnings.pending-txs-part3' | translate }} +
+
+ {{ 'header.warnings.synchronizing' | translate }} +
+
+
diff --git a/src/gui/static/src/app/components/layout/header/header.component.scss b/src/gui/static/src/app/components/layout/header/header.component.scss new file mode 100644 index 0000000..7b5f558 --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/header.component.scss @@ -0,0 +1,88 @@ +@import '../../../../theme/variables'; + +.-container { + background-color: $white; + border-bottom: 2px solid $grey-very-light; +} + +.large-header { + background-repeat: no-repeat; + background-position: center center; + background-size: 100% auto; + background-size: cover; + + .gradient { + background-size: 100% 100%; + display: flex; + flex-flow: column; + align-items: stretch; + min-height: 190px; + } +} + +.balance-container { + align-items: center; + display: flex; + flex: 1 1 auto; + font-size: $font-size-standard-minus; + justify-content: center; + text-align: center; + + .balance { + .coins { + line-height: 1; + margin: 0 0 0.5em; + + span { + font-size: 4em; + } + } + + .loading-header { + margin: 0 0 0.5em; + font-size: 2em; + } + } + + .dollars { + margin: 0; + } +} + +.hour-balance { + text-align: center; + + p { + border-radius: 1000px; + display: inline-block; + font-size: $font-size-standard-minus; + line-height: 1.8; + margin: 1em 0 2em; + padding: 0 30px; + } +} + +.empty-hour-balance { + height: 30px; +} + +.notification-bar { + background-color: $red; + color: $white; + min-height: 64px; + display: flex; + font-size: 18px; + padding: 15px 30px; + text-align: center; + line-height: 1.2; + + div { + margin: auto; + + a { + text-decoration: underline; + color: $white; + cursor: pointer; + } + } +} diff --git a/src/gui/static/src/app/components/layout/header/header.component.ts b/src/gui/static/src/app/components/layout/header/header.component.ts new file mode 100644 index 0000000..144c180 --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/header.component.ts @@ -0,0 +1,160 @@ +import { filter } from 'rxjs/operators'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { SubscriptionLike } from 'rxjs'; +import { BigNumber } from 'bignumber.js'; + +import { PriceService } from '../../../services/price.service'; +import { BlockchainService } from '../../../services/blockchain.service'; +import { NetworkService } from '../../../services/network.service'; +import { AppConfig } from '../../../app.config'; +import { BalanceAndOutputsService } from '../../../services/wallet-operations/balance-and-outputs.service'; +import { AddressWithBalance, AddressMap } from '../../../services/wallet-operations/wallet-objects'; +import { Coin } from '../../../coins/coin'; +import { CoinService } from '../../../services/coin.service'; +import { AppUpdateService } from '../../../services/app-update.service'; +import { NodeService } from '../../../services/node.service'; +import { TransactionListComponent } from '../../pages/transaction-list/transaction-list.component'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; + +/** + * Header shown at the top of most pages. + */ +@Component({ + selector: 'app-header', + templateUrl: './header.component.html', + styleUrls: ['./header.component.scss'], +}) +export class HeaderComponent implements OnInit, OnDestroy { + @Input() headline: string; + + currentCoin: Coin; + + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + // Data about the synchronization status of the node. + synchronizationInfoObtained = false; + synchronizationPercentage: number; + // Use synchronizationInfoObtained to know if the value has been already updated. + synchronized = false; + currentBlock: number; + highestBlock: number; + + // Params for the style of some UI elements. + textColor = ''; + hoursTextColor = ''; + hoursBackgroundColor = ''; + + // Data about the balance. + coins: string; + hours: string; + + showPrice = false; + price: number; + // If the node has pending transactions potentially affecting the user balance. + hasPendingTxs: boolean; + // If the app already got the balance from the node. + balanceObtained = false; + walletDownloadUrl = AppConfig.walletDownloadUrl; + /** + * If it is possible to show the progress of the blockchain synchronization while the + * backend is out of sync. + */ + showBlockchainSyncProgress = true; + + historyPage = TransactionListComponent; + + private subscriptionsGroup: SubscriptionLike[] = []; + + constructor( + public nodeService: NodeService, + public appUpdateService: AppUpdateService, + public networkService: NetworkService, + private blockchainService: BlockchainService, + private priceService: PriceService, + private balanceAndOutputsService: BalanceAndOutputsService, + private coinService: CoinService, + private msgBarService: MsgBarService, + private walletsAndAddressesService: WalletsAndAddressesService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.showBlockchainSyncProgress = coinService.currentCoinInmediate.coinTypeFeatures.blockchainSyncProgress; + } + + ngOnInit() { + // Get the currently selected coin. + this.subscriptionsGroup.push(this.coinService.currentCoin.subscribe((coin: Coin) => { + this.showPrice = !!coin.priceTickerId; + this.currentCoin = coin; + + this.textColor = coin.styleConfig.headerTextColor; + this.hoursTextColor = coin.styleConfig.headerHoursTextColor; + this.hoursBackgroundColor = coin.styleConfig.headerHoursBackgroundColor; + })); + + // Get the synchronization status. + this.subscriptionsGroup.push(this.blockchainService.progress.pipe(filter(response => !!response)).subscribe(response => { + this.synchronizationInfoObtained = true; + this.highestBlock = response.highestBlock; + this.currentBlock = response.currentBlock; + this.synchronizationPercentage = this.currentBlock && this.highestBlock ? (this.currentBlock / this.highestBlock) : 0; + this.synchronized = response.synchronized; + })); + + // Get the current price. + this.subscriptionsGroup.push(this.priceService.price.subscribe(price => this.price = price)); + + // Get the current balance. + this.subscriptionsGroup.push(this.balanceAndOutputsService.walletsWithBalance.subscribe(wallets => { + const addressMap = new AddressMap(this.walletsAndAddressesService.formatAddress); + wallets.forEach(wallet => { + wallet.addresses.forEach(address => { + if (!addressMap.has(address.printableAddress)) { + addressMap.set(address.printableAddress, address); + } else { + // This prevents a minor glich due to an edge case in which, just for a few seconds, + // some addresses of a newly added hw wallet which has also been added as a software + // wallet can report 0 coins while the node is reporting some coins on the same + // addresses on the previously created software wallet. + const previouslySavedAddress = addressMap.get(address.printableAddress); + if (previouslySavedAddress.coins.isLessThan(address.coins)) { + addressMap.set(address.printableAddress, address); + } + } + }); + }); + + let coins = new BigNumber(0); + let hours = new BigNumber(0); + addressMap.forEach(addr => { + coins = coins.plus(addr.coins); + if (addr.hours) { + hours = hours.plus(addr.hours); + } + }); + this.coins = coins.toString(); + this.hours = hours.toString(); + + })); + + // Know if there are pending transactions. + this.subscriptionsGroup.push(this.balanceAndOutputsService.hasPendingTransactions.subscribe(hasPendingTxs => { + this.hasPendingTxs = hasPendingTxs; + })); + + // Know when the app gets the balance from the node. + this.subscriptionsGroup.push(this.balanceAndOutputsService.firstFullUpdateMade.subscribe(firstFullUpdateMade => { + this.balanceObtained = firstFullUpdateMade; + })); + } + + // Shows a msg telling the user that the transaction history is already being displayed. + informAlreadyShowingHistory() { + this.msgBarService.showError('header.warnings.pending-link-error'); + } + + ngOnDestroy() { + this.subscriptionsGroup.forEach(sub => sub.unsubscribe()); + this.msgBarService.hide(); + } +} diff --git a/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.html b/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.html new file mode 100644 index 0000000..f7e4784 --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.html @@ -0,0 +1,34 @@ + diff --git a/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.scss b/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.scss new file mode 100644 index 0000000..026af73 --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.scss @@ -0,0 +1,62 @@ +@import '../../../../../theme/variables'; + +$nav-bar-height: 66px; + +.-buttons { + display: flex; + width: 100%; + + .-button { + cursor: pointer; + padding: 0 20px; + opacity: 0.2; + display: block; + text-decoration: none; + color: $black; + display: flex; + height: $nav-bar-height; + align-items: center; + + &:hover { + opacity: 0.4; + } + + &:active { + opacity: 0.55; + } + + img { + float: left; + height: $normal-icon-size; + width: $normal-icon-size; + + @media (max-width: $max-sm-width) { + & { + height: $normal-icon-size * 0.85; + width: $normal-icon-size * 0.85; + } + } + } + + span { + font-size: $font-size-standard-plus; + line-height: 1.3; + margin: 0 5px; + + @media (max-width: $max-sm-width) { + & { + font-size: $font-size-standard-plus * 0.85; + } + } + } + } + + .-switch { + align-self: center; + padding: 0 20px; + } +} + +.full-opacity { + opacity: 1 !important; +} diff --git a/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.ts b/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.ts new file mode 100644 index 0000000..ffbf50c --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/nav-bar/nav-bar.component.ts @@ -0,0 +1,44 @@ +import { Component, OnDestroy } from '@angular/core'; +import { SubscriptionLike } from 'rxjs'; + +import { AppConfig } from '../../../../app.config'; +import { NavBarSwitchService } from '../../../../services/nav-bar-switch.service'; +import { environment } from '../../../../../environments/environment'; +import { CoinService } from '../../../../services/coin.service'; + +/** + * Navigation bar shown on the header. + */ +@Component({ + selector: 'app-nav-bar', + templateUrl: './nav-bar.component.html', + styleUrls: ['./nav-bar.component.scss'], +}) +export class NavBarComponent implements OnDestroy { + otcEnabled = AppConfig.otcEnabled; + exchangeEnabled = !!environment.swaplab.apiKey; + + private coinSubscription: SubscriptionLike; + + constructor( + public navBarSwitchService: NavBarSwitchService, + private coinService: CoinService, + ) { + // Currently the exchange option must only appear for Skycoin. + this.coinSubscription = this.coinService.currentCoin.subscribe(coin => { + this.exchangeEnabled = !!environment.swaplab.apiKey; + + if (coin.coinName.toLowerCase() !== 'skycoin') { + this.exchangeEnabled = false; + } + }); + } + + ngOnDestroy() { + this.coinSubscription.unsubscribe(); + } + + changeActiveComponent(value) { + this.navBarSwitchService.setActiveComponent(value); + } +} diff --git a/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.html b/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.html new file mode 100644 index 0000000..c3e1b34 --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.html @@ -0,0 +1,76 @@ +
+ +
+ +
+ +
+ +
+
+ +
+ {{ headline }} +
+
+ + + + + + + + {{ 'header.explorer-link' | translate:{coinName: currentCoin.coinName} }} + +
+ +
+ +
+ + +
diff --git a/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.scss b/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.scss new file mode 100644 index 0000000..b5366bf --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.scss @@ -0,0 +1,128 @@ +@import '../../../../../theme/variables'; + +$side-containers-width: 230px; +$bar-height: 50px; + +:host { + display: flex; + width: 100%; +} + +.buttons-left { + height: 0px; + padding: 10px 0px 10px 10px; + width: $side-containers-width; +} + +.round-button { + border-radius: 1000px; + overflow: hidden; + margin-bottom: 10px; + min-width: 0px !important; + line-height: 1; + height: 40px; + + .coin-icon { + margin-left: 4px; + width: 20px; + height: 20px; + } + + .coin-name { + margin-left: 5px; + margin-right: 2px; + font-size: $font-size-mini; + } + + .main-container { + display: flex; + align-items: center; + padding: 5px 0px; + + mat-icon { + width: 22px; + height: 22px; + font-size: 22px; + } + + .spinner-container { + width: 22px; + height: 22px; + + mat-spinner { + height: 18px !important; + width: 18px !important; + opacity: 0.5; + margin: 0 !important; + position: relative; + top: 2px; + + ::ng-deep svg { + height: 18px !important; + width: 18px !important; + } + } + } + + .text-container { + font-size: $font-size-mini; + text-align: left; + margin: 1px 8px 3px 8px; + + .first-label { + opacity: 0.7; + line-height: 1; + } + + .second-label { + line-height: 1; + } + } + } +} + +.blinking-warning-icon { + font-size: 18px; + vertical-align: middle; + animation: alert-blinking 2s linear infinite; +} + +.title { + font-size: $font-size-standard; + font-weight: 700; + flex: 1 1 auto; + letter-spacing: 1px; + line-height: $bar-height; + text-align: center; +} + +.buttons-right { + height: 0px; + text-align: right; + width: $side-containers-width; + + .button { + height: $bar-height; + width: $bar-height; + } +} + +.mat-menu-item { + height: 50px; + line-height: 50px; + font-size: $font-size-standard-plus; +} + +.separator { + width: 100%; + height: 2px; + background-color: $grey-very-light; + margin: 8px 0px; +} + +.flag { + width: 16px; + height: 16px; + position: relative; + top: 3px; +} diff --git a/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.ts b/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.ts new file mode 100644 index 0000000..f0c75c0 --- /dev/null +++ b/src/gui/static/src/app/components/layout/header/top-bar/top-bar.component.ts @@ -0,0 +1,150 @@ +import { Component, Input, OnInit, OnDestroy, NgZone, Renderer2, ViewChild } from '@angular/core'; +import { Subscription, interval } from 'rxjs'; +import { MatDialog } from '@angular/material/dialog'; +import { Overlay } from '@angular/cdk/overlay'; +import { MatSpinner } from '@angular/material/progress-spinner'; + +import { LanguageData, LanguageService } from '../../../../services/language.service'; +import { SelectLanguageComponent } from '../../select-language/select-language.component'; +import { BalanceAndOutputsService } from '../../../../services/wallet-operations/balance-and-outputs.service'; +import { CoinService } from '../../../../services/coin.service'; +import { Coin } from '../../../../coins/coin'; +import { AppUpdateService } from '../../../../services/app-update.service'; +import { SelectCoinOverlayComponent } from '../../select-coin-overlay/select-coin-overlay.component'; + +/** + * Area of the header with the title and the menu. + */ +@Component({ + selector: 'app-top-bar', + templateUrl: './top-bar.component.html', + styleUrls: ['./top-bar.component.scss'], +}) +export class TopBarComponent implements OnInit, OnDestroy { + @ViewChild('balanceSpinner') balanceSpinner: MatSpinner; + @Input() headline: string; + + // Currently selected language. + language: LanguageData; + // If the balance is currently beeing refreshed. + refreshingBalance = false; + // If the last time the system tried to refresh the balance there was an error. + problemRefreshingBalance = false; + // If the app already got the balance from the node. + balanceObtained = false; + // How many minutes ago the balance was refreshed. + timeSinceLastBalanceUpdate = 0; + // If the app currently allows the user to select more than one coin. + hasManyCoins = false; + // Currently selected coin. + currentCoin: Coin; + // The last moment in which the balance was updated. + lastBalancesUpdateTime = new Date(2000, 1); + + // Vars for showing only the options available for the current coin. + showNetworkOption: boolean; + showBackupOption: boolean; + showOutputsOption: boolean; + showPendingTxsOption: boolean; + + // Params for the style of some UI elements. + textColor = ''; + buttonBorder = ''; + + private subscriptionsGroup: Subscription[] = []; + + constructor( + public appUpdateService: AppUpdateService, + private languageService: LanguageService, + private dialog: MatDialog, + private balanceAndOutputsService: BalanceAndOutputsService, + private ngZone: NgZone, + private coinService: CoinService, + private overlay: Overlay, + private renderer: Renderer2, + ) { + this.showNetworkOption = this.coinService.currentCoinInmediate.coinTypeFeatures.networkingStats; + this.showBackupOption = this.coinService.currentCoinInmediate.coinTypeFeatures.softwareWallets; + this.showOutputsOption = this.coinService.currentCoinInmediate.coinTypeFeatures.outputs; + this.showPendingTxsOption = this.coinService.currentCoinInmediate.coinTypeFeatures.showAllPendingTransactions; + } + + ngOnInit() { + this.subscriptionsGroup.push(this.languageService.currentLanguage.subscribe(lang => this.language = lang)); + + this.subscriptionsGroup.push(this.coinService.currentCoin.subscribe(coin => { + this.currentCoin = coin; + + this.textColor = coin.styleConfig.headerTextColor; + this.buttonBorder = coin.styleConfig.headerTextColor + ' 1px solid'; + })); + + this.hasManyCoins = this.coinService.coins.length > 1; + + // Update the vars related to the balance. + + this.subscriptionsGroup.push(this.balanceAndOutputsService.firstFullUpdateMade.subscribe(firstFullUpdateMade => { + this.balanceObtained = firstFullUpdateMade; + })); + + this.subscriptionsGroup.push( + this.balanceAndOutputsService.lastBalancesUpdateTime.subscribe(date => { + this.lastBalancesUpdateTime = date; + this.timeSinceLastBalanceUpdate = this.getTimeSinceLastBalanceUpdate(); + }), + ); + + this.subscriptionsGroup.push( + this.balanceAndOutputsService.refreshingBalance.subscribe(response => { + this.refreshingBalance = response; + + if (response) { + // Update the color of the spinner. + setTimeout(() => { + const circle = this.balanceSpinner._elementRef.nativeElement.querySelector('circle'); + if (circle) { + this.renderer.setStyle(circle, 'stroke', this.textColor); + } + }); + } + }), + ); + + this.subscriptionsGroup.push( + this.balanceAndOutputsService.hadErrorRefreshingBalance.subscribe(response => this.problemRefreshingBalance = response), + ); + + this.ngZone.runOutsideAngular(() => { + this.subscriptionsGroup.push( + interval(5000).subscribe(() => { + this.ngZone.run(() => this.timeSinceLastBalanceUpdate = this.getTimeSinceLastBalanceUpdate()); + }), + ); + }); + } + + ngOnDestroy() { + this.subscriptionsGroup.forEach(sub => sub.unsubscribe()); + } + + changeCoin() { + SelectCoinOverlayComponent.openOverlay(this.dialog, this.renderer, this.overlay); + } + + refresBalance() { + if (!this.refreshingBalance) { + this.balanceAndOutputsService.refreshBalance(); + } + } + + changelanguage() { + SelectLanguageComponent.openDialog(this.dialog); + } + + // Gets how many minutes ago the balance was refreshed. + private getTimeSinceLastBalanceUpdate(): number { + const diffMs: number = new Date().getTime() - this.lastBalancesUpdateTime.getTime(); + + return Math.floor(diffMs / 60000); + } +} diff --git a/src/gui/static/src/app/components/layout/loading-content/loading-content.component.html b/src/gui/static/src/app/components/layout/loading-content/loading-content.component.html new file mode 100644 index 0000000..0c17084 --- /dev/null +++ b/src/gui/static/src/app/components/layout/loading-content/loading-content.component.html @@ -0,0 +1,10 @@ +
+
+ +

{{ 'common.loading' | translate }}

+
+
+ announcement +

{{ noDataText | translate }}

+
+
diff --git a/src/gui/static/src/app/components/layout/loading-content/loading-content.component.scss b/src/gui/static/src/app/components/layout/loading-content/loading-content.component.scss new file mode 100644 index 0000000..4491e61 --- /dev/null +++ b/src/gui/static/src/app/components/layout/loading-content/loading-content.component.scss @@ -0,0 +1,27 @@ +@import '../../../../theme/variables'; + +.-content { + text-align: center; + margin: 50px 0; + font-size: $font-size-standard; + opacity: 0.5; + + p { + margin-top: 15px; + } + + i { + color: $grey; + font-size: 40px; + opacity: 0.5; + } + + mat-spinner { + display: inline-block; + opacity: 0.5; + + ::ng-deep circle { + stroke: $grey; + } + } +} diff --git a/src/gui/static/src/app/components/layout/loading-content/loading-content.component.ts b/src/gui/static/src/app/components/layout/loading-content/loading-content.component.ts new file mode 100644 index 0000000..1c9954b --- /dev/null +++ b/src/gui/static/src/app/components/layout/loading-content/loading-content.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; + +/** + * Shows a loading animation. When the animation is not active, it shows an info msg and an + * info icon, useful for indicating that no data was found or any other problem related to + * loading the data. + */ +@Component({ + selector: 'app-loading-content', + templateUrl: './loading-content.component.html', + styleUrls: ['./loading-content.component.scss'], +}) +export class LoadingContentComponent { + // When true, the loading animation and a predefined loading msg is shown. + @Input() isLoading = true; + // Msg shown if isLoading is false. + @Input() noDataText: string; +} diff --git a/src/gui/static/src/app/components/layout/modal/modal.component.html b/src/gui/static/src/app/components/layout/modal/modal.component.html new file mode 100644 index 0000000..68311c7 --- /dev/null +++ b/src/gui/static/src/app/components/layout/modal/modal.component.html @@ -0,0 +1,9 @@ +
+ {{ headline }} + +
+ diff --git a/src/gui/static/src/app/components/layout/modal/modal.component.scss b/src/gui/static/src/app/components/layout/modal/modal.component.scss new file mode 100644 index 0000000..dc73231 --- /dev/null +++ b/src/gui/static/src/app/components/layout/modal/modal.component.scss @@ -0,0 +1,43 @@ +@import '../../../../theme/variables'; + +$close-button-size: $normal-icon-size; + +.-header { + background-color: $grey-lightest; + line-height: 50px; + position: relative; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: 0 $close-button-size 0 $close-button-size; + font-size: $font-size-standard-plus; + + img { + height: $close-button-size; + position: absolute; + right: 9px; + top: 9px; + } +} + +mat-dialog-content::before { + content: ''; + padding-top: $modal-content-padding; + height: 0px; + display: block; +} + +mat-dialog-content::after { + content: ''; + padding-top: $modal-content-padding; + height: 0px; + display: block; +} + +.red-title { + text-transform: uppercase; + font-weight: bold; + letter-spacing: 1px; + color: $red; +} diff --git a/src/gui/static/src/app/components/layout/modal/modal.component.ts b/src/gui/static/src/app/components/layout/modal/modal.component.ts new file mode 100644 index 0000000..ba683dc --- /dev/null +++ b/src/gui/static/src/app/components/layout/modal/modal.component.ts @@ -0,0 +1,44 @@ +import { Component, Input, HostListener } from '@angular/core'; +import { MatDialogRef, MatDialog } from '@angular/material/dialog'; + +/** + * Parent component for the content of all modal windows. It provides the title, scroll + * bars and more. It is designed to be added in the HTML of modal window components, + * wrapping the content. + */ +@Component({ + selector: 'app-modal', + templateUrl: './modal.component.html', + styleUrls: ['./modal.component.scss'], +}) +export class ModalComponent { + @Input() useRedTitle = false; + @Input() headline: string; + // This disables all the ways provided by default by the UI for closing the modal window. + @Input() disableDismiss: boolean; + + // MatDialogRef of the modal window component which is using this component for wrapping + // the contents. + private dialogInternal: MatDialogRef; + @Input() set dialog(val: MatDialogRef) { + val.disableClose = true; + this.dialogInternal = val; + } + + @HostListener('window:keyup.esc') onKeyUp() { + this.closePopup(); + } + + constructor( + private matDialog: MatDialog, + ) { } + + closePopup() { + if (!this.disableDismiss) { + // Continue only if the current modal window is the topmost one. + if (this.matDialog.openDialogs[this.matDialog.openDialogs.length - 1].id === this.dialogInternal.id) { + this.dialogInternal.close(); + } + } + } +} diff --git a/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.html b/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.html new file mode 100644 index 0000000..cb310e3 --- /dev/null +++ b/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.html @@ -0,0 +1,11 @@ +
+
+
{{ config.icon }}
+
+
{{ config.title | translate }}
+
{{ config.text | translate }} + {{ config.link }}
+
+
close
+
+
diff --git a/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.scss b/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.scss new file mode 100644 index 0000000..39fa8f0 --- /dev/null +++ b/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.scss @@ -0,0 +1,57 @@ +@import '../../../../theme/variables'; + +.main-container { + position: fixed; + bottom: 0px; + width: 100%; + z-index: 1000000; + display: flex; + flex-direction: row; + justify-content: center; +} + +.internal-container { + color: white; + width: fit-content; + min-width: 40%; + max-width: 90%; + display: flex; + padding: 10px; + border-top-left-radius: $rounded-element-border-radius; + border-top-right-radius: $rounded-element-border-radius; +} + +.red-background { + background-color: rgba(255, 0, 0, 0.7); +} + +.green-background { + background-color: rgba(31, 177, 31, 0.7); +} + +.yellow-background { + background-color: rgba(255, 94, 0, 0.7); +} + +.icon-container { + margin-right: 10px; +} + +.text-container { + flex-grow: 1; + margin-right: 10px; + + .title { + font-size: $font-size-big; + margin-top: -1px; + } + + .text { + font-size: $font-size-standard; + margin-top: 2px; + } + + .link { + color: white; + } +} diff --git a/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.ts b/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.ts new file mode 100644 index 0000000..03215fc --- /dev/null +++ b/src/gui/static/src/app/components/layout/msg-bar/msg-bar.component.ts @@ -0,0 +1,64 @@ +import { Component } from '@angular/core'; + +/** + * Icons the msg bar can show. + */ +export enum MsgBarIcons { + Error = 'error', + Done = 'done', + Warning = 'warning', +} + +// The enum has the names of the classes used for displaying the colors. +/** + * Colors the msg bar can show. + */ +export enum MsgBarColors { + Red = 'red-background', + Green = 'green-background', + Yellow = 'yellow-background', +} + +/** + * Settings for the msg bar. + */ +export class MsgBarConfig { + title?: string; + text: string; + /** + * If set, the link will be shown after the text. Must be a valid URL. + */ + link?: string; + icon?: MsgBarIcons; + color?: MsgBarColors; +} + +/** + * Small horizontal bar used by the app for showing notifications. It was made to be created + * and added to the UI just after starting the app and being controlled by a service. + */ +@Component({ + selector: 'app-msg-bar', + templateUrl: './msg-bar.component.html', + styleUrls: ['./msg-bar.component.scss'], +}) +export class MsgBarComponent { + config = new MsgBarConfig(); + visible = false; + + constructor() { } + + show() { + if (this.visible) { + this.visible = false; + // Gives the illusion of the bar reapering if it was already being shown. + setTimeout(() => this.visible = true, 32); + } else { + this.visible = true; + } + } + + hide() { + this.visible = false; + } +} diff --git a/src/gui/static/src/app/components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component.html b/src/gui/static/src/app/components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component.html new file mode 100644 index 0000000..2f415fe --- /dev/null +++ b/src/gui/static/src/app/components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component.html @@ -0,0 +1,24 @@ + + + {{ 'send.bulk-send.indications' | translate }} + + + {{ 'send.bulk-send.indications-without-hours' | translate }} + + +
+ + {{ 'send.bulk-send.process-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component.scss b/src/gui/static/src/app/components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component.ts b/src/gui/static/src/app/components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component.ts new file mode 100644 index 0000000..f70fc5b --- /dev/null +++ b/src/gui/static/src/app/components/layout/multiple-destinations-dialog/multiple-destinations-dialog.component.ts @@ -0,0 +1,164 @@ +import { Component, OnInit, OnDestroy, Inject } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +import { MsgBarService } from '../../../services/msg-bar.service'; +import { AppConfig } from '../../../app.config'; +import { Destination } from '../../pages/send-coins/form-parts/form-destination/form-destination.component'; +import { CoinService } from '../../../services/coin.service'; + +/** + * Modal window which allows the user to enter multiple destinations with just a text + * string, when creating a transaction. The format of the string is just each destination + * in a new line, each one with the address, coins and hours (optional and only if the + * currently selected coin includes coin hours), separated by commas, + * in that order. If a destination has hours, all destinations must have hours. Destinations + * can have invalid addresses, coins and hours, the only thing this component checks is if + * there is a string value for each property of the destinations. In the "afterClosed" event + * it returns an array with all the destinations as instances of BasicDestinationData, or + * null, if the operation was cancelled. + */ +@Component({ + selector: 'app-multiple-destinations-dialog', + templateUrl: './multiple-destinations-dialog.component.html', + styleUrls: ['./multiple-destinations-dialog.component.scss'], +}) +export class MultipleDestinationsDialogComponent implements OnInit, OnDestroy { + form: FormGroup; + + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + + // Vars with the validation error messages. + inputErrorMsg = ''; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, content: string): MatDialogRef { + const config = new MatDialogConfig(); + config.data = content; + config.autoFocus = true; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(MultipleDestinationsDialogComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) private data: string, + private formBuilder: FormBuilder, + private msgBarService: MsgBarService, + coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + } + + ngOnInit() { + this.form = this.formBuilder.group({ + data: [this.data], + }); + + this.form.setValidators(this.validateForm.bind(this)); + } + + ngOnDestroy() { + this.msgBarService.hide(); + } + + /** + * Process the text entered by the user. If there are no errors, it closes the modal window and + * returns the list will all the destinations. + */ + processData() { + try { + // Check if empty. + if ((this.form.value.data as string).trim().length === 0) { + this.msgBarService.showError('send.bulk-send.no-data-error'); + + return; + } + + // Get all destinations. + let entries = (this.form.value.data as string).split(/\r?\n/); + if (!entries || entries.length === 0) { + this.msgBarService.showError('send.bulk-send.no-data-error'); + + return; + } + + // Remove empty lines. + entries = entries.filter(entry => entry.trim().length > 0); + + // Destination must have 2 or 3 (if including hours) parts. + const firstElementParts = entries[0].split(',').length; + if (firstElementParts !== 2 && (firstElementParts !== 3 || !this.coinHasHours)) { + this.msgBarService.showError('send.bulk-send.invalid-data-error'); + + return; + } + + // Separate all the parts each destination. + const processedEntries: Destination[] = []; + let consistentNumberOfParts = true; + let invalidDataFound = false; + entries.forEach(entry => { + const entryDataParts = entry.split(','); + if (entryDataParts.length !== 2 && (entryDataParts.length !== 3 || !this.coinHasHours)) { + invalidDataFound = true; + } + + if (!invalidDataFound) { + const data: Destination = { + address: entryDataParts[0].trim(), + coins: entryDataParts[1].trim(), + originalAmount: null, + }; + data.hours = entryDataParts.length === 3 ? entryDataParts[2].trim() : undefined; + processedEntries.push(data); + + // Check if this has the same number of parts as the first one. + if (entryDataParts.length !== firstElementParts) { + consistentNumberOfParts = false; + } + } + }); + + // Do not allow a mix of some destinations with hours and others without them. + if (invalidDataFound) { + this.msgBarService.showError('send.bulk-send.invalid-data-error'); + + return; + } + + // Do not allow a mix of some destinations with hours and others without them. + if (!consistentNumberOfParts) { + this.msgBarService.showError('send.bulk-send.inconsistent-data-error'); + + return; + } + + this.dialogRef.close(processedEntries); + } catch (e) { + this.msgBarService.showError('send.bulk-send.invalid-data-error'); + } + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.inputErrorMsg = ''; + + let valid = true; + + if (!this.form.get('data').value || !this.form.get('data').value.trim()) { + valid = false; + if (this.form.get('data').touched) { + this.inputErrorMsg = 'send.bulk-send.data-error-info'; + } + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.html b/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.html new file mode 100644 index 0000000..f4f7cc9 --- /dev/null +++ b/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.html @@ -0,0 +1,45 @@ + +
{{ data.description | translate }}
+
+
+ + +
+
+ + +
+
+ + {{ 'password.reset-link' | translate }} + +
+ + {{ 'password.proceed-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.scss b/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.scss new file mode 100644 index 0000000..69ef3ae --- /dev/null +++ b/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.scss @@ -0,0 +1,7 @@ +@import '../../../../theme/variables'; + +.link { + width: 100%; + display: inline-block; + text-align: center; +} diff --git a/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.ts b/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.ts new file mode 100644 index 0000000..cd56a48 --- /dev/null +++ b/src/gui/static/src/app/components/layout/password-dialog/password-dialog.component.ts @@ -0,0 +1,203 @@ +import { Component, Inject, OnDestroy, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { MatDialogRef } from '@angular/material/dialog'; +import { FormControl, FormGroup } from '@angular/forms'; +import { Subject } from 'rxjs'; + +import { ButtonComponent } from '../button/button.component'; +import { processServiceError } from '../../../utils/errors'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { AppConfig } from '../../../app.config'; +import { OperationError } from './../../../utils/operation-error'; +import { WalletBase, WalletTypes } from '../../../services/wallet-operations/wallet-objects'; + +export interface PasswordSubmitEvent { + /** + * Password entered by the user. + */ + password: string; + /** + * Function for closing the modal window after completing the operation. + */ + close(): void; + /** + * Function for informing the modal window about an error while completing the operation. + */ + error(error: OperationError): void; +} + +/** + * Settings for PasswordDialogComponent. + */ +export interface PasswordDialogParams { + /** + * If true, the user will have to confirm the password in a second field. + */ + confirm?: boolean; + /** + * Optional help text. + */ + description?: string; + /** + * Optional warning text. + */ + warning?: boolean; + /** + * Custom title for the modal window. + */ + title?: string; + /** + * Wallet to which the resquested password corresponds. + */ + wallet: WalletBase; +} + +/** + * Modal window for requesting the password of a wallet. After the user enters the password, + * it sends the passwordSubmit event, with the password, to let the code which openned this + * modal window to continue with the operation. After finishing the operation, the code + * must use the object returned by the passwordSubmit event to close the modal window + * or for informing about an error. + */ +@Component({ + selector: 'app-password-dialog', + templateUrl: './password-dialog.component.html', + styleUrls: ['./password-dialog.component.scss'], +}) +export class PasswordDialogComponent implements OnInit, OnDestroy { + @ViewChild('button') button: ButtonComponent; + form: FormGroup; + passwordSubmit = new Subject(); + working = false; + + // Vars with the validation error messages. + password1ErrorMsg = ''; + password2ErrorMsg = ''; + + walletTypes = WalletTypes; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, params: PasswordDialogParams, smallSize = true): MatDialogRef { + const config = new MatDialogConfig(); + config.data = params; + config.autoFocus = true; + config.width = smallSize ? '260px' : AppConfig.mediumModalWidth; + + return dialog.open(PasswordDialogComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public data: PasswordDialogParams, + public dialogRef: MatDialogRef, + private msgBarService: MsgBarService, + private changeDetector: ChangeDetectorRef, + ) { + // Se default values. + this.data = Object.assign({ + confirm: false, + description: null, + warning: false, + title: null, + wallet: null, + }, data || {}); + } + + ngOnInit() { + this.form = new FormGroup({}); + this.form.addControl('password', new FormControl('')); + this.form.addControl('confirm_password', new FormControl('')); + + if (this.data.confirm) { + this.form.get('confirm_password').enable(); + } else { + this.form.get('confirm_password').disable(); + } + + this.form.setValidators(this.validateForm.bind(this)); + + // Make the window bigger if a help msg is going to be shown. + if (this.data.description) { + this.dialogRef.updateSize('400px'); + } + } + + ngOnDestroy() { + this.msgBarService.hide(); + this.passwordSubmit.complete(); + } + + /** + * Deactivates the UI and sends the password. + */ + proceed() { + if (this.working || !this.form.valid) { + return; + } + + this.msgBarService.hide(); + + this.button.setLoading(); + this.working = true; + + this.passwordSubmit.next({ + password: this.form.get('password').value, + close: this.close.bind(this), + error: this.error.bind(this), + }); + + this.changeDetector.detectChanges(); + } + + validateForm() { + this.password1ErrorMsg = ''; + this.password2ErrorMsg = ''; + + let valid = true; + + if (!this.form.get('password').value) { + valid = false; + if (this.form.get('password').touched) { + this.password1ErrorMsg = 'password.password-error-info'; + } + } + + if (this.data.confirm) { + if (!this.form.get('confirm_password').value) { + valid = false; + if (this.form.get('confirm_password').touched) { + this.password2ErrorMsg = 'password.password-error-info'; + } + } + + // If both password fields have a value, check if the 2 passwords entered by the user + // are equal. + if (valid && this.form.get('password').value !== this.form.get('confirm_password').value) { + valid = false; + this.password2ErrorMsg = 'password.confirm-error-info'; + } + } + + return valid ? null : { Invalid: true }; + } + + private close() { + this.dialogRef.close(); + } + + /** + * Reactivates the UI and shows an error. + */ + private error(error: OperationError) { + if (!error.type) { + error = processServiceError(error); + } + + error.translatableErrorMsg = error.translatableErrorMsg ? error.translatableErrorMsg : 'password.decrypting-error'; + + this.msgBarService.showError(error); + this.button.resetState(); + this.working = false; + } +} diff --git a/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.html b/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.html new file mode 100644 index 0000000..4e96618 --- /dev/null +++ b/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.html @@ -0,0 +1 @@ + diff --git a/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.scss b/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.scss new file mode 100644 index 0000000..c416c25 --- /dev/null +++ b/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.scss @@ -0,0 +1,12 @@ +@import '../../../../theme/variables'; +@import '../../../../theme/buttons'; + +:host { + display: inline-flex; + flex-shrink: 0; +} + +img { + @extend .image-button; + width: $qr-code-button-size; +} diff --git a/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.ts b/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.ts new file mode 100644 index 0000000..c503ef8 --- /dev/null +++ b/src/gui/static/src/app/components/layout/qr-code-button/qr-code-button.component.ts @@ -0,0 +1,36 @@ +import { Component, Input } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; + +import { QrCodeComponent, QrDialogConfig } from '../qr-code/qr-code.component'; + +/** + * Simple inline img button which opens the QR code modal window when pressed. + */ +@Component({ + selector: 'app-qr-code-button', + templateUrl: './qr-code-button.component.html', + styleUrls: ['./qr-code-button.component.scss'], +}) +export class QrCodeButtonComponent { + // Address the QR code modal window will show. + @Input() address: string; + // If true, the QR code modal window will not show the coin request form and the addreess + // will not have the BIP21 prefix. + @Input() showAddressOnly = false; + + constructor( + private dialog: MatDialog, + ) { } + + showQrCode(event) { + event.stopPropagation(); + + const config: QrDialogConfig = { + showSpecificAddress: true, + address: this.address, + showAddressOnly: this.showAddressOnly, + }; + + QrCodeComponent.openDialog(this.dialog, config); + } +} diff --git a/src/gui/static/src/app/components/layout/qr-code/qr-code.component.html b/src/gui/static/src/app/components/layout/qr-code/qr-code.component.html new file mode 100644 index 0000000..800a8d2 --- /dev/null +++ b/src/gui/static/src/app/components/layout/qr-code/qr-code.component.html @@ -0,0 +1,87 @@ + + + + + + +
+
+
+
+ +
+
{{ 'qr.data-label' | translate }}
+
{{ currentQrContent }}
+
+ +
+
+ {{ 'qr.address-label' | translate }} + help + + warning +
+
{{ currentAddress }}
+
+ + + + + +
+ + +
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
diff --git a/src/gui/static/src/app/components/layout/qr-code/qr-code.component.scss b/src/gui/static/src/app/components/layout/qr-code/qr-code.component.scss new file mode 100644 index 0000000..506aa86 --- /dev/null +++ b/src/gui/static/src/app/components/layout/qr-code/qr-code.component.scss @@ -0,0 +1,68 @@ +@import '../../../../theme/variables'; + +$data-container-margin: 14px; + +.qr-container { + text-align: center; + margin-bottom: 24px; + + .qr { + height: 180px; + width: 180px; + display: inline-block; + } +} + +.separator { + background-color: $grey-light; + height: 1px; + width: 100%; +} + +.form-separator { + margin-bottom: $data-container-margin; +} + +.data-container { + margin: $data-container-margin 0; + + .title { + color: $grey; + } + + .data { + color: $black; + cursor: pointer; + + .text { + margin-right: 5px; + word-break: break-word; + } + + .copy { + opacity: 0.25; + } + } + + .data:hover { + .copy { + opacity: 0.75; + } + } + + .data:active { + .copy { + opacity: 1; + } + } +} + +.warning-icon { + position: relative; + top: 2px; + animation: alert-blinking 1s linear infinite; +} + +.addresses-link-container { + margin-bottom: 5px; +} diff --git a/src/gui/static/src/app/components/layout/qr-code/qr-code.component.ts b/src/gui/static/src/app/components/layout/qr-code/qr-code.component.ts new file mode 100644 index 0000000..8dbb426 --- /dev/null +++ b/src/gui/static/src/app/components/layout/qr-code/qr-code.component.ts @@ -0,0 +1,343 @@ +import { Component, Inject, ViewChild, OnDestroy, ElementRef, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { MatDialogRef } from '@angular/material/dialog'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { Router } from '@angular/router'; +import { SubscriptionLike, Subject, Observable } from 'rxjs'; +import { debounceTime } from 'rxjs/operators'; +import { BigNumber } from 'bignumber.js'; + +import { copyTextToClipboard } from '../../../utils/general-utils'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { WalletBase, WalletTypes } from '../../../services/wallet-operations/wallet-objects'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; +import { PasswordDialogComponent, PasswordSubmitEvent, PasswordDialogParams } from '../password-dialog/password-dialog.component'; +import { OperationError } from '../../../utils/operation-error'; +import { processServiceError } from '../../../utils/errors'; +import { NodeService } from '../../../services/node.service'; +import { CoinService } from '../../../services/coin.service'; +import { LastAddress } from '../../../services/coin-specific/wallets-and-addresses-operator'; + +// Gives access to qrcode.js, imported from the resources folder. +declare const QRCode: any; + +/** + * Default QR code graphical config. + */ +class DefaultQrConfig { + static readonly size = 180; + static readonly level = 'M'; + static readonly colordark = '#000000'; + static readonly colorlight = '#ffffff'; + static readonly usesvg = false; +} + +/** + * Settings for QrCodeComponent. + */ +export interface QrDialogConfig { + /** + * If true, the modal window will show the specific address passed on the "address" + * param. If false, it will show the last unused address of the wallet provided + * in the wallet param. + */ + showSpecificAddress: boolean; + /** + * Wallet from which the last address for receiving coins will be shown, if + * showSpecificAddress is false. Not for deterministic wallets. + */ + wallet?: WalletBase; + /** + * Address the QR code will have, if showSpecificAddress is true. + */ + address?: string; + /** + * If true, the modal window will not show the coin request form and the addreess will not + * have the BIP21 prefix. + */ + showAddressOnly?: boolean; +} + +/** + * Modal window used for showing QR codes. It allows to show the QR code of an specific address, + * but it can also get what the next address of a wallet is and show it (not for + * deterministic wallets). + */ +@Component({ + selector: 'app-qr-code', + templateUrl: './qr-code.component.html', + styleUrls: ['./qr-code.component.scss'], +}) +export class QrCodeComponent implements OnInit, OnDestroy { + @ViewChild('qrArea') qrArea: ElementRef; + + form: FormGroup; + currentQrContent: string; + formVisible = false; + // For knowing if the form fields have errors. + invalidCoins = false; + invalidHours = false; + + loading = true; + // Error to show if the loading procedure failed. + loadingErrorMsg = null; + // Address to show to the user. + currentAddress = ''; + // If the window is displaying the last unused address of a wallet. + showingLastOfWallet = false; + // If showing the last address of a wallet, this var contains how many unused addresses + // are before it. + previouslyUsedAddresses = 0; + // If showing the last address of a wallet, this var allow to know if that address has + // been already used (meaning if it has already received any coins). + lastAdderessIsUnused = true; + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + + private loadAddressSubscription: SubscriptionLike; + private subscriptionsGroup: SubscriptionLike[] = []; + // Emits every time the content of the QR code must be updated. + private updateQrEvent: Subject = new Subject(); + + // Modal window for asking the user for the password. + private passwordDialogRef: MatDialogRef; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + static openDialog(dialog: MatDialog, config: QrDialogConfig) { + const dialogConfig = new MatDialogConfig(); + dialogConfig.data = config; + dialogConfig.width = '390px'; + dialog.open(QrCodeComponent, dialogConfig); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public data: QrDialogConfig, + public dialogRef: MatDialogRef, + public formBuilder: FormBuilder, + private msgBarService: MsgBarService, + private nodeService: NodeService, + private walletsAndAddressesService: WalletsAndAddressesService, + private dialog: MatDialog, + private router: Router, + private coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + } + + ngOnInit() { + if (this.data.showSpecificAddress) { + this.currentAddress = this.data.address; + this.initForm(); + } else { + if (!this.data.wallet || this.data.wallet.walletType === WalletTypes.Deterministic) { + this.dialogRef.close(); + + return; + } + this.showingLastOfWallet = true; + this.loadWalletAddress(); + } + } + + ngOnDestroy() { + this.subscriptionsGroup.forEach(sub => sub.unsubscribe()); + this.removeLoadAddressSubscription(); + this.msgBarService.hide(); + } + + goToAddressHistory() { + this.router.navigate(['/addresses', { id: this.data.wallet.id }]); + this.dialogRef.close(); + } + + showForm() { + this.formVisible = true; + } + + copyText(text) { + copyTextToClipboard(text); + this.msgBarService.showDone('common.copied', 4000); + } + + /** + * Loads the next address of a wallet. If the last address of the wallet has already + * been used, it automatically asks for the password and creates a new address. + * @param passwordSubmitEvent Event of the modal window used for asking the user for + * the password. Should not be provided, it is used internally. + * @param avoidCreating If true, the function will not try to create a new address if the + * last one has already been used. Should not be provided, it is used internally. + */ + private loadWalletAddress(passwordSubmitEvent?: PasswordSubmitEvent, avoidCreating?: boolean) { + this.removeLoadAddressSubscription(); + + const password = passwordSubmitEvent ? passwordSubmitEvent.password : null; + + let operation: Observable; + if (!avoidCreating) { + operation = this.walletsAndAddressesService.getNextAddressAndUpdateWallet(this.data.wallet, password); + } else { + operation = this.walletsAndAddressesService.getLastAddressAndUpdateWallet(this.data.wallet, true); + } + + // Get the address. + this.loadAddressSubscription = operation.subscribe(response => { + // The service returns null if the wallet is encrypted, a new address must be created and + // no password was provided, so the password must be requested. + if (!response && this.data.wallet.encrypted && !passwordSubmitEvent) { + const params: PasswordDialogParams = { + wallet: this.data.wallet, + description: 'qr.password-info', + }; + this.passwordDialogRef = PasswordDialogComponent.openDialog(this.dialog, params); + + this.passwordDialogRef.afterClosed().subscribe(() => { + // If the user closes the window without providing the password, skip the new + // address creation part. + if (this.loading) { + this.loadWalletAddress(null, true); + } + }); + + this.passwordDialogRef.componentInstance.passwordSubmit.subscribe(eventData => { + // Repeat the operation, this time with the password. + this.loadWalletAddress(eventData); + }); + + return; + } + + // Close the password modal window, if any. + if (passwordSubmitEvent) { + passwordSubmitEvent.close(); + } + + // Save the address and initialice the window. + this.currentAddress = response.lastAddress; + this.previouslyUsedAddresses = response.previousUnusedAddresses; + this.lastAdderessIsUnused = !response.alreadyUsed; + this.initForm(); + + // Show a warning if the address has already been used. + if (response.alreadyUsed) { + setTimeout(() => { + this.msgBarService.showWarning('qr.used-address-warning'); + }); + } + }, (err: OperationError) => { + if (passwordSubmitEvent) { + passwordSubmitEvent.error(err); + } else { + err = processServiceError(err); + this.loadingErrorMsg = err.translatableErrorMsg; + this.loading = false; + } + }); + } + + private initForm() { + this.loading = false; + + this.form = this.formBuilder.group({ + coins: [''], + hours: [''], + note: [''], + }); + + // Each time a field is updated, update the content of the QR, but wait a prudential time. + this.subscriptionsGroup.push(this.form.get('coins').valueChanges.subscribe(this.reportValueChanged.bind(this))); + this.subscriptionsGroup.push(this.form.get('hours').valueChanges.subscribe(this.reportValueChanged.bind(this))); + this.subscriptionsGroup.push(this.form.get('note').valueChanges.subscribe(this.reportValueChanged.bind(this))); + this.subscriptionsGroup.push(this.updateQrEvent.pipe(debounceTime(500)).subscribe(() => { + this.updateQrContent(); + })); + + // Wait a moment for the new value of the loading property to be used for updating the ui, to + // avoid problems. + setTimeout(() => { + this.updateQrContent(); + }); + } + + private reportValueChanged() { + this.updateQrEvent.next(true); + } + + /** + * Updates the content of the QR code. + */ + private updateQrContent() { + this.currentQrContent = this.currentAddress; + + // If true, the QR only contains the address. + if (this.data.showAddressOnly) { + this.updateQrCode(); + + return; + } + + // Add the BIP21 prefix. + if (this.coinService.currentCoinInmediate.uriSpecificatioPrefix) { + this.currentQrContent = this.coinService.currentCoinInmediate.uriSpecificatioPrefix.toLowerCase() + ':' + this.currentQrContent; + } + + this.invalidCoins = false; + this.invalidHours = false; + + let nextSeparator = '?'; + + // Add the coins or alert if the value is not valid. + if (this.form.get('coins').value) { + const coins = new BigNumber(this.form.get('coins').value); + if (!coins.isNaN() && coins.isGreaterThan(0) && coins.decimalPlaces() <= this.nodeService.currentMaxDecimals) { + this.currentQrContent += nextSeparator + 'amount=' + coins.toString(); + nextSeparator = '&'; + } else { + this.invalidCoins = true; + } + } + + // Add the hours or alert if the value is not valid. + if (this.form.get('hours').value) { + const hours = new BigNumber(this.form.get('hours').value); + if (!hours.isNaN() && hours.isGreaterThan(0) && hours.decimalPlaces() === 0) { + this.currentQrContent += nextSeparator + 'hours=' + hours.toString(); + nextSeparator = '&'; + } else { + this.invalidHours = true; + } + } + + // Add the note. + const note = this.form.get('note').value; + if (note) { + this.currentQrContent += nextSeparator + 'message=' + encodeURIComponent(note); + } + + // Update the QR code image. + this.updateQrCode(); + } + + private updateQrCode() { + // Clean the area of the QR code. + (this.qrArea.nativeElement as HTMLDivElement).innerHTML = ''; + + // Creates a new QR code and adds it to the designated area. + const qrCode = new QRCode(this.qrArea.nativeElement, { + text: this.currentQrContent, + width: DefaultQrConfig.size, + height: DefaultQrConfig.size, + colorDark: DefaultQrConfig.colordark, + colorLight: DefaultQrConfig.colorlight, + useSVG: DefaultQrConfig.usesvg, + correctLevel: QRCode.CorrectLevel[DefaultQrConfig.level], + }); + } + + private removeLoadAddressSubscription() { + if (this.loadAddressSubscription) { + this.loadAddressSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.html b/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.html new file mode 100644 index 0000000..8a77518 --- /dev/null +++ b/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.html @@ -0,0 +1,37 @@ + + + + + + + +
+ + {{ 'common.continue-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.scss b/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.scss new file mode 100644 index 0000000..d7a2ff2 --- /dev/null +++ b/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.scss @@ -0,0 +1,6 @@ +@import '../../../../theme/variables'; + +.option { + font-size: $font-size-standard; + height: 42px; +} diff --git a/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.ts b/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.ts new file mode 100644 index 0000000..ae4d95a --- /dev/null +++ b/src/gui/static/src/app/components/layout/seed-word-dialog/seed-word-dialog.component.ts @@ -0,0 +1,159 @@ +import { Component, OnInit, OnDestroy, Inject } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { Observable, SubscriptionLike } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; +import { map } from 'rxjs/operators'; + +import { Bip39WordListService } from '../../../services/bip39-word-list.service'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { HwWalletService } from '../../../services/hw-wallet.service'; +import { MessageIcons } from '../hardware-wallet/hw-message/hw-message.component'; + +/** + * Reasons for asking a seed word. + */ +export enum WordAskedReasons { + HWWalletOperation = 'HWWalletOperation', + CreatingSoftwareWallet = 'CreatingSoftwareWallet', + RecoveringSoftwareWallet = 'RecoveringSoftwareWallet', + RecoveringSoftwareWalletPassword = 'RecoveringSoftwareWalletPassword', +} + +/** + * Settings for SeedWordDialogComponent. + */ +export interface SeedWordDialogParams { + /** + * Reason why the word is being requested. + */ + reason: WordAskedReasons; + /** + * Number of the requested word, if it is not for a hw wallet. + */ + wordNumber?: number; +} + +/** + * Modal window used to ask the user to enter a word of a seed. If used to request a word for a + * hw wallet, the modal window is automatically closed if the device is disconnected. It only + * allows BIP38 words. In the "afterClosed" event it returns the word the user entered, or + * null, if the operation was cancelled. + */ +@Component({ + selector: 'app-seed-word-dialog', + templateUrl: './seed-word-dialog.component.html', + styleUrls: ['./seed-word-dialog.component.scss'], +}) +export class SeedWordDialogComponent implements OnInit, OnDestroy { + form: FormGroup; + filteredOptions: Observable; + + msgIcons = MessageIcons; + wordAskedReasons = WordAskedReasons; + + // Vars with the validation error messages. + inputErrorMsg = ''; + + private sendingWord = false; + private valueChangeSubscription: SubscriptionLike; + private hwConnectionSubscription: SubscriptionLike; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, params: SeedWordDialogParams): MatDialogRef { + const config = new MatDialogConfig(); + config.data = params; + config.autoFocus = true; + config.width = '350px'; + + return dialog.open(SeedWordDialogComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public data: SeedWordDialogParams, + public dialogRef: MatDialogRef, + private formBuilder: FormBuilder, + private bip38WordList: Bip39WordListService, + private msgBarService: MsgBarService, + private translateService: TranslateService, + hwWalletService: HwWalletService, + ) { + if (data.reason === WordAskedReasons.HWWalletOperation) { + // Close the window if the device is disconnected. + this.hwConnectionSubscription = hwWalletService.walletConnectedAsyncEvent.subscribe(connected => { + if (!connected) { + this.dialogRef.close(); + } + }); + } + } + + ngOnInit() { + this.form = this.formBuilder.group({ + word: [''], + }); + + this.form.setValidators(this.validateForm.bind(this)); + + // Search for sugestions when the user changes the content of the word field. + this.valueChangeSubscription = this.form.controls.word.valueChanges.subscribe(value => { + this.bip38WordList.setSearchTerm(value.trim().toLowerCase()); + }); + + // Get the sugestions. + this.filteredOptions = this.bip38WordList.searchResults.pipe(map(value => value)); + } + + ngOnDestroy() { + this.msgBarService.hide(); + this.valueChangeSubscription.unsubscribe(); + if (this.hwConnectionSubscription) { + this.hwConnectionSubscription.unsubscribe(); + } + } + + sendWord() { + if (!this.sendingWord) { + this.sendingWord = true; + this.msgBarService.hide(); + + // If the user selected a sugested word, the wait allows time for the word to be + // added to the form field. + setTimeout(() => { + if (this.form.valid) { + const validation = this.bip38WordList.validateWord(this.form.value.word.trim().toLowerCase()); + if (validation) { + this.dialogRef.close((this.form.value.word as string).trim().toLowerCase()); + } else { + if (validation === null) { + this.msgBarService.showError(this.translateService.instant('hardware-wallet.seed-word.error-loading-words')); + } else { + this.msgBarService.showError(this.translateService.instant('hardware-wallet.seed-word.error-invalid-word')); + } + } + } + this.sendingWord = false; + }, 32); + } + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.inputErrorMsg = ''; + + let valid = true; + + if (!this.form.get('word').value) { + valid = false; + if (this.form.get('word').touched) { + this.inputErrorMsg = 'wallet.new.seed.word-error-info'; + } + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/layout/select-address/select-address.component.html b/src/gui/static/src/app/components/layout/select-address/select-address.component.html new file mode 100644 index 0000000..b30c32d --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-address/select-address.component.html @@ -0,0 +1,63 @@ + +
+ +
{{ element.label }} + +
+ + {{ 'wallet.legacy-small-label' | translate }} + help + +
+
+ + {{ 'wallet.xpub-small-label' | translate }} + help + +
+
+ + + + + + + + + + + + + +
error{{ 'select-address.no-addresses' | translate }}
+
+
+
diff --git a/src/gui/static/src/app/components/layout/select-address/select-address.component.scss b/src/gui/static/src/app/components/layout/select-address/select-address.component.scss new file mode 100644 index 0000000..5f4189b --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-address/select-address.component.scss @@ -0,0 +1,54 @@ +@import '../../../../theme/variables'; + +.wallet-container { + padding-top: 30px; + + &:first-child { + padding-top: 0px; + } + + .title { + color: $black; + border-bottom: 1px solid $grey-very-light; + padding: 0px 10px; + font-size: $font-size-very-big; + line-height: 1.8; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + + .wallet-type-label { + color: $red; + font-size: $font-size-mini; + line-height: 1; + position: relative; + top: -5px; + + mat-icon { + vertical-align: text-bottom; + } + } + } + + .address { + font-size: $font-size-standard; + line-height: 1.7; + color: $black; + } + + .balance { + font-size: $font-size-standard-minus; + line-height: 1.5; + color: $black; + } + + .no-addresses-msg { + padding: 10px; + + mat-icon { + margin-right: 5px; + position: relative; + top: 2px; + } + } +} diff --git a/src/gui/static/src/app/components/layout/select-address/select-address.component.ts b/src/gui/static/src/app/components/layout/select-address/select-address.component.ts new file mode 100644 index 0000000..5768f65 --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-address/select-address.component.ts @@ -0,0 +1,104 @@ +import { Component } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { Router } from '@angular/router'; +import { first } from 'rxjs/operators'; +import BigNumber from 'bignumber.js'; + +import { AppConfig } from '../../../app.config'; +import { BalanceAndOutputsService } from '../../../services/wallet-operations/balance-and-outputs.service'; +import { WalletTypes, WalletBase, AddressWithBalance } from '../../../services/wallet-operations/wallet-objects'; +import { CoinService } from '../../../services/coin.service'; + +/** + * Represents a wallet shown on the list. The wallet object is not used directly to be able to + * remove unwanted elements from the address list. + */ +class ListElement { + label: string; + originalWallet: WalletBase; + addresses: AddressWithBalance[] = []; +} + +/** + * Modal window used for allowing the user to select an address for any of the registered + * wallets. If the user selects an address, the modal window is closed and the address string + * is returned in the "afterClosed" event. If the user selects the option for getting + * an address from a bip44 wallet, the modal window is closed and the selected wallet is + * returned in the "afterClosed" event. + */ +@Component({ + selector: 'app-select-address', + templateUrl: './select-address.component.html', + styleUrls: ['./select-address.component.scss'], +}) +export class SelectAddressComponent { + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + // True if the wallets shown by the component don't have the same value on the walletType param. + hasVariousWalletTypes = false; + walletTypes = WalletTypes; + // Wallets to show on the list. + listElements: ListElement[] = []; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = false; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(SelectAddressComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + private balanceAndOutputsService: BalanceAndOutputsService, + private router: Router, + coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + + // Get the wallet list. + this.balanceAndOutputsService.walletsWithBalance.pipe(first()).subscribe(wallets => { + const typeOfTheFirstWallet = wallets.length > 0 ? wallets[0].walletType : null; + this.hasVariousWalletTypes = false; + + wallets.forEach(wallet => { + const element = new ListElement(); + element.label = wallet.label; + element.originalWallet = wallet; + + if (wallet.walletType !== typeOfTheFirstWallet) { + this.hasVariousWalletTypes = true; + } + + // Exclude all unconfirmed addresses from the hw wallets. + wallet.addresses.forEach(address => { + if (!wallet.isHardware || address.confirmed) { + element.addresses.push(address); + } + }); + + this.listElements.push(element); + }); + }); + } + + // Closes the modal window and returns the selected address. + select(value: string) { + this.dialogRef.close(value); + } + + // Opens the address history page of the selected wallet. + viewAddresses(wallet: WalletBase) { + this.router.navigate(['/addresses', { id: wallet.id }]); + this.dialogRef.close(); + } + + // Closes the modal window and returns a value indicating that the user selected the option + // for getting an address from a bip44 wallet. + getAddress(wallet: WalletBase) { + this.dialogRef.close(wallet); + } +} diff --git a/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.html b/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.html new file mode 100644 index 0000000..3bb4a35 --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.html @@ -0,0 +1,31 @@ + +
+ +
+
+
+
+
+ {{ 'change-coin.title' | translate }} +
+ search + +
+
+ +
+
{{ section.name | translate }}
+
+ +
+
+ + + +
+
+
+
diff --git a/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.scss b/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.scss new file mode 100644 index 0000000..8f40076 --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.scss @@ -0,0 +1,109 @@ +@import '../../../../theme/_variables'; + +mat-dialog-content { + width: 100%; + max-height: 100% !important; + padding: 0; + margin: 0; +} + +.x-container { + width: 0px; + height: 0px; + float: right; + position: relative; + left: -42px; + z-index: 1; + + img { + width: 42px; + height: 42px; + } +} + +.container { + text-align: center; + color: $black; +} + +.search-container { + max-width: 700px; + display: inline-block; + width: 100%; + font-size: $font-size-big; + margin: 25px 0px; + + mat-icon { + width: 0px; + height: 0px; + display: block; + position: relative; + top: 10px; + left: 12px; + color: $grey-light; + } + + .input-container { + margin-top: 10px; + } + + input { + border: 0px solid white; + background-color: white; + border-radius: $input-border-radius; + box-sizing: border-box; + display: block; + line-height: 20px; + padding: 10px 10px; + width: 100%; + outline: none; + padding: 12px 48px; + } + + input::placeholder { + color: $grey-light; + } + + input:-ms-input-placeholder { + color: $grey-light; + } +} + +.options-container { + font-size: $font-size-standard-minus; + + .title { + margin: 10px 0px; + } + + .buttons-container { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + + .button { + width: 130px; + margin: 20px; + font-size: $font-size-standard-minus; + line-height: unset; + padding: 0; + color: unset; + min-width: 0; + + img { + width: 64px; + height: 64px; + margin: 10px 0px; + } + + .label { + background-color: $grey-very-light; + padding: 4px 10px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + } +} diff --git a/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.ts b/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.ts new file mode 100644 index 0000000..ec4af30 --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-coin-overlay/select-coin-overlay.component.ts @@ -0,0 +1,167 @@ +import { Component, HostListener, ViewChild, ElementRef, OnInit, OnDestroy, Renderer2 } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { Subscription, fromEvent } from 'rxjs'; +import { Overlay } from '@angular/cdk/overlay'; +import { debounceTime, first } from 'rxjs/operators'; + +import { CoinService } from '../../../services/coin.service'; +import { Coin } from '../../../coins/coin'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; + +/** + * Data for the sections this component can show. + */ +class Section { + /** + * String to be used as the title of the section. + */ + name: string; + /** + * Coins to show on the section. + */ + coins: Coin[]; +} + +/** + * Allows to change the currently selected coin. The process for changing the coin is + * made internally. + */ +@Component({ + selector: 'app-select-coin-overlay', + templateUrl: './select-coin-overlay.component.html', + styleUrls: ['./select-coin-overlay.component.scss'], +}) +export class SelectCoinOverlayComponent implements OnInit, OnDestroy { + // Search field. + @ViewChild('searchInput') private searchInput: ElementRef; + private searchSuscription: Subscription; + // Allows to know which coins have registered wallets. + private coinsWithWallets = new Map(); + + // List with the sections this component must show. + sections: Section[] = []; + + /** + * Shows the overlay. Please use this function instead of opening the component "by hand". + */ + public static openOverlay(dialog: MatDialog, renderer: Renderer2, overlay: Overlay): MatDialogRef { + // Remove the scroll bars of the main area of the app. + renderer.addClass(document.body, 'no-overflow'); + + const config = new MatDialogConfig(); + config.maxWidth = '100%'; + config.width = '100%'; + config.height = '100%'; + config.scrollStrategy = overlay.scrollStrategies.noop(); + config.disableClose = true; + config.panelClass = 'transparent-background-dialog'; + config.backdropClass = 'clear-dialog-background'; + config.autoFocus = false; + + const componentRef = dialog.open(SelectCoinOverlayComponent, config); + + componentRef.afterClosed().subscribe(() => { + // Restore the scroll bars of the main area of the app. + renderer.removeClass(document.body, 'no-overflow'); + }); + + return componentRef; + } + + constructor( + private dialogRef: MatDialogRef, + private coinService: CoinService, + private walletsAndAddressesService: WalletsAndAddressesService, + ) { } + + ngOnInit() { + + this.walletsAndAddressesService.allWallets.pipe(first()).subscribe(wallets => { + // Check which coins have wallets. + wallets.forEach(value => { + this.coinsWithWallets.set(value.coin, true); + }); + + // Show all the coins. + this.createSections(this.coinService.coins); + }); + + // Search as the user types. + setTimeout(() => { + this.searchSuscription = fromEvent(this.searchInput.nativeElement, 'keyup').pipe(debounceTime(500)).subscribe(() => this.search()); + }); + } + + // Filters the coins this component shows, using the search term entered by the user. + search() { + let coins: Coin[]; + const term: string = this.searchInput.nativeElement.value.trim().toLocaleUpperCase(); + + if (term.length === 0) { + coins = this.coinService.coins; + } else { + // Seach by name and symbol. + coins = this.coinService.coins.filter((element) => element.coinName.toLocaleUpperCase().includes(term) || element.coinSymbol.toLocaleUpperCase().includes(term)); + } + + this.createSections(coins); + } + + // Checks a list of coins, put them on the corresponding section and updates the array used for + // showing the coins on the UI. + createSections(coins: Coin[]) { + // Create sections for coins with and without wallets. + const withWallets: Section = { + name: 'change-coin.with-wallet', + coins: [], + }; + const withoutWallets: Section = { + name: 'change-coin.without-wallet', + coins: [], + }; + + // Put the coins in the corresponding section. + coins.forEach((coin: Coin) => { + if (this.coinsWithWallets.has(coin.coinName)) { + withWallets.coins.push(coin); + } else { + withoutWallets.coins.push(coin); + } + }); + + // Add the sections to the UI, if there are coins in them. + this.sections = []; + if (withWallets.coins.length > 0) { + this.sections.push(withWallets); + } + if (withoutWallets.coins.length > 0) { + this.sections.push(withoutWallets); + } + } + + ngOnDestroy() { + if (this.searchSuscription) { + this.searchSuscription.unsubscribe(); + } + } + + // Close if the esc key is pressed. + @HostListener('document:keydown', ['$event']) + handleKeyboardEvent(event: KeyboardEvent) { + if (event.keyCode === 27) { + this.close(null); + } + } + + /** + * Closes the component. + * @param result If provided, the coin on this param is set as the currently selected coin. + */ + close(result: Coin | null) { + if (result) { + this.coinService.changeCoin(result); + } + + this.dialogRef.close(result); + } +} diff --git a/src/gui/static/src/app/components/layout/select-coin/select-coin.component.html b/src/gui/static/src/app/components/layout/select-coin/select-coin.component.html new file mode 100644 index 0000000..4925731 --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-coin/select-coin.component.html @@ -0,0 +1,4 @@ +
+ +
+ diff --git a/src/gui/static/src/app/components/layout/select-coin/select-coin.component.scss b/src/gui/static/src/app/components/layout/select-coin/select-coin.component.scss new file mode 100644 index 0000000..8f26372 --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-coin/select-coin.component.scss @@ -0,0 +1,17 @@ +input { + cursor: default; + padding-left: 48px; +} + +.icon-container { + width: 0px; + height: 0px; + + img { + position: relative; + top: 5px; + left: 10px; + width: 32px; + height: 32px; + } +} diff --git a/src/gui/static/src/app/components/layout/select-coin/select-coin.component.ts b/src/gui/static/src/app/components/layout/select-coin/select-coin.component.ts new file mode 100644 index 0000000..f867e03 --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-coin/select-coin.component.ts @@ -0,0 +1,42 @@ +import { Component, Renderer2, OnDestroy } from '@angular/core'; +import { Overlay } from '@angular/cdk/overlay'; +import { MatDialog } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; + +import { Coin } from '../../../coins/coin'; +import { SelectCoinOverlayComponent } from '../select-coin-overlay/select-coin-overlay.component'; +import { CoinService } from '../../../services/coin.service'; + +/** + * Control for selecting the active coin, with the design for showing it in a form. + */ +@Component({ + selector: 'app-select-coin', + templateUrl: 'select-coin.component.html', + styleUrls: ['select-coin.component.scss'], +}) +export class SelectCoinComponent implements OnDestroy { + currentCoin: Coin; + + private coinSubscription: SubscriptionLike; + + constructor( + private dialog: MatDialog, + private overlay: Overlay, + private renderer: Renderer2, + coinService: CoinService, + ) { + this.coinSubscription = coinService.currentCoin.subscribe(currentCoin => { + this.currentCoin = currentCoin; + }); + } + + ngOnDestroy() { + this.coinSubscription.unsubscribe(); + } + + // Opens the coin selection screen. + onInputClick() { + SelectCoinOverlayComponent.openOverlay(this.dialog, this.renderer, this.overlay); + } +} diff --git a/src/gui/static/src/app/components/layout/select-language/select-language.component.html b/src/gui/static/src/app/components/layout/select-language/select-language.component.html new file mode 100644 index 0000000..1155259 --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-language/select-language.component.html @@ -0,0 +1,8 @@ + +
+ +
+
diff --git a/src/gui/static/src/app/components/layout/select-language/select-language.component.scss b/src/gui/static/src/app/components/layout/select-language/select-language.component.scss new file mode 100644 index 0000000..a5eecfa --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-language/select-language.component.scss @@ -0,0 +1,32 @@ +@import '../../../../theme/_variables'; + +.options-container { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + + .button { + width: 118px; + margin: 20px; + font-size: $font-size-standard-minus; + line-height: 1.4; + padding: 0; + min-width: 0px; + + img { + width: 64px; + height: 64px; + margin: 10px 0px; + } + + .label { + background-color: $grey-very-light; + padding: 4px 10px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + color: $black; + } + } +} diff --git a/src/gui/static/src/app/components/layout/select-language/select-language.component.ts b/src/gui/static/src/app/components/layout/select-language/select-language.component.ts new file mode 100644 index 0000000..750ea7b --- /dev/null +++ b/src/gui/static/src/app/components/layout/select-language/select-language.component.ts @@ -0,0 +1,49 @@ +import { Component, OnInit } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +import { LanguageData, LanguageService } from '../../../services/language.service'; + +/** + * Allows to change the language displayed by the UI. + */ +@Component({ + selector: 'app-select-language', + templateUrl: './select-language.component.html', + styleUrls: ['./select-language.component.scss'], +}) +export class SelectLanguageComponent implements OnInit { + languages: LanguageData[]; + disableDismiss: boolean; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + * @param disableClose Disables the options for closing the modal window without + * selecting a langhuage. + */ + public static openDialog(dialog: MatDialog, disableClose = false): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = false; + config.disableClose = disableClose; + config.width = '600px'; + + return dialog.open(SelectLanguageComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + private languageService: LanguageService, + ) { } + + ngOnInit() { + this.disableDismiss = this.dialogRef.disableClose; + this.languages = this.languageService.languages; + } + + closePopup(language: LanguageData = null) { + if (language) { + this.languageService.changeLanguage(language.code); + } + + this.dialogRef.close(); + } +} diff --git a/src/gui/static/src/app/components/pages/address-history/address-history.component.html b/src/gui/static/src/app/components/pages/address-history/address-history.component.html new file mode 100644 index 0000000..ddf2768 --- /dev/null +++ b/src/gui/static/src/app/components/pages/address-history/address-history.component.html @@ -0,0 +1,82 @@ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+
#
+
+ {{ ('address-history.' + (i === 0 ? 'normal-address-table-label' : 'change-address-table-label')) | translate }} + help +
+
{{ 'coinSymbol' | commonText }}
+
{{ 'hours' | commonText }}
+
{{ 'address-history.unused-table-label' | translate }}
+
+
+
+ +
+
{{ address.indexInWallet + 1 }}
+
+ + {{ address.address.printableAddress }} +
+
+ {{ address.address.coins | amount:true:'first' }} + warning +
+
+ {{ address.address.hours | amount:false:'first' }} + warning +
+
+ {{ ('address-history.' + (address.alreadyUsed ? 'used-no' : 'used-yes')) | translate }} + help +
+
+ more_vert + + + + +
+
+ +
+ {{ 'address-history.view-all' | translate:{ current:maxInitialElements, total:allAddresses[i].length } }} +
+
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/address-history/address-history.component.scss b/src/gui/static/src/app/components/pages/address-history/address-history.component.scss new file mode 100644 index 0000000..9cb0a63 --- /dev/null +++ b/src/gui/static/src/app/components/pages/address-history/address-history.component.scss @@ -0,0 +1,42 @@ +@import '../../../../theme/variables'; + +.number-cell { + width: 85px; + flex-shrink: 0; +} + +.options-cell { + width: 40px; + flex-shrink: 0; + text-align: right; + padding-left: 0px !important; + + mat-icon { + cursor: pointer; + color: lighten($grey, 30%); + font-size: 18px; + width: unset; + vertical-align: text-bottom; + } +} + +app-qr-code-button { + vertical-align: middle; + margin-right: 10px; +} + +.view-all-button { + font-size: $font-size-standard; + text-align: center; + padding: 20px; + cursor: pointer; + + &:hover { + background-color: $white-hover; + } +} + +.button-container { + text-align: right; + margin: 15px $main-containers-margin 5px; +} diff --git a/src/gui/static/src/app/components/pages/address-history/address-history.component.ts b/src/gui/static/src/app/components/pages/address-history/address-history.component.ts new file mode 100644 index 0000000..02e91bd --- /dev/null +++ b/src/gui/static/src/app/components/pages/address-history/address-history.component.ts @@ -0,0 +1,164 @@ +import { Component, OnDestroy } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { MatDialog } from '@angular/material/dialog'; +import { SubscriptionLike, combineLatest } from 'rxjs'; +import { first, map } from 'rxjs/operators'; + +import { HistoryService, AddressesState } from '../../../services/wallet-operations/history.service'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; +import { WalletBase, WalletTypes } from '../../../services/wallet-operations/wallet-objects'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { WalletOptionsComponent } from '../wallets/wallet-options/wallet-options.component'; +import { CoinService } from '../../../services/coin.service'; + +/** + * Allows to see the address history of a wallet (not for deterministic wallets). The URL for + * opening this page must have a param called "id", with the ID of the wallet to consult. + */ +@Component({ + selector: 'app-address-history', + templateUrl: './address-history.component.html', + styleUrls: ['./address-history.component.scss'], +}) +export class AddressHistoryComponent implements OnDestroy { + // All addresses on the wallet. The first element is the array of external addresses and the + // second one is the list of change addresses. + allAddresses: AddressesState[][]; + // Addresses to show on the UI. + addresses: AddressesState[][]; + + // Vars for showing only some elements at the same time by default. + readonly maxInitialElements = 5; + showAllExternalAddresses = false; + showAllChangeAddresses = false; + externalAddressesTruncated = false; + changeAddressesTruncated = false; + + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + // If the page is loading the data. + loading = true; + // If the id on the URL does not correspond to a valid wallet. + invalidWallet = false; + + // Vars for showing only the options available for the current coin. + showOutputsOption: boolean; + + private wallet: WalletBase; + private basicDataSubscription: SubscriptionLike; + private addressesSubscription: SubscriptionLike; + + constructor( + private historyService: HistoryService, + private walletsAndAddressesService: WalletsAndAddressesService, + private route: ActivatedRoute, + private msgBarService: MsgBarService, + private dialog: MatDialog, + coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.showOutputsOption = coinService.currentCoinInmediate.coinTypeFeatures.outputs; + + // Get the wallets and route params. + this.basicDataSubscription = combineLatest([this.route.params, this.walletsAndAddressesService.currentWallets.pipe(first())]).pipe(map(result => { + const params = result[0]; + const wallets = result[1]; + + this.loading = true; + this.invalidWallet = false; + this.showAllExternalAddresses = false; + this.showAllChangeAddresses = false; + this.externalAddressesTruncated = false; + this.changeAddressesTruncated = false; + + this.removeAddressesSubscription(); + + this.wallet = wallets.find(w => w.id === params['id']); + // Abort if a valid wallet is not found. + if (!this.wallet || this.wallet.walletType === WalletTypes.Deterministic) { + this.invalidWallet = true; + + return; + } else { + this.invalidWallet = false; + } + + this.startDataRefreshSubscription(); + })).subscribe(); + } + + ngOnDestroy() { + this.basicDataSubscription.unsubscribe(); + this.removeAddressesSubscription(); + this.msgBarService.hide(); + } + + // Makes the page show all the external or change addresses, depending on the param. + showAll(external: boolean) { + if (external) { + this.showAllExternalAddresses = true; + this.externalAddressesTruncated = false; + this.addresses[0] = this.allAddresses[0]; + } else { + this.showAllChangeAddresses = true; + this.changeAddressesTruncated = false; + this.addresses[1] = this.allAddresses[1]; + } + } + + // Opens the modal window for adding addresses to the wallet. + addAddress() { + WalletOptionsComponent.openDialog(this.dialog, {wallet: this.wallet, automaticallyAddAddresses: true}); + } + + /** + * Makes the page start updating the data periodically. If this function was called before, + * the previous updating procedure is cancelled. + */ + private startDataRefreshSubscription() { + this.removeAddressesSubscription(); + + this.addressesSubscription = this.historyService.getAddressesHistory(this.wallet).subscribe(response => { + // Order the lists last to first. + response.externalAddresses.reverse(); + response.changeAddresses.reverse(); + + // Save all addresses. + this.allAddresses = []; + this.allAddresses.push(response.externalAddresses); + this.allAddresses.push(response.changeAddresses); + + // If there are too many addresses, calculate which ones will be shown. + this.addresses = []; + if (this.showAllExternalAddresses || response.externalAddresses.length <= this.maxInitialElements) { + this.externalAddressesTruncated = false; + this.addresses.push(response.externalAddresses); + } else { + this.externalAddressesTruncated = true; + this.addresses.push(response.externalAddresses.slice(0, this.maxInitialElements)); + } + + if (this.showAllChangeAddresses || response.changeAddresses.length <= this.maxInitialElements) { + this.changeAddressesTruncated = false; + this.addresses.push(response.changeAddresses); + } else { + this.changeAddressesTruncated = true; + this.addresses.push(response.changeAddresses.slice(0, this.maxInitialElements)); + } + + this.loading = false; + + if (response.omitedAddresses) { + this.msgBarService.showWarning('address-history.omited-addresses-warning'); + } + }, err => { + this.startDataRefreshSubscription(); + }); + } + + private removeAddressesSubscription() { + if (this.addressesSubscription) { + this.addressesSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.css b/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.css new file mode 100644 index 0000000..d273ddc --- /dev/null +++ b/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.css @@ -0,0 +1,12 @@ +/* + IMPORTANT: Unused for a long time, it may need changes to work properly. +*/ +mat-select { + width: 100%; + padding: 40px 0 20px; +} + +.button-line { + margin-top: 40px; + text-align: right; +} diff --git a/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.html b/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.html new file mode 100644 index 0000000..0b400f1 --- /dev/null +++ b/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.html @@ -0,0 +1,14 @@ + +

{{ 'buy.deposit-address' | translate }}

+
+ + + {{ address.printableAddress }} + + +
+ diff --git a/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.ts b/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.ts new file mode 100644 index 0000000..6969b20 --- /dev/null +++ b/src/gui/static/src/app/components/pages/buy/add-deposit-address/add-deposit-address.component.ts @@ -0,0 +1,52 @@ +/* + IMPORTANT: Unused for a long time, it may need changes to work properly. +*/ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { PurchaseService } from '../../../../services/purchase.service'; +import { MatDialogRef } from '@angular/material/dialog'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; +import { Subscription } from 'rxjs'; +import { AddressBase } from '../../../../services/wallet-operations/wallet-objects'; + +@Component({ + selector: 'app-add-deposit-address', + templateUrl: './add-deposit-address.component.html', + styleUrls: ['./add-deposit-address.component.css'], +}) +export class AddDepositAddressComponent implements OnInit, OnDestroy { + + form: FormGroup; + addresses: AddressBase[] = []; + + private getWalletsSubscription: Subscription; + + constructor( + public walletsAndAddressesService: WalletsAndAddressesService, + private dialogRef: MatDialogRef, + private formBuilder: FormBuilder, + private purchaseService: PurchaseService, + ) {} + + ngOnInit() { + this.initForm(); + + this.getWalletsSubscription = this.walletsAndAddressesService.currentWallets.subscribe(wallets => { + this.addresses = wallets.reduce((array, wallet) => array.concat(wallet.addresses), [] as AddressBase[]); + }); + } + + ngOnDestroy() { + this.getWalletsSubscription.unsubscribe(); + } + + generate() { + this.purchaseService.generate(this.form.value.address).subscribe(() => this.dialogRef.close()); + } + + private initForm() { + this.form = this.formBuilder.group({ + address: ['', Validators.required], + }); + } +} diff --git a/src/gui/static/src/app/components/pages/buy/buy.component.html b/src/gui/static/src/app/components/pages/buy/buy.component.html new file mode 100644 index 0000000..76d233a --- /dev/null +++ b/src/gui/static/src/app/components/pages/buy/buy.component.html @@ -0,0 +1,62 @@ + + +
+
+
+
+
+ 1 +
+
+

{{ 'buy.deposit-location' | translate }}

+

{{ 'buy.deposit-location-desc' | translate }}

+
+
+ +
+
+ {{ 'buy.wallets-desc' | translate }} +
+
+
+
+ 2 +
+
+

{{ 'buy.send' | translate }}

+

{{ 'buy.send-desc' | translate:{rate: config.sky_btc_exchange_rate} }}

+ + {{ order.deposit_address }} + + {{ 'buy.fraction-warning' | translate }} +
+
+
+
+ 3 +
+
+

{{ 'buy.receive' | translate }}

+

{{ 'buy.receive-desc' | translate }}

+ + {{ 'buy.status-button' | translate }} {{ order.status | tellerStatus | translate }} + + + {{ 'buy.check-status-button' | translate }} + + + {{ 'buy.new-order-button' | translate }} + +
+
+
+ +
+
diff --git a/src/gui/static/src/app/components/pages/buy/buy.component.scss b/src/gui/static/src/app/components/pages/buy/buy.component.scss new file mode 100644 index 0000000..835980d --- /dev/null +++ b/src/gui/static/src/app/components/pages/buy/buy.component.scss @@ -0,0 +1,132 @@ +/* + IMPORTANT: Unused for a long time, it may need changes to work properly. +*/ +.-background-container { + background-color: #fbfbfb; + padding-top: 30px; + max-width: 100%; + min-height: calc(100% - 190px); + overflow: hidden; + position: relative; +} + +.-background-image { + display: none; +} + +@media (min-width: 768px) { + .-background-image { + display: block; + left: 50%; + width: 80%; + position: absolute; + top: 0; + } +} + +@media (min-width: 992px) { + .-background-image { + left: 40%; + width: 90%; + max-width: 850px; + } +} + +@media (min-width: 1200px) { + .-background-image { + left: 40%; + width: 80%; + max-width: 850px; + } +} + +.-paper { + background-color: #fbfbfb; + border-radius: 10px; + box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.01), 1px 1px 2px 2px rgba(0, 0, 0, 0.01); + padding: 30px; + position: relative; + margin-top: 30px; + max-width: 540px; + z-index: 5; + + .-step { + display: flex; + margin-bottom: 30px; + + .-number { + width: 60px; + + span { + border-radius: 50%; + color: white; + display: inline-block; + font-size: 16px; + font-weight: 700; + height: 40px; + line-height: 46px; + text-align: center; + width: 40px; + } + } + + .-instructions { + flex: 1 1; + + ::ng-deep button { + margin-left: 0; + } + + h3 { + color: #1E2227; + font-size: 16px; + font-weight: 700; + margin: 0; + line-height: 46px; + } + + p { + color: rgba(30, 34, 39, 0.8); + font-size: 14px; + font-weight: 300; + line-height: 20px; + margin-top: 0; + } + + .-address, .-status { + background-color: white; + border: 2px solid rgba(0, 0, 0, 0.05); + border-radius: 6px; + box-sizing: border-box; + color: rgba(30, 34, 39, 0.8); + display: block; + font-size: 14px; + line-height: 20px; + margin-bottom: 15px; + padding: 10px 10px; + width: 100%; + } + + .-coins { + color: #0072FF; + } + + .form-field { + margin-bottom: 15px; + } + + .-subtitle { + color: #8C8E90; + font-size: 12px; + line-height: 18px; + font-weight: 300; + opacity: 0.8; + } + + .-wallet { + color: rgba(30, 34, 39, 0.8); + font-size: 14px; + } + } + } +} diff --git a/src/gui/static/src/app/components/pages/buy/buy.component.ts b/src/gui/static/src/app/components/pages/buy/buy.component.ts new file mode 100644 index 0000000..3c945c1 --- /dev/null +++ b/src/gui/static/src/app/components/pages/buy/buy.component.ts @@ -0,0 +1,117 @@ +/* + IMPORTANT: Unused for a long time, it may need changes to work properly. +*/ +import { filter, first } from 'rxjs/operators'; +import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { PurchaseService } from '../../../services/purchase.service'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { PurchaseOrder } from '../../../app.datatypes'; +import { ButtonComponent } from '../../layout/button/button.component'; +import { SubscriptionLike } from 'rxjs'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { WalletBase, AddressBase } from '../../../services/wallet-operations/wallet-objects'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; + +@Component({ + selector: 'app-buy', + templateUrl: './buy.component.html', + styleUrls: ['./buy.component.scss'], +}) +export class BuyComponent implements OnInit, OnDestroy { + @ViewChild('button') button: ButtonComponent; + + address: AddressBase; + config: any; + form: FormGroup; + order: PurchaseOrder; + wallets: WalletBase[]; + + private subscriptionsGroup: SubscriptionLike[] = []; + + constructor( + private formBuilder: FormBuilder, + private purchaseService: PurchaseService, + private msgBarService: MsgBarService, + private walletsAndAddressesService: WalletsAndAddressesService, + ) {} + + ngOnInit() { + this.initForm(); + this.loadData(); + } + + ngOnDestroy() { + this.subscriptionsGroup.forEach(sub => sub.unsubscribe()); + } + + checkStatus() { + this.button.setLoading(); + this.purchaseService.scan(this.order.recipient_address).subscribe( + response => { + this.button.setSuccess(); + this.order.status = response.status; + }, + // On this part the error was shown on the button. Now it would have to be shown on the msg bar. + error => this.button.resetState(), + ); + } + + removeOrder() { + window.localStorage.removeItem('purchaseOrder'); + this.order = null; + } + + private initForm() { + this.form = this.formBuilder.group({ + wallet: ['', Validators.required], + }); + + this.subscriptionsGroup.push(this.form.get('wallet').valueChanges.subscribe(id => { + const wallet = this.wallets.find(wlt => wlt.id === id); + console.log('changing wallet value', id); + this.purchaseService.generate(wallet).subscribe( + order => this.saveData(order), + error => this.msgBarService.showError(error.toString()), + ); + })); + } + + private loadConfig() { + this.purchaseService.config().pipe( + filter(config => !!config && !!config.sky_btc_exchange_rate), first()) + .subscribe(config => this.config = config); + } + + private loadData() { + this.loadConfig(); + this.loadOrder(); + + this.subscriptionsGroup.push(this.walletsAndAddressesService.currentWallets.subscribe(wallets => { + this.wallets = wallets; + + if (this.order) { + this.form.get('wallet').setValue(this.order.filename, { emitEvent: false }); + } + })); + } + + private loadOrder() { + const order: PurchaseOrder = JSON.parse(window.localStorage.getItem('purchaseOrder')); + if (order) { + this.order = order; + this.updateOrder(); + } + } + + private saveData(order: PurchaseOrder) { + this.order = order; + window.localStorage.setItem('purchaseOrder', JSON.stringify(order)); + } + + private updateOrder() { + this.purchaseService.scan(this.order.recipient_address).pipe(first()).subscribe( + response => this.order.status = response.status, + error => console.log(error), + ); + } +} diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.html b/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.html new file mode 100644 index 0000000..573627d --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.html @@ -0,0 +1,118 @@ + + +
+ +
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+ +
+
+
+ +
+ + +
+ + +
+ + {{ 'exchange.agree-part1' | translate }} + + {{ 'exchange.agree-part2' | translate }} + + {{ 'exchange.agree-part3' | translate }} + + {{ 'exchange.agree-part4' | translate }} + + + + + + {{ 'exchange.exchange-button' | translate }} + +
+
+ + +
+
+
{{ 'exchange.label-you-send' | translate }}
+
{{ sendAmount }} {{ form.get('fromCoin').value }}
+
+ +
+
{{ 'exchange.label-you-get' | translate }}
+
≈ {{ toAmount }} {{ toCoin }}
+
+ +
+
{{ 'exchange.label-to-address' | translate:{coin: toCoin} }}
+
{{ form.get('toAddress').value || '-' }}
+
+ +
+
{{ 'exchange.label-price' | translate }}
+
1 {{ form.get('fromCoin').value }} ≈ {{ activeTradingPair.price.toFixed(6) }} {{ toCoin }}
+
+ +
+
{{ 'exchange.label-stimate-transaction-time' | translate }}
+
≈ 15 minutes
+
+
+
diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.scss b/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.scss new file mode 100644 index 0000000..a8ab26a --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.scss @@ -0,0 +1,60 @@ +@import '../../../../../theme/variables'; + +.-create { + display: flex; + + .-form { + flex: .6; + } + + .-info { + flex: .4; + margin-left: 40px; + } +} + +.form-field { + .-error { + color: $red; + margin-left: 20px; + } + + .-inputs { + display: flex; + + input { + flex: .7; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .-select, .-input { + flex: .3; + + select, input { + border-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } + } +} + +.-item { + font-size: $font-size-standard; + + &:not(:last-child) { + margin-bottom: 20px; + } + + .-key { + color: $grey; + margin-bottom: 5px; + } +} + +.-buttons { + display: flex; + flex-direction: column; + align-items: center; +} diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.ts b/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.ts new file mode 100644 index 0000000..d2dd39a --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-create/exchange-create.component.ts @@ -0,0 +1,360 @@ +import { throwError as observableThrowError, SubscriptionLike, of, concat } from 'rxjs'; +import { Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'; +import * as moment from 'moment'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { TranslateService } from '@ngx-translate/core'; +import { retryWhen, delay, take, mergeMap } from 'rxjs/operators'; + +import { ButtonComponent } from '../../../layout/button/button.component'; +import { ExchangeService, StoredExchangeOrder, TradingPair, ExchangeOrder } from '../../../../services/exchange.service'; +import { SelectAddressComponent } from '../../../layout/select-address/select-address.component'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { WalletBase } from '../../../../services/wallet-operations/wallet-objects'; +import { GetNextAddressComponent } from '../../../layout/get-next-address/get-next-address.component'; +import { NodeService } from '../../../../services/node.service'; +import { WalletUtilsService } from '../../../../services/wallet-operations/wallet-utils.service'; + +/** + * Shows the form for creating an exchange order. + */ +@Component({ + selector: 'app-exchange-create', + templateUrl: './exchange-create.component.html', + styleUrls: ['./exchange-create.component.scss'], +}) +export class ExchangeCreateComponent implements OnInit, OnDestroy { + // Default coin the user will have to deposit. + readonly defaultFromCoin = 'BTC'; + // Default amount of coins the user will have to deposit. + readonly defaultFromAmount = '0.1'; + // Coin the user will receive. + readonly toCoin = 'SKY'; + + @ViewChild('exchangeButton') exchangeButton: ButtonComponent; + // Event emited when the order has been created. + @Output() submitted = new EventEmitter(); + + form: FormGroup; + tradingPairs: TradingPair[]; + // Currently selected trading pair + activeTradingPair: TradingPair; + problemGettingPairs = false; + // If true, the form is shown deactivated. + busy = false; + // If the node service already has updated info about the remote node. + nodeDataUpdated = false; + + // If the user has acepted the agreement. + private agreement = false; + + // Vars with the validation error messages. + coinErrorMsg = ''; + amountErrorMsg = ''; + addressErrorMsg = ''; + amountTooLow = false; + amountTooHight = false; + + private subscriptionsGroup: SubscriptionLike[] = []; + private exchangeSubscription: SubscriptionLike; + private priceUpdateSubscription: SubscriptionLike; + + // Approximately how many coin will be received for the amount of coins the user will send, + // as per the value entered on the form and the current price. + get toAmount(): string { + if (!this.activeTradingPair) { + return '0'; + } + + const fromAmount = this.form.get('fromAmount').value; + if (isNaN(fromAmount)) { + return '0'; + } else { + return (this.form.get('fromAmount').value * this.activeTradingPair.price).toFixed(this.nodeService.currentMaxDecimals); + } + } + + // How many coin the user will send, converted to a valid number. + get sendAmount(): number { + const val = this.form.get('fromAmount').value; + + return isNaN(parseFloat(val)) ? 0 : val; + } + + constructor( + private exchangeService: ExchangeService, + private formBuilder: FormBuilder, + private msgBarService: MsgBarService, + private dialog: MatDialog, + private nodeService: NodeService, + private translateService: TranslateService, + private walletUtilsService: WalletUtilsService, + ) { } + + ngOnInit() { + // Check if the node service has updated data. + this.subscriptionsGroup.push(this.nodeService.remoteNodeDataUpdated.subscribe(response => { + this.nodeDataUpdated = response; + })); + + this.createForm(); + this.loadData(); + } + + ngOnDestroy() { + this.subscriptionsGroup.forEach(sub => sub.unsubscribe()); + this.removeExchangeSubscription(); + this.removePriceUpdateSubscription(); + this.msgBarService.hide(); + this.submitted.complete(); + } + + // Called when the user presses the checkbox for acepting the agreement. + setAgreement(event) { + this.agreement = event.checked; + this.form.updateValueAndValidity(); + } + + // Opens the modal window for selecting one of the addresses the user has. + selectAddress(event) { + event.stopPropagation(); + event.preventDefault(); + + SelectAddressComponent.openDialog(this.dialog).afterClosed().subscribe(response => { + if (response) { + if ((response as WalletBase).id) { + GetNextAddressComponent.openDialog(this.dialog, response).afterClosed().subscribe(resp => { + if (resp) { + this.form.get('toAddress').setValue(resp); + } + }); + } else if (typeof response === 'string') { + this.form.get('toAddress').setValue(response); + } + } + }); + } + + // Creates the order. + exchange() { + if (!this.form.valid || this.busy) { + return; + } + + // Prepare the UI. + this.busy = true; + this.msgBarService.hide(); + this.exchangeButton.resetState(); + this.exchangeButton.setLoading(); + this.exchangeButton.setDisabled(); + + const amount = parseFloat(this.form.get('fromAmount').value); + + const toAddress = (this.form.get('toAddress').value as string).trim(); + + // Check if the address is valid. + this.removeExchangeSubscription(); + this.exchangeSubscription = this.walletUtilsService.verifyAddress(toAddress).subscribe(addressIsValid => { + if (addressIsValid) { + // Create the order. + this.exchangeSubscription = this.exchangeService.exchange( + this.activeTradingPair.pair, + amount, + toAddress, + this.activeTradingPair.price, + ).subscribe((order: ExchangeOrder) => { + this.busy = false; + // Emit the event. + this.submitted.emit({ + id: order.id, + pair: order.pair, + fromAmount: order.fromAmount, + toAmount: order.toAmount, + address: order.toAddress, + timestamp: moment().unix(), + price: this.activeTradingPair.price, + }); + }, err => { + this.busy = false; + this.exchangeButton.resetState().setEnabled(); + this.msgBarService.showError(err); + }); + } else { + this.showInvalidAddress(); + } + }, () => { + this.showInvalidAddress(); + }); + } + + // Reactivates the form and shows a msg indicating that the address is invalid. + private showInvalidAddress() { + this.busy = false; + + this.exchangeButton.resetState().setEnabled(); + + const errMsg = this.translateService.instant('exchange.invalid-address-error'); + this.msgBarService.showError(errMsg); + } + + // Inits the form. + private createForm() { + this.form = this.formBuilder.group({ + fromCoin: [this.defaultFromCoin], + fromAmount: [this.defaultFromAmount], + toAddress: [''], + }); + + this.form.setValidators(this.validateForm.bind(this)); + + this.subscriptionsGroup.push(this.form.get('fromCoin').valueChanges.subscribe(() => { + this.updateActiveTradingPair(); + })); + } + + // Loads the available trading pairs from the backend. + private loadData() { + this.subscriptionsGroup.push(this.exchangeService.tradingPairs() + .pipe(retryWhen(errors => concat(errors.pipe(delay(2000), take(10)), observableThrowError('')))) + .subscribe(pairs => { + this.tradingPairs = []; + + // Use only the trading pairs which include the wallet coin. + pairs.forEach(pair => { + if (pair.to === this.toCoin) { + this.tradingPairs.push(pair); + } + }); + + this.updateActiveTradingPair(); + this.updatePrices(); + }, () => { + this.problemGettingPairs = true; + }), + ); + } + + // Periodically updates the value of each trading pair indicating how many coins will be + // received per coin sent. + private updatePrices() { + this.removePriceUpdateSubscription(); + + this.priceUpdateSubscription = of(1).pipe(delay(60000), mergeMap(() => this.exchangeService.tradingPairs()), + retryWhen(errors => errors.pipe(delay(60000)))) + .subscribe(pairs => { + pairs.forEach(pair => { + if (pair.to === this.toCoin) { + const alreadySavedPair = this.tradingPairs.find(oldPair => oldPair.from === pair.from); + if (alreadySavedPair) { + alreadySavedPair.price = pair.price; + } + } + }); + this.updatePrices(); + }); + } + + // Updates the var with the currently selected trading pair. + private updateActiveTradingPair() { + this.activeTradingPair = this.tradingPairs.find(p => { + return p.from === this.form.get('fromCoin').value; + }); + + if (!this.activeTradingPair && this.tradingPairs.length > 0) { + this.activeTradingPair = this.tradingPairs[0]; + this.form.get('fromCoin').setValue(this.activeTradingPair.from); + } + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.coinErrorMsg = ''; + this.amountErrorMsg = ''; + this.addressErrorMsg = ''; + this.amountTooLow = false; + this.amountTooHight = false; + + if (!this.activeTradingPair) { + return null; + } + + let valid = true; + + const fromAmount = this.form.get('fromAmount').value; + + // The must be a from amount. + if (!fromAmount || isNaN(fromAmount)) { + valid = false; + if (this.form.get('fromAmount').touched) { + this.amountErrorMsg = 'exchange.invalid-value-error-info'; + } + } else { + const parts = (fromAmount as string).split('.'); + + // If there is a from amount, it must not have more than 6 decimals. + if (parts.length > 1 && parts[1].length > 6) { + valid = false; + if (this.form.get('fromAmount').touched) { + this.amountErrorMsg = 'exchange.invalid-value-error-info'; + } + } + } + + // If there is a from amount, it must be inside the limits. + if (valid) { + if (fromAmount < this.activeTradingPair.min) { + this.amountTooLow = true; + valid = false; + if (this.form.get('fromAmount').touched) { + this.amountErrorMsg = 'exchange.invalid-value-error-info'; + } + } + + if (fromAmount > this.activeTradingPair.max) { + this.amountTooHight = true; + valid = false; + if (this.form.get('fromAmount').touched) { + this.amountErrorMsg = 'exchange.invalid-value-error-info'; + } + } + } + + // There must be a selected coin for the from amount. + if (!this.form.get('fromCoin').value) { + valid = false; + if (this.form.get('fromCoin').touched) { + this.coinErrorMsg = 'exchange.from-coin-error-info'; + } + } + + // There must be a valid destination address. + const address = this.form.get('toAddress').value as string; + if (!address || address.length < 20) { + valid = false; + if (this.form.get('toAddress').touched) { + this.addressErrorMsg = 'exchange.address-error-info'; + } + } + + // The user must accept the agreement. + if (!this.agreement) { + valid = false; + } + + return valid ? null : { Invalid: true }; + } + + private removeExchangeSubscription() { + if (this.exchangeSubscription) { + this.exchangeSubscription.unsubscribe(); + } + } + + private removePriceUpdateSubscription() { + if (this.priceUpdateSubscription) { + this.priceUpdateSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.html b/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.html new file mode 100644 index 0000000..456b2be --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.html @@ -0,0 +1,12 @@ + + +
+ +
+
diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.scss b/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.scss new file mode 100644 index 0000000..8ee8b46 --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.scss @@ -0,0 +1,22 @@ +@import '../../../../../theme/variables'; + +.info { + font-size: $font-size-standard; + line-height: 1.7; + color: $black; + + div { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + + mat-icon { + font-size: 16px; + width: 16px; + height: 16px; + position: relative; + top: 3px; + margin: 0px 5px; + } + } +} \ No newline at end of file diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.ts b/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.ts new file mode 100644 index 0000000..4da0b28 --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-history/exchange-history.component.ts @@ -0,0 +1,70 @@ +import { Component, OnInit } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +import { ExchangeService, StoredExchangeOrder } from '../../../../services/exchange.service'; +import { BlockchainService } from '../../../../services/blockchain.service'; +import { AppConfig } from '../../../../app.config'; + +/** + * Modal window for checking the lists of previously saved orders. If the user selects an order, + * the modal window is closed and the selected order is returned in the "afterClosed" event. + */ +@Component({ + selector: 'app-exchange-history', + templateUrl: './exchange-history.component.html', + styleUrls: ['./exchange-history.component.scss'], +}) +export class ExchangeHistoryComponent implements OnInit { + // List of saved orders. + orders: StoredExchangeOrder[]; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = false; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(ExchangeHistoryComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + public blockchainService: BlockchainService, + private exchangeService: ExchangeService, + ) { } + + ngOnInit() { + // Get the saved transactions. + this.exchangeService.history().subscribe( + (orders: StoredExchangeOrder[]) => { + if (orders) { + this.orders = orders.reverse(); + } else { + this.orders = []; + } + }, + () => this.orders = [], + ); + } + + closePopup() { + this.dialogRef.close(); + } + + // Closes the modal window and returns the selected order. + select(value: StoredExchangeOrder) { + this.dialogRef.close(value); + } + + // Gets the "from" part of the name of a trading pair. + getFromCoin(pair: string) { + return pair.split('/')[0].toUpperCase(); + } + + // Gets the "to" part of the name of a trading pair. + getToCoin(pair: string) { + return pair.split('/')[1].toUpperCase(); + } +} diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.html b/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.html new file mode 100644 index 0000000..36cb884 --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.html @@ -0,0 +1,163 @@ + + + + +
+
+ {{ statusIcon }} +
+
{{ 'exchange.label-status' | translate }}
+
{{ translatedStatus.text | translate:translatedStatus.params }} help
+
+
+ {{ 'exchange.exchanging' | translate:{from: fromCoin, to: toCoin} }} +
+ + + + + +
+ +
+
+
+
{{ 'exchange.details.order-id-label' | translate }}
+
{{ order.id }}
+
+
+ + + + +
+
+
+
{{ 'exchange.label-you-send' | translate }}
+
{{ order.fromAmount }} {{ fromCoin }}
+
+
+ + +
+
+ +
+
+
{{ 'exchange.details.exchange-addr-label' | translate }}
+
{{ order.exchangeAddress }}
+
+
+ + +
+
+ +
+
+
{{ 'exchange.details.exchange-addr-tag-label' | translate }}
+
{{ order.exchangeTag }}
+
+
+
+ + + + + + +
+
+
+
{{ 'exchange.details.tx-id-label' | translate }}
+
+ {{ order.toTx }} + + launch + +
+
+
+ + +
+
+
+
{{ 'exchange.details.error-msg-label' | translate }}
+
{{ order.message }}
+
+
+ + +
+
+ + +
+ + + + +
+
+
+
{{ 'exchange.details.start-date-label' | translate }}
+
{{ _orderDetails.timestamp | dateTime }}
+
+
+ + + + + + +
+
+
+
{{ 'exchange.label-you-get' | translate }}
+
{{ order.toAmount | amount:true:'first' }} {{ toCoin }}
+
+
+ + +
+
+
+
{{ 'exchange.label-to-address' | translate:{coin: toCoin} }}
+
{{ order.toAddress }}
+
+
+ + +
+
+
+
{{ 'exchange.details.initial-price-label' | translate }}
+
1 {{ fromCoin }} ≈ {{ _orderDetails.price }} {{ toCoin }}
+
+
+
+
+
+ + +
+ + {{ 'common.back-button' | translate }} + +
diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.scss b/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.scss new file mode 100644 index 0000000..7eef900 --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.scss @@ -0,0 +1,87 @@ +@import '../../../../../theme/variables'; + +.-wrapper { + font-size: $font-size-standard; + display: flex; + justify-content: space-between; + align-items: center; + + .-status { + display: flex; + align-items: center; + + mat-icon { + margin-right: 15px; + width: 18px; + height: 18px; + font-size: 18px; + + &.-spin { + animation: spin 1s infinite linear; + } + } + + .-value { + padding-right: 30px; + word-break: normal; + } + } +} + +mat-progress-bar { + margin: 30px -30px; + width: calc(100% + 60px); +} + +.-details { + .-box { + display: flex; + align-items: center; + + &:not(:last-child) { + margin-bottom: 20px; + } + + > .-img { + width: $qr-code-button-size; + margin-right: 15px; + flex-shrink: 0; + } + } +} + +.-item { + font-size: $font-size-standard; + + &:not(:last-child) { + margin-bottom: 20px; + } + + .-key { + color: $grey; + margin-bottom: 5px; + } + + .-value { + word-break: break-all; + } +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(359deg); + } +} + +.-external mat-icon { + line-height: $font-size-standard; + height: $font-size-standard; + width: $font-size-standard; + font-size: 16px; + vertical-align: middle; + margin-left: 10px; +} diff --git a/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.ts b/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.ts new file mode 100644 index 0000000..6748044 --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange-status/exchange-status.component.ts @@ -0,0 +1,211 @@ +import { Component, Input, OnDestroy, Output, EventEmitter } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { SubscriptionLike, of } from 'rxjs'; +import { delay, mergeMap } from 'rxjs/operators'; + +import { ExchangeService, ExchangeOrder, StoredExchangeOrder } from '../../../../services/exchange.service'; +import { BlockchainService } from '../../../../services/blockchain.service'; +import { environment } from '../../../../../environments/environment'; +import { ConfirmationParams, DefaultConfirmationButtons, ConfirmationComponent } from '../../../layout/confirmation/confirmation.component'; +import { CoinService } from '../../../../services/coin.service'; +import { Coin } from '../../../../coins/coin'; + +/** + * Shows the current status of a previously saved order. The data is updated periodically. + * It needs a previously saved order because, depending on the current status of the order, + * the backend may not return all the data, data which is normally added to a locally saved + * order at creation time. + */ +@Component({ + selector: 'app-exchange-status', + templateUrl: './exchange-status.component.html', + styleUrls: ['./exchange-status.component.scss'], +}) +export class ExchangeStatusComponent implements OnDestroy { + // If the page must work in test mode. If true, the page will use the sandbox API endpoints + // and show simulated state updates. + private readonly TEST_MODE = environment.swaplab.activateTestMode; + // If true and in test mode, the page will show an error as the last state of the order. + private readonly TEST_ERROR = environment.swaplab.endStatusInError; + // Known states the backend return. + readonly statuses = [ + 'user_waiting', + 'market_waiting_confirmations', + 'market_confirmed', + 'market_exchanged', + 'market_withdraw_waiting', + 'complete', + 'error', + 'user_deposit_timeout', + ]; + + // True while the page is getting the data of the order for the first time. + loading = true; + // If there was an error when trying to get the data from the backend for the first time. + showError = false; + // If the UI must show the detailed information panel openned. + expanded = false; + + currentCoin: Coin; + + private subscription: SubscriptionLike; + private coinSubscription: SubscriptionLike; + // If in test mode, the index inside the statuses var of the status currently being shown. + private testStatusIndex = 0; + // Data obtained from the backend. + private order: ExchangeOrder; + + // Previously saved order for which the data will be shown. + _orderDetails: StoredExchangeOrder; + @Input() set orderDetails(val: StoredExchangeOrder) { + const oldOrderDetails = this._orderDetails; + this._orderDetails = val; + + // As the value can be updated without recreaating the page, the state of the page is + // resetted, but only if the order was changed. + if (val !== null && (!oldOrderDetails || oldOrderDetails.id !== val.id)) { + this.exchangeService.lastViewedOrder = this._orderDetails; + this.testStatusIndex = 0; + this.loading = true; + this.getStatus(); + } + } + + // Emits when the user presses the button for returning to the form. + @Output() goBack = new EventEmitter(); + + // Gets the "from" part of the name of a trading pair. + get fromCoin(): string { + return this.order.pair.split('/')[0].toUpperCase(); + } + + // Gets the "to" part of the name of a trading pair. + get toCoin(): string { + return this.order.pair.split('/')[1].toUpperCase(); + } + + // Gets the params needed for using the translate pipe for showing the name and info + // of the current state. + get translatedStatus() { + const status = this.order.status.replace(/_/g, '-'); + const params = { + from: this.fromCoin, + amount: this.order.fromAmount, + to: this.toCoin, + }; + + return { + text: `exchange.statuses.${status}`, + info: `exchange.statuses.${status}-info`, + params, + }; + } + + // Gets the icon for the current status. + get statusIcon(): string { + if (this.order.status === this.statuses[5]) { + return 'done'; + } + + if (this.order.status === this.statuses[6] || this.order.status === this.statuses[7]) { + return 'close'; + } + + return 'refresh'; + } + + // Gets the completion percentage of the order, according to its current status. + get progress() { + let index = this.statuses.indexOf(this.order.status); + + index = Math.min(index, 5) + 1; + + return Math.ceil((100 / 6) * index); + } + + constructor( + private exchangeService: ExchangeService, + private dialog: MatDialog, + public blockchainService: BlockchainService, + public coinService: CoinService, + ) { + this.coinSubscription = this.coinService.currentCoin.subscribe(coin => { + this.currentCoin = coin; + }); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + this.coinSubscription.unsubscribe(); + this.goBack.complete(); + } + + // Opens or closes the detailed information panel. + toggleDetails() { + this.expanded = !this.expanded; + } + + // Sends the event for returning to the form. If the order has not been finished, the + // user is asked for confirmation. + close() { + if (this.loading || this.exchangeService.isOrderFinished(this.order)) { + this.goBack.emit(); + } else { + const confirmationParams: ConfirmationParams = { + text: 'exchange.details.back-alert', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.goBack.emit(); + } + }); + } + } + + // Periodically updates the status of the order. + private getStatus(delayTime = 0) { + if (this.subscription) { + this.subscription.unsubscribe(); + } + + const fromAmount = this._orderDetails.fromAmount; + + // Go to the correct status if using the test mode. + if (this.TEST_MODE && this.TEST_ERROR && this.testStatusIndex === this.statuses.length - 2) { + this.testStatusIndex = this.statuses.length - 1; + } + + this.subscription = of(0).pipe(delay(delayTime), mergeMap(() => { + // Orders created using the sandbox methods are not saved on the backend, so a + // predefined ID is provided if the tests mode is being used, and a simulated status. + return this.exchangeService.status( + !this.TEST_MODE ? this._orderDetails.id : '4729821d-390d-4ef8-a31e-2465d82a142f', + !this.TEST_MODE ? null : this.statuses[this.testStatusIndex++], + ); + })).subscribe(order => { + // Restore the amount of coins the user must send, as the backend may have not included it. + this.order = { ...order, fromAmount }; + this._orderDetails.id = order.id; + // Remember the last viewed order. + this.exchangeService.lastViewedOrder = this._orderDetails; + + if (!this.exchangeService.isOrderFinished(order)) { + this.getStatus(this.TEST_MODE ? 3000 : 30000); + } else { + // If the order is already finished, forget about it as the last viewed order, to avoid + // restoring it when returning to this section of the app, instead of showing the form. + this.exchangeService.lastViewedOrder = null; + } + + this.loading = false; + }, () => { + if (this.loading) { + this.showError = true; + } else { + this.getStatus(this.TEST_MODE ? 3000 : 30000); + } + }); + } +} diff --git a/src/gui/static/src/app/components/pages/exchange/exchange.component.html b/src/gui/static/src/app/components/pages/exchange/exchange.component.html new file mode 100644 index 0000000..2032a61 --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange.component.html @@ -0,0 +1,47 @@ + +
+
+ + + + + + + + +
+ +
+ + + +
+ + {{ 'exchange.need-help' | translate }} + + {{ 'exchange.support-portal' | translate }} + + + | + + {{ 'exchange.powered-by' | translate }} + SWAPLAB.CC + +
+
+
diff --git a/src/gui/static/src/app/components/pages/exchange/exchange.component.scss b/src/gui/static/src/app/components/pages/exchange/exchange.component.scss new file mode 100644 index 0000000..f2ab049 --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange.component.scss @@ -0,0 +1,30 @@ +@import '../../../../theme/variables'; + +.-contact { + margin: 15px 30px; + display: flex; + justify-content: space-between; + + span { + font-size: $font-size-standard; + margin: 0 5px; + opacity: .5; + vertical-align: middle; + } + + .history { + opacity: 1; + } + + mat-icon { + font-size: 18px; + width: 18px; + height: 18px; + vertical-align: middle; + } + + .history-text { + font-size: $font-size-standard-plus; + opacity: 1; + } +} diff --git a/src/gui/static/src/app/components/pages/exchange/exchange.component.ts b/src/gui/static/src/app/components/pages/exchange/exchange.component.ts new file mode 100644 index 0000000..4ba18f7 --- /dev/null +++ b/src/gui/static/src/app/components/pages/exchange/exchange.component.ts @@ -0,0 +1,113 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; +import { Router } from '@angular/router'; + +import { ExchangeService, StoredExchangeOrder } from '../../../services/exchange.service'; +import { ExchangeHistoryComponent } from './exchange-history/exchange-history.component'; +import { environment } from '../../../../environments/environment'; +import { CoinService } from '../../../services/coin.service'; + +/** + * Allows to buy coins using the Swaplab service. + */ +@Component({ + selector: 'app-exchange', + templateUrl: './exchange.component.html', + styleUrls: ['./exchange.component.scss'], +}) +export class ExchangeComponent implements OnInit, OnDestroy { + // Order for which the status must be shown. If null, the form for creating a new order is shown. + currentOrderDetails: StoredExchangeOrder; + // If there are previously created orders saved on the persistent storage. + hasHistory = false; + // If the page is loading the initial data needed for starting to show anything. + loading = true; + // If the service is not available. + unavailable = false; + + private lastViewedSubscription: SubscriptionLike; + private historySubscription: SubscriptionLike; + private coinSubscription: SubscriptionLike; + + constructor( + private exchangeService: ExchangeService, + private dialog: MatDialog, + private coinService: CoinService, + private router: Router, + ) { } + + ngOnInit() { + // The service is not available in the portable version, as the backend would return cors + // errors and there is no dev proxy or Electron process for fixing the problem. + if (environment.production && navigator.userAgent.toLowerCase().indexOf('electron') === -1) { + this.unavailable = true; + + return; + } + + // Check if there is a "last vieved" order saved and, if there is one, show its status. + this.lastViewedSubscription = this.exchangeService.lastViewedOrderLoaded.subscribe(response => { + if (response) { + const lastViewedOrder = this.exchangeService.lastViewedOrder; + if (lastViewedOrder) { + this.currentOrderDetails = lastViewedOrder; + } + + setTimeout(() => this.lastViewedSubscription.unsubscribe()); + this.loading = false; + } + }); + + // Check if there is an previously created orders history. + this.historySubscription = this.exchangeService.history().subscribe(response => { + if (response) { + this.hasHistory = true; + } + }); + + // Currently the exchange option is only available for Skycoin. + this.coinSubscription = this.coinService.currentCoin.subscribe(coin => { + if (coin.coinName.toLowerCase() !== 'skycoin') { + this.router.navigate([''], {replaceUrl: true}); + } + }); + } + + ngOnDestroy() { + if (this.lastViewedSubscription) { + this.lastViewedSubscription.unsubscribe(); + } + if (this.historySubscription) { + this.historySubscription.unsubscribe(); + } + if (this.coinSubscription) { + this.coinSubscription.unsubscribe(); + } + } + + // Shows the control for displaying the status of an order. + showStatus(order: StoredExchangeOrder) { + this.currentOrderDetails = order; + this.hasHistory = true; + } + + // Opens the modal window with the list of previously created orders. + showHistory(event) { + event.preventDefault(); + + ExchangeHistoryComponent.openDialog(this.dialog).afterClosed().subscribe((oldOrder: StoredExchangeOrder) => { + if (oldOrder) { + this.currentOrderDetails = oldOrder; + } + }); + } + + // Returns to the form. + goBack() { + this.currentOrderDetails = null; + // Prevent this page for showing the details of the order when returning to the + // exchange section. + this.exchangeService.lastViewedOrder = null; + } +} diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.html b/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.html new file mode 100644 index 0000000..d852374 --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.html @@ -0,0 +1,41 @@ +
+ +
+
+
+ {{ 'wizard.create-title' | translate }} +
+
+

{{ 'wizard.create-desc' | translate }}

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ {{ ('wizard.hardware-wallet-' + (softwareWalletsAllowedForCoin ? 'link' : 'alt-link')) | translate }} +
+ + +
diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.scss b/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.scss new file mode 100644 index 0000000..9d198aa --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.scss @@ -0,0 +1,12 @@ +@import '../../../../../theme/variables'; + +.-toggle-container { + margin: 10px auto; +} + +.hw-link { + cursor: pointer; + color: $white; + font-size: $font-size-standard; + margin-bottom: 20px; +} diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.ts b/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.ts new file mode 100644 index 0000000..e973562 --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding-create-wallet/onboarding-create-wallet.component.ts @@ -0,0 +1,140 @@ +import { Component, EventEmitter, Input, OnInit, Output, ViewChild, OnDestroy } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { Router } from '@angular/router'; +import { SubscriptionLike } from 'rxjs'; + +import { DoubleButtonActive } from '../../../layout/double-button/double-button.component'; +import { CreateWalletFormComponent, WalletFormData } from '../../wallets/create-wallet/create-wallet-form/create-wallet-form.component'; +import { HwOptionsDialogComponent } from '../../../layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component'; +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { BlockchainService } from '../../../../services/blockchain.service'; +import { ConfirmationParams, ConfirmationComponent, DefaultConfirmationButtons } from '../../../layout/confirmation/confirmation.component'; +import { WalletTypes } from '../../../../services/wallet-operations/wallet-objects'; +import { CoinService } from '../../../../services/coin.service'; + +/** + * Shows the first step of the wizard, which allows the user to create a new wallet or load + * a wallet using a seed. + */ +@Component({ + selector: 'app-onboarding-create-wallet', + templateUrl: './onboarding-create-wallet.component.html', + styleUrls: ['./onboarding-create-wallet.component.scss'], +}) +export class OnboardingCreateWalletComponent implements OnInit, OnDestroy { + @ViewChild('formControl') formControl: CreateWalletFormComponent; + // Data for filling the form just after loading it. + @Input() fill: WalletFormData = null; + // Emits when the user press the button for going to the next step of the wizard, after + // filling the form. Includes an object with the data entered on the form. + @Output() onLabelAndSeedCreated = new EventEmitter(); + + // Current selection on the double button for choosing if the form must be shown for + // creating a new wallet (left) or for loading a wallet using a seed (right). + currentFormSelection = DoubleButtonActive.LeftButton; + // If the option for adding a hw wallet must be shown. + hwCompatibilityActivated = false; + // If the currently selected coin is compatible with the hw wallet. + hardwareWalletsAllowedForCoin = true; + // If the currently selected coin is compatible with software wallets. + softwareWalletsAllowedForCoin = true; + + doubleButtonActive = DoubleButtonActive; + + // If the blockchain is synchronized. + private synchronized = true; + private blockchainSubscription: SubscriptionLike; + + constructor( + private dialog: MatDialog, + private router: Router, + hwWalletService: HwWalletService, + blockchainService: BlockchainService, + coinService: CoinService, + ) { + this.hwCompatibilityActivated = hwWalletService.hwWalletCompatibilityActivated; + this.hardwareWalletsAllowedForCoin = !!coinService.currentCoinInmediate.skywalletCoinType; + this.softwareWalletsAllowedForCoin = !!coinService.currentCoinInmediate.coinTypeFeatures.softwareWallets; + this.blockchainSubscription = blockchainService.progress.subscribe(response => this.synchronized = response.synchronized); + } + + ngOnInit() { + // Fill the form. + setTimeout(() => { this.formControl.initForm(null, this.fill); }); + // Show the correct form. + if (this.fill) { + this.currentFormSelection = this.fill.creatingNewWallet ? DoubleButtonActive.LeftButton : DoubleButtonActive.RightButton; + } + } + + ngOnDestroy() { + this.blockchainSubscription.unsubscribe(); + this.onLabelAndSeedCreated.complete(); + } + + // Changes the form currently shown on the UI. + changeForm(newState: DoubleButtonActive) { + this.currentFormSelection = newState; + // Resets the form. + this.fill = null; + this.formControl.initForm(this.currentFormSelection === DoubleButtonActive.LeftButton, this.fill); + } + + // Shows an alert asking for confirmation and emits an event for going to the next step + // of the wizard. + createWallet() { + if (this.formControl.getData().type === WalletTypes.XPub) { + this.emitCreatedData(); + } else { + const confirmationParams: ConfirmationParams = { + headerText: 'wizard.confirm.title', + redTitle: true, + text: 'wizard.confirm.desc', + checkboxText: 'wizard.confirm.checkbox', + confirmButtonText: 'common.continue-button', + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.emitCreatedData(); + } + }); + } + } + + // Emits an event for going to the next step of the wizard. If the blockchain is not + // synchronized, it shows an alert first, asking for confirmation. + loadWallet() { + if (this.synchronized) { + this.emitCreatedData(); + } else { + const confirmationParams: ConfirmationParams = { + headerText: 'common.warning-title', + text: 'wallet.new.synchronizing-warning-text', + defaultButtons: DefaultConfirmationButtons.ContinueCancel, + redTitle: true, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.emitCreatedData(); + } + }); + } + } + + // Opens the hw wallet options modal window, which will try to add the connected hw wallet + // to the wallet list. If at the end the wallet is on the list, the wizard is closed. + useHardwareWallet() { + HwOptionsDialogComponent.openDialog(this.dialog, true).afterClosed().subscribe(result => { + if (result) { + this.router.navigate(['/wallets']); + } + }); + } + + // Emits an event for going to the next step of the wizard. + private emitCreatedData() { + this.onLabelAndSeedCreated.emit(this.formControl.getData()); + } +} diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.html b/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.html new file mode 100644 index 0000000..725fa9f --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.html @@ -0,0 +1,69 @@ +
+ +
+
+
+ {{ 'wizard.encrypt-title' | translate }} +
+
+

{{ 'wizard.encrypt-desc' | translate }}

+
+
+
+ +
+
+ + + + {{ 'wallet.new.encrypt-check' | translate }} + + +
+
+ +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.scss b/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.scss new file mode 100644 index 0000000..73740ce --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.scss @@ -0,0 +1,11 @@ +@import '../../../../../theme/variables'; + +.-check-container { + margin: 10px auto; +} + +.-check ::ng-deep { + .mat-checkbox-checkmark-path { + stroke: $white !important; + } +} diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.ts b/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.ts new file mode 100644 index 0000000..d98d144 --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding-encrypt-wallet/onboarding-encrypt-wallet.component.ts @@ -0,0 +1,113 @@ +import { Component, EventEmitter, OnInit, Output, ViewChild, ChangeDetectorRef, OnDestroy } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; + +import { ButtonComponent } from '../../../layout/button/button.component'; + +/** + * Shows the second step of the wizard, which allows the user to set the password. + */ +@Component({ + selector: 'app-onboarding-encrypt-wallet', + templateUrl: './onboarding-encrypt-wallet.component.html', + styleUrls: ['./onboarding-encrypt-wallet.component.scss'], +}) +export class OnboardingEncryptWalletComponent implements OnInit, OnDestroy { + @ViewChild('button') button: ButtonComponent; + // Emits when the user presses the button for going to the next step of the wizard, after + // filling the form. Includes the password entered by the user, or null, if the user + // selected not to encrypt the wallet. + @Output() onPasswordCreated = new EventEmitter(); + // Emits when the user presses the button for going back to the previous step of the wizard. + @Output() onBack = new EventEmitter(); + form: FormGroup; + + // Vars with the validation error messages. + password1ErrorMsg = ''; + password2ErrorMsg = ''; + + constructor( + private formBuilder: FormBuilder, + private changeDetector: ChangeDetectorRef, + ) { } + + ngOnInit() { + this.form = this.formBuilder.group({ + password: new FormControl(''), + confirm: new FormControl(''), + }, + ); + + this.form.setValidators(this.validateForm.bind(this)); + } + + ngOnDestroy() { + this.onPasswordCreated.complete(); + this.onBack.complete(); + } + + // Called after pressing the checkbox for selecting if the wallet must be encrypted with + // a password or not. + setEncrypt(event) { + event.checked ? this.form.enable() : this.form.disable(); + } + + // Emits an event for going to the next step of the wizard. + emitCreatedPassword() { + if ((this.form.enabled && !this.form.valid) || this.button.isLoading()) { + return; + } + + this.button.setLoading(); + + this.onPasswordCreated.emit(this.form.enabled ? this.form.get('password').value : null); + + this.changeDetector.detectChanges(); + } + + // Emits an event for going to the previous step of the wizard. + emitBack() { + this.onBack.emit(); + } + + resetButton() { + this.button.resetState(); + } + + // Allows to know if the app is processing and the form must be shown disabled. + get isWorking() { + return this.button ? this.button.isLoading() : false; + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.password1ErrorMsg = ''; + this.password2ErrorMsg = ''; + + let valid = true; + + if (!this.form.get('password').value) { + valid = false; + if (this.form.get('password').touched) { + this.password1ErrorMsg = 'password.password-error-info'; + } + } + + if (!this.form.get('confirm').value) { + valid = false; + if (this.form.get('confirm').touched) { + this.password2ErrorMsg = 'password.password-error-info'; + } + } + + // If both password fields have a value, check if the 2 passwords entered by the user + // are equal. + if (valid && this.form.get('password').value !== this.form.get('confirm').value) { + valid = false; + this.password2ErrorMsg = 'password.confirm-error-info'; + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding.component.html b/src/gui/static/src/app/components/pages/onboarding/onboarding.component.html new file mode 100644 index 0000000..1827430 --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding.component.html @@ -0,0 +1,21 @@ +
+ + + + + + + + +
diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding.component.scss b/src/gui/static/src/app/components/pages/onboarding/onboarding.component.scss new file mode 100644 index 0000000..38c4ab5 --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding.component.scss @@ -0,0 +1,23 @@ +@import '../../../../theme/variables'; + +.main-container { + height: 100%; +} + +button { + position: fixed; + right: 30px; + top: 20px; + background-color: $white !important; + + &:hover { + background-color: $white-hover !important; + } +} + +.flag { + width: 16px; + height: 16px; + position: relative; + top: -3px; +} diff --git a/src/gui/static/src/app/components/pages/onboarding/onboarding.component.ts b/src/gui/static/src/app/components/pages/onboarding/onboarding.component.ts new file mode 100644 index 0000000..af71a32 --- /dev/null +++ b/src/gui/static/src/app/components/pages/onboarding/onboarding.component.ts @@ -0,0 +1,102 @@ +import { Component, OnInit, OnDestroy, ViewChild, Renderer2, AfterViewInit, ElementRef } from '@angular/core'; +import { Router } from '@angular/router'; +import { SubscriptionLike } from 'rxjs'; +import { MatDialog } from '@angular/material/dialog'; + +import { LanguageData, LanguageService } from '../../../services/language.service'; +import { WalletFormData } from '../wallets/create-wallet/create-wallet-form/create-wallet-form.component'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { OnboardingEncryptWalletComponent } from './onboarding-encrypt-wallet/onboarding-encrypt-wallet.component'; +import { SelectLanguageComponent } from '../../layout/select-language/select-language.component'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; +import { CreateWalletArgs } from '../../../services/coin-specific/wallets-and-addresses-operator'; +import { CoinService } from '../../../services/coin.service'; + +/** + * Wizard for creating the first wallet. + */ +@Component({ + selector: 'app-onboarding', + templateUrl: './onboarding.component.html', + styleUrls: ['./onboarding.component.scss'], +}) +export class OnboardingComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild('encryptForm') encryptForm: OnboardingEncryptWalletComponent; + @ViewChild('container') container: ElementRef; + + // Current stept to show. + step = 1; + // Data entered on the form of the first step. + formData: WalletFormData; + // Currently selected language. + language: LanguageData; + + private coinSubscription: SubscriptionLike; + private subscription: SubscriptionLike; + + constructor( + private router: Router, + private languageService: LanguageService, + private dialog: MatDialog, + private msgBarService: MsgBarService, + private walletsAndAddressesService: WalletsAndAddressesService, + private coinService: CoinService, + private renderer: Renderer2, + ) { } + + ngOnInit() { + this.subscription = this.languageService.currentLanguage.subscribe(lang => this.language = lang); + } + + ngAfterViewInit() { + // Update the background. + this.coinSubscription = this.coinService.currentCoin.subscribe(coin => { + const background = 'linear-gradient(to bottom right, ' + coin.styleConfig.onboardingGradientDark + ', ' + coin.styleConfig.onboardingGradientLight + ')'; + this.renderer.setStyle(this.container.nativeElement, 'background', background); + }); + } + + ngOnDestroy() { + this.coinSubscription.unsubscribe(); + this.subscription.unsubscribe(); + } + + // Called when the user finishes the first step. + onLabelAndSeedCreated(data: WalletFormData) { + this.formData = data, + this.step = 2; + } + + // Called when the user finishes the second step. + onPasswordCreated(password: string|null) { + const args: CreateWalletArgs = { + isHardwareWallet: false, + softwareWalletArgs: { + label: this.formData.label, + type: this.formData.type, + seed: this.formData.enterSeedWithAssistance ? this.formData.lastAssistedSeed : this.formData.lastCustomSeed, + password: password, + passphrase: this.formData.passphrase, + xPub: this.formData.xPub, + }, + }; + + // Create the wallet. + this.walletsAndAddressesService.createWallet(args).subscribe(() => { + this.router.navigate(['/wallets']); + }, e => { + this.msgBarService.showError(e); + // Make the form usable again. + this.encryptForm.resetButton(); + }); + } + + // Return to step 1. + onBack() { + this.step = 1; + } + + changelanguage() { + SelectLanguageComponent.openDialog(this.dialog); + } +} diff --git a/src/gui/static/src/app/components/pages/reset-password/reset-password.component.html b/src/gui/static/src/app/components/pages/reset-password/reset-password.component.html new file mode 100644 index 0000000..a9b4dc3 --- /dev/null +++ b/src/gui/static/src/app/components/pages/reset-password/reset-password.component.html @@ -0,0 +1,98 @@ + +
+ + + + +
+
+ +
+ + +
+
+ +
+ + + +
+ + format_list_numbered{{ 'wallet.new.seed.use-normal' | translate }} + +
+
+ +
+ +
+ +
+
+ +
+ + + + +
+ + edit {{ 'wallet.new.seed.use-custom' | translate }} + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + {{ 'reset.reset-button' | translate }} + +
+
+
+
diff --git a/src/gui/static/src/app/components/pages/reset-password/reset-password.component.scss b/src/gui/static/src/app/components/pages/reset-password/reset-password.component.scss new file mode 100644 index 0000000..9b01a31 --- /dev/null +++ b/src/gui/static/src/app/components/pages/reset-password/reset-password.component.scss @@ -0,0 +1,8 @@ +.seed-type-button { + text-align: right; + + mat-icon { + position: relative; + top: 1px; + } +} diff --git a/src/gui/static/src/app/components/pages/reset-password/reset-password.component.ts b/src/gui/static/src/app/components/pages/reset-password/reset-password.component.ts new file mode 100644 index 0000000..ef973fa --- /dev/null +++ b/src/gui/static/src/app/components/pages/reset-password/reset-password.component.ts @@ -0,0 +1,192 @@ +import { Component, OnDestroy, ViewChild, ChangeDetectorRef, OnInit } from '@angular/core'; +import { SubscriptionLike, combineLatest } from 'rxjs'; +import { ActivatedRoute, Router } from '@angular/router'; +import { FormGroup, FormBuilder, FormControl } from '@angular/forms'; +import { map } from 'rxjs/operators'; + +import { ButtonComponent } from '../../layout/button/button.component'; +import { MsgBarService } from '../../../services/msg-bar.service'; +import { SoftwareWalletService } from '../../../services/wallet-operations/software-wallet.service'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; +import { WalletBase, WalletTypes } from '../../../services/wallet-operations/wallet-objects'; +import { AssistedSeedFieldComponent } from '../wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component'; +import { WordAskedReasons } from '../../layout/seed-word-dialog/seed-word-dialog.component'; + +/** + * Allows to use the seed to remove or change the password of an encrypted software wallet. + * The URL for opening this page must have a param called "id", with the ID of the wallet + * to which the password will be changed. + */ +@Component({ + selector: 'app-reset-password', + templateUrl: './reset-password.component.html', + styleUrls: ['./reset-password.component.scss'], +}) +export class ResetPasswordComponent implements OnInit, OnDestroy { + @ViewChild('resetButton') resetButton: ButtonComponent; + // Component for entering the seed using the assisted mode. + @ViewChild('assistedSeed') assistedSeed: AssistedSeedFieldComponent; + + form: FormGroup; + wallet: WalletBase; + // Allows to deactivate the form while the component is busy. + busy = true; + // If the id on the URL does not correspond to a valid wallet. + invalidWallet = false; + // If true, the user must enter the ssed using the asisted mode. + enterSeedWithAssistance = true; + + walletTypes = WalletTypes; + wordAskedReasons = WordAskedReasons; + + // Vars with the validation error messages. + seedErrorMsg = ''; + passwordErrorMsg = ''; + + private subscription: SubscriptionLike; + private done = false; + private hideBarWhenClosing = true; + + constructor( + public formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private msgBarService: MsgBarService, + private softwareWalletService: SoftwareWalletService, + private walletsAndAddressesService: WalletsAndAddressesService, + private changeDetector: ChangeDetectorRef, + ) { } + + ngOnInit() { + this.initForm(); + // Get the wallets and route params. + this.subscription = combineLatest([this.route.params, this.walletsAndAddressesService.currentWallets]).pipe(map(result => { + const params = result[0]; + const wallets = result[1]; + + const wallet = wallets.find(w => w.id === params['id']); + this.invalidWallet = false; + + // Abort if the requested wallet does not exists. + if (!wallet) { + this.invalidWallet = true; + + return; + } + + this.wallet = wallet; + this.form.get('wallet').setValue(wallet.label); + // Activate the form. + this.busy = false; + })).subscribe(); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + if (this.hideBarWhenClosing) { + this.msgBarService.hide(); + } + } + + // Returns the value of the number_of_words form field. + get selectedNumberOfWords(): number { + return this.form ? this.form.value.number_of_words : 0; + } + + initForm() { + this.form = new FormGroup({}); + this.form.addControl('wallet', new FormControl()); + this.form.addControl('number_of_words', new FormControl(12)); + this.form.addControl('seed', new FormControl('')); + this.form.addControl('passphrase', new FormControl('')); + this.form.addControl('password', new FormControl('')); + this.form.addControl('confirm', new FormControl('')); + + // If assistedSeed already exists, reset it. + if (this.assistedSeed) { + this.assistedSeed.lastAssistedSeed = ''; + } + + this.form.setValidators(this.validateForm.bind(this)); + } + + // Switches between the assisted mode and the manual mode for entering the seed. + changeSeedType() { + this.enterSeedWithAssistance = !this.enterSeedWithAssistance; + this.form.updateValueAndValidity(); + } + + assistedSeedChanged() { + this.form.updateValueAndValidity(); + } + + // Resets the wallet password. + reset() { + if (!this.form.valid || this.busy || this.done) { + return; + } + + this.busy = true; + this.msgBarService.hide(); + this.resetButton.setLoading(); + + const seed = this.enterSeedWithAssistance ? this.assistedSeed.lastAssistedSeed : this.form.value.seed; + + this.softwareWalletService.resetPassword(this.wallet, seed, this.form.value.password, this.form.value.passphrase) + .subscribe(() => { + this.resetButton.setSuccess(); + this.resetButton.setDisabled(); + this.done = true; + + // Show a success msg and avoid closing it after closing this page. + this.msgBarService.showDone('reset.done'); + this.hideBarWhenClosing = false; + + // Navigate from the page after a small delay. + setTimeout(() => { + this.router.navigate(['']); + }, 2000); + }, error => { + // Reactivate the UI and show the error msg. + this.busy = false; + this.resetButton.resetState(); + this.msgBarService.showError(error); + }); + + // Avoids a problem with the change detection system. + this.changeDetector.detectChanges(); + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.seedErrorMsg = ''; + this.passwordErrorMsg = ''; + + let valid = true; + + if (this.enterSeedWithAssistance) { + if (!this.assistedSeed || !this.assistedSeed.lastAssistedSeed) { + valid = false; + } + } else { + if (!this.form.get('seed').value) { + valid = false; + if (this.form.get('seed').touched) { + this.seedErrorMsg = 'reset.seed-error-info'; + } + } + } + + // Check if the 2 passwords entered by the user are equal. + if (this.form.get('password').value !== this.form.get('confirm').value) { + valid = false; + if (this.form.get('confirm').touched) { + this.passwordErrorMsg = 'reset.confirm-error-info'; + } + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.html b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.html new file mode 100644 index 0000000..ba01141 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.html @@ -0,0 +1,108 @@ +
+ +
+ + +
+ +
+ + + +
+ +
+ + + + + + +
+
+ +
+ +
+ +
+
+ + {{ selectedCurrency === doubleButtonActive.LeftButton ? ('coinSymbol' | commonText) : ('common.usd' | translate) }} +
+ +
+ {{ 'send.invalid-amount' | translate }} + + ~ {{ values[i].toString() | number:'1.0-2' }} {{ 'common.usd' | translate }} + + + ~ {{ values[i] | amount }} + + +
+
+ +
+
+ + {{ 'hours' | commonText }} +
+
+
+ plus + minus +
+
+
+
+
+
+
+ {{ 'send.total-to-send' | translate }} {{ totalCoins | amount }} + / {{ totalFiat.toString() | number:'1.0-2' }} {{ 'common.usd' | translate }} +
+
+
+
+ {{ 'send.total-to-send' | translate }} {{ totalHours | amount:false }} +
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.scss b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.scss new file mode 100644 index 0000000..831518f --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.scss @@ -0,0 +1,54 @@ +@import '../../../../../../theme/variables'; + +.-destination { + &:not(:last-child) { + margin-bottom: 5px; + } + + .-icons { + text-align: right; + padding-top: 5px; + + img { + width: $normal-icon-size; + } + } +} + +.destinations-label { + display: inline-block; +} + +.coin-selector-container { + display: inline-block; + margin-left: 5px; + margin-bottom: 5px; +} + +.coins-value-label { + font-size: $font-size-mini; + margin-top: 1px; + padding: 3px 10px; + background-color: $grey-lightest; + border-radius: $input-border-radius; + + span { + opacity: 0.5; + } + + .link { + display: inline-block; + margin-bottom: 3px; + margin-top: -5px; + } + + .centerd-link { + width: 100%; + text-align: center; + } +} + +.error-coins-value { + background-color: $red !important; + color: $white !important +} diff --git a/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.ts b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.ts new file mode 100644 index 0000000..4d29f35 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-destination/form-destination.component.ts @@ -0,0 +1,833 @@ +import { SubscriptionLike } from 'rxjs'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { BigNumber } from 'bignumber.js'; +import { TranslateService } from '@ngx-translate/core'; + +import { DoubleButtonActive } from '../../../../layout/double-button/double-button.component'; +import { PriceService } from '../../../../../services/price.service'; +import { MsgBarService } from '../../../../../services/msg-bar.service'; +import { AvailableBalanceData } from '../../form-parts/form-source-selection/form-source-selection.component'; +import { ConfirmationParams, ConfirmationComponent, DefaultConfirmationButtons } from '../../../../layout/confirmation/confirmation.component'; +import { SendCoinsData } from '../../send-coins-form/send-coins-form.component'; +import { CoinService } from '../../../../../services/coin.service'; +import { NodeService } from '../../../../../services/node.service'; + +/** + * Data about the destinations entered by the user on FormDestinationComponent. + */ +export interface Destination { + /** + * Destination address. + */ + address: string; + /** + * How many coins to send to the destination. + */ + coins: string; + /** + * Original value entered by the user as the amount to send. It can be how many coins to send, + * in which case the value will be the same as the one on the "coins" property, but it can + * also contain a fiat value. + */ + originalAmount: string; + /** + * How many hours to send to the destination. + */ + hours?: string; +} + +/** + * Allows the user to set the destinations to were the coins will be sent, including how many + * coins and hours to send to each one. + */ +@Component({ + selector: 'app-form-destination', + templateUrl: './form-destination.component.html', + styleUrls: ['./form-destination.component.scss'], +}) +export class FormDestinationComponent implements OnInit, OnDestroy { + /** + * How many decimals the user can use when entering a value in usd. the UI can use a different + * value when showing usd values (normally 2). + */ + private static readonly MaxUsdDecimals = 6; + + // Allows to deactivate the form while the system is busy. + @Input() busy: boolean; + // If the form is still waiting for a valid fee for being able to calculate the + // available balance. + @Input() validFeeNeeded: boolean; + // Emits when there have been changes in the contents of the component, so the validation + // status could have changed. + @Output() onChanges = new EventEmitter(); + // Emits when the user asks to open the modal window for bulk sending. + @Output() onBulkRequested = new EventEmitter(); + + // Balance available to send. + private availableBalanceInternal: AvailableBalanceData; + @Input() set availableBalance(val: AvailableBalanceData) { + if (!this.availableBalance || !val.availableCoins.isEqualTo(this.availableBalance.availableCoins) || !val.availableHours.isEqualTo(this.availableBalance.availableHours)) { + this.availableBalanceInternal = val; + + // Update the validation, as the available balance is used for it. + if (this.form) { + this.form.get('destinations').updateValueAndValidity(); + this.onChanges.emit(); + } + } + } + get availableBalance(): AvailableBalanceData { + return this.availableBalanceInternal; + } + + // If the manual hours field must be shown. + private showHourFieldsInternal: boolean; + @Input() set showHourFields(val: boolean) { + if (!this.coinHasHours) { + this.showHourFieldsInternal = false; + + return; + } + + if (val !== this.showHourFieldsInternal) { + this.showHourFieldsInternal = val; + if (this.form) { + this.destControls.forEach(dest => { + dest.get('hours').setValue(''); + }); + } + } + } + get showHourFields(): boolean { + return this.showHourFieldsInternal; + } + + // If true, the form only allows to enter one destination and the amount of coins to send + // to it. If false, the form allows multiple destinations, with their coins and hours. + private showSimpleFormInternal: boolean; + @Input() set showSimpleForm(val: boolean) { + this.showSimpleFormInternal = val; + + if (this.form) { + if (val) { + this.form.get('address').setValidators(Validators.required); + } else { + this.form.get('address').clearValidators(); + } + + this.form.get('address').updateValueAndValidity(); + this.form.get('destinations').updateValueAndValidity(); + } + } + get showSimpleForm(): boolean { + return this.showSimpleFormInternal; + } + + form: FormGroup; + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + doubleButtonActive = DoubleButtonActive; + // Allows to know if the user is entering the values in the coin (left) or usd (right). + selectedCurrency = DoubleButtonActive.LeftButton; + // If the user is entering the values in USD, it contains the coins value of each destination. + // if the user is entering the values in coins, it contains the USD value of each destination. + values: BigNumber[]; + // Current USD price per coin. + price: number; + // Total amount of coins that will be sent to all destinations. + totalCoins = new BigNumber(0); + // Total usd value that will be sent to all destinations. + totalFiat = new BigNumber(0); + // Total amount of hours that will be sent to all destinations, if the manual hours are active. + totalHours = new BigNumber(0); + // If the coin only allows to send transactions to a single destination and does not allow + // to select the change address. + limitedSendingOptions = false; + + // List for knowing which destination addresses were indentified as valid by the server, + // by index. + validAddressesList: boolean[]; + + // Vars with the validation error messages. + addressErrorMsgs: string[] = []; + coinsErrorMsgs: string[] = []; + hoursErrorMsgs: string[] = []; + singleAddressErrorMsg = ''; + insufficientCoins = false; + insufficientHours = false; + + private priceSubscription: SubscriptionLike; + private addressSubscription: SubscriptionLike; + private destinationSubscriptions: SubscriptionLike[] = []; + + // Gets all the form field groups on the destinations array. + get destControls() { + return (this.form.get('destinations') as FormArray).controls; + } + + constructor( + private nodeService: NodeService, + private formBuilder: FormBuilder, + private dialog: MatDialog, + private msgBarService: MsgBarService, + private translate: TranslateService, + private priceService: PriceService, + private coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.limitedSendingOptions = coinService.currentCoinInmediate.coinTypeFeatures.limitedSendingOptions; + } + + ngOnInit() { + this.form = this.formBuilder.group({ + address: [''], + destinations: this.formBuilder.array([]), + }); + this.form.setValidators(this.validateForm.bind(this)); + + this.addDestination(); + + // Inform when there are changes on the address field, shown on the simple form. + this.addressSubscription = this.form.get('address').valueChanges.subscribe(() => { + this.onChanges.emit(); + }); + + // Keep the price updated. + this.priceSubscription = this.priceService.price.subscribe(price => { + this.price = price; + this.updateValuesAndValidity(); + }); + } + + ngOnDestroy() { + this.addressSubscription.unsubscribe(); + this.priceSubscription.unsubscribe(); + this.destinationSubscriptions.forEach(s => s.unsubscribe()); + this.onChanges.complete(); + this.onBulkRequested.complete(); + } + + get destinationsLabel() { + if (this.showSimpleForm) { + return 'send.amount-label'; + } else { + if (!this.limitedSendingOptions) { + return 'send.destinations-label'; + } else { + return 'send.destination-label'; + } + } + } + + get destinationsHelp() { + if (!this.limitedSendingOptions) { + return 'send.destinations-help' + (!this.showHourFields ? '1' : '2'); + } else { + return 'send.destination-help'; + } + } + + // Changes the currency in which the user enters the values on the UI. + changeActiveCurrency(value: DoubleButtonActive) { + if (value !== this.selectedCurrency) { + this.selectedCurrency = value; + this.askIfConvertAmount(); + this.updateValuesAndValidity(); + (this.form.get('destinations') as FormArray).updateValueAndValidity(); + } + } + + // Must be called just after changing the currency in which the user enters the values on + // the UI. It asks the user if the current values must be converted to the new currency. + // If the user accepts, it calls the function to convert the values. + private askIfConvertAmount() { + // Before asking, check if there are valid values to convert. + let validAmounts = 0; + this.destControls.forEach(dest => { + let value: string = dest.get('coins').value; + value = value ? value.trim() : value; + const currentValue = new BigNumber(value); + + if (!value || currentValue.isNaN()) { + return; + } + + validAmounts += 1; + }); + if (validAmounts === 0) { + return; + } + + // Prepare the values for the confirmation modal. + const usd = this.translate.instant('common.usd'); + const currentCoinName = this.coinService.currentCoinInmediate.coinSymbol; + let fromText: string; + let toText: string; + if (this.selectedCurrency === DoubleButtonActive.LeftButton) { + fromText = usd; + toText = currentCoinName; + } else { + fromText = currentCoinName; + toText = usd; + } + + const confirmationParams: ConfirmationParams = { + text: this.translate.instant(validAmounts === 1 ? 'send.convert-confirmation' : 'send.convert-confirmation-plural', {from: fromText, to: toText}), + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + // Ask for confirmation. + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.convertAmounts(); + } + }); + } + + // If the component is set for the user to enter the values in usd, converts all the + // destination values from the coin to usd. If it is set for the user to enter the + // values in the coin, converts all the destination values from usd to the coin. + private convertAmounts() { + this.msgBarService.hide(); + + // How many values were invalid numbers and it was not possible to convert them. + let invalidValues = 0; + // How many values were converted but had precision problems due to the amount of + // decimal places. + let valuesWithPrecisionErrors = 0; + + this.destControls.forEach(dest => { + let value: string = dest.get('coins').value; + value = value ? value.trim() : value; + const currentValue = new BigNumber(value); + + if (value) { + if (currentValue.isNaN()) { + invalidValues += 1; + + return; + } + + // Convert the value and check for precision errors. + if (this.selectedCurrency === DoubleButtonActive.LeftButton) { + const newValue = currentValue.dividedBy(this.price).decimalPlaces(this.nodeService.currentMaxDecimals); + const recoveredValue = newValue.multipliedBy(this.price).decimalPlaces(FormDestinationComponent.MaxUsdDecimals, BigNumber.ROUND_FLOOR); + if (!recoveredValue.isEqualTo(currentValue)) { + valuesWithPrecisionErrors += 1; + } + + dest.get('coins').setValue(newValue.toString()); + } else { + const newValue = currentValue.multipliedBy(this.price).decimalPlaces(FormDestinationComponent.MaxUsdDecimals, BigNumber.ROUND_FLOOR); + const recoveredValue = newValue.dividedBy(this.price).decimalPlaces(this.nodeService.currentMaxDecimals); + if (!recoveredValue.isEqualTo(currentValue)) { + valuesWithPrecisionErrors += 1; + } + + dest.get('coins').setValue(newValue.toString()); + } + } + }); + + // Inform about any problem found during the procedure. + if (invalidValues > 0 && valuesWithPrecisionErrors > 0) { + this.msgBarService.showWarning(this.translate.instant('send.multiple-problems-warning')); + } else if (invalidValues === 1) { + this.msgBarService.showWarning(this.translate.instant('send.invaid-amount-warning')); + } else if (invalidValues > 1) { + this.msgBarService.showWarning(this.translate.instant('send.invaid-amounts-warning')); + } else if (valuesWithPrecisionErrors === 1) { + this.msgBarService.showWarning(this.translate.instant('send.precision-error-warning')); + } else if (valuesWithPrecisionErrors > 1) { + this.msgBarService.showWarning(this.translate.instant('send.precision-errors-warning')); + } + } + + // Assigns all the remaining coins to the destination corresponding to the provided index. + assignAll(index: number) { + this.msgBarService.hide(); + + // If the form is still waiting for a valid fee for being able to calculate the + // available balance, show an error msg. + if (this.validFeeNeeded || this.availableBalance.loading) { + this.msgBarService.showError(this.translate.instant('send.no-available-balance-error')); + + return; + } + + // If there are no available coins on the selected sources, show an error msg. + if (this.availableBalance.availableCoins.isEqualTo(0)) { + this.msgBarService.showError(this.translate.instant('send.no-wallet-selected-error')); + + return; + } + + // Calculate the total available balance, in the currency being used on the UI. + let availableBalance: BigNumber = this.availableBalance.availableCoins; + if (this.selectedCurrency === DoubleButtonActive.RightButton) { + availableBalance = availableBalance.multipliedBy(this.price).decimalPlaces(FormDestinationComponent.MaxUsdDecimals, BigNumber.ROUND_FLOOR); + } + + // Subtract to the available balance all the values already asigned to the other destinations. + this.destControls.forEach((dest, i) => { + if (i !== index) { + const value = this.getAmount((dest.get('coins').value as string).trim(), true); + if (!value || value.isNaN()) { + return; + } else { + availableBalance = availableBalance.minus(value); + } + } + }); + + // Limit the decimal places. + if (this.selectedCurrency === DoubleButtonActive.LeftButton) { + availableBalance = availableBalance.decimalPlaces(this.nodeService.currentMaxDecimals, BigNumber.ROUND_FLOOR); + } else { + availableBalance = availableBalance.decimalPlaces(FormDestinationComponent.MaxUsdDecimals, BigNumber.ROUND_FLOOR); + } + + // Use the value or show an error, if there are no enough coins. + if (availableBalance.isLessThanOrEqualTo(0)) { + this.msgBarService.showError(this.translate.instant('send.no-coins-left-error')); + } else { + this.destControls[index].get('coins').setValue(availableBalance.toString()); + } + } + + // Updates the total and converted values and then updates the form validity. + updateValuesAndValidity() { + let inputInUsd = this.selectedCurrency !== DoubleButtonActive.LeftButton; + let currentPrice = this.price; + if (!this.price) { + inputInUsd = false; + currentPrice = 0; + } + + // Reset the values. + this.values = []; + this.totalCoins = new BigNumber(0); + this.totalFiat = new BigNumber(0); + this.totalHours = new BigNumber(0); + + this.destControls.forEach((dest, i) => { + // Update the coin values. + let stringValue: string = dest.get('coins').value; + let value = this.getAmount(stringValue, true); + + if (!value) { + this.values[i] = new BigNumber(-1); + } else { + if (!inputInUsd) { + // Calculate the value in USD. + const convertedValue = value.multipliedBy(currentPrice).decimalPlaces(2); + + // Update the values. + this.totalCoins = this.totalCoins.plus(value); + this.totalFiat = this.totalFiat.plus(convertedValue); + this.values[i] = convertedValue; + } else { + // Calculate the value in coins. + const convertedValue = value.dividedBy(currentPrice).decimalPlaces(this.nodeService.currentMaxDecimals); + + // Update the values. + this.totalCoins = this.totalCoins.plus(convertedValue); + this.totalFiat = this.totalFiat.plus(value); + this.values[i] = convertedValue; + } + } + + // Update the hour values. + if (this.showHourFields) { + stringValue = dest.get('hours').value; + value = this.getAmount(stringValue, false); + if (value) { + this.totalHours = this.totalHours.plus(value); + } + } + }); + + // Update the form validity. + setTimeout(() => { + (this.form.get('destinations') as FormArray).updateValueAndValidity(); + this.onChanges.emit(); + }); + } + + // Adds a new empty destination to the form. + addDestination() { + const group = this.formBuilder.group({ + address: '', + coins: '', + hours: '', + }); + + this.destinationSubscriptions.push(group.valueChanges.subscribe(() => { + // Inform when there are changes. + this.updateValuesAndValidity(); + })); + + (this.form.get('destinations') as FormArray).push(group); + this.addressErrorMsgs.push(''); + this.coinsErrorMsgs.push(''); + this.hoursErrorMsgs.push(''); + + this.updateValuesAndValidity(); + } + + // Removes from the form the destination corresponding to the provided index. + removeDestination(index) { + const destinations = this.form.get('destinations') as FormArray; + destinations.removeAt(index); + + // Remove the associated entries in the error arrays, if needed. + if (this.validAddressesList && this.validAddressesList.length > index) { + this.validAddressesList.splice(index, 1); + } + if (this.addressErrorMsgs && this.addressErrorMsgs.length > index) { + this.addressErrorMsgs.splice(index, 1); + } + if (this.coinsErrorMsgs && this.coinsErrorMsgs.length > index) { + this.coinsErrorMsgs.splice(index, 1); + } + if (this.hoursErrorMsgs && this.hoursErrorMsgs.length > index) { + this.hoursErrorMsgs.splice(index, 1); + } + + // Remove the subscription used to check the changes made to the fields of the destination. + this.destinationSubscriptions[index].unsubscribe(); + this.destinationSubscriptions.splice(index, 1); + + this.updateValuesAndValidity(); + } + + requestBulkSend() { + this.onBulkRequested.emit(); + } + + /** + * Fills the form with the provided values. + */ + fill(formData: SendCoinsData) { + setTimeout(() => { + this.selectedCurrency = formData.form.currency; + + for (let i = 0; i < formData.form.destinations.length - 1; i++) { + this.addDestination(); + } + + this.destControls.forEach((destControl, i) => { + ['address', 'hours'].forEach(name => { + destControl.get(name).setValue(formData.form.destinations[i][name]); + }); + destControl.get('coins').setValue(formData.form.destinations[i].originalAmount); + + if (this.showSimpleForm) { + this.form.get('address').setValue(formData.form.destinations[i]['address']); + } + }); + + this.updateValuesAndValidity(); + }); + } + + /** + * Allows to change all the destinations. + */ + setDestinations(newDestinations: Destination[]) { + while (this.destControls.length > 0) { + (this.form.get('destinations') as FormArray).removeAt(0); + } + + newDestinations.forEach((destination, i) => { + this.addDestination(); + this.destControls[i].get('address').setValue(destination.address); + this.destControls[i].get('coins').setValue(destination.coins); + if (destination.hours) { + this.destControls[i].get('hours').setValue(destination.hours); + } + }); + } + + /** + * Allows to know if the form is valid. + */ + get valid(): boolean { + return this.form.valid; + } + + /** + * Allows to know if the user is entering the values in coins (left) or usd (right). + */ + get currentlySelectedCurrency(): DoubleButtonActive { + return this.selectedCurrency; + } + + /** + * Allows to set a list indicating which addresses are valid, as validated by + * the backend. + * @param list Validity list. It must include if the address is valid for the index of + * each destination. It can be null, to show all addresses as valid. + */ + setValidAddressesList(list: boolean[]) { + this.validAddressesList = list; + + if (this.validAddressesList && this.validAddressesList.length > this.destControls.length) { + this.validAddressesList = this.validAddressesList.slice(0, this.destControls.length); + } + } + + /** + * Allows to check if the address of a destination must be shown as valid, as validated by + * the backend. + * @param addressIndex Index of the address. + */ + isAddressValid(addressIndex: number): boolean { + if (this.validAddressesList && this.validAddressesList.length > addressIndex) { + return this.validAddressesList[addressIndex]; + } + + return true; + } + + /** + * Gets the error msg that has to be shown for the coins field of a destination. + * @param destinationIndex Index of the destination. + */ + getCoinsErrorMsg(destinationIndex: number): string { + if (destinationIndex < this.coinsErrorMsgs.length) { + // Check if there is a validation error. + if (this.coinsErrorMsgs[destinationIndex]) { + return this.coinsErrorMsgs[destinationIndex]; + } + + // Check if the user is trying to send more coins than available, but only if + // there is just one destination. + if (this.destControls.length === 1 && this.insufficientCoins) { + return 'send.insufficient-funds-error-info'; + } + } + + return ''; + } + + /** + * Gets the error msg that has to be shown for the hours field of a destination. + * @param destinationIndex Index of the destination. + */ + gethoursErrorMsg(destinationIndex: number): string { + if (destinationIndex < this.hoursErrorMsgs.length) { + // Check if there is a validation error. + if (this.hoursErrorMsgs[destinationIndex]) { + return this.hoursErrorMsgs[destinationIndex]; + } + + // Check if the user is trying to send more hours than available, but only if + // there is just one destination. + if (this.destControls.length === 1 && this.insufficientHours) { + return 'send.insufficient-funds-error-info'; + } + } + + return ''; + } + + /** + * Returns all the destinations on the form. The hours are returned only if the form is showing + * the fields for manually entering them. + * @param cleanNumbers If true, the returned strings for the coins and hours will be cleaned + * to be valid numbers. If false, function will just return exactly what the user wrote on + * the form fields. + */ + getDestinations(cleanNumbers: boolean): Destination[] { + return this.destControls.map((destControl, i) => { + // Get the string values. + const destination = { + address: this.showSimpleForm ? ((this.form.get('address').value) as string).trim() : ((destControl.get('address').value) as string).trim(), + coins: ((this.selectedCurrency === DoubleButtonActive.LeftButton ? destControl.get('coins').value : this.values[i].toString()) as string).trim(), + originalAmount: destControl.get('coins').value, + }; + + // Clean the values values. + if (cleanNumbers) { + destination.coins = new BigNumber(destination.coins).toString(10); + destination.originalAmount = new BigNumber(destination.originalAmount).toString(10); + } + + if (this.showHourFields) { + destination['hours'] = destControl.get('hours').value; + if (cleanNumbers) { + destination['hours'] = new BigNumber(destination['hours']).toString(); + } + } + + return destination; + }); + } + + /** + * Makes sure an errors array is the same size as "this.destControls.length" and sets all the + * values to empty strings. + */ + private resetErrorMsgsArray(array: string[]) { + while (array.length > this.destControls.length) { + array.pop(); + } + while (array.length < this.destControls.length) { + array.push(''); + } + for (let i = 0; i < array.length; i++) { + array[i] = ''; + } + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.singleAddressErrorMsg = ''; + this.resetErrorMsgsArray(this.addressErrorMsgs); + this.resetErrorMsgsArray(this.coinsErrorMsgs); + this.resetErrorMsgsArray(this.hoursErrorMsgs); + this.insufficientCoins = false; + this.insufficientHours = false; + + let valid = true; + + // Check the address field of the simple form. + if (this.showSimpleForm) { + const address = this.form.get('address').value as string; + if (!address || address.length < 20) { + valid = false; + if (this.form.get('address').touched) { + this.singleAddressErrorMsg = 'send.address-error-info'; + } + } + } + + // Check if there are invalid values. + this.destControls.forEach((control, i) => { + // Check the address, but not if showing the simple form. + if (!this.showSimpleForm) { + const address = control.get('address').value as string; + if (!address || address.length < 20) { + valid = false; + if (control.get('address').touched) { + this.addressErrorMsgs[i] = 'send.address-error-info'; + } + } + } + + // Check the coins. + const coinsValue: string = control.get('coins').value; + if (this.getAmount(coinsValue, true) === null) { + valid = false; + if (control.get('coins').touched) { + this.coinsErrorMsgs[i] = 'send.invalid-value-error-info'; + } + } + + // Check the hours, if showing the hours field. + if (this.showHourFields) { + const hoursValue: string = control.get('hours').value; + if (this.getAmount(hoursValue, false) === null) { + valid = false; + if (control.get('hours').touched) { + this.hoursErrorMsgs[i] = 'send.invalid-value-error-info'; + } + } + } + }); + + // Check how many coins and hours the user is trying to send. + let destinationsCoins = new BigNumber(0); + if (this.selectedCurrency === DoubleButtonActive.LeftButton) { + this.destControls.map(control => { + const value = new BigNumber(control.get('coins').value); + if (!value.isNaN()) { + destinationsCoins = destinationsCoins.plus(value); + } + }); + } else { + this.updateValuesAndValidity(); + this.values.map(value => { + if (!value.isNaN()) { + destinationsCoins = destinationsCoins.plus(value); + } + }); + } + let destinationsHours = new BigNumber(0); + if (this.showHourFields) { + this.destControls.map(control => { + const value = new BigNumber(control.get('hours').value); + if (!value.isNaN()) { + destinationsHours = destinationsHours.plus(value); + } + }); + } + + // Fail if the user does not have enough coins or hours. + if (destinationsCoins.isGreaterThan(this.availableBalance.availableCoins)) { + this.insufficientCoins = true; + valid = false; + } + if (destinationsHours.isGreaterThan(this.availableBalance.availableHours) && this.showHourFields) { + this.insufficientHours = true; + valid = false; + } + + return valid ? null : { Invalid: true }; + } + + /** + * Process a string and converts it to a BigNumber representing a coins or hours amount. If + * the string is not a valid value, it returns null. + * @param stringValue String to process. + * @param checkingCoins If the function must treat the value as coins or hours while checking + * for validity. + */ + private getAmount(stringValue: string, checkingCoins: boolean): BigNumber { + stringValue = stringValue ? stringValue.trim() : stringValue; + const value = new BigNumber(stringValue); + + // Check for basic validity. + if (!stringValue || value.isNaN() || value.isLessThanOrEqualTo(0)) { + return null; + } + + // Check the decimals. + if (checkingCoins) { + const parts = stringValue.split('.'); + + if (this.selectedCurrency === DoubleButtonActive.LeftButton) { + if (parts.length === 2 && parts[1].length > this.nodeService.currentMaxDecimals) { + return null; + } + } else { + if (parts.length === 2 && parts[1].length > FormDestinationComponent.MaxUsdDecimals) { + return null; + } + } + } else { + if (!value.isEqualTo(value.decimalPlaces(0))) { + return null; + } + } + + return value; + } + + resetForm() { + this.form.get('address').setValue(''); + + while (this.destControls.length > 0) { + (this.form.get('destinations') as FormArray).removeAt(0); + } + + this.addDestination(); + + this.updateValuesAndValidity(); + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.html b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.html new file mode 100644 index 0000000..fc74ccf --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.html @@ -0,0 +1,103 @@ +
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ +
+ + + {{ addr.printableAddress }} - {{ (addr.availableCoins ? addr.availableCoins : 0) | amount }} + {{ !coinHasHours ? '' : ' - ' + (addr.availableHours | amount:false) }} + ({{ 'send.available-balance-indication' | translate }}) + + +
+ {{ address.printableAddress }} - {{ (address.availableCoins ? address.availableCoins : 0) | amount }} + {{ !coinHasHours ? '' : ' - ' + (address.availableHours | amount:false) }} + ({{ 'send.available-balance-indication' | translate }}) +
+
+
+
+
+ +
+ +
+ + + {{ out.hash }} - {{ (out.coins ? out.coins : 0) | amount }} + {{ !coinHasHours ? '' : ' - ' + (out.hours | amount:false) }} + + +
+ {{ out.hash }} - {{ (out.coins ? out.coins : 0) | amount }} + {{ !coinHasHours ? '' : ' - ' + (out.hours | amount:false) }} +
+
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.scss b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.scss new file mode 100644 index 0000000..7bd4f17 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.scss @@ -0,0 +1,19 @@ +@import '../../../../../../theme/variables'; + +.form-field { + mat-spinner { + height: 12px !important; + width: 12px !important; + opacity: 0.5; + margin: 0 !important; + display: inline-block; + position: relative; + top: 2px; + margin-left: 8px; + + ::ng-deep svg { + height: 12px !important; + width: 12px !important; + } + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.ts b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.ts new file mode 100644 index 0000000..058a105 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/form-parts/form-source-selection/form-source-selection.component.ts @@ -0,0 +1,596 @@ +import { throwError as observableThrowError, SubscriptionLike, of } from 'rxjs'; +import { retryWhen, delay, mergeMap, debounceTime } from 'rxjs/operators'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { BigNumber } from 'bignumber.js'; +import { HttpErrorResponse } from '@angular/common/http'; + +import { BalanceAndOutputsService } from '../../../../../services/wallet-operations/balance-and-outputs.service'; +import { WalletWithBalance, AddressWithBalance, WalletTypes, AddressMap } from '../../../../../services/wallet-operations/wallet-objects'; +import { Output as UnspentOutput } from '../../../../../services/wallet-operations/transaction-objects'; +import { processServiceError } from '../../../../../utils/errors'; +import { OperationError } from '../../../../../utils/operation-error'; +import { SendCoinsData } from '../../send-coins-form/send-coins-form.component'; +import { NodeService } from '../../../../../services/node.service'; +import { CoinService } from '../../../../../services/coin.service'; +import { CoinTypes } from '../../../../../coins/settings/coin-types'; +import { MsgBarService } from '../../../../../services/msg-bar.service'; +import { WalletsAndAddressesService } from '../../../../../services/wallet-operations/wallets-and-addresses.service'; + +/** + * Info about the balance which is available with the selections the user has + * made in FormSourceSelectionComponent. + */ +export class AvailableBalanceData { + /** + * How many coins the user can send. + */ + availableCoins = new BigNumber(0); + /** + * How many hours the user can send. It is not the total amount of hours in the selected + * sources, because the fee for sending all the coins has been subtracted from the value. + */ + availableHours = new BigNumber(0); + /** + * Minimum fee in hours the user must pay for sending all the available coins. If the user + * does not send all the coins, the fee could be lower. + */ + minimumFee = new BigNumber(0); + /** + * In how many outputs the available balance is divided. Only for btc-like coins. + */ + outputs = 0; + /** + * If the data is still being loded. Only for the manual mode and btc-like coins. + */ + loading = false; +} + +/** + * Sources the user has selected using FormSourceSelectionComponent. + */ +export interface SelectedSources { + /** + * Selected wallet. + */ + wallet: WalletWithBalance; + /** + * Optional selected addresses. The addresses are from the selected wallet. + */ + addresses?: AddressWithBalance[]; + /** + * Addresses the user has entered manually. Only for the manual mode. + */ + manualAddresses?: string[]; + /** + * Optional selected unspent outputs. The outputs are from the selected wallet and addresses + * or the manually entered addresses. + */ + unspentOutputs: UnspentOutput[]; +} + +/** + * Modes in which FormSourceSelectionComponent can work. + */ +export enum SourceSelectionModes { + /** + * Simple mode in which the user can only select a wallet. + */ + Wallet = 'Wallet', + /** + * Advanced mode in which the user can selected a wallet and then choose specific addresses and + * outputs to have more control about the source from were the coins will be sent. + */ + All = 'All', + /** + * Manual mode in which the user must enter the addresses manually, and have the option for + * selecting specific outputs. + */ + Manual = 'Manual', +} + +/** + * Allows the user to select the sources from were the coins will be sent. It has various modes + * which allow different levels of control. + */ +@Component({ + selector: 'app-form-source-selection', + templateUrl: './form-source-selection.component.html', + styleUrls: ['./form-source-selection.component.scss'], +}) +export class FormSourceSelectionComponent implements OnInit, OnDestroy { + // Allows to deactivate the form while the system is busy. + @Input() busy: boolean; + // Event for informing when the user selection has changed or when there was a change in + // the available balance. + @Output() onSelectionChanged = new EventEmitter(); + + // Sets the mode in which the component works. + private selectionModeInternal: SourceSelectionModes; + @Input() set selectionMode(val: SourceSelectionModes) { + this.selectionModeInternal = val; + if (this.form) { + this.resetForm(); + this.form.updateValueAndValidity(); + } + } + get selectionMode(): SourceSelectionModes { + return this.selectionModeInternal; + } + + sourceSelectionModes = SourceSelectionModes; + form: FormGroup; + // All available wallets. + allWallets: WalletWithBalance[]; + // Wallet selected by the user. + wallet: WalletWithBalance; + // List with all addresses from the selected wallet. + addresses: AddressWithBalance[] = []; + // List of the addresses manually entered by the user, if in manual mode. + manualAddresses: string[] = []; + // List with all the outputs on the selected wallet or the manually entered addresses, + // depending on the selected mode. + allUnspentOutputs: UnspentOutput[] = []; + // Filtered version of allUnspentOutputs shown on the UI. It does not contain the + // outputs which are irrelevant for the other selected sources. + unspentOutputs: UnspentOutput[] = []; + // If the list of unspent outputs is being downloaded from the node. + loadingUnspentOutputs = false; + // If there was an error downloading the list of unspent outputs from the node. + errorLoadingManualOutputs = false; + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + // If true, the currently selected coin uses outputs. + coinHasOutputs = true; + + walletTypes = WalletTypes; + + // Vars with the validation error messages. + manualAddressesErrorMsg = ''; + walletErrorMsg = ''; + + private subscriptionsGroup: SubscriptionLike[] = []; + private getOutputsSubscription: SubscriptionLike; + + constructor( + private nodeService: NodeService, + private formBuilder: FormBuilder, + private balanceAndOutputsService: BalanceAndOutputsService, + private coinService: CoinService, + private msgBarService: MsgBarService, + private walletsAndAddressesService: WalletsAndAddressesService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.coinHasOutputs = coinService.currentCoinInmediate.coinTypeFeatures.outputs; + } + + ngOnInit() { + this.form = this.formBuilder.group({ + manualAddresses: [''], + wallet: [''], + addresses: [null], + outputs: [null], + }); + + this.form.setValidators(this.validateForm.bind(this)); + + // When the user enters the addresses manually. + this.subscriptionsGroup.push(this.form.get('manualAddresses').valueChanges.pipe(debounceTime(500)).subscribe(() => { + // Separate all addresses. + const manuallyEnteredAddresses = (this.form.get('manualAddresses').value as string); + let manualAddresses: string[] = []; + if (manuallyEnteredAddresses && manuallyEnteredAddresses.trim().length > 0) { + manualAddresses = manuallyEnteredAddresses.split(','); + manualAddresses = manualAddresses.map(address => address.trim()); + manualAddresses = manualAddresses.filter(address => address.length > 0); + } + + // Check if there was a change. + let addressesChanged = false; + if (manualAddresses.length !== this.manualAddresses.length) { + addressesChanged = true; + } else { + manualAddresses.forEach((address, i) => { + if (this.manualAddresses[i] !== address) { + addressesChanged = true; + } + }); + } + + // If a change was detected, save the list and reset the form before loading the data again. + if (addressesChanged) { + this.manualAddresses = manualAddresses; + + this.closeGetOutputsSubscription(); + this.allUnspentOutputs = []; + this.unspentOutputs = []; + + this.form.get('outputs').setValue(null); + + this.loadingUnspentOutputs = manualAddresses.length !== 0; + this.errorLoadingManualOutputs = false; + // Inform about the changes in the available balance and loading status. + this.onSelectionChanged.emit(); + } + + if (manualAddresses.length !== 0 && addressesChanged) { + // Get the outputs of the entered addresses. + this.getOutputsSubscription = this.balanceAndOutputsService.getOutputs((this.form.get('manualAddresses').value as string).replace(/ /g, '')).pipe( + // Retry if there is an error, but not if the server returns 400 as response, which + // means the user entered at least one invalid address. + retryWhen((err) => { + return err.pipe(mergeMap((response: OperationError) => { + response = processServiceError(response); + if (response.originalError && (response.originalError as HttpErrorResponse).status && (response.originalError as HttpErrorResponse).status === 400) { + this.errorLoadingManualOutputs = true; + + return observableThrowError(response); + } + + return of(response); + }), delay(4000)); + }), + ).subscribe( + result => { + this.loadingUnspentOutputs = false; + this.allUnspentOutputs = result; + this.unspentOutputs = this.filterUnspentOutputs(); + + // Inform about the changes in the available balance and loading status. + this.onSelectionChanged.emit(); + }, + () => { + this.loadingUnspentOutputs = false; + // Inform about the changes in the available balance and loading status. + this.onSelectionChanged.emit(); + }, + ); + } + })); + + // When the user changes the wallet using the dropdown. + this.subscriptionsGroup.push(this.form.get('wallet').valueChanges.subscribe(wallet => { + this.wallet = wallet; + + // Reset the form. + this.closeGetOutputsSubscription(); + this.allUnspentOutputs = []; + this.unspentOutputs = []; + this.form.get('addresses').setValue(null); + this.form.get('outputs').setValue(null); + this.loadingUnspentOutputs = false; + + // Load the output list, if the form is showing a dropdown for selecting them or if + // using a btc-like coin (needed for calculating the fee). + if (wallet && (this.selectionMode === SourceSelectionModes.All || this.coinService.currentCoinInmediate.coinType === CoinTypes.BTC) && this.coinHasOutputs) { + this.loadingUnspentOutputs = true; + this.getOutputsSubscription = this.balanceAndOutputsService.getWalletUnspentOutputs(wallet).pipe( + retryWhen(errors => errors.pipe(delay(4000)))) + .subscribe( + result => { + this.loadingUnspentOutputs = false; + this.allUnspentOutputs = result; + this.unspentOutputs = this.filterUnspentOutputs(); + + this.onSelectionChanged.emit(); + }, + () => this.loadingUnspentOutputs = false, + ); + } + + if (wallet) { + this.addresses = wallet.addresses.filter(addr => addr.availableCoins > 0); + } else { + this.addresses = []; + } + + this.onSelectionChanged.emit(); + })); + + this.subscriptionsGroup.push(this.form.get('addresses').valueChanges.subscribe(() => { + this.form.get('outputs').setValue(null); + this.unspentOutputs = this.filterUnspentOutputs(); + + this.onSelectionChanged.emit(); + })); + + this.subscriptionsGroup.push(this.form.get('outputs').valueChanges.subscribe(() => { + this.onSelectionChanged.emit(); + })); + + this.subscriptionsGroup.push(this.balanceAndOutputsService.walletsWithBalance.subscribe(wallets => { + if (this.allWallets) { + // balanceAndOutputsService returns the same array unless some important changes in the + // wallets were detected. If that happens, this part of the form is cleaned, to + // avoid problems. + if (this.allWallets !== wallets) { + this.msgBarService.showWarning('send.wallets-updated-warning'); + this.allWallets = null; + this.resetForm(); + } else { + // Inform about the changes in the available balance and loading status. + this.onSelectionChanged.emit(); + } + } + + this.allWallets = wallets; + if (wallets.length === 1) { + setTimeout(() => { + try { + this.form.get('wallet').setValue(wallets[0]); + } catch (e) { } + }); + } + })); + } + + ngOnDestroy() { + this.closeGetOutputsSubscription(); + this.subscriptionsGroup.forEach(sub => sub.unsubscribe()); + this.onSelectionChanged.complete(); + this.msgBarService.hide(); + } + + resetForm() { + // If there is only one wallet, there is no need for restarting the value. + if (!this.allWallets || this.allWallets.length !== 1) { + this.form.get('wallet').setValue(''); + } + + this.form.get('manualAddresses').setValue(''); + this.form.get('addresses').setValue(null); + this.form.get('outputs').setValue(null); + + this.wallet = null; + } + + /** + * Fills the form with the provided values. + */ + fill(formData: SendCoinsData) { + setTimeout(() => { + if (this.selectionMode === SourceSelectionModes.Manual) { + let addressesString = ''; + + const addresses = (formData.form.manualAddresses as string[]); + addresses.forEach((address, i) => { + addressesString += address; + if (i < addresses.length - 1) { + addressesString += ', '; + } + }); + + this.form.get('manualAddresses').setValue(addressesString, { emitEvent: false }); + this.manualAddresses = formData.form.manualAddresses; + } else { + this.addresses = formData.form.wallet.addresses; + + ['wallet', 'addresses'].forEach(name => { + this.form.get(name).setValue(formData.form[name]); + }); + } + + this.closeGetOutputsSubscription(); + this.allUnspentOutputs = formData.form.allUnspentOutputs; + this.unspentOutputs = this.filterUnspentOutputs(); + this.form.get('outputs').setValue(formData.form.outputs); + }); + } + + // Text shown in the addresses dropdown while no value is selected. + get addressessPlaceholder(): string { + if (this.wallet) { + return 'send.all-addresses'; + } else { + return 'send.enter-wallet-for-outputs-and-addresses'; + } + } + + // Text shown in the outputs dropdown while no value is selected. + get outputsPlaceholder(): string { + if (this.selectionMode !== SourceSelectionModes.Manual) { + if (this.wallet) { + return 'send.all-outputs'; + } else { + return 'send.enter-wallet-for-outputs-and-addresses'; + } + } else { + if (this.loadingUnspentOutputs) { + return 'send.all-outputs'; + } else if (this.errorLoadingManualOutputs) { + return 'send.invalid-addresses-for-outputs'; + } else if (!this.manualAddresses || this.manualAddresses.length === 0) { + return 'send.enter-addresses-for-outputs'; + } else { + return 'send.all-outputs'; + } + } + } + + get valid(): boolean { + return this.form.valid; + } + + /** + * Allows to know the available balance with the selected sources. + */ + get availableBalance(): AvailableBalanceData { + const response = new AvailableBalanceData(); + + // While in manual mode, the balance is obtained from the available or selected + // unspent outputs. + if (this.selectionMode === SourceSelectionModes.Manual && this.unspentOutputs && this.unspentOutputs.length > 0) { + const selectedOutputs: UnspentOutput[] = this.form.get('outputs').value; + + if (selectedOutputs && selectedOutputs.length > 0) { + selectedOutputs.map(output => { + response.availableCoins = response.availableCoins.plus(output.coins); + if (this.coinHasHours) { + response.availableHours = response.availableHours.plus(output.hours); + } + }); + + if (this.coinService.currentCoinInmediate.coinType === CoinTypes.BTC) { + response.outputs = selectedOutputs.length; + } + } else { + this.unspentOutputs.forEach(output => { + response.availableCoins = response.availableCoins.plus(output.coins); + if (this.coinHasHours) { + response.availableHours = response.availableHours.plus(output.hours); + } + }); + + if (this.coinService.currentCoinInmediate.coinType === CoinTypes.BTC) { + response.outputs = this.unspentOutputs.length; + } + } + } + + if (this.selectionMode === SourceSelectionModes.Manual || this.coinService.currentCoinInmediate.coinType === CoinTypes.BTC) { + response.loading = this.loadingUnspentOutputs; + } + + // Only if not in manual mode (it is not possible to select a wallet in manual mode). + if (this.form.get('wallet').value) { + const outputs: UnspentOutput[] = this.form.get('outputs').value; + const addresses: AddressWithBalance[] = this.form.get('addresses').value; + + // Get the balance from the selected outputs, the selected addresses, or the + // selected wallet, depending on what the user has selected. + if (outputs && outputs.length > 0) { + outputs.map(control => { + response.availableCoins = response.availableCoins.plus(control.coins); + if (this.coinHasHours) { + response.availableHours = response.availableHours.plus(control.hours); + } + }); + + if (this.coinService.currentCoinInmediate.coinType === CoinTypes.BTC) { + response.outputs = outputs.length; + } + } else if (addresses && addresses.length > 0) { + addresses.map(control => { + response.availableCoins = response.availableCoins.plus(control.availableCoins); + if (this.coinHasHours) { + response.availableHours = response.availableHours.plus(control.availableHours); + } + }); + + if (this.coinService.currentCoinInmediate.coinType === CoinTypes.BTC) { + response.outputs = this.unspentOutputs.length; + } + } else if (this.form.get('wallet').value) { + const wallet: WalletWithBalance = this.form.get('wallet').value; + response.availableCoins = wallet.availableCoins; + if (this.coinHasHours) { + response.availableHours = wallet.availableHours; + } + + if (this.coinService.currentCoinInmediate.coinType === CoinTypes.BTC) { + response.outputs = this.allUnspentOutputs.length; + } + } + } + + // Calculate the max number of hours that can be sent. + if (this.coinHasHours && response.availableCoins.isGreaterThan(0)) { + const unburnedHoursRatio = new BigNumber(1).minus(new BigNumber(1).dividedBy(this.nodeService.burnRate)); + const sendableHours = response.availableHours.multipliedBy(unburnedHoursRatio).decimalPlaces(0, BigNumber.ROUND_FLOOR); + response.minimumFee = response.availableHours.minus(sendableHours); + response.availableHours = sendableHours; + } + + return response; + } + + /** + * Returns the sources the user has selected. + */ + get selectedSources(): SelectedSources { + if (this.selectionMode === SourceSelectionModes.Manual) { + return { + wallet: null, + manualAddresses: this.manualAddresses, + unspentOutputs: this.form.get('outputs').value, + }; + } else { + return { + wallet: this.form.get('wallet').value, + addresses: (this.form.get('addresses').value as AddressWithBalance[]), + unspentOutputs: this.form.get('outputs').value, + }; + } + } + + /** + * Returns the last list of unspent outputs obtained from the node. + */ + get unspentOutputsList(): UnspentOutput[] { + return this.loadingUnspentOutputs ? null : this.allUnspentOutputs; + } + + /** + * Filters the list of unspent outputs obtained from the node, to contain only the outputs + * relevant for the currently selected sources, and saves it to be shown by the unspent + * outputs dropdown. + */ + private filterUnspentOutputs(): UnspentOutput[] { + if (this.selectionMode === SourceSelectionModes.Manual) { + return this.allUnspentOutputs; + } + + // Use only the outputs of the selected addresses, if the user has selected one or more. + if (this.allUnspentOutputs.length === 0) { + return []; + } else if (!this.form.get('addresses').value || (this.form.get('addresses').value as AddressWithBalance[]).length === 0) { + return this.allUnspentOutputs; + } else { + const addressMap = new AddressMap(this.walletsAndAddressesService.formatAddress); + (this.form.get('addresses').value as AddressWithBalance[]).forEach(address => addressMap.set(address.printableAddress, true)); + + return this.allUnspentOutputs.filter(out => addressMap.has(out.address)); + } + } + + private closeGetOutputsSubscription() { + this.loadingUnspentOutputs = false; + + if (this.getOutputsSubscription) { + this.getOutputsSubscription.unsubscribe(); + } + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + if (!this.form) { + return { Required: true }; + } + + this.manualAddressesErrorMsg = ''; + this.walletErrorMsg = ''; + + let valid = true; + + // The validation depends on the current mode. + if (this.selectionMode === SourceSelectionModes.Manual) { + if (!this.form.get('manualAddresses').value || (this.form.get('manualAddresses').value as string).length < 20) { + valid = false; + if (this.form.get('manualAddresses').touched) { + this.manualAddressesErrorMsg = 'send.addresses-error-info'; + } + } + } else { + if (!this.form.get('wallet').value) { + valid = false; + if (this.form.get('wallet').touched) { + this.walletErrorMsg = 'send.wallet-error-info'; + } + } + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/broadcast-raw-tx.component.ts b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/broadcast-raw-tx.component.ts new file mode 100644 index 0000000..0cbe688 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/broadcast-raw-tx.component.ts @@ -0,0 +1,96 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { FormBuilder } from '@angular/forms'; +import { SubscriptionLike } from 'rxjs'; + +import { OfflineDialogsBaseComponent, OfflineDialogsStates } from '../offline-dialogs-base.component'; +import { MsgBarService } from '../../../../../services/msg-bar.service'; +import { AppConfig } from '../../../../../app.config'; +import { BalanceAndOutputsService } from '../../../../../services/wallet-operations/balance-and-outputs.service'; +import { SpendingService } from '../../../../../services/wallet-operations/spending.service'; + +/** + * Allows to send a signed raw transaction to the network, to spend the coins. + */ +@Component({ + selector: 'app-broadcast-raw-tx', + templateUrl: '../offline-dialogs-base.component.html', + styleUrls: ['../offline-dialogs-base.component.scss'], +}) +export class BroadcastRawTxComponent extends OfflineDialogsBaseComponent implements OnInit, OnDestroy { + // Configure the UI. + title = 'offline-transactions.broadcast-tx.title'; + text = 'offline-transactions.broadcast-tx.text'; + inputLabel = 'offline-transactions.broadcast-tx.input-label'; + cancelButtonText = 'common.cancel-button'; + okButtonText = 'offline-transactions.broadcast-tx.send-button'; + validateForm = true; + + private operationSubscription: SubscriptionLike; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = true; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(BroadcastRawTxComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + private msgBarService: MsgBarService, + private balanceAndOutputsService: BalanceAndOutputsService, + private spendingService: SpendingService, + formBuilder: FormBuilder, + ) { + super(formBuilder); + + this.currentState = OfflineDialogsStates.ShowingForm; + } + + ngOnInit() { + // Needed for making the form validation work. + this.form.get('dropdown').setValue('dummy'); + } + + ngOnDestroy() { + this.closeOperationSubscription(); + } + + cancelPressed() { + this.dialogRef.close(); + } + + // Sends the transaction to the network. + okPressed() { + if (this.working) { + return; + } + + this.msgBarService.hide(); + this.working = true; + this.okButton.setLoading(); + + this.closeOperationSubscription(); + this.operationSubscription = this.spendingService.injectTransaction(this.form.get('input').value, null).subscribe(() => { + this.balanceAndOutputsService.refreshBalance(); + + this.msgBarService.showDone('offline-transactions.broadcast-tx.sent'); + this.cancelPressed(); + }, error => { + this.working = false; + this.okButton.resetState(); + + this.msgBarService.showError(error); + }); + } + + closeOperationSubscription() { + if (this.operationSubscription) { + this.operationSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/copy-raw-tx.component.ts b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/copy-raw-tx.component.ts new file mode 100644 index 0000000..2e8e08a --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/copy-raw-tx.component.ts @@ -0,0 +1,80 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { FormBuilder } from '@angular/forms'; + +import { OfflineDialogsBaseComponent, OfflineDialogsStates } from '../offline-dialogs-base.component'; +import { copyTextToClipboard } from '../../../../../utils/general-utils'; +import { MsgBarService } from '../../../../../services/msg-bar.service'; +import { AppConfig } from '../../../../../app.config'; + +/** + * Settings for CopyRawTxComponent. + */ +export interface CopyRawTxData { + /** + * Raw transaction text. + */ + rawTx: string; + /** + * If the transaction is signed or not. + */ + isUnsigned: boolean; +} + +/** + * Allows to see and copy a raw transaction, which is a hex string. + */ +@Component({ + selector: 'app-copy-raw-tx', + templateUrl: '../offline-dialogs-base.component.html', + styleUrls: ['../offline-dialogs-base.component.scss'], +}) +export class CopyRawTxComponent extends OfflineDialogsBaseComponent implements OnInit { + // Set the contents of some of the UI elements. + cancelButtonText = 'common.close-button'; + okButtonText = 'offline-transactions.copy-tx.copy-button'; + inputLabel = 'offline-transactions.copy-tx.input-label'; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, data: CopyRawTxData): MatDialogRef { + const config = new MatDialogConfig(); + config.data = data; + config.autoFocus = true; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(CopyRawTxComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) private data: CopyRawTxData, + public dialogRef: MatDialogRef, + private msgBarService: MsgBarService, + formBuilder: FormBuilder, + ) { + super(formBuilder); + + this.title = 'offline-transactions.copy-tx.' + (data.isUnsigned ? 'unsigned' : 'signed') + '-title'; + this.text = 'offline-transactions.copy-tx.text-' + (data.isUnsigned ? 'unsigned' : 'signed'); + this.contents = data.rawTx; + + this.currentState = OfflineDialogsStates.ShowingForm; + } + + ngOnInit() { + setTimeout(() => { + this.okButton.focus(); + }); + } + + cancelPressed() { + this.dialogRef.close(); + } + + okPressed() { + // Copy the tx to the clipboad. + copyTextToClipboard(this.data.rawTx); + this.msgBarService.showDone('common.copied', 4000); + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/sign-raw-tx.component.ts b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/sign-raw-tx.component.ts new file mode 100644 index 0000000..cf5143a --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/implementations/sign-raw-tx.component.ts @@ -0,0 +1,161 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { FormBuilder } from '@angular/forms'; +import { SubscriptionLike } from 'rxjs'; +import { first } from 'rxjs/operators'; + +import { OfflineDialogsBaseComponent, OfflineDialogsStates } from '../offline-dialogs-base.component'; +import { MsgBarService } from '../../../../../services/msg-bar.service'; +import { CopyRawTxData, CopyRawTxComponent } from './copy-raw-tx.component'; +import { PasswordDialogComponent } from '../../../../../components/layout/password-dialog/password-dialog.component'; +import { AppConfig } from '../../../../../app.config'; +import { SpendingService } from '../../../../../services/wallet-operations/spending.service'; +import { WalletsAndAddressesService } from '../../../../../services/wallet-operations/wallets-and-addresses.service'; +import { WalletBase, WalletTypes } from '../../../../../services/wallet-operations/wallet-objects'; + +/** + * Allows to sign an unsigned raw tx. For it to be able to sign the transaction, all the + * inputs must belong to one (only one) of the registered software wallets. After signing + * the transaction, it opens a new modal window for showing the signed raw tx. + */ +@Component({ + selector: 'app-sign-raw-tx', + templateUrl: '../offline-dialogs-base.component.html', + styleUrls: ['../offline-dialogs-base.component.scss'], +}) +export class SignRawTxComponent extends OfflineDialogsBaseComponent implements OnInit, OnDestroy { + // Configure the UI. + title = 'offline-transactions.sign-tx.title'; + text = 'offline-transactions.sign-tx.text'; + dropdownLabel = 'offline-transactions.sign-tx.wallet-label'; + defaultDropdownText = 'offline-transactions.sign-tx.select-wallet'; + inputLabel = 'offline-transactions.sign-tx.input-label'; + cancelButtonText = 'common.cancel-button'; + okButtonText = 'offline-transactions.sign-tx.sign-button'; + validateForm = true; + + private walletsSubscription: SubscriptionLike; + private operationSubscription: SubscriptionLike; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = true; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(SignRawTxComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + private msgBarService: MsgBarService, + private dialog: MatDialog, + private spendingService: SpendingService, + private walletsAndAddressesService: WalletsAndAddressesService, + formBuilder: FormBuilder, + ) { + super(formBuilder); + + this.currentState = OfflineDialogsStates.Loading; + } + + ngOnInit() { + // Get the wallet list. + this.walletsSubscription = this.walletsAndAddressesService.currentWallets.pipe(first()).subscribe(wallets => { + if (wallets) { + this.dropdownElements = []; + + // Create a list with the software wallets, for the dropdown control. + wallets.forEach(wallet => { + if (!wallet.isHardware && wallet.walletType !== WalletTypes.XPub) { + this.dropdownElements.push({ + name: wallet.label, + value: wallet, + }); + } + }); + + // Fill the dropdown control. + this.currentState = OfflineDialogsStates.ShowingForm; + + setTimeout(() => { + try { + if (wallets.length === 1) { + this.form.get('dropdown').setValue(wallets[0]); + } + } catch (e) { } + }); + } else { + this.currentState = OfflineDialogsStates.ErrorLoading; + } + }, () => this.currentState = OfflineDialogsStates.ErrorLoading); + } + + ngOnDestroy() { + this.walletsSubscription.unsubscribe(); + this.closeOperationSubscription(); + this.msgBarService.hide(); + } + + cancelPressed() { + this.dialogRef.close(); + } + + okPressed() { + if (this.working) { + return; + } + + this.msgBarService.hide(); + + // Get the wallet password, if needed, and start signing the transaction. + if ((this.form.get('dropdown').value as WalletBase).encrypted) { + PasswordDialogComponent.openDialog(this.dialog, { wallet: this.form.get('dropdown').value }).componentInstance.passwordSubmit + .subscribe(passwordDialog => { + passwordDialog.close(); + this.signTransaction(passwordDialog.password); + }); + } else { + this.signTransaction(null); + } + } + + // Signs the transaction with the selected wallet. + private signTransaction(password: string) { + this.working = true; + this.okButton.setLoading(); + + this.closeOperationSubscription(); + this.operationSubscription = this.spendingService.signTransaction( + this.form.get('dropdown').value, + password, + null, + this.form.get('input').value).subscribe(encodedSignedTx => { + this.cancelPressed(); + setTimeout(() => this.msgBarService.showDone('offline-transactions.sign-tx.signed')); + + // After a short delay, open the copy modal window, to see the signed transaction. + setTimeout(() => { + const data: CopyRawTxData = { + rawTx: encodedSignedTx, + isUnsigned: false, + }; + + CopyRawTxComponent.openDialog(this.dialog, data); + }, 500); + }, error => { + this.working = false; + this.okButton.resetState(); + + this.msgBarService.showError(error); + }); + } + + closeOperationSubscription() { + if (this.operationSubscription) { + this.operationSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/offline-dialogs-base.component.html b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/offline-dialogs-base.component.html new file mode 100644 index 0000000..0b4063b --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/offline-dialogs-base.component.html @@ -0,0 +1,60 @@ + + + + + + + {{ text | translate }} + + +
+ + {{ cancelButtonText | translate }} + + + {{ okButtonText | translate }} + +
+
+
diff --git a/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/offline-dialogs-base.component.scss b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/offline-dialogs-base.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/offline-dialogs-base.component.ts b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/offline-dialogs-base.component.ts new file mode 100644 index 0000000..3bb10c2 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/offline-dialogs/offline-dialogs-base.component.ts @@ -0,0 +1,100 @@ +import { Component, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +import { ButtonComponent } from '../../../layout/button/button.component'; + +/** + * States in which OfflineDialogsBaseComponent and derived classes can be. + */ +export enum OfflineDialogsStates { + Loading = 'Loading', + ErrorLoading = 'ErrorLoading', + ShowingForm = 'ShowingForm', +} + +/** + * Data for an element of the dropdown control. + */ +export interface OfflineDialogsDropdownElement { + /** + * Text to show on the UI. + */ + name: string; + /** + * Actual value. + */ + value: any; +} + +/** + * Base component for the modal windows used for operations related to creating transactions + * with an offline wallet. It provides the UI and some functionality. + */ +@Component({ + template: '', +}) +export class OfflineDialogsBaseComponent { + @ViewChild('okButton') okButton: ButtonComponent; + // Allows to deactivate the form while the component is busy. + working = false; + form: FormGroup; + currentState: OfflineDialogsStates = OfflineDialogsStates.Loading; + states = OfflineDialogsStates; + validateForm = false; + + // Basic info for the UI. The values must be set by the subclasses. + title = ''; + text = ''; + dropdownLabel = ''; + defaultDropdownText = ''; + inputLabel = ''; + // If it has a value, the textarea will be in read only mode. + contents = ''; + cancelButtonText = ''; + okButtonText = ''; + + // Vars with the validation error messages. + dropdownErrorMsg = ''; + inputErrorMsg = ''; + + // If not set, the dropdown control is not shown. + dropdownElements: OfflineDialogsDropdownElement[]; + + constructor( + _formBuilder: FormBuilder, + ) { + this.form = _formBuilder.group({ + dropdown: [''], + input: [''], + }); + + this.form.setValidators(this.validate.bind(this)); + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validate() { + this.dropdownErrorMsg = ''; + this.inputErrorMsg = ''; + + let valid = true; + + if (!this.form.get('dropdown').value) { + valid = false; + if (this.form.get('dropdown').touched) { + this.dropdownErrorMsg = 'offline-transactions.wallet-error-info'; + } + } + + const inputValue = this.form.get('input').value as string; + if (!inputValue || inputValue.length < 300 || !/^[0-9a-fA-F]+$/.test(inputValue)) { + valid = false; + if (this.form.get('input').touched) { + this.inputErrorMsg = 'offline-transactions.tx-error-info'; + } + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.html b/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.html new file mode 100644 index 0000000..dbd73c4 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.html @@ -0,0 +1,269 @@ +
+ + +
+ +
+ + + + + +
+ + + {{ 'send.available-funds-msg-part1' | translate }} + + {{ availableBalance.availableCoins | amount }} + + {{ 'send.available-funds-msg-part2' | translate }} + + {{ availableBalance.availableHours | amount:false }} + + {{ 'send.available-funds-msg-part3' | translate }} + + {{ availableBalance.minimumFee | amount:false }} + + {{ 'send.available-funds-msg-part4' | translate }} + + + {{ 'send.available-funds-without-hours-msg-part1' | translate }} + + {{ availableBalance.availableCoins | amount }} + + {{ 'send.available-funds-without-hours-msg-part2' | translate }} + + {{ feeForSendingAll | amount }} + + {{ 'send.available-funds-without-hours-msg-part3' | translate }} + + + + {{ 'send.loading-available' | translate }} + + + {{ 'send.waiting-for-available' | translate }} + +
+ + + + + + +
+ + +
+ + +
+ + +
+ + + + +
+ +
+ +
+
+
+ +
+
+ +
+
+ + {{ 'send.fee-measure' | translate:{measure: feePaymentCoinUnit} }} +
+
+
+
+ + + +
+ +
+ +
+
+
+ +
+
+ +
+
+ + {{ feePaymentCoinUnit }} +
+
+
+
+ + +
+ + +
+
+ + +
+ + +
+ +
+ +
+ + +
+
+
+ + {{ 'send.hours-allocation-check' | translate:{coinHoursName: ('hours' | commonText)} }} + + + +
+
+ + +
+ +
+
+
+ + +
+ + {{ 'send.preview-button' | translate }} + + + {{ ('send.' + (showForManualUnsigned ? 'show' : 'send') + '-button') | translate }} + +
+ + +
+
+ + +
+
+
diff --git a/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.scss b/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.scss new file mode 100644 index 0000000..72f1b8e --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.scss @@ -0,0 +1,74 @@ +@import '../../../../../theme/variables'; + +.mode-selector { + text-align: right; + height: 0px; + + app-double-button { + display: inline-block; + position: relative; + top: -27px; + right: -27px; + } +} + +.-options-wrapper { + margin-top: 20px; +} + +.-space-between { + display: flex; + justify-content: space-between; +} + +.-available-msg { + background-color: $grey-lightest; + border: 1px dotted $grey-light; + border-radius: $input-border-radius; + padding: 10px; + font-size: $font-size-mini; + text-align: center; + + span { + opacity: 0.7; + } + + .value { + opacity: 1 !important; + font-weight: bold; + font-size: $font-size-standard; + } +} + +.fee-spinner { + mat-spinner { + position: absolute; + height: 10px !important; + width: 10px !important; + display: inline; + + ::ng-deep svg { + height: 10px !important; + width: 10px !important; + } + } +} + +.fee-spinner-internal { + height: 0px; + position: relative; + top: 5px; + left: 5px; +} + +.fee-link-container { + display: flex; + align-items: center; + + .fee-spinner-external { + display: inline-block; + width: 10px; + height: 10px; + margin-left: 5px; + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.ts b/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.ts new file mode 100644 index 0000000..3f0c914 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-coins-form/send-coins-form.component.ts @@ -0,0 +1,1251 @@ +import { SubscriptionLike, of, forkJoin, throwError } from 'rxjs'; +import { first, mergeMap } from 'rxjs/operators'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, ViewChild, ChangeDetectorRef, Output as AgularOutput } from '@angular/core'; +import { FormGroup, FormControl } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { BigNumber } from 'bignumber.js'; +import { TranslateService } from '@ngx-translate/core'; + +import { PasswordDialogComponent } from '../../../layout/password-dialog/password-dialog.component'; +import { ButtonComponent } from '../../../layout/button/button.component'; +import { NavBarSwitchService } from '../../../../services/nav-bar-switch.service'; +import { SelectAddressComponent } from '../../../layout/select-address/select-address.component'; +import { BlockchainService } from '../../../../services/blockchain.service'; +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { ChangeNoteComponent } from '../send-preview/transaction-info/change-note/change-note.component'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { MultipleDestinationsDialogComponent } from '../../../layout/multiple-destinations-dialog/multiple-destinations-dialog.component'; +import { FormSourceSelectionComponent, AvailableBalanceData, SelectedSources, SourceSelectionModes } from '../form-parts/form-source-selection/form-source-selection.component'; +import { FormDestinationComponent, Destination } from '../form-parts/form-destination/form-destination.component'; +import { CopyRawTxComponent, CopyRawTxData } from '../offline-dialogs/implementations/copy-raw-tx.component'; +import { DoubleButtonActive } from '../../../../components/layout/double-button/double-button.component'; +import { ConfirmationParams, DefaultConfirmationButtons, ConfirmationComponent } from '../../../../components/layout/confirmation/confirmation.component'; +import { SpendingService, HoursDistributionOptions, HoursDistributionTypes, RecommendedFees } from '../../../../services/wallet-operations/spending.service'; +import { GeneratedTransaction, Output } from '../../../../services/wallet-operations/transaction-objects'; +import { WalletWithBalance, AddressWithBalance, WalletTypes, WalletBase } from '../../../../services/wallet-operations/wallet-objects'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; +import { GetNextAddressComponent } from '../../../layout/get-next-address/get-next-address.component'; +import { CoinService } from '../../../../services/coin.service'; +import { CoinTypes } from '../../../../coins/settings/coin-types'; +import { BtcCoinConfig } from '../../../../coins/coin-type-configs/btc.coin-config'; +import { EthCoinConfig } from '../../../../coins/coin-type-configs/eth.coin-config'; +import { WalletUtilsService } from 'app/services/wallet-operations/wallet-utils.service'; + +/** + * Data returned when SendCoinsFormComponent asks to show the preview of a transaction. Useful + * for showing a preview and for restoring the state of the form. + */ +export interface SendCoinsData { + /** + * Data entered on the form. + */ + form: FormData; + /** + * How many coins is the user trying to send. + */ + amount: BigNumber; + /** + * List of all the destination addresses. + */ + to: string[]; + /** + * Unsigned transaction which was created and the user wants to preview. + */ + transaction: GeneratedTransaction; + /** + * If true, the transaction is a manually created unsigned transaction which is not mean to be + * sent to the network. The raw transaction text must be shown to the user, so it can be + * signed and sent later. + */ + showForManualUnsigned: boolean; +} + +/** + * Contents of a send coins form. + */ +export interface FormData { + wallet: WalletWithBalance; + addresses: AddressWithBalance[]; + /** + * Addresses the user entered manually. Used when manually creating an unsigned transaction, + * so there are no fields for selecting a wallet or addresses. + */ + manualAddresses: string[]; + changeAddress: string; + destinations: Destination[]; + hoursSelection: HoursDistributionOptions; + /** + * If true, the options for selecting the auto hours distribution factor are shown. + */ + showAutoHourDistributionOptions: boolean; + /** + * All unspent outputs obtained from the node, not the selected ones. + */ + allUnspentOutputs: Output[]; + outputs: Output[]; + /** + * Button selected for choosing which currency to use for the amounts. + */ + currency: DoubleButtonActive; + note: string; + /** + * Recommended fees obtained from the node. + */ + recommendedFees: RecommendedFees; + /** + * If the fee options are visible or not. + */ + showFeeOptions: boolean; + /** + * Fee type selected from the list, for btc-like coins. + */ + feeType: number; + /** + * Fee entered by the user, for btc-like coins. + */ + fee: string; + /** + * Fee type selected from the list, for eth-like coins. + */ + ethFeeType: number; + gasPrice: string; + gasLimit: string; + +} + +/** + * Enums the modes for paying fess with coins (not hours). + */ +enum FeeTypes { + /** + * No fees must be paid with the currently selected coin. + */ + None = 'None', + /** + * BTC fee mode (sats per byte). + */ + Btc = 'Btc', + /** + * Eth fee mode (gas price and gas limit). + */ + Eth = 'Eth', +} + +/** + * Form for sending coins. + */ +@Component({ + selector: 'app-send-coins-form', + templateUrl: './send-coins-form.component.html', + styleUrls: ['./send-coins-form.component.scss'], +}) +export class SendCoinsFormComponent implements OnInit, OnDestroy { + // Default factor used for automatically distributing the coins. + private readonly defaultAutoShareValue = '0.5'; + // Max number of decimals that can be entered for the fee. + private readonly maxFeeDecimals = 5; + + // Subform for selecting the sources. + @ViewChild('formSourceSelection') formSourceSelection: FormSourceSelectionComponent; + // Subform for entering the destinations. + @ViewChild('formMultipleDestinations') formMultipleDestinations: FormDestinationComponent; + @ViewChild('previewButton') previewButton: ButtonComponent; + @ViewChild('sendButton') sendButton: ButtonComponent; + // Data the form must have just after being created. + @Input() formData: SendCoinsData; + // If true, the simple form will be used. + @Input() showSimpleForm: boolean; + // Event emited when the transaction has been created and the user wants to see a preview. + @AgularOutput() onFormSubmitted = new EventEmitter(); + + sourceSelectionModes = SourceSelectionModes; + doubleButtonActive = DoubleButtonActive; + + // Max chars the note field can have. + maxNoteChars = ChangeNoteComponent.MAX_NOTE_CHARS; + form: FormGroup; + // How many coins the user can send with the selected sources. + availableBalance = new AvailableBalanceData(); + // If true, the balance available to be sent will also be shown in the simple form. + alwaysShowAvailableBalance = false; + // If the available balance is still being loaded. + loadingAvailableBalance = true; + // The fee that must be paid for sending all the available balance, in coins, if applicable + // for the current coin. + feeForSendingAll: BigNumber; + // If the user must enter a valid fee before being able to calculate the available balance. + validFeeNeeded = false; + // Recommended fees obtained from the node, if the current coin needs fees to be paid. + recommendedFees: RecommendedFees; + // Map for getting the recommended fee for each option of the fee types control. + recommendedFeesMap: Map; + // Minimum fee the node accepts. + minimumfee: BigNumber; + // If true, the hours are distributed automatically. If false, the user can manually + // enter how many hours to send to each destination. Must be true if the coin does not have + // hours. + autoHours = true; + // If true, the options for selecting the auto hours distribution factor are shown. + showAutoHourDistributionOptions = false; + // If the UI must show the options for setting the fee. + showFeeOptions = false; + // Factor used for automatically distributing the coins. + autoShareValue = this.defaultAutoShareValue; + // If true, the form is shown deactivated. + busy = false; + // If true, the form is used for manually creating unsigned transactions. + showForManualUnsigned = false; + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + // Name of the coin unit in which the fee is measured. + feePaymentCoinUnit = ''; + // Type of the fees, in coins, that must be paid for sending transactions. + coinFeeType: FeeTypes; + // If the coin only allows to send transactions to a single destination and does not allow + // to select the change address. + limitedSendingOptions = false; + // If true, the form will show the option for creating unsigned transactions. + showUsignedOptions = false; + + feeTypes = FeeTypes; + + // Sources the user has selected. + private selectedSources: SelectedSources; + + // Vars with the validation error messages. + changeAddressErrorMsg = ''; + btcFeeErrorMsg = ''; + gasPriceAddressErrorMsg = ''; + gasLimitAddressErrorMsg = ''; + invalidChangeAddress = false; + + private syncCheckSubscription: SubscriptionLike; + private processingSubscription: SubscriptionLike; + private getRecommendedFeesSubscription: SubscriptionLike; + private fieldsSubscriptions: SubscriptionLike[] = []; + + constructor( + private blockchainService: BlockchainService, + private dialog: MatDialog, + private msgBarService: MsgBarService, + private navBarSwitchService: NavBarSwitchService, + private hwWalletService: HwWalletService, + private translate: TranslateService, + private changeDetector: ChangeDetectorRef, + private spendingService: SpendingService, + private walletsAndAddressesService: WalletsAndAddressesService, + private walletUtilsService: WalletUtilsService, + coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.feePaymentCoinUnit = coinService.currentCoinInmediate.feePaymentCoinUnit; + this.limitedSendingOptions = coinService.currentCoinInmediate.coinTypeFeatures.limitedSendingOptions; + this.showUsignedOptions = coinService.currentCoinInmediate.coinTypeFeatures.softwareWallets; + + if (!this.coinHasHours) { + if (coinService.currentCoinInmediate.coinType === CoinTypes.BTC) { + this.coinFeeType = FeeTypes.Btc; + this.minimumfee = (coinService.currentCoinInmediate.config as BtcCoinConfig).minFee; + } else if (coinService.currentCoinInmediate.coinType === CoinTypes.ETH) { + this.coinFeeType = FeeTypes.Eth; + this.minimumfee = (coinService.currentCoinInmediate.config as EthCoinConfig).minFee; + } else { + this.coinFeeType = FeeTypes.None; + } + } else { + this.coinFeeType = FeeTypes.None; + } + + // Always show the available balance if the fee must be paid in coins. + this.alwaysShowAvailableBalance = this.coinFeeType !== FeeTypes.None; + } + + ngOnInit() { + this.form = new FormGroup({}); + this.form.addControl('changeAddress', new FormControl('')); + this.form.addControl('note', new FormControl('')); + this.form.addControl('fee', new FormControl('')); + // Custom fee is selected by default. + this.form.addControl('feeType', new FormControl(5)); + // Custom gas price is selected by default. + this.form.addControl('ethFeeType', new FormControl(1)); + this.form.addControl('gasPrice', new FormControl('')); + this.form.addControl('gasLimit', new FormControl('')); + + this.form.setValidators(this.validateForm.bind(this)); + + // If the user changes the fee, select the custom fee type and update the available balance. + this.fieldsSubscriptions.push(this.form.get('fee').valueChanges.subscribe(() => { + this.form.get('feeType').setValue(5); + this.updateAvailableBalance(); + })); + this.fieldsSubscriptions.push(this.form.get('gasPrice').valueChanges.subscribe(() => { + this.form.get('ethFeeType').setValue(1); + this.updateAvailableBalance(); + })); + + // If the user changes the fee type, change the value of the fee field and update the + // available balance. + this.fieldsSubscriptions.push(this.form.get('feeType').valueChanges.subscribe(() => { + this.useSelectedFee(); + this.updateAvailableBalance(); + })); + this.fieldsSubscriptions.push(this.form.get('ethFeeType').valueChanges.subscribe(() => { + this.useSelectedFee(); + this.updateAvailableBalance(); + })); + + // Update the available balance if the gas limit is changed. + this.fieldsSubscriptions.push(this.form.get('gasLimit').valueChanges.subscribe(() => { + this.updateAvailableBalance(); + })); + + if (this.formData) { + setTimeout(() => this.fillForm()); + } else { + // Get the recommended fees, as fillForm will not call it. + setTimeout(() => this.getRecommendedFees()); + } + } + + ngOnDestroy() { + if (this.processingSubscription && !this.processingSubscription.closed) { + this.processingSubscription.unsubscribe(); + } + this.closeGetRecommendedFeesSubscription(); + this.closeSyncCheckSubscription(); + this.fieldsSubscriptions.forEach(sub => sub.unsubscribe()); + this.msgBarService.hide(); + } + + // If true, the animation indicating that the recommended fees are being loaded must be shown. + get showFeesLoading(): boolean { + if (!this.recommendedFees) { + return true; + } + + return false; + } + + // Called when there are changes in the source selection form. + sourceSelectionChanged() { + this.selectedSources = this.formSourceSelection.selectedSources; + this.formMultipleDestinations.updateValuesAndValidity(); + this.updateAvailableBalance(); + setTimeout(() => { + this.form.updateValueAndValidity(); + }); + } + + // Called when there are changes in the destinations form. + destinationsChanged() { + this.updateAvailableBalance(); + setTimeout(() => { + this.form.updateValueAndValidity(); + }); + } + + // Updates the available balance. It uses the balance in the sources and the fee that must be + // paid for sending all the coins. + private updateAvailableBalance() { + if (this.formSourceSelection) { + // Get the balance available in the sources. + const reportedAvailable = this.formSourceSelection.availableBalance; + this.loadingAvailableBalance = reportedAvailable.loading; + + this.validFeeNeeded = !this.validateFee(); + + if (!reportedAvailable.loading && !this.validFeeNeeded) { + const reportedDestinations = this.formMultipleDestinations.getDestinations(false); + + // Get the appropiate fee per unit. + let selectedFee: BigNumber; + if (this.coinFeeType === FeeTypes.Btc) { + selectedFee = new BigNumber(this.form.get('fee').value); + } else if (this.coinFeeType === FeeTypes.Eth) { + selectedFee = new BigNumber(this.form.get('gasPrice').value); + } else { + selectedFee = new BigNumber(0); + } + + // Calculate the aproximate fee for sending the transaction and subtract it from + // the balance. + this.feeForSendingAll = this.spendingService.calculateFinalFee( + reportedAvailable.outputs, + reportedDestinations.length, + selectedFee, + new BigNumber(this.form.get('gasLimit').value), + ); + reportedAvailable.availableCoins = reportedAvailable.availableCoins.minus(this.feeForSendingAll); + if (reportedAvailable.availableCoins.isLessThanOrEqualTo(0)) { + reportedAvailable.availableCoins = new BigNumber(0); + this.feeForSendingAll = new BigNumber(0); + } + } + + this.availableBalance = reportedAvailable; + } + } + + // Starts the process for creating a transaction for previewing it. + preview() { + this.checkFeeBeforeCreatingTx(true); + this.changeDetector.detectChanges(); + } + + // Starts the process for creating a transaction for sending it without preview. + send() { + this.checkFeeBeforeCreatingTx(false); + } + + // Chages the mode of the advanced form. The form can be in normal mode and a special + // mode for manually creating unsigned transactions. + changeFormType(value: DoubleButtonActive) { + if ((value === DoubleButtonActive.LeftButton && !this.showForManualUnsigned) || (value === DoubleButtonActive.RightButton && this.showForManualUnsigned)) { + return; + } + + if (value === DoubleButtonActive.RightButton) { + // Ask for confirmation before activating the manual unsigned tx mode. + const confirmationParams: ConfirmationParams = { + text: 'send.unsigned-confirmation', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.showForManualUnsigned = true; + } + }); + } else { + this.showForManualUnsigned = false; + } + } + + // Sets the factor that will be used for distributing the hours. + setShareValue(event) { + this.autoShareValue = parseFloat(event.value).toFixed(2); + } + + // Opens a modal window for selecting the change address. + selectChangeAddress() { + SelectAddressComponent.openDialog(this.dialog).afterClosed().subscribe(response => { + if (response) { + if ((response as WalletBase).id) { + GetNextAddressComponent.openDialog(this.dialog, response).afterClosed().subscribe(resp => { + if (resp) { + this.form.get('changeAddress').setValue(resp); + } + }); + } else if (typeof response === 'string') { + this.form.get('changeAddress').setValue(response); + } + } + }); + } + + // Opens the bulk sending modal window with the data the user already added to the form. + openMultipleDestinationsPopup() { + let currentString = ''; + + // Create a string with the data the user has already entered, using the format of the + // bulk sending modal window. + const currentDestinations = this.formMultipleDestinations.getDestinations(false); + currentDestinations.map(destControl => { + // Ignore the destinations with no data. + if (destControl.address.trim().length > 0 || + destControl.originalAmount.trim().length > 0 || + (!this.autoHours && destControl.hours.trim().length > 0)) { + // Add the data without potentially problematic characters. + currentString += destControl.address.replace(',', ''); + currentString += ', ' + destControl.originalAmount.replace(',', ''); + if (!this.autoHours) { + currentString += ', ' + destControl.hours.replace(',', ''); + } + currentString += '\r\n'; + } + }); + + MultipleDestinationsDialogComponent.openDialog(this.dialog, currentString).afterClosed().subscribe((response: Destination[]) => { + if (response) { + if (response.length > 0) { + // If the first destination does not have hours, no destination has hours. + if (this.coinHasHours) { + this.autoHours = response[0].hours === undefined; + } + setTimeout(() => this.formMultipleDestinations.setDestinations(response)); + } else { + this.formMultipleDestinations.resetForm(); + } + } + }); + } + + toggleFeeOptions() { + this.showFeeOptions = !this.showFeeOptions; + } + + // Shows or hides the hours distribution options. + toggleAutoHourDistributionOptions(event) { + event.stopPropagation(); + event.preventDefault(); + + if (this.showAutoHourDistributionOptions && this.autoShareValue !== this.defaultAutoShareValue) { + // Ask for confirmation before closing the options and resetting the value. + const confirmationParams: ConfirmationParams = { + text: 'send.close-hours-share-factor-alert', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + // Resets the hours distribution options. + this.autoShareValue = this.defaultAutoShareValue; + + this.showAutoHourDistributionOptions = !this.showAutoHourDistributionOptions; + } + }); + } else { + // Resets the hours distribution options. + this.autoShareValue = this.defaultAutoShareValue; + + this.showAutoHourDistributionOptions = !this.showAutoHourDistributionOptions; + } + } + + // Activates/deactivates the option for automatic hours distribution. + setAutoHours(event) { + this.autoHours = event.checked; + this.formMultipleDestinations.updateValuesAndValidity(); + + if (!this.autoHours) { + this.showAutoHourDistributionOptions = false; + } + } + + // Populates the fee or gas price field with the value corresponding to the current value of + // the feeType or ethFeeType field. + private useSelectedFee() { + if (this.coinFeeType === FeeTypes.Btc) { + const value = this.form.get('feeType').value; + if (this.recommendedFeesMap && this.recommendedFeesMap.has(value)) { + this.form.get('fee').setValue(this.recommendedFeesMap.get(value), { emitEvent: false }); + } + } else if (this.coinFeeType === FeeTypes.Eth) { + const value = this.form.get('ethFeeType').value; + if (value === 0) { + this.form.get('gasPrice').setValue(this.recommendedFees.recommendedEthFees.gasPrice.decimalPlaces(this.maxFeeDecimals).toString(10), { emitEvent: false }); + } + } + + this.updateAvailableBalance(); + } + + // Connects to the node to get the recommended fees. If the current coin uses coin hours, + // it does nothing. + private getRecommendedFees() { + if (this.coinFeeType !== FeeTypes.None) { + this.closeGetRecommendedFeesSubscription(); + // Get the data. + this.getRecommendedFeesSubscription = this.spendingService.getCurrentRecommendedFees().subscribe(fees => { + // Update the vars and select the recommended fee. + this.populateRecommendedFees(fees); + this.selecRecommendedFee(true); + + // If there was a problem getting the recommended fee, show a warning. + if (fees.thereWereProblems) { + this.msgBarService.showWarning(this.translate.instant('send.fee-problem-warning')); + } + }); + } + } + + /** + * Checks this.recommendedFees and set the best value as the selected one. + * @param changeOnlyIfNotEdited If true, no changes will be made to fields the user + * already modified. + */ + private selecRecommendedFee(changeOnlyIfNotEdited: boolean) { + // Check if there were errors trying to get the recommended fee. + if (!this.recommendedFees || this.recommendedFees.thereWereProblems) { + if (this.coinFeeType === FeeTypes.Eth && (!changeOnlyIfNotEdited || this.form.get('gasLimit').value === '')) { + // Having errors getting the recommended fee does not always means having errors + // getting the recommended gas limit. + if (this.recommendedFees.recommendedEthFees.gasLimit) { + this.form.get('gasLimit').setValue(this.recommendedFees.recommendedEthFees.gasLimit, { emitEvent: false }); + } else { + this.form.get('gasLimit').setValue('0', { emitEvent: false }); + } + } + + // Set the fee per unit to 0. That will also make the fee type field to be set to "custom". + if (!changeOnlyIfNotEdited || this.form.get('fee').value === '') { + this.form.get('fee').setValue('0'); + } + if (!changeOnlyIfNotEdited || this.form.get('gasPrice').value === '') { + this.form.get('gasPrice').setValue('0'); + } + + // Open the fee options. + this.showFeeOptions = true; + + this.updateAvailableBalance(); + + return; + } + + if (this.coinFeeType === FeeTypes.Btc) { + // If the user has not entered a fee, the normal fee type is selected and the fee + // field is populated with the corresponding value. However, if a faster type has an + // a lower or equal cost, the faster method is used. + if (!changeOnlyIfNotEdited || this.form.get('fee').value === '') { + const recommendedBtcFees = this.recommendedFees.recommendedBtcFees; + if (recommendedBtcFees.high.decimalPlaces(this.maxFeeDecimals).isLessThanOrEqualTo(recommendedBtcFees.normal.decimalPlaces(this.maxFeeDecimals))) { + if (recommendedBtcFees.veryHigh.decimalPlaces(this.maxFeeDecimals).isLessThanOrEqualTo(recommendedBtcFees.high.decimalPlaces(this.maxFeeDecimals))) { + this.form.get('feeType').setValue(0, { emitEvent: false }); + } else { + this.form.get('feeType').setValue(1, { emitEvent: false }); + } + } else { + this.form.get('feeType').setValue(2, { emitEvent: false }); + } + } + + // Update the fee field. + this.useSelectedFee(); + } else if (this.coinFeeType === FeeTypes.Eth) { + // If the user has not entered a gas price, the one returned by the service is used. + if (!changeOnlyIfNotEdited || this.form.get('gasPrice').value === '') { + this.form.get('ethFeeType').setValue(0, { emitEvent: false }); + } + + // If the user has not entered a gas limit, the one returned by the service is used. + if (!changeOnlyIfNotEdited || this.form.get('gasLimit').value === '') { + this.form.get('gasLimit').setValue(this.recommendedFees.recommendedEthFees.gasLimit, { emitEvent: false }); + } + + // Update the fee field. + this.useSelectedFee(); + } + } + + // Populates the vars with the recommended fees and zeroFeeAllowed. + private populateRecommendedFees(recommendedFees: RecommendedFees) { + this.recommendedFees = recommendedFees; + + if (this.coinFeeType === FeeTypes.Btc) { + this.recommendedFeesMap = new Map(); + this.recommendedFeesMap.set(0, recommendedFees.recommendedBtcFees.veryHigh.decimalPlaces(this.maxFeeDecimals).toString(10)); + this.recommendedFeesMap.set(1, recommendedFees.recommendedBtcFees.high.decimalPlaces(this.maxFeeDecimals).toString(10)); + this.recommendedFeesMap.set(2, recommendedFees.recommendedBtcFees.normal.decimalPlaces(this.maxFeeDecimals).toString(10)); + this.recommendedFeesMap.set(3, recommendedFees.recommendedBtcFees.low.decimalPlaces(this.maxFeeDecimals).toString(10)); + this.recommendedFeesMap.set(4, recommendedFees.recommendedBtcFees.veryLow.decimalPlaces(this.maxFeeDecimals).toString(10)); + } + } + + // Fills the form with the provided values. + private fillForm() { + this.showForManualUnsigned = this.formData.showForManualUnsigned, + + this.formSourceSelection.fill(this.formData); + this.formMultipleDestinations.fill(this.formData); + + ['changeAddress', 'note'].forEach(name => { + this.form.get(name).setValue(this.formData.form[name]); + }); + + if (!this.coinHasHours || this.formData.form.hoursSelection.type === HoursDistributionTypes.Auto) { + this.autoHours = true; + + if (this.formData.form.hoursSelection.share_factor) { + this.autoShareValue = this.formData.form.hoursSelection.share_factor; + } else { + this.autoShareValue = '0'; + } + } else { + this.autoHours = false; + } + + this.showAutoHourDistributionOptions = this.formData.form.showAutoHourDistributionOptions; + this.showFeeOptions = this.formData.form.showFeeOptions; + + if (this.formData.form.recommendedFees) { + // If the data already includes recommended fees, use them and update the fee type. + this.populateRecommendedFees(this.formData.form.recommendedFees); + this.form.get('feeType').setValue(this.formData.form.feeType); + this.form.get('ethFeeType').setValue(this.formData.form.ethFeeType); + } else { + // If not, get them from the node. + this.getRecommendedFees(); + } + + this.form.get('fee').setValue(this.formData.form.fee, { emitEvent: false }); + this.form.get('gasPrice').setValue(this.formData.form.gasPrice, { emitEvent: false }); + this.form.get('gasLimit').setValue(this.formData.form.gasLimit); + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.changeAddressErrorMsg = ''; + + let valid = true; + + const changeAddress = this.form.get('changeAddress').value as string; + if (changeAddress && changeAddress.length < 20) { + valid = false; + if (this.form.get('changeAddress').touched) { + this.changeAddressErrorMsg = 'send.address-error-info'; + } + } + + const feeValidationResult = this.validateFee(); + if (!feeValidationResult) { + valid = false; + } + + // Check the validity of the subforms. + if (!this.formSourceSelection || !this.formSourceSelection.valid || !this.formMultipleDestinations || !this.formMultipleDestinations.valid) { + valid = false; + } + + return valid ? null : { Invalid: true }; + } + + // Validates the fee entered in the form. + private validateFee(): boolean { + this.btcFeeErrorMsg = ''; + this.gasPriceAddressErrorMsg = ''; + this.gasLimitAddressErrorMsg = ''; + + if (!this.form || !this.form.get('fee')) { + return false; + } + + let valid = true; + + // Validate the fee, if appropiate. + if (this.coinFeeType === FeeTypes.Btc) { + // The fee must be a valid number, more than the minimum and with a limit in its decimals. + const fee = new BigNumber(this.form.get('fee').value); + if (fee.isNaN() || fee.isLessThan(this.minimumfee) || !fee.isEqualTo(fee.decimalPlaces(this.maxFeeDecimals))) { + valid = false; + if (this.form.get('fee').touched) { + this.btcFeeErrorMsg = 'send.fee-error-info'; + } + } + } else if (this.coinFeeType === FeeTypes.Eth) { + // The gas price must be a valid number, more than the minimum and with a limit in its decimals. + const gasPrice = new BigNumber(this.form.get('gasPrice').value); + if (gasPrice.isNaN() || gasPrice.isLessThan(this.minimumfee) || !gasPrice.isEqualTo(gasPrice.decimalPlaces(this.maxFeeDecimals))) { + valid = false; + if (this.form.get('gasPrice').touched) { + this.gasPriceAddressErrorMsg = 'send.fee-error-info'; + } + } + + // The gas limit must be a valid integer number. + const gasLimit = new BigNumber(this.form.get('gasLimit').value); + if (gasLimit.isNaN() || gasLimit.isLessThanOrEqualTo(0) || !gasLimit.isEqualTo(gasLimit.decimalPlaces(0))) { + valid = false; + if (this.form.get('gasLimit').touched) { + this.gasLimitAddressErrorMsg = 'send.fee-error-info'; + } + } + } + + return valid; + } + + // Checks if the fee the user entered is not potentially incorrect and shows a warning + // before continuing creating the transaction, if appropiate. It does nothing if the + // form is not valid or busy. + private checkFeeBeforeCreatingTx(creatingPreviewTx: boolean) { + if (!this.form.valid || this.busy) { + return; + } + + if (this.coinFeeType === FeeTypes.None) { + // Ignore this step if it is not needed. + this.checkBeforeCreatingTx(creatingPreviewTx); + } else { + let warningMsg: string; + + // Check if the fee is too high, too low or unknown. + if (this.coinFeeType === FeeTypes.Btc) { + if (!this.recommendedFeesMap) { + warningMsg = 'send.fee-unknown-warning'; + } else if (this.recommendedFees.thereWereProblems) { + warningMsg = 'send.fee-problem-warning2'; + } else if (new BigNumber(this.form.get('fee').value).isLessThan(this.recommendedFeesMap.get(4))) { + warningMsg = 'send.fee-low-warning'; + } else if (new BigNumber(this.form.get('fee').value).isGreaterThan(this.recommendedFeesMap.get(0))) { + warningMsg = 'send.fee-high-warning'; + } + } else if (this.coinFeeType === FeeTypes.Eth) { + if (!this.recommendedFees) { + warningMsg = 'send.fee-unknown-warning'; + } else if (this.recommendedFees.thereWereProblems) { + warningMsg = 'send.fee-problem-warning2'; + } else if (new BigNumber(this.form.get('gasPrice').value).isLessThan(this.recommendedFees.recommendedEthFees.gasPrice.dividedBy(2))) { + warningMsg = 'send.fee-low-warning'; + } else if (new BigNumber(this.form.get('gasPrice').value).isGreaterThan(this.recommendedFees.recommendedEthFees.gasPrice.multipliedBy(2))) { + warningMsg = 'send.fee-high-warning'; + } + } + + if (!warningMsg) { + // If no problem was found, continue. + this.checkBeforeCreatingTx(creatingPreviewTx); + } else { + // Ask for confirmation before continuing. + const confirmationParams: ConfirmationParams = { + redTitle: true, + headerText: 'common.warning-title', + text: warningMsg, + checkboxText: 'common.generic-confirmation-check', + defaultButtons: DefaultConfirmationButtons.ContinueCancel, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.checkBeforeCreatingTx(creatingPreviewTx); + } + }); + } + } + } + + // Checks if the blockchain is synchronized. It continues normally creating the tx if the + // blockchain is synchronized and asks for confirmation if it is not. It does nothing if + // the form is not valid or busy. + private checkBeforeCreatingTx(creatingPreviewTx: boolean) { + if (!this.form.valid || this.busy) { + return; + } + + this.closeSyncCheckSubscription(); + this.syncCheckSubscription = this.blockchainService.progress.pipe(first()).subscribe(response => { + if (response.synchronized) { + this.checkHoursBeforeCreatingTx(creatingPreviewTx); + } else { + const confirmationParams: ConfirmationParams = { + text: 'send.synchronizing-warning', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.checkHoursBeforeCreatingTx(creatingPreviewTx); + } + }); + } + }); + } + + // Checks if the user is going to send or burn all the hours. If true, it asks for + // confirmation before continuing. It does nothing if the form is not valid or busy. + // If the selected coin does not use hours, it moves to the next step. + private checkHoursBeforeCreatingTx(creatingPreviewTx: boolean) { + if (!this.form.valid || this.busy) { + return; + } + + if (!this.coinHasHours) { + this.prepareTransaction(creatingPreviewTx); + + return; + } + + // Check how many hours the user manually selected to send. + let coinsToSend = new BigNumber(0); + let hoursToSend = new BigNumber(0); + this.formMultipleDestinations.getDestinations(true).forEach(destination => { + coinsToSend = coinsToSend.plus(destination.coins); + if (!this.autoHours) { + hoursToSend = hoursToSend.plus(destination.hours); + } + }); + + // Check if all hours are going to be sent due to the values entered by the user or the + // value entered with the share slider. + if ( + coinsToSend.isEqualTo(this.availableBalance.availableCoins) || + hoursToSend.isEqualTo(this.availableBalance.availableHours) || + (Number(this.autoShareValue) === 1 && this.autoHours) + ) { + // Msg that will be shown in the confirmation window. + let confirmationText = ''; + if (hoursToSend.isEqualTo(this.availableBalance.availableHours)) { + // Sending all hours because the user entered them manually. + confirmationText = 'send.sending-all-hours-waning'; + } else { + if (coinsToSend.isEqualTo(this.availableBalance.availableCoins)) { + if ((this.formSourceSelection.wallet.availableCoins.isEqualTo(this.availableBalance.availableCoins))) { + // Sending all hours in the wallet, because the user is sending all the coins it has. + confirmationText = 'send.sending-all-hours-with-coins-waning'; + } else { + // Sending all hours in the selected sources, because the user is sending all available coins. + confirmationText = 'send.advanced-sending-all-hours-with-coins-waning'; + } + } else { + if ((this.formSourceSelection.wallet.availableCoins.isEqualTo(this.availableBalance.availableCoins))) { + // Potentially sending all hours in the selected wallet, due to the sharing factor. + confirmationText = 'send.high-hours-share-waning'; + } else { + // Potentially sending all hours in the selected sources, due to the sharing factor. + confirmationText = 'send.advanced-high-hours-share-waning'; + } + } + } + + // Ask for confirmation. + const confirmationParams: ConfirmationParams = { + headerText: 'common.warning-title', + redTitle: true, + text: confirmationText, + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.prepareTransaction(creatingPreviewTx); + } + }); + } else { + // Continue normally. + this.prepareTransaction(creatingPreviewTx); + } + } + + // Makes the preparation steps, like asking for the password, and then calls the function + // for creating the transaction. + private prepareTransaction(creatingPreviewTx: boolean) { + this.msgBarService.hide(); + this.previewButton.resetState(); + if (this.sendButton) { + this.sendButton.resetState(); + } + + // Request the password only if the wallet is encrypted and the transaction is going + // to be sent without preview. If the wallet is bipp44 and encrypted, the password is + // always requested. + if ( + !this.showForManualUnsigned && + !this.selectedSources.wallet.isHardware && + this.selectedSources.wallet.encrypted && + (!creatingPreviewTx || this.selectedSources.wallet.walletType === WalletTypes.Bip44) + ) { + PasswordDialogComponent.openDialog(this.dialog, { wallet: this.selectedSources.wallet }).componentInstance.passwordSubmit + .subscribe(passwordDialog => { + this.createTransaction(creatingPreviewTx, passwordDialog); + }); + } else { + if (creatingPreviewTx || this.showForManualUnsigned || !this.selectedSources.wallet.isHardware) { + this.createTransaction(creatingPreviewTx); + } else { + // If using a hw wallet, check the device first. + this.showBusy(creatingPreviewTx); + this.processingSubscription = this.hwWalletService.checkIfCorrectHwConnected(this.selectedSources.wallet).subscribe( + () => this.createTransaction(creatingPreviewTx), + err => this.showError(err), + ); + } + } + } + + // Creates a transaction with the data entered on the form. + private createTransaction(creatingPreviewTx: boolean, passwordDialog?: any) { + this.showBusy(creatingPreviewTx); + + // Process the source addresses. + let selectedAddresses: string[]; + if (!this.showForManualUnsigned) { + selectedAddresses = this.selectedSources.addresses && this.selectedSources.addresses.length > 0 ? + this.selectedSources.addresses.map(addr => addr.printableAddress) : null; + } else { + selectedAddresses = this.selectedSources.manualAddresses; + } + + // Process the source outputs. + const selectedOutputs = this.selectedSources.unspentOutputs && this.selectedSources.unspentOutputs.length > 0 ? + this.selectedSources.unspentOutputs : null; + + const destinations = this.formMultipleDestinations.getDestinations(true); + let transaction: GeneratedTransaction; + + let fee = ''; + if (this.coinFeeType === FeeTypes.Btc) { + fee = this.form.get('fee').value; + } else if (this.coinFeeType === FeeTypes.Eth) { + fee = this.form.get('gasPrice').value + '/' + this.form.get('gasLimit').value; + } + + // Stop showing addresses as invalid. + this.formMultipleDestinations.setValidAddressesList(null); + + // Remove any error previously detected by the node in the change address. + this.invalidChangeAddress = false; + const customChangeAddress = this.form.get('changeAddress').value; + + // Create a list with the destination addresses, to check them with the node. If there is + // a custom change address, it is added. + const addresses = destinations.map(destination => destination.address); + if (customChangeAddress) { + addresses.push(customChangeAddress); + } + + // Check if the addresses are valid. + this.processingSubscription = forkJoin(addresses.map(address => this.walletUtilsService.verifyAddress(address))).pipe( + mergeMap(validityList => { + if (customChangeAddress) { + this.invalidChangeAddress = !validityList.pop(); + + if (this.invalidChangeAddress) { + return throwError(this.translate.instant('send.change-address-error-info')); + } + } + + // Check how many addresses are invalid. + let invalidAddresses = 0; + validityList.forEach(valid => { + if (!valid) { + invalidAddresses += 1; + } + }); + + if (invalidAddresses === 0) { + // Create the transaction. The transaction is signed if the wallet is bip44 or the + // user wants to send the transaction immediately, without preview. + return this.spendingService.createTransaction( + this.selectedSources.wallet, + selectedAddresses ? selectedAddresses : this.selectedSources.wallet.addresses.map(address => address.printableAddress), + selectedOutputs, + destinations, + this.hoursSelection, + this.form.get('changeAddress').value ? this.form.get('changeAddress').value : null, + passwordDialog ? passwordDialog.password : null, + this.showForManualUnsigned || (this.selectedSources.wallet.walletType !== WalletTypes.Bip44 && creatingPreviewTx), + fee, + ); + } else { + this.formMultipleDestinations.setValidAddressesList(validityList); + + // Show the appropiate error msg. + if (destinations.length > 1) { + if (invalidAddresses === destinations.length) { + return throwError(this.translate.instant('send.all-addresses-invalid-error')); + } else if (invalidAddresses === 1) { + return throwError(this.translate.instant('send.one-invalid-address-error')); + } else { + return throwError(this.translate.instant('send.various-invalid-addresses-error')); + } + } + + return throwError(this.translate.instant('send.invalid-address-error')); + } + }), mergeMap(response => { + transaction = response; + + // If using a bip44 wallet, update its address list, to let the preview know about any + // newly created return address. + if (creatingPreviewTx && this.selectedSources.wallet && this.selectedSources.wallet.walletType === WalletTypes.Bip44) { + return this.walletsAndAddressesService.updateWallet(this.selectedSources.wallet); + } + + return of(null); + }), + ).subscribe(() => { + // Close the password dialog, if it exists. + if (passwordDialog) { + passwordDialog.close(); + } + + const note = this.form.value.note.trim(); + transaction.note = note; + + if (!creatingPreviewTx) { + if (!this.showForManualUnsigned) { + // Send the transaction to the network. + this.processingSubscription = this.spendingService.injectTransaction(transaction.encoded, note) + .subscribe(noteSaved => { + let showDone = true; + // Show a warning if the transaction was sent but the note was not saved. + if (note && !noteSaved) { + this.msgBarService.showWarning(this.translate.instant('send.saving-note-error')); + showDone = false; + } + + this.showSuccess(showDone); + }, error => this.showError(error)); + } else { + const data: CopyRawTxData = { + rawTx: transaction.encoded, + isUnsigned: true, + }; + + // Show the raw transaction. + CopyRawTxComponent.openDialog(this.dialog, data).afterClosed().subscribe(() => { + this.resetState(); + + const confirmationParams: ConfirmationParams = { + text: 'offline-transactions.copy-tx.reset-confirmation', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + // Ask the user if the form should be cleaned, to be able to create a new transaction. + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.resetForm(); + this.msgBarService.showDone('offline-transactions.copy-tx.reset-done', 4000); + } + }); + }); + } + } else { + // Create an object with the form data and emit an event for opening the preview. + let amount = new BigNumber('0'); + destinations.map(destination => amount = amount.plus(destination.coins)); + this.onFormSubmitted.emit({ + form: { + wallet: this.selectedSources.wallet, + addresses: this.selectedSources.addresses, + manualAddresses: this.selectedSources.manualAddresses, + changeAddress: this.form.get('changeAddress').value, + destinations: destinations, + hoursSelection: this.hoursSelection, + showAutoHourDistributionOptions: this.showAutoHourDistributionOptions, + allUnspentOutputs: this.formSourceSelection.unspentOutputsList, + outputs: this.selectedSources.unspentOutputs, + currency: this.formMultipleDestinations.currentlySelectedCurrency, + note: note, + recommendedFees: this.recommendedFees, + showFeeOptions: this.showFeeOptions, + feeType: this.form.get('feeType').value, + fee: this.form.get('fee').value, + ethFeeType: this.form.get('ethFeeType').value, + gasPrice: this.form.get('gasPrice').value, + gasLimit: this.form.get('gasLimit').value, + }, + amount: amount, + to: destinations.map(d => this.walletsAndAddressesService.formatAddress(d.address)), + transaction, + showForManualUnsigned: this.showForManualUnsigned, + }); + this.busy = false; + this.navBarSwitchService.enableSwitch(); + } + }, error => { + if (passwordDialog) { + passwordDialog.error(error); + } + + this.showError(error); + }); + } + + private resetForm() { + this.formSourceSelection.resetForm(); + this.formMultipleDestinations.resetForm(); + this.form.get('changeAddress').setValue(''); + this.form.get('note').setValue(''); + this.autoHours = true; + this.showAutoHourDistributionOptions = false; + this.autoShareValue = this.defaultAutoShareValue; + this.showFeeOptions = false; + if (this.coinFeeType !== FeeTypes.None) { + this.selecRecommendedFee(false); + } + } + + // Returns the hours distribution options selected on the form, but with the format needed + // for creating the transaction using the node. + private get hoursSelection(): HoursDistributionOptions { + let hoursSelection: HoursDistributionOptions = { + type: HoursDistributionTypes.Manual, + }; + + if (this.autoHours) { + hoursSelection = { + type: HoursDistributionTypes.Auto, + mode: 'share', + share_factor: this.autoShareValue, + }; + } + + return hoursSelection; + } + + private closeSyncCheckSubscription() { + if (this.syncCheckSubscription) { + this.syncCheckSubscription.unsubscribe(); + } + } + + // Makes the UI to be shown busy and disables the navbar switch. + private showBusy(creatingPreviewTx: boolean) { + if (creatingPreviewTx) { + this.previewButton.setLoading(); + if (this.sendButton) { + this.sendButton.setDisabled(); + } + } else { + if (this.sendButton) { + this.sendButton.setLoading(); + } + this.previewButton.setDisabled(); + } + this.busy = true; + this.navBarSwitchService.disableSwitch(); + } + + // Cleans the form, stops showing the UI busy, reactivates the navbar switch and, if showDone + // is true, shows a msg confirming that the transaction has been sent. + private showSuccess(showDone: boolean) { + this.busy = false; + this.navBarSwitchService.enableSwitch(); + this.resetForm(); + + if (showDone) { + this.msgBarService.showDone('send.sent'); + if (this.sendButton) { + this.sendButton.resetState(); + } + } else { + if (this.sendButton) { + this.sendButton.setSuccess(); + setTimeout(() => { + this.sendButton.resetState(); + }, 3000); + } + } + } + + // Stops showing the UI busy, reactivates the navbar switch and shows the error msg. + private showError(error) { + this.busy = false; + this.msgBarService.showError(error); + this.navBarSwitchService.enableSwitch(); + this.previewButton.resetState().setEnabled(); + if (this.sendButton) { + this.sendButton.resetState().setEnabled(); + } + } + + // Stops showing the UI busy and reactivates the navbar switch. + private resetState() { + this.busy = false; + this.navBarSwitchService.enableSwitch(); + this.previewButton.resetState().setEnabled(); + if (this.sendButton) { + this.sendButton.resetState().setEnabled(); + } + } + + private closeGetRecommendedFeesSubscription() { + if (this.getRecommendedFeesSubscription) { + this.getRecommendedFeesSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-coins.component.html b/src/gui/static/src/app/components/pages/send-coins/send-coins.component.html new file mode 100644 index 0000000..83508a3 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-coins.component.html @@ -0,0 +1,37 @@ + + + + + +
+
+ + + + + +
+ + +
diff --git a/src/gui/static/src/app/components/pages/send-coins/send-coins.component.scss b/src/gui/static/src/app/components/pages/send-coins/send-coins.component.scss new file mode 100644 index 0000000..a73c59e --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-coins.component.scss @@ -0,0 +1,12 @@ +@import '../../../../theme/variables'; + +.-links { + text-align: center; + font-size: $font-size-standard; + margin-top: -15px; + margin-bottom: 15px; + + .separator { + margin: 0 10px; + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-coins.component.ts b/src/gui/static/src/app/components/pages/send-coins/send-coins.component.ts new file mode 100644 index 0000000..27bca70 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-coins.component.ts @@ -0,0 +1,92 @@ +import { Component, OnDestroy, ChangeDetectorRef } from '@angular/core'; +import { SubscriptionLike } from 'rxjs'; +import { MatDialog } from '@angular/material/dialog'; + +import { NavBarSwitchService } from '../../../services/nav-bar-switch.service'; +import { DoubleButtonActive } from '../../layout/double-button/double-button.component'; +import { SignRawTxComponent } from './offline-dialogs/implementations/sign-raw-tx.component'; +import { BroadcastRawTxComponent } from './offline-dialogs/implementations/broadcast-raw-tx.component'; +import { SendCoinsData } from './send-coins-form/send-coins-form.component'; +import { NodeService } from '../../../services/node.service'; +import { CoinService } from '../../../services/coin.service'; + +/** + * Shows the form which allows the user to send coins. + */ +@Component({ + selector: 'app-send-coins', + templateUrl: './send-coins.component.html', + styleUrls: ['./send-coins.component.scss'], +}) +export class SendCoinsComponent implements OnDestroy { + // If the node service already has updated info about the remote node. + nodeDataUpdated = false; + // If true, the form for sending coins is shown. If false, the tx preview is shown. + showForm = true; + // Saves the last data entered on the form. + formData: SendCoinsData; + // If the page must show the simple form (left) or the advanced one (right). + activeForm: DoubleButtonActive; + activeForms = DoubleButtonActive; + // If true, the page will show the options related to raw transactions. + showRawTxOptions = false; + + private subscriptionsGroup: SubscriptionLike[] = []; + + constructor( + private navBarSwitchService: NavBarSwitchService, + private changeDetector: ChangeDetectorRef, + private dialog: MatDialog, + private nodeService: NodeService, + coinService: CoinService, + ) { + this.showRawTxOptions = coinService.currentCoinInmediate.coinTypeFeatures.softwareWallets; + + // Check if the node service has updated data. + this.subscriptionsGroup.push(this.nodeService.remoteNodeDataUpdated.subscribe(response => { + this.nodeDataUpdated = response; + })); + + // Show the switch for changing the form and react to its event. + this.navBarSwitchService.showSwitch('send.simple-form-button', 'send.advanced-form-button', DoubleButtonActive.LeftButton); + this.subscriptionsGroup.push(navBarSwitchService.activeComponent.subscribe(value => { + if (this.activeForm !== value) { + this.activeForm = value; + this.formData = null; + } + })); + } + + ngOnDestroy() { + this.subscriptionsGroup.forEach(sub => sub.unsubscribe()); + this.navBarSwitchService.hideSwitch(); + } + + // Called when the form requests to show the preview. The param includes the data entered + // on the form. + onFormSubmitted(data: SendCoinsData) { + this.formData = data; + this.showForm = false; + } + + // Returns from the tx preview to the form. + onBack(deleteFormData) { + // Erase the form data if requested. + if (deleteFormData) { + this.formData = null; + } + + this.showForm = true; + this.changeDetector.detectChanges(); + } + + // Opens the modal window for signing raw unsigned transactions. + signTransaction() { + SignRawTxComponent.openDialog(this.dialog); + } + + // Opens the modal window for sending raw signed transactions. + broadcastTransaction() { + BroadcastRawTxComponent.openDialog(this.dialog); + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.html b/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.html new file mode 100644 index 0000000..e8ee8d9 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.html @@ -0,0 +1,11 @@ + + +
+ {{ 'common.back-button' | translate }} + + {{ ('send.' + (transaction && !transaction.wallet ? 'show' : 'send') + '-button') | translate }} + +
diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.scss b/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.scss new file mode 100644 index 0000000..4bf1cca --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.scss @@ -0,0 +1,4 @@ +.-buttons { + margin-top: 10px; + text-align: center; +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.ts b/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.ts new file mode 100644 index 0000000..b89c7d4 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-preview/send-preview.component.ts @@ -0,0 +1,179 @@ +import { Component, EventEmitter, Input, OnDestroy, Output, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { SubscriptionLike, Observable, of } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; +import { mergeMap } from 'rxjs/operators'; + +import { ButtonComponent } from '../../../layout/button/button.component'; +import { PasswordDialogComponent } from '../../../layout/password-dialog/password-dialog.component'; +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { CopyRawTxData, CopyRawTxComponent } from '../offline-dialogs/implementations/copy-raw-tx.component'; +import { ConfirmationParams, DefaultConfirmationButtons, ConfirmationComponent } from '../../../layout/confirmation/confirmation.component'; +import { BalanceAndOutputsService } from '../../../../services/wallet-operations/balance-and-outputs.service'; +import { SpendingService } from '../../../../services/wallet-operations/spending.service'; +import { GeneratedTransaction } from '../../../../services/wallet-operations/transaction-objects'; +import { WalletTypes } from '../../../../services/wallet-operations/wallet-objects'; + +/** + * Shows the preview of a transaction before sending it to the network. + */ +@Component({ + selector: 'app-send-preview', + templateUrl: './send-preview.component.html', + styleUrls: ['./send-preview.component.scss'], +}) +export class SendVerifyComponent implements OnDestroy { + @ViewChild('sendButton') sendButton: ButtonComponent; + @ViewChild('backButton') backButton: ButtonComponent; + // Transaction which is going to be shown. + @Input() transaction: GeneratedTransaction; + // Emits when the preview must be removed from the UI and the form must be shown again. The + // boolean value indicates if the form must be cleaned before showing it (true) or if it must + // show the previously entered data again (false). + @Output() onBack = new EventEmitter(); + + private sendSubscription: SubscriptionLike; + + constructor( + private msgBarService: MsgBarService, + private dialog: MatDialog, + private hwWalletService: HwWalletService, + private translate: TranslateService, + private balanceAndOutputsService: BalanceAndOutputsService, + private spendingService: SpendingService, + ) {} + + ngOnDestroy() { + this.msgBarService.hide(); + + if (this.sendSubscription) { + this.sendSubscription.unsubscribe(); + } + + this.onBack.complete(); + } + + // Returns to the form. + back() { + this.onBack.emit(false); + } + + // Sends the transaction. + send() { + if (this.sendButton.isLoading()) { + return; + } + + this.msgBarService.hide(); + this.sendButton.resetState(); + + // If there is no wallet, the transaction is a manually created unsigned transaction, so + // the raw transaction is shown in a modal window, so the user can sign it later, + // instead of being sent. + if (!this.transaction.wallet) { + const data: CopyRawTxData = { + rawTx: this.transaction.encoded, + isUnsigned: true, + }; + + CopyRawTxComponent.openDialog(this.dialog, data).afterClosed().subscribe(() => { + const confirmationParams: ConfirmationParams = { + text: 'offline-transactions.copy-tx.reset-confirmation', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + // Ask the user if the form should be cleaned and shown again, to be able to create + // a new transaction. + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.onBack.emit(true); + } + }); + }); + + return; + } + + // Transactions made with bip44 wallets are already signed. + if (this.transaction.wallet.encrypted && !this.transaction.wallet.isHardware && this.transaction.wallet.walletType !== WalletTypes.Bip44) { + // If the wallet is encrypted, ask for the password and continue. + PasswordDialogComponent.openDialog(this.dialog, { wallet: this.transaction.wallet }).componentInstance.passwordSubmit + .subscribe(passwordDialog => { + this.finishSending(passwordDialog); + }); + } else { + if (!this.transaction.wallet.isHardware) { + // If the wallet is not encrypted, continue. + this.finishSending(); + } else { + // If using a hw wallet, check the device first. + this.showBusy(); + this.sendSubscription = this.hwWalletService.checkIfCorrectHwConnected(this.transaction.wallet).subscribe( + () => this.finishSending(), + err => this.showError(err), + ); + } + } + } + + // Finish sending the transaction. + private finishSending(passwordDialog?: any) { + this.showBusy(); + + const note = this.transaction.note.trim(); + + // Transactions made with bip44 wallets are already signed. Transactions made with other + // wallet types must be signed. + let operation: Observable; + if (this.transaction.wallet.walletType === WalletTypes.Bip44) { + operation = of(this.transaction.encoded); + } else { + operation = this.spendingService.signTransaction( + this.transaction.wallet, + passwordDialog ? passwordDialog.password : null, + this.transaction, + ); + } + + this.sendSubscription = operation.pipe(mergeMap(encodedSignedTx => { + // Close the password dialog, if it exists. + if (passwordDialog) { + passwordDialog.close(); + } + + // Send the transaction. + return this.spendingService.injectTransaction(encodedSignedTx, note); + })).subscribe(noteSaved => { + // Show the final result. + if (note && !noteSaved) { + setTimeout(() => this.msgBarService.showWarning(this.translate.instant('send.saving-note-error'))); + } else { + setTimeout(() => this.msgBarService.showDone('send.sent')); + } + + this.balanceAndOutputsService.refreshBalance(); + + this.onBack.emit(true); + }, error => { + if (passwordDialog) { + passwordDialog.error(error); + } + + this.showError(error); + }); + } + + // Makes the UI to be shown busy. + private showBusy() { + this.sendButton.setLoading(); + this.backButton.setDisabled(); + } + + // Stops showing the UI busy and shows the error msg. + private showError(error) { + this.msgBarService.showError(error); + this.sendButton.resetState(); + this.backButton.resetState().setEnabled(); + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component.html b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component.html new file mode 100644 index 0000000..4e42868 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component.html @@ -0,0 +1,21 @@ + + +
+
+ + +
+
+ +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'edit-note.change-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component.scss b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component.ts b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component.ts new file mode 100644 index 0000000..5599ed4 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/change-note/change-note.component.ts @@ -0,0 +1,102 @@ +import { Component, OnInit, Inject, ViewChild, OnDestroy } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; + +import { ButtonComponent } from '../../../../../layout/button/button.component'; +import { StorageService, StorageType } from '../../../../../../services/storage.service'; +import { MsgBarService } from '../../../../../../services/msg-bar.service'; +import { AppConfig } from '../../../../../../app.config'; +import { OldTransaction } from '../../../../../../services/wallet-operations/transaction-objects'; + +/** + * Modal window used for changing the note of a transaction from the history. If the note is + * changed, the modal window is closed and new note is returned in the "afterClosed" event. + */ +@Component({ + selector: 'app-change-note', + templateUrl: './change-note.component.html', + styleUrls: ['./change-note.component.scss'], +}) +export class ChangeNoteComponent implements OnInit, OnDestroy { + // Max chars the note can have. + public static readonly MAX_NOTE_CHARS = 64; + + @ViewChild('button') button: ButtonComponent; + form: FormGroup; + maxNoteChars = ChangeNoteComponent.MAX_NOTE_CHARS; + // Deactivates the form while the system is busy. + busy = false; + + private OperationSubscription: SubscriptionLike; + private originalNote: string; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, transaction: OldTransaction): MatDialogRef { + const config = new MatDialogConfig(); + config.data = transaction; + config.autoFocus = true; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(ChangeNoteComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) private data: OldTransaction, + private formBuilder: FormBuilder, + private msgBarService: MsgBarService, + private storageService: StorageService, + ) {} + + ngOnInit() { + this.originalNote = this.data.note ? this.data.note : ''; + + this.form = this.formBuilder.group({ + note: [this.data.note], + }); + } + + ngOnDestroy() { + this.msgBarService.hide(); + if (this.OperationSubscription) { + this.OperationSubscription.unsubscribe(); + } + } + + closePopup() { + this.dialogRef.close(); + } + + // Changes the note. + changeNote() { + if (this.busy) { + return; + } + + const newNote = this.form.value.note ? this.form.value.note.trim() : ''; + + // If the new note is equal to the original one, do nothing. + if (this.originalNote === newNote) { + this.closePopup(); + + return; + } + + this.busy = true; + this.msgBarService.hide(); + this.button.setLoading(); + + // Change the note. + this.OperationSubscription = this.storageService.store(StorageType.NOTES, this.data.id, newNote).subscribe(() => { + this.busy = false; + this.dialogRef.close(newNote); + }, error => { + this.busy = false; + this.msgBarService.showError(error); + this.button.resetState().setEnabled(); + }); + } +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.html b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.html new file mode 100644 index 0000000..ed2a7a8 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.html @@ -0,0 +1,216 @@ +
+
+ +

{{ 'tx.confirm-transaction-title' | translate }}

+

+ + {{ ('history.' + (oldTransaction.confirmed ? 'sent' : 'sending')) | translate:{coinName: ('coinSymbol' | commonText)} }} + + + {{ ('history.' + (oldTransaction.confirmed ? 'received' : 'receiving')) | translate:{coinName: ('coinSymbol' | commonText)} }} + + + {{ ('history.' + (oldTransaction.confirmed ? 'moved' : 'moving')) | translate:{coinName: ('coinSymbol' | commonText)} }} + + + {{ ('history.' + (oldTransaction.confirmed ? 'moved-wallet' : 'moving-wallet')) | translate:{coinName: ('coinSymbol' | commonText)} }} + + + {{ 'history.complex-oldTransaction' | translate }} + +

+
+ +
+ +
+ {{ 'tx.from-small-label' | translate }} {{ transaction.from }} +
+
+ {{ 'tx.to-small-label' | translate }} {{ transaction.to }} +
+
+ +
+ {{ 'tx.status-small-label' | translate }} + + {{ 'history.failed' | translate }} + help + + + {{ (transaction.confirmed ? 'tx.confirmed-transaction' : 'tx.pending-transaction') | translate:{currentConfirmations: transaction.confirmations, confirmationsNeeded: confirmationsNeeded} }} + + + help + + + +
+
+ {{ ('tx.wallet' + (oldTransaction.numberOfInvolvedLocalWallets > 1 ? 's' : '') + '-small-label') | translate }} + {{ oldTransaction.involvedLocalWallets }} +
+
+ {{ 'tx.date-small-label' | translate }} {{ transaction.timestamp | dateTime }} +
+
+
+ {{ 'tx.hours-small-label' | translate }} + + + {{ sentOrReceivedHours | amount:false:'first' }} {{ hoursText | translate }} + | + + {{ transaction.fee | amount:false:'first' }} {{ 'tx.hours-burned' | translate }} + +
+
+ {{ 'tx.amount-small-label' | translate }} + + {{ balanceToShow | amount }} + + ({{ balanceToShow.multipliedBy(price).toString(10) | currency:'USD':'symbol':'1.2-2' }}) + + +
+
+ {{ 'tx.fee-small-label' | translate }} + + {{ transaction.fee | amount }} + + ({{ transaction.fee.multipliedBy(price).toString(10) | currency:'USD':'symbol':'1.2-2' }}) + + + {{ 'tx.approximate-fee-warning' | translate }} + help + +
+
+ {{ 'tx.id-small-label' | translate }} {{ transaction.id }} +
+
+ {{ 'tx.note-small-label' | translate }} + {{ transaction.note }} + {{ 'tx.without-note' | translate }} + edit +
+
+ + +
+
+ +
+ +

+ {{ balanceToShow | amount }} + + help + +

+

+ {{ balanceToShow.plus(transaction.fee) | amount }} + help +

+

+ + {{ balanceToShow.multipliedBy(price).toString() | currency:'USD':'symbol':'1.2-2' }}* + + + {{ balanceToShow.plus(transaction.fee).multipliedBy(price).toString() | currency:'USD':'symbol':'1.2-2' }}* + +

+
+
+
+ + +
+ + +
+
+ + + + +
+

{{ 'tx.inputs-title' | translate }}

+ +
+
{{ i + 1 }}
+ +
+
+ + {{ input.address }} + + +
+ + {{ 'tx.internal' | translate }} + + + {{ internalAddressesMap.get(input.address).label }} + +
+
+
+ {{ 'tx.coins-small-label' | translate }} {{ input.coins | amount:true:'first' }} +
+
+ {{ 'tx.hours-small-label' | translate }} {{ input.hours | amount:false:'first' }} +
+
+ +
+
+ {{ 'tx.coinbase' | translate }} +
+
+
+
+ +
+

{{ 'tx.outputs-title' | translate }}

+ +
+
{{ i + 1 }}
+
+
+ {{ output.address }} + +
+ + {{ 'tx.internal' | translate }} + + + {{ internalAddressesMap.get(output.address).label }} + +
+
+
+ {{ 'tx.coins-small-label' | translate }} {{ output.coins | amount:true:'first' }} +
+
+ {{ 'tx.hours-small-label' | translate }} {{ output.hours | amount:false:'first' }} +
+
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.scss b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.scss new file mode 100644 index 0000000..d1836c8 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.scss @@ -0,0 +1,126 @@ +@import '../../../../../../theme/variables'; + +h4 { + font-size: $font-size-standard-plus; + margin: 0 0 30px; +} + +.-item { + display: flex; + font-size: $font-size-standard; + + &:not(:last-child) { + margin-bottom: 10px; + } + + .-number { + padding: 10px; + background: $grey-lightest; + align-self: flex-start; + border-radius: $very-rounded-element-border-radius; + } + + .-info { + margin-left: 10px; + display: flex; + flex-direction: column; + word-break: break-all; + + .-address { + padding: 10px 0; + margin-bottom: 5px; + + .-internal-label { + height: 0px; + font-size: 10px; + + mat-icon { + position: relative; + top: 1px; + } + } + } + } +} + +.-data { + font-size: $font-size-standard; + display: flex; + + &:not(:last-child) { + margin-bottom: 5px; + } + + mat-icon { + position: relative; + top: 1px; + opacity: 0.7; + } + + span:first-child { + color: $grey; + width: 80px; + flex-shrink: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + span:nth-child(2) { + word-break: break-word; + } + + &.-more { + margin-top: 20px; + } +} + +.edit-button { + font-size: 20px; + padding-left: 5px; +} + +.-tx-meta { + .-data { + margin-bottom: 10px; + } +} + +.-tx-price { + text-align: center; + display: flex; + flex-direction: column; + justify-content: center; + + .-icon { + img { + width: 30px; + } + } + + h4 { + color: $black; + font-size: $font-size-very-big; + font-weight: 700; + margin: 10px 0 5px; + word-break: break-word; + } + + .-balance-help { + font-size: 14px; + opacity: 0.3; + } + + p { + color: $grey; + font-size: $font-size-standard; + margin: 0; + + span { + color: lighten($grey, 40%); + } + } +} + +.-margin-top { + margin-top: 30px; +} diff --git a/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.ts b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.ts new file mode 100644 index 0000000..b5f2354 --- /dev/null +++ b/src/gui/static/src/app/components/pages/send-coins/send-preview/transaction-info/transaction-info.component.ts @@ -0,0 +1,143 @@ +import { Component, Input, OnDestroy } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; +import { first } from 'rxjs/operators'; +import { BigNumber } from 'bignumber.js'; + +import { ChangeNoteComponent } from './change-note/change-note.component'; +import { GeneratedTransaction, OldTransaction, OldTransactionTypes } from '../../../../../services/wallet-operations/transaction-objects'; +import { PriceService } from '../../../../../services/price.service'; +import { WalletsAndAddressesService } from '../../../../../services/wallet-operations/wallets-and-addresses.service'; +import { getTransactionIconName } from '../../../../../utils/history-utils'; +import { WalletBase, AddressMap } from '../../../../../services/wallet-operations/wallet-objects'; +import { CoinService } from '../../../../../services/coin.service'; +import { CoinTypes } from '../../../../../coins/settings/coin-types'; + +/** + * Allows to view the details of a transaction which is about to be sent or a transaction + * from the history. + */ +@Component({ + selector: 'app-transaction-info', + templateUrl: './transaction-info.component.html', + styleUrls: ['./transaction-info.component.scss'], +}) +export class TransactionInfoComponent implements OnDestroy { + // Transaction which is going to be shown. + @Input() transaction: GeneratedTransaction|OldTransaction; + // True if the provided transaction was created to be sent, false if it is from the history. + @Input() isPreview: boolean; + // Current price per coin, in usd. + price: number; + showInputsOutputs = false; + + // If the user has more than one wallet. + userHasMultipleWallets = false; + // List with all the addresses the user has and their corresponding wallets. + internalAddressesMap = new AddressMap(this.walletsAndAddressesService.formatAddress); + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + // How many confirmations a transaction must have to be considered fully confirmed. + confirmationsNeeded = 0; + // If the currently selected coin uses gas for the fee calculation. + currentCoinUsesGas = false; + + oldTransactionTypes = OldTransactionTypes; + + private subscription: SubscriptionLike; + + constructor( + private priceService: PriceService, + private dialog: MatDialog, + private walletsAndAddressesService: WalletsAndAddressesService, + coinService: CoinService, + ) { + this.subscription = this.priceService.price.subscribe(price => this.price = price); + + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.confirmationsNeeded = coinService.currentCoinInmediate.confirmationsNeeded; + this.currentCoinUsesGas = coinService.currentCoinInmediate.coinType === CoinTypes.ETH; + + // Get the list of internal addresses, to be able to identify them on the UI. + walletsAndAddressesService.currentWallets.pipe(first()).subscribe(wallets => { + this.userHasMultipleWallets = wallets.length > 1; + wallets.forEach(wallet => { + wallet.addresses.forEach(address => { + this.internalAddressesMap.set(address.printableAddress, wallet); + }); + }); + }); + } + + // Returns the transaction as an OldTransaction instance, to avoid problems with the compiler. + get oldTransaction(): OldTransaction { + if (!this.isPreview) { + return this.transaction as OldTransaction; + } else { + return null; + } + } + + // Gets the text which says what was done with the moved coins (if were received, sent or moved). + get hoursText(): string { + if (!this.isPreview) { + if ((this.transaction as OldTransaction).type === OldTransactionTypes.Incoming) { + return 'tx.hours-received'; + } else if ((this.transaction as OldTransaction).type === OldTransactionTypes.Outgoing) { + return 'tx.hours-sent'; + } + + return 'tx.hours-moved'; + } else { + return 'tx.hours-sent'; + } + } + + // Gets the amount of moved hours. + get sentOrReceivedHours(): BigNumber { + return this.isPreview ? + (this.transaction as GeneratedTransaction).hoursToSend : + (this.transaction as OldTransaction).hoursBalance; + } + + // If the UI must show the coins received icon (true) or the coins sent icon (false). + get shouldShowIncomingIcon(): boolean { + return !this.isPreview && (this.transaction as OldTransaction).type !== OldTransactionTypes.Outgoing; + } + + // Returns how many coins were moved. + get balanceToShow(): BigNumber { + return this.isPreview ? + (this.transaction as GeneratedTransaction).coinsToSend : + (this.transaction as OldTransaction).balance; + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } + + // Makes visible the list of the inputs and outputs. + toggleInputsOutputs(event) { + event.preventDefault(); + + this.showInputsOutputs = !this.showInputsOutputs; + } + + // Opens the modal window for editing the note of the transaction. + editNote() { + ChangeNoteComponent.openDialog(this.dialog, this.transaction as OldTransaction).afterClosed().subscribe(newNote => { + if (newNote || newNote === '') { + this.transaction.note = newNote; + } + }); + } + + // Gets the name of the icon that should be shown. + getTransactionIconName(transaction: OldTransaction): string { + if (!this.isPreview) { + return getTransactionIconName(transaction); + } else { + return 'sent'; + } + } +} diff --git a/src/gui/static/src/app/components/pages/settings/backup/backup.component.html b/src/gui/static/src/app/components/pages/settings/backup/backup.component.html new file mode 100644 index 0000000..e46e84d --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/backup/backup.component.html @@ -0,0 +1,52 @@ +
+ + + +
+
+

{{ 'backup.wallet-directory' | translate }} {{ folder }}

+

{{ 'backup.seed-warning' | translate }}

+

+ +

+
+ + + + +
+
+
{{ 'backup.wallet-table-label' | translate }}
+
{{ 'backup.filename-table-label' | translate }}
+
+
+
+
+
{{ wallet.label }}
+
{{ wallet.id }}
+
+ + + + +
+ help + help + help + {{ 'backup.show-seed-button' | translate }} +
+
+
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/settings/backup/backup.component.scss b/src/gui/static/src/app/components/pages/settings/backup/backup.component.scss new file mode 100644 index 0000000..cf14c34 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/backup/backup.component.scss @@ -0,0 +1,3 @@ +.address-link { + margin-bottom: 2px; +} diff --git a/src/gui/static/src/app/components/pages/settings/backup/backup.component.ts b/src/gui/static/src/app/components/pages/settings/backup/backup.component.ts new file mode 100644 index 0000000..ed224b3 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/backup/backup.component.ts @@ -0,0 +1,101 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { Subscription } from 'rxjs'; +import { Router } from '@angular/router'; + +import { SeedModalComponent } from './seed-modal/seed-modal.component'; +import { PasswordDialogComponent } from '../../../layout/password-dialog/password-dialog.component'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; +import { SoftwareWalletService } from '../../../../services/wallet-operations/software-wallet.service'; +import { WalletBase, WalletTypes } from '../../../../services/wallet-operations/wallet-objects'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { WalletUtilsService } from '../../../../services/wallet-operations/wallet-utils.service'; +import { CoinService } from '../../../../services/coin.service'; + +/** + * Allows to create a backup of the seed of an encrypted software wallet. + */ +@Component({ + selector: 'app-backup', + templateUrl: './backup.component.html', + styleUrls: ['./backup.component.scss'], +}) +export class BackupComponent implements OnInit, OnDestroy { + // Path of the folder which contains the software wallet files. + folder: string; + // Wallet list. + wallets: WalletBase[] = []; + + walletTypes = WalletTypes; + + private folderSubscription: Subscription; + private walletSubscription: Subscription; + + constructor( + private dialog: MatDialog, + private walletsAndAddressesService: WalletsAndAddressesService, + private walletUtilsService: WalletUtilsService, + private softwareWalletService: SoftwareWalletService, + private msgBarService: MsgBarService, + private coinService: CoinService, + private router: Router, + ) { } + + ngOnInit() { + this.folderSubscription = this.walletUtilsService.folder().subscribe(folder => { + this.folder = folder; + }, err => { + this.folder = '?'; + this.msgBarService.showError(err); + }); + + this.walletSubscription = this.walletsAndAddressesService.currentWallets.subscribe(wallets => { + this.wallets = wallets; + }); + + if (!this.coinService.currentCoinInmediate.coinTypeFeatures.softwareWallets) { + this.router.navigate([''], {replaceUrl: true}); + } + } + + ngOnDestroy() { + this.folderSubscription.unsubscribe(); + this.walletSubscription.unsubscribe(); + } + + // Creates a csv file with the addresses and makes the browser download it. + saveAddresses(wallet: WalletBase) { + // Create the address list. + let addresses = ''; + wallet.addresses.forEach(address => { + addresses += address.printableAddress + '\n'; + }); + addresses = addresses.substr(0, addresses.length - 1); + + // Create an invisible link and click it to download the data. + const blob = new Blob([addresses], { type: 'text/csv;charset=utf-8;' }); + const link = document.createElement('a'); + if (link.download !== undefined) { + const url = URL.createObjectURL(blob); + link.setAttribute('href', url); + link.setAttribute('download', wallet.label + '.csv'); + link.style.visibility = 'hidden'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } else { + this.msgBarService.showError('backup.not-compatible-error'); + } + } + + // Retrieves the seed from the node and shows it in a modal window. + showSeed(wallet: WalletBase) { + // Ask for the password and get the seed. + PasswordDialogComponent.openDialog(this.dialog, { wallet: wallet }).componentInstance.passwordSubmit.subscribe(passwordDialog => { + this.softwareWalletService.getWalletSeed(wallet, passwordDialog.password).subscribe(response => { + passwordDialog.close(); + SeedModalComponent.openDialog(this.dialog, response); + }, err => passwordDialog.error(err)); + }); + } +} diff --git a/src/gui/static/src/app/components/pages/settings/backup/seed-modal/seed-modal.component.html b/src/gui/static/src/app/components/pages/settings/backup/seed-modal/seed-modal.component.html new file mode 100644 index 0000000..5ee874d --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/backup/seed-modal/seed-modal.component.html @@ -0,0 +1,19 @@ + +
+ + +
+
+ + +
+
+ + +
+
+ + {{ 'common.close-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/pages/settings/backup/seed-modal/seed-modal.component.scss b/src/gui/static/src/app/components/pages/settings/backup/seed-modal/seed-modal.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/pages/settings/backup/seed-modal/seed-modal.component.ts b/src/gui/static/src/app/components/pages/settings/backup/seed-modal/seed-modal.component.ts new file mode 100644 index 0000000..c5b70e1 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/backup/seed-modal/seed-modal.component.ts @@ -0,0 +1,48 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +import { AppConfig } from '../../../../../app.config'; +import { SeedResponse } from '../../../../../services/wallet-operations/software-wallet.service'; +import { WalletTypes } from '../../../../../services/wallet-operations/wallet-objects'; + +/** + * Modal window for displaying the seed of a wallet, for making a backup. + */ +@Component({ + selector: 'app-seed-modal', + templateUrl: './seed-modal.component.html', + styleUrls: ['./seed-modal.component.scss'], +}) +export class SeedModalComponent { + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, seedData: SeedResponse): MatDialogRef { + const config = new MatDialogConfig(); + config.data = seedData; + config.autoFocus = true; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(SeedModalComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public data: SeedResponse, + public dialogRef: MatDialogRef, + ) {} + + // Returns the text to show on the wallet type field. + get walletTypeText(): string { + if (this.data.walletType) { + if (this.data.walletType === WalletTypes.XPub) { + return 'backup.seed-modal-window.type-xpub'; + } else if (this.data.walletType === WalletTypes.Deterministic) { + return 'backup.seed-modal-window.type-deterministic'; + } else if (this.data.walletType === WalletTypes.Bip44) { + return 'backup.seed-modal-window.type-bip44'; + } + } + + return null; + } +} diff --git a/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.html b/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.html new file mode 100644 index 0000000..7d91142 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.html @@ -0,0 +1,75 @@ +
+ + + + +
+
+ +
+
+
+
{{ 'blockchain.blocks-label' | translate }}
+
{{ block.seq | number }}
+
+
+
{{ 'blockchain.time-label' | translate }}
+
{{ block.timestamp | dateTime }}
+
+
+
{{ 'blockchain.hash-label' | translate }}
+
{{ block.hash }}
+
+
+
{{ 'blockchain.confirmations-label' | translate }}
+
+ {{ confirmations }} + + warning + + edit +
+
+
+
+ +
+
+
+
+
+
{{ 'blockchain.current-supply-label' | translate:{coinName: ('coinSymbol' | commonText)} }}
+
{{ coinSupply.currentSupply | amount:true:'first' }}
+
+
+
{{ 'blockchain.total-supply-label' | translate:{coinName: ('coinSymbol' | commonText)} }}
+
{{ coinSupply.totalSupply | amount:true:'first' }}
+
+
+
+
+
{{ 'blockchain.current-coinhour-supply-label' | translate:{coinHoursName: ('hours' | commonText)} }}
+
{{ coinSupply.currentCoinhourSupply | amount:false:'first' }}
+
+
+
{{ 'blockchain.total-coinhour-supply-label' | translate:{coinHoursName: ('hours' | commonText)} }}
+
{{ coinSupply.totalCoinhourSupply | amount:false:'first' }}
+
+
+
+
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.scss b/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.scss new file mode 100644 index 0000000..06221ce --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.scss @@ -0,0 +1,30 @@ +@import '../../../../../theme/variables'; + +.-wrapper { + margin: $main-containers-margin; +} + +.paper { + margin: 0; +} + +.-item { + &:not(:last-child) { + margin-bottom: 20px; + } + + .-key { + color: $grey; + margin-bottom: 5px; + } + + mat-icon { + position: relative; + top: 1px; + } + + .warning-icon { + animation: alert-blinking 1s linear infinite; + cursor: default; + } +} diff --git a/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.ts b/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.ts new file mode 100644 index 0000000..695d475 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/blockchain/blockchain.component.ts @@ -0,0 +1,104 @@ +import { mergeMap, delay } from 'rxjs/operators'; +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { SubscriptionLike, of } from 'rxjs'; +import { MatDialog } from '@angular/material/dialog'; + +import { BlockchainService, BasicBlockInfo, CoinSupply } from '../../../../services/blockchain.service'; +import { CoinService } from '../../../../services/coin.service'; +import { SelectConfirmationsComponent } from './select-confirmations/select-confirmations.component'; +import { ConfirmationParams, DefaultConfirmationButtons, ConfirmationComponent } from '../../../layout/confirmation/confirmation.component'; + +/** + * Shows the state of the the blockchain on the node. + */ +@Component({ + selector: 'app-blockchain', + templateUrl: './blockchain.component.html', + styleUrls: ['./blockchain.component.scss'], +}) +export class BlockchainComponent implements OnInit, OnDestroy { + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + block: BasicBlockInfo; + coinSupply: CoinSupply; + // Info about the confirmations needed for considering a transaction final. + confirmations = 0; + recommendedConfirmations = 0; + + private operationSubscription: SubscriptionLike; + private coinSubscription: SubscriptionLike; + + // Time interval in which periodic data updates will be made. + private updatePeriod = 5 * 1000; + // Time interval in which the periodic data updates will be restarted after an error. + private errorUpdatePeriod = 2 * 1000; + + constructor( + private blockchainService: BlockchainService, + private dialog: MatDialog, + coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + + // Update the confirmations info. + this.coinSubscription = coinService.currentCoin.subscribe(coin => { + this.confirmations = coin.confirmationsNeeded; + this.recommendedConfirmations = coin.normalConfirmationsNeeded; + }); + + // Intervals for updating the data must be longer if connecting to a remote node. + if (!coinService.currentCoinInmediate.isLocal) { + this.updatePeriod = 60 * 1000; + this.errorUpdatePeriod = 10 * 1000; + } + } + + ngOnInit() { + this.startDataRefreshSubscription(0); + } + + changeConfirmations() { + // Ask for confirmation before continuing. + const confirmationParams: ConfirmationParams = { + redTitle: true, + headerText: 'common.warning-title', + text: 'blockchain.edit-confirmations-warning', + checkboxText: 'common.generic-confirmation-check', + defaultButtons: DefaultConfirmationButtons.ContinueCancel, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + SelectConfirmationsComponent.openDialog(this.dialog); + } + }); + } + + /** + * Makes the page start updating the data periodically. If this function was called before, + * the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the data. + */ + private startDataRefreshSubscription(delayMs: number) { + this.removeOperationSubscription(); + + this.operationSubscription = of(0).pipe(delay(delayMs), mergeMap(() => this.blockchainService.getBlockchainState())).subscribe(state => { + this.block = state.lastBlock; + this.coinSupply = state.coinSupply; + + // Update again after a delay. + this.startDataRefreshSubscription(this.updatePeriod); + }, () => this.startDataRefreshSubscription(this.errorUpdatePeriod)); + } + + ngOnDestroy() { + this.removeOperationSubscription(); + this.coinSubscription.unsubscribe(); + } + + private removeOperationSubscription() { + if (this.operationSubscription) { + this.operationSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/settings/blockchain/select-confirmations/select-confirmations.component.html b/src/gui/static/src/app/components/pages/settings/blockchain/select-confirmations/select-confirmations.component.html new file mode 100644 index 0000000..8f9e3ff --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/blockchain/select-confirmations/select-confirmations.component.html @@ -0,0 +1,28 @@ + + +
+ +
+ + +
+
+ +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'blockchain.select-confirmation.apply-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/pages/settings/blockchain/select-confirmations/select-confirmations.component.scss b/src/gui/static/src/app/components/pages/settings/blockchain/select-confirmations/select-confirmations.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/pages/settings/blockchain/select-confirmations/select-confirmations.component.ts b/src/gui/static/src/app/components/pages/settings/blockchain/select-confirmations/select-confirmations.component.ts new file mode 100644 index 0000000..d72c239 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/blockchain/select-confirmations/select-confirmations.component.ts @@ -0,0 +1,95 @@ +import { Component, OnInit, ChangeDetectorRef } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import BigNumber from 'bignumber.js'; + +import { MsgBarService } from '../../../../../services/msg-bar.service'; +import { CoinService } from '../../../../../services/coin.service'; +import { TranslateService } from '@ngx-translate/core'; + +/** + * Modal window for changing how many confirmation the transactions of the currently selected + * coin must have to be considered final. + */ +@Component({ + selector: 'app-select-confirmations', + templateUrl: './select-confirmations.component.html', + styleUrls: ['./select-confirmations.component.scss'], +}) +export class SelectConfirmationsComponent implements OnInit { + // Max value allowed in the form. + readonly maxAllowedValue = 100; + + form: FormGroup; + + // Vars with the validation error messages. + confirmationsErrorMsg = ''; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = true; + config.width = '450px'; + + return dialog.open(SelectConfirmationsComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + private formBuilder: FormBuilder, + private msgBarService: MsgBarService, + private changeDetector: ChangeDetectorRef, + private coinService: CoinService, + private translateService: TranslateService, + ) {} + + ngOnInit() { + this.form = this.formBuilder.group({ + confirmations: [this.coinService.currentCoinInmediate.confirmationsNeeded], + }); + + this.form.setValidators(this.validateForm.bind(this)); + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.confirmationsErrorMsg = ''; + + let valid = true; + + const confirmations = this.form.get('confirmations').value; + const confirmationsBn = new BigNumber(confirmations); + + if ( + confirmationsBn.isNaN() || + confirmationsBn.isLessThan(0) || + confirmationsBn.isGreaterThan(this.maxAllowedValue) || + !confirmationsBn.isEqualTo(confirmationsBn.decimalPlaces(0)) + ) { + valid = false; + if (this.form.get('confirmations').touched) { + this.confirmationsErrorMsg = this.translateService.instant('blockchain.select-confirmation.confirmations-error-info', { max: this.maxAllowedValue }); + } + } + + return valid ? null : { Invalid: true }; + } + + closePopup() { + this.dialogRef.close(); + } + + // Changes the confirmations needed for the currently selected coin. + changeConfirmations() { + this.changeDetector.detectChanges(); + + this.coinService.updateConfirmationsNeeded(this.form.get('confirmations').value); + setTimeout(() => this.msgBarService.showDone('common.changes-made')); + + this.closePopup(); + } +} diff --git a/src/gui/static/src/app/components/pages/settings/network/network.component.html b/src/gui/static/src/app/components/pages/settings/network/network.component.html new file mode 100644 index 0000000..c0a3539 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/network/network.component.html @@ -0,0 +1,45 @@ +
+ + + + +
+
+
+
+
{{ 'network.peer-small-table-label' | translate }}
+
{{ 'network.source-small-table-label' | translate }}
+
{{ 'network.block-height-small-table-label' | translate }}
+
{{ 'network.block-height-short-small-table-label' | translate }}
+
{{ 'network.last-seen-small-table-label' | translate }}
+
+
+
+
+ + +
+
+ {{ peer.address.split(':')[0] }}:{{ peer.listenPort }} +
+
{{ ('network.sources.' + peer.source) | translate }}
+
{{ peer.height }}
+
+
+ keyboard_arrow_up + {{ peer.lastSent | dateFromNow }} +
+
+ keyboard_arrow_down + {{ peer.lastReceived | dateFromNow }} +
+
+
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/settings/network/network.component.scss b/src/gui/static/src/app/components/pages/settings/network/network.component.scss new file mode 100644 index 0000000..63b3067 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/network/network.component.scss @@ -0,0 +1,62 @@ +@import '../../../../../theme/variables'; + +.-direction-cell { + width: 72px; + flex-shrink: 0; +} + +.-direction-container { + display: flex; + justify-content: center; + align-items: center; + + img { + width: $normal-icon-size; + } +} + +.-last-seen-cell { + width: 180px; + flex-shrink: 0; +} + +.-last-seen-container { + display: flex; + flex-direction: column; + font-size: $font-size-mini; + line-height: 1; + justify-content: center; + + mat-icon { + font-size: 12px; + display: inline; + vertical-align: middle; + padding-right: 5px; + } +} + +.-address-cell { + width: 200px; + flex-shrink: 0; + padding-left: 0 !important; +} + +.-block-cell { + width: 150px; + flex-shrink: 0; + text-align: right; +} + +@media (max-width: $max-sm-width) { + .-row { + font-size: $font-size-standard-minus !important; + } + + .-address-cell { + width: 160px !important; + } + + .-block-cell { + width: 100px; + } +} diff --git a/src/gui/static/src/app/components/pages/settings/network/network.component.ts b/src/gui/static/src/app/components/pages/settings/network/network.component.ts new file mode 100644 index 0000000..5b7b9dc --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/network/network.component.ts @@ -0,0 +1,40 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { SubscriptionLike } from 'rxjs'; +import { Router } from '@angular/router'; + +import { NetworkService } from '../../../../services/network.service'; +import { Connection } from '../../../../services/coin-specific/network-operator'; +import { CoinService } from '../../../../services/coin.service'; + +/** + * Allows to see the list of connections the node currently has with other nodes. + */ +@Component({ + selector: 'app-network', + templateUrl: './network.component.html', + styleUrls: ['./network.component.scss'], +}) +export class NetworkComponent implements OnInit, OnDestroy { + peers: Connection[]; + + private subscription: SubscriptionLike; + + constructor( + private networkService: NetworkService, + private coinService: CoinService, + private router: Router, + ) { } + + ngOnInit() { + // Periodically get the list of connected nodes. + this.subscription = this.networkService.connections().subscribe(peers => this.peers = peers); + + if (!this.coinService.currentCoinInmediate.coinTypeFeatures.networkingStats) { + this.router.navigate([''], {replaceUrl: true}); + } + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } +} diff --git a/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.html b/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.html new file mode 100644 index 0000000..e6a747d --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.html @@ -0,0 +1,42 @@ +
+ + + + +
+
+
+
{{ wallet.label }}
+
{{ 'coinSymbol' | commonText }}
+
{{ 'hours' | commonText }}
+
{{ 'common.confirmations' | translate }}
+
+
+ +
+
+ + {{ address.printableAddress }} +
+
+
+
{{ output.hash }}
+
{{ output.coins | amount:true:'first' }}
+
{{ output.hours | amount:false:'first' }}
+
+ {{ output.confirmations }} / {{ confirmationsNeeded }} +
+
+
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.scss b/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.scss new file mode 100644 index 0000000..f9a3c86 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.scss @@ -0,0 +1,17 @@ +@import '../../../../../theme/variables'; + +$qr-code-margin: 10px; + +.-hash { + margin-left: $qr-code-button-size + $qr-code-margin; + word-break: break-all; +} + +app-qr-code-button { + vertical-align: middle; + margin-right: $qr-code-margin; +} + +.address { + vertical-align: middle; +} diff --git a/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.ts b/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.ts new file mode 100644 index 0000000..e7a5145 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/outputs/outputs.component.ts @@ -0,0 +1,86 @@ +import { Component, OnDestroy } from '@angular/core'; +import { ActivatedRoute, Params, Router } from '@angular/router'; +import { SubscriptionLike } from 'rxjs'; +import { retryWhen, delay } from 'rxjs/operators'; + +import { BalanceAndOutputsService } from '../../../../services/wallet-operations/balance-and-outputs.service'; +import { WalletWithOutputs } from '../../../../services/wallet-operations/wallet-objects'; +import { CoinService } from '../../../../services/coin.service'; +import { CoinTypes } from '../../../../coins/settings/coin-types'; + +/** + * Allows to see the list of unspent outputs of the registered wallets. The list can be + * limited to one address by setting the"addr" param, on the URL, to the desired address. + */ +@Component({ + selector: 'app-outputs', + templateUrl: './outputs.component.html', + styleUrls: ['./outputs.component.scss'], +}) +export class OutputsComponent implements OnDestroy { + wallets: WalletWithOutputs[]|null; + + // If true, the page will show a column with how many confirmations the outputs has, instead + // of the hours column. + showConfirmations = false; + // Now many confirmations a transaction must have to be considered fully confirmed. + confirmationsNeeded = 0; + + private outputsSubscription: SubscriptionLike; + private navigationSubscription: SubscriptionLike; + + constructor( + route: ActivatedRoute, + private balanceAndOutputsService: BalanceAndOutputsService, + private coinService: CoinService, + private router: Router, + ) { + // Reload the data every time the url params change. + this.navigationSubscription = route.queryParams.subscribe(params => { + this.wallets = null; + this.loadData(params); + }); + + this.showConfirmations = coinService.currentCoinInmediate.coinType !== CoinTypes.Fiber; + this.confirmationsNeeded = coinService.currentCoinInmediate.confirmationsNeeded; + + if (!this.coinService.currentCoinInmediate.coinTypeFeatures.outputs) { + this.router.navigate([''], {replaceUrl: true}); + } + } + + ngOnDestroy() { + this.removeOutputsSubscription(); + this.navigationSubscription.unsubscribe(); + } + + private loadData(lastRouteParams: Params) { + const addr = lastRouteParams['addr']; + + this.removeOutputsSubscription(); + + // Periodically get the list of wallets with the outputs. + this.outputsSubscription = this.balanceAndOutputsService.outputsWithWallets + .pipe(retryWhen(errors => errors.pipe(delay(2000)))) + .subscribe(wallets => { + // The original response object is modified. No copy is created before doing this + // because the data is only used by this page. + this.wallets = wallets.map(wallet => { + // Include only addresses with outputs or the requested address. + wallet.addresses = wallet.addresses.filter(address => { + if (address.outputs.length > 0) { + return addr ? address.compareAddress(addr) : true; + } + }); + + return wallet; + }).filter(wallet => wallet.addresses.length > 0); + }); + } + + private removeOutputsSubscription() { + if (this.outputsSubscription) { + this.outputsSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/settings/pending-transactions/pending-transactions.component.html b/src/gui/static/src/app/components/pages/settings/pending-transactions/pending-transactions.component.html new file mode 100644 index 0000000..c4fbab1 --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/pending-transactions/pending-transactions.component.html @@ -0,0 +1,30 @@ +
+ + + + +
+
+
+
{{ 'pending-txs.txid-table-label' | translate }}
+
{{ 'coinSymbol' | commonText }}
+
{{ 'hours' | commonText }}
+
{{ 'common.confirmations' | translate }}
+
{{ 'pending-txs.timestamp-table-label' | translate }}
+
+
+
+
{{ tx.id }}
+
{{ tx.coins | amount:true:'first' }}
+
{{ tx.hours | amount:false:'first' }}
+
{{ tx.confirmations }} / {{ confirmationsNeeded }}
+
{{ tx.timestamp ? (tx.timestamp | dateTime) : ('pending-txs.unknown-date' | translate) }}
+
+
+
+
+
diff --git a/src/gui/static/src/app/components/pages/settings/pending-transactions/pending-transactions.component.scss b/src/gui/static/src/app/components/pages/settings/pending-transactions/pending-transactions.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/pages/settings/pending-transactions/pending-transactions.component.ts b/src/gui/static/src/app/components/pages/settings/pending-transactions/pending-transactions.component.ts new file mode 100644 index 0000000..6bbadab --- /dev/null +++ b/src/gui/static/src/app/components/pages/settings/pending-transactions/pending-transactions.component.ts @@ -0,0 +1,100 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { SubscriptionLike, of } from 'rxjs'; +import { delay, mergeMap } from 'rxjs/operators'; +import { Router } from '@angular/router'; + +import { NavBarSwitchService } from '../../../../services/nav-bar-switch.service'; +import { DoubleButtonActive } from '../../../layout/double-button/double-button.component'; +import { HistoryService, PendingTransactionData } from '../../../../services/wallet-operations/history.service'; +import { CoinService } from '../../../../services/coin.service'; +import { CoinTypes } from '../../../../coins/settings/coin-types'; + +/** + * Allows to see the list of pending transactions. It uses the nav bar to know if it must show + * all pending tx or just the pending tx affecting the user. + */ +@Component({ + selector: 'app-pending-transactions', + templateUrl: './pending-transactions.component.html', + styleUrls: ['./pending-transactions.component.scss'], +}) +export class PendingTransactionsComponent implements OnInit, OnDestroy { + // Transactions to show on the UI. + transactions: PendingTransactionData[] = null; + + private transactionsSubscription: SubscriptionLike; + private navbarSubscription: SubscriptionLike; + + private selectedNavbarOption: DoubleButtonActive; + + // Time interval in which periodic data updates will be made. + private updatePeriod = 10 * 1000; + // Time interval in which the periodic data updates will be restarted after an error. + private errorUpdatePeriod = 2 * 1000; + + // If true, the page will show a column with how many confirmations the transactions have, + // instead of the hours column. + showConfirmations = false; + // Now many confirmations a transaction must have to be considered fully confirmed. + confirmationsNeeded = 0; + + constructor( + private navBarSwitchService: NavBarSwitchService, + private historyService: HistoryService, + private coinService: CoinService, + private router: Router, + ) { + // Intervals for updating the data must be longer if connecting to a remote node. + if (!coinService.currentCoinInmediate.isLocal) { + this.updatePeriod = 60 * 1000; + this.errorUpdatePeriod = 10 * 1000; + } + + this.showConfirmations = coinService.currentCoinInmediate.coinType !== CoinTypes.Fiber; + this.confirmationsNeeded = coinService.currentCoinInmediate.confirmationsNeeded; + + this.navbarSubscription = this.navBarSwitchService.activeComponent.subscribe(value => { + this.selectedNavbarOption = value; + this.transactions = null; + this.startDataRefreshSubscription(0); + }); + + if (!this.coinService.currentCoinInmediate.coinTypeFeatures.showAllPendingTransactions) { + this.router.navigate([''], {replaceUrl: true}); + } + } + + ngOnInit() { + this.navBarSwitchService.showSwitch('pending-txs.my-transactions-button', 'pending-txs.all-transactions-button'); + } + + ngOnDestroy() { + if (this.navbarSubscription) { + this.navbarSubscription.unsubscribe(); + } + this.removeTransactionsSubscription(); + this.navBarSwitchService.hideSwitch(); + } + + /** + * Makes the page start updating the data periodically. If this function was called before, + * the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the data. + */ + private startDataRefreshSubscription(delayMs: number) { + this.removeTransactionsSubscription(); + + this.transactionsSubscription = of(0).pipe(delay(delayMs), mergeMap(() => this.historyService.getPendingTransactions())).subscribe(transactions => { + this.transactions = this.selectedNavbarOption === DoubleButtonActive.LeftButton ? transactions.user : transactions.all; + + // Update again after a delay. + this.startDataRefreshSubscription(this.updatePeriod); + }, () => this.startDataRefreshSubscription(this.errorUpdatePeriod)); + } + + private removeTransactionsSubscription() { + if (this.transactionsSubscription) { + this.transactionsSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.html b/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.html new file mode 100644 index 0000000..2bf7c28 --- /dev/null +++ b/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.html @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.scss b/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.scss new file mode 100644 index 0000000..b428151 --- /dev/null +++ b/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.scss @@ -0,0 +1,5 @@ +@import '../../../../../theme/variables'; + +app-transaction-info { + color: $black; +} diff --git a/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.ts b/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.ts new file mode 100644 index 0000000..965347a --- /dev/null +++ b/src/gui/static/src/app/components/pages/transaction-list/transaction-detail/transaction-detail.component.ts @@ -0,0 +1,35 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +import { OldTransaction } from '../../../../services/wallet-operations/transaction-objects'; + +/** + * Modal window for showing the details of a transaction from the transaction history. + */ +@Component({ + selector: 'app-transaction-detail', + templateUrl: './transaction-detail.component.html', + styleUrls: ['./transaction-detail.component.scss'], +}) +export class TransactionDetailComponent { + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, transaction: OldTransaction): MatDialogRef { + const config = new MatDialogConfig(); + config.data = transaction; + config.autoFocus = false; + config.width = '800px'; + + return dialog.open(TransactionDetailComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public transaction: OldTransaction, + public dialogRef: MatDialogRef, + ) {} + + closePopup() { + this.dialogRef.close(); + } +} diff --git a/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.html b/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.html new file mode 100644 index 0000000..c660d6f --- /dev/null +++ b/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.html @@ -0,0 +1,200 @@ + + + +
+ +
+ + +
+ +
+ + + + + {{ 'history.all-addresses' | translate }} + + + {{ address.printableAddress }} - {{ address.coins | amount }} + {{ !coinHasHours ? '' : ' (' + (address.hours | amount:false) + ')' }} + + + + + + + {{ wallet.label }} - {{ wallet.coins | amount }} + {{ !coinHasHours ? '' : ' (' + (wallet.hours | amount:false) + ')' }} + + + + + + + {{ address.walletName }} - {{ address.printableAddress }} - {{ address.coins | amount }} + {{ !coinHasHours ? '' : ' (' + (address.hours | amount:false) + ')' }} + + + + + {{ 'history.filter' | translate }} + {{ 'history.filters' | translate }} + +
+ {{ filter.label }} + {{ filter.walletName }} - + {{ filter.printableAddress }} + - {{ filter.coins | amount }} + {{ !coinHasHours ? '' : ' (' + (filter.hours | amount:false) + ')' }} +
+
+
+
+ + more_vert + + + +
+ + + + +
+ +
+ +
+ + +
+
+ +

+ + {{ 'history.failed' | translate }} + help + - + + + {{ ('history.' + (transaction.confirmed ? 'sent' : 'sending')) | translate:{coinName: ('coinSymbol' | commonText)} }} + + + {{ ('history.' + (transaction.confirmed ? 'received' : 'receiving')) | translate:{coinName: ('coinSymbol' | commonText)} }} + + + {{ ('history.' + (transaction.confirmed ? 'moved' : 'moving')) | translate:{coinName: ('coinSymbol' | commonText)} }} + + + {{ ('history.' + (transaction.confirmed ? 'moved-wallet' : 'moving-wallet')) | translate:{coinName: ('coinSymbol' | commonText)} }} + + + {{ 'history.complex-transaction' | translate }} + + + + {{ ('history.involved-wallet' + (transaction.numberOfInvolvedLocalWallets !== 1 ? 's' : '') + '-small-label') | translate }} + {{ transaction.involvedLocalWallets }} + +

+ + +
+ + {{ address }} +
+
+ +
+ {{ 'history.transaction-note-small-label' | translate }} {{ transaction.note }} +
+ +
+ + {{ ('history.involved-wallet' + (transaction.numberOfInvolvedLocalWallets !== 1 ? 's' : '') + '-small-label') | translate }} + {{ transaction.involvedLocalWallets }} + +
+
+
+
{{ transaction.timestamp | dateTime }}
+
+ {{ 'history.pending-indication' | translate:{currentConfirmations: transaction.confirmations, confirmationsNeeded: confirmationsNeeded} }} + + help + +
+ +

+ {{ transaction.balance.toString() | amount }} + + help + +

+

+ {{ transaction.balance * price | currency:'USD':'symbol':'1.2-2' }}* +

+
+

+ whatshot + {{ transaction.fee | amount:false:'first' }} +

+
+
+
+
+
+
+ {{ 'history.view-all' | translate:{ number:totalElements } }} +
+
+ {{ 'history.load-more' | translate }} + +
+ + + {{ 'history.use-explorer' | translate }} + +
+ {{ 'history.use-explorer' | translate }} +
+
+
diff --git a/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.scss b/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.scss new file mode 100644 index 0000000..2683e57 --- /dev/null +++ b/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.scss @@ -0,0 +1,228 @@ +@import '../../../../theme/variables'; + +.form-field { + margin: 10px $main-containers-margin; + margin-bottom: -($main-containers-margin * 0.7); + display: flex; + + mat-select { + background: transparent; + border: 0; + border-radius: 0; + ::ng-deep .mat-select-value { + font-size: $font-size-standard; + line-height: 1.7; + } + + .left-icon { + content: 'filter_list'; + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 13px; + margin-right: 10px; + position: relative; + top: 1px; + } + + ::ng-deep .mat-select-placeholder { + color: $grey !important; + + &::before { + @extend .left-icon; + } + } + + mat-select-trigger::before { + @extend .left-icon; + } + + .filter { + font-size: $font-size-standard; + margin-left: 28px; + color: $grey; + } + } + + .x-button { + width: 24px; + height: 24px; + margin-top: 10px; + } + + .options-button { + cursor: pointer; + color: lighten($grey, 30%); + margin-top: 10px; + margin-left: 20px; + font-size: 22px; + align-self: baseline; + } +} + +.bottom-line { + border-bottom: 2px solid $grey-very-light; +} + +.paper { + padding: 0; +} + +.-pending { + opacity: 0.5; +} + +.-transaction-container { + background-color: $white; + border-bottom: 1px solid $grey-very-light; + cursor: pointer; + + &:hover { + background-color: $white-hover; + } +} + +.-transaction { + display: flex; + padding: 20px 12px; + + > div { + padding: 0 8px; + } + + .-icon { + margin-top: 5px; + + img { + width: $normal-icon-size; + } + } + + .-address { + flex: 1; + + h4 { + color: $black; + font-size: $font-size-standard; + font-weight: 700; + line-height: 1.15; + margin: 0 0 8px 0; + + .wallets-text { + font-size: $font-size-mini; + line-height: 1.2; + padding-left: 5px; + font-weight: 300; + word-break: break-word; + } + } + + .-item { + word-break: break-word; + + &:not(:last-child) { + margin-bottom: 5px; + } + + app-qr-code-button { + vertical-align: middle; + margin-right: 4px; + } + + span { + color: $grey; + font-size: $font-size-standard; + line-height: 1.15; + } + } + } + + .-balance { + width: 200px; + text-align: right; + font-size: $font-size-standard; + line-height: 1.15; + + .-top-line { + font-size: $font-size-mini; + font-weight: 300; + margin: 0 0 4px 0; + + mat-icon { + position: relative; + top: 1px; + opacity: 0.7; + } + } + + h4 { + color: $black; + font-weight: 700; + margin: 0 0 8px 0; + + mat-icon { + position: relative; + top: 1px; + font-size: $font-size-mini; + opacity: 0.7; + } + } + + p { + color: $grey; + display: inline-block; + margin: 0; + } + + .burned { + margin: 8px 0 0 0; + + mat-icon { + position: relative; + top: 1px; + } + } + } +} + +.view-all-button { + display: block; + text-decoration: none; + font-size: $font-size-standard; + text-align: center; + padding: 20px; + cursor: pointer; + + &:hover { + background-color: $white-hover; + } +} + +.no-selectable { + color: $black !important; + cursor: unset !important; + + &:hover { + background-color: transparent !important; + } +} + +.disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +mat-spinner { + display: inline-block; + height: 12px !important; + width: 12px !important; + margin-left: 7px !important; + position: relative; + top: 2px; + + ::ng-deep svg { + height: 12px !important; + width: 12px !important; + } +} diff --git a/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.ts b/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.ts new file mode 100644 index 0000000..1c26b01 --- /dev/null +++ b/src/gui/static/src/app/components/pages/transaction-list/transaction-list.component.ts @@ -0,0 +1,585 @@ +import { delay, mergeMap, filter } from 'rxjs/operators'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { SubscriptionLike, of } from 'rxjs'; +import { MatDialog } from '@angular/material/dialog'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; + +import { PriceService } from '../../../services/price.service'; +import { TransactionDetailComponent } from './transaction-detail/transaction-detail.component'; +import { HistoryService, TransactionLimits } from '../../../services/wallet-operations/history.service'; +import { BalanceAndOutputsService } from '../../../services/wallet-operations/balance-and-outputs.service'; +import { OldTransaction, OldTransactionTypes } from '../../../services/wallet-operations/transaction-objects'; +import { WalletTypes, AddressMap } from '../../../services/wallet-operations/wallet-objects'; +import { getTransactionIconName } from '../../../utils/history-utils'; +import { CoinService } from '../../../services/coin.service'; +import { AppConfig } from '../../../app.config'; +import { Coin } from '../../../coins/coin'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; + +/** + * Represents a wallet, to be used as filter. + */ +class Wallet { + id: string; + type: WalletTypes; + label: string; + coins: string; + hours?: string; + addresses: Address[]; + /** + * If true, the user selected the option for showing all transactions affecting the wallet, + * which means all addresses must be considered selected. + */ + allAddressesSelected: boolean; +} + +/** + * Represents an address, to be used as filter. + */ +class Address { + walletID: string; + printableAddress: string; + coins: string; + hours?: string; + /** + * If true, the user selected the option for showing all transactions affecting the wallet, + * which means this address must be considered selected, even if the user did not select + * it directly. + */ + showingWholeWallet: boolean; + /** + * Name of the wallet which contains this address. NOTE: should only have a value if the + * address is on a wallet which is not suposed to show its addresses on the filter list, + * but the address was specifically selected as a filter via URL params. + */ + walletName?: string; +} + +/** + * Steps the page can go through to get the the data. In each step some transaction may have + * been ignored due to the limitations in transactions per address. + */ +enum LoadingSteps { + /** + * The page is loading the initial data. + */ + Starting = 1, + /** + * The page loaded the history using the standard limitations for transactions per address. + */ + FirstGroup = 2, + /** + * The page loaded the history using the extended limitations for transactions per address. + */ + SecondGroup = 3, + /** + * The page loaded the history using the maximum allowed limit for transactions per address. + */ + LastGroup = 4, +} + +/** + * Steps the page can go through to show the the data. + */ +enum ShowingSteps { + /** + * Showing the initial group, which includes at most the transactions available in + * LoadingSteps.FirstGroup. + */ + InitialGroup = 1, + /** + * Showing the estended group, which includes at most the transactions available in + * LoadingSteps.SecondGroup. + */ + ExtraGroup = 2, + /** + * Showing the full history obtained from the backend. Should only be used when no + * trasnsactions have been ignored due to the limitations in transactions per address or + * when the loading state is LoadingSteps.LastGroup. + */ + All = 3, +} + +/** + * Shows the transaction history and options for the user to filter it. The "addr" and "wal" + * params can be added to the url to limit the history to a list of wallet IDs (as a comma + * separated string) or a list of addresses, respectively. + */ +@Component({ + selector: 'app-transaction-list', + templateUrl: './transaction-list.component.html', + styleUrls: ['./transaction-list.component.scss'], +}) +export class TransactionListComponent implements OnInit, OnDestroy { + private static pageLoadedInternal = false; + /** + * Allows to know if the page is currently being shown. + */ + public static get pageLoaded(): boolean { + return TransactionListComponent.pageLoadedInternal; + } + + // If the user has at least one wallet for the currently selected coin. + userHasWallets = true; + // Contains all transactions on the user history. + allTransactions: OldTransaction[]; + // Contains the filtered transaction list. + transactions: OldTransaction[]; + // Current step in the process for loading the data. The app will only perform additional steps + // if the previous ones did not recover all the transactions and the user requested more data. + loadingStep = LoadingSteps.Starting; + // If true, some transactions were ignored for the wallets and addresses currently selected as + // filter, due to the limitations in transactions per address. + someTransactionsWereIgnored: boolean; + // List with the addresses for which transactions were ignored the last time the history + // was recovered. + addressesWitMoreTransactions: AddressMap; + // All wallets the user has, for filtering. + wallets: Wallet[]; + // All wallets that must be shown in the filter list with all its addresses. + walletsShowingAllAddresses: Wallet[]; + // All wallets that must be shown in the filter list without the addresses. + walletsNotShowingAddresses: Wallet[]; + // Contains the addresses which were specifically selected as filters via URL params, but are + // part of wallets which are not suposed to show its addresses on the filter list. + addresses: Address[]; + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + currentCoin: Coin; + // How many confirmations a transaction must have to be considered fully confirmed. + confirmationsNeeded = 0; + transactionsLoadedForTheFirsTime = false; + loadingTransactions = false; + form: FormGroup; + + // If the involved addresses of every transaction must be shown. + showAddresses = false; + // If the user has more than one wallet. + userHasMultipleWallets = false; + + oldTransactionTypes = OldTransactionTypes; + showingSteps = ShowingSteps; + + // Vars for showing only some elements at the same time by default. + maxInitialElements = 40; + maxExtraElements = 80; + showingStep = ShowingSteps.InitialGroup; + viewingTruncatedList = false; + totalElements: number; + + price: number; + + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 2 * 1000; + private requestedFilters: string[]; + + private priceSubscription: SubscriptionLike; + private filterSubscription: SubscriptionLike; + private walletsSubscription: SubscriptionLike; + private transactionsSubscription: SubscriptionLike; + private routeSubscription: SubscriptionLike; + + constructor( + private dialog: MatDialog, + private priceService: PriceService, + private formBuilder: FormBuilder, + private historyService: HistoryService, + private walletsAndAddressesService: WalletsAndAddressesService, + balanceAndOutputsService: BalanceAndOutputsService, + route: ActivatedRoute, + coinService: CoinService, + ) { + this.form = this.formBuilder.group({ + filter: [[]], + }); + + this.currentCoin = coinService.currentCoinInmediate; + + // Intervals for updating the data must be longer if connecting to a remote backend. + if (!coinService.currentCoinInmediate.isLocal) { + this.errorUpdatePeriod = 60 * 1000; + } + + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.confirmationsNeeded = coinService.currentCoinInmediate.confirmationsNeeded; + + // Get the filters requested in the URL. + this.routeSubscription = route.queryParams.subscribe(params => { + let Addresses = params['addr'] ? (params['addr'] as string).split(',') : []; + let Wallets = params['wal'] ? (params['wal'] as string).split(',') : []; + // Add prefixes to make it easier to identify the requested filters. + Addresses = Addresses.map(element => 'a-' + this.walletsAndAddressesService.formatAddress(element)); + Wallets = Wallets.map(element => 'w-' + element); + this.showingStep = ShowingSteps.InitialGroup; + + // Save the list of requested filters. + this.requestedFilters = Addresses.concat(Wallets); + // Apply the requested filters. If the wallet list has not been loaded, this call + // will do nothing. + this.showRequestedFilters(); + }); + + // Maintain an updated list of the registered wallets and update the transactions every time + // the wallets or their balances change. + this.walletsSubscription = balanceAndOutputsService.firstFullUpdateMade.pipe( + filter(result => result), mergeMap(() => balanceAndOutputsService.walletsWithBalance), + ).subscribe(wallets => { + if (wallets.length === 0) { + this.userHasWallets = false; + + return; + } + + this.userHasWallets = true; + + // Limit the max number of transactions to show per step to make it not bigger than how many + // transactions can be obtained per address, to avoid showing an invalid transaction order + // in edge cases. + let addressCount = 0; + wallets.forEach(wallet => { + addressCount += wallet.addresses.length; + }); + const maxTxsPerAddress = addressCount > AppConfig.fewAddressesLimit ? AppConfig.maxTxPerAddressIfManyAddresses : AppConfig.maxTxPerAddressIfFewAddresses; + this.maxInitialElements = Math.min(this.maxInitialElements, maxTxsPerAddress); + this.maxExtraElements = Math.min(this.maxExtraElements, maxTxsPerAddress * AppConfig.maxTxPerAddressMultiplier); + + // Reset the values. + this.showingStep = ShowingSteps.InitialGroup; + this.loadingStep = LoadingSteps.Starting; + + // If the user only has one wallet, the addresses of each transaction will be shown. + this.userHasMultipleWallets = wallets.length > 1; + this.showAddresses = !this.userHasMultipleWallets; + + // Save the currently selected filters on 2 maps. + const selectedAddresses: Map = new Map(); + const selectedWallets: Map = new Map(); + const selectedFilters: (Wallet|Address)[] = this.form.get('filter').value; + selectedFilters.forEach(currentFilter => { + if ((currentFilter as Wallet).addresses) { + selectedWallets.set((currentFilter as Wallet).id, true); + } else { + selectedAddresses.set((currentFilter as Address).walletID + '/' + (currentFilter as Address).printableAddress, true); + } + }); + // As all wallets and address used as filters will be recreated, this array saves the list + // of the new objects which must be used as filters for the UI to stay the same. + const newFilters: (Wallet|Address)[] = []; + + this.wallets = []; + + // A local copy of the data is created, to use it for filtering. + wallets.forEach(wallet => { + const newWallet: Wallet = { + id: wallet.id, + type: wallet.walletType, + label: wallet.label, + coins: wallet.coins.toString(), + hours: wallet.hours ? wallet.hours.toString() : undefined, + addresses: [], + allAddressesSelected: selectedWallets.has(wallet.id), + }; + this.wallets.push(newWallet); + + // Use as filter, if appropiate. + if (selectedWallets.has(wallet.id)) { + newFilters.push(newWallet); + } + + wallet.addresses.forEach(address => { + const newAddress: Address = { + walletID: wallet.id, + printableAddress: address.printableAddress, + coins: address.coins.toString(), + hours: address.hours ? address.hours.toString() : undefined, + showingWholeWallet: selectedWallets.has(wallet.id), + }; + this.wallets[this.wallets.length - 1].addresses.push(newAddress); + + // Use as filter, if appropiate. + if (selectedAddresses.has(wallet.id + '/' + address.printableAddress)) { + newFilters.push(newAddress); + } + }); + }); + + this.form.get('filter').setValue(newFilters, { emitEvent: false }); + + // Prepare the arrays of elements which will be shown on the filter list. + this.prepareWalletsForFiltering(); + + this.loadTransactions(0); + }); + } + + ngOnInit() { + this.priceSubscription = this.priceService.price.subscribe(price => this.price = price); + + this.filterSubscription = this.form.get('filter').valueChanges.subscribe(() => { + this.showingStep = ShowingSteps.InitialGroup; + this.filterTransactions(); + }); + + setTimeout(() => TransactionListComponent.pageLoadedInternal = true); + } + + ngOnDestroy() { + this.priceSubscription.unsubscribe(); + this.filterSubscription.unsubscribe(); + this.walletsSubscription.unsubscribe(); + this.routeSubscription.unsubscribe(); + this.removeTransactionsSubscription(); + + TransactionListComponent.pageLoadedInternal = false; + } + + // Shows all transactions. + showAll() { + if (this.showingStep !== ShowingSteps.All) { + this.showingStep = ShowingSteps.All; + this.filterTransactions(); + } + } + + // Show or load more transactions. + loadMore() { + // Compare the current step the page is in for showing data with the step for + // loading the data, to be able to know if more data must be loaded or the page + // only needs to show previously obtained data. + if (this.showingStep === ShowingSteps.InitialGroup) { + if (this.loadingStep === LoadingSteps.FirstGroup) { + this.loadTransactions(0); + } else if (this.loadingStep === LoadingSteps.SecondGroup) { + this.showingStep = ShowingSteps.ExtraGroup; + this.filterTransactions(); + } else if (this.loadingStep === LoadingSteps.LastGroup) { + this.showingStep = ShowingSteps.All; + this.filterTransactions(); + } + } else if (this.showingStep === ShowingSteps.ExtraGroup) { + if (this.loadingStep === LoadingSteps.SecondGroup) { + this.loadTransactions(0); + } else if (this.loadingStep === LoadingSteps.LastGroup) { + this.showingStep = ShowingSteps.All; + this.filterTransactions(); + } + } + } + + showTransaction(transaction: OldTransaction) { + TransactionDetailComponent.openDialog(this.dialog, transaction); + } + + // Gets the name of the icon that should be shown for a specific transaction. + getTransactionIconName(transaction: OldTransaction): string { + return getTransactionIconName(transaction); + } + + // Cleans the filter list. + removeFilters() { + this.form.get('filter').setValue([]); + } + + // Switches between showing the addresses of each transaction or not. + switchAddressesVisibility() { + this.showAddresses = !this.showAddresses; + } + + // Prepares the arrays which are used to build the filter list. + private prepareWalletsForFiltering() { + this.walletsShowingAllAddresses = []; + this.walletsNotShowingAddresses = []; + + this.wallets.forEach(wallet => { + if (wallet.type === WalletTypes.Deterministic) { + this.walletsShowingAllAddresses.push(wallet); + } else { + this.walletsNotShowingAddresses.push(wallet); + } + }); + + // Save a map with the addresses currently selected as filters. + const selectedAddresses: Map = new Map(); + const selectedfilters: (Wallet|Address)[] = this.form.get('filter').value; + selectedfilters.forEach(currentFilter => { + if ((currentFilter as Address).printableAddress) { + selectedAddresses.set((currentFilter as Address).walletID + '/' + (currentFilter as Address).printableAddress, true); + } + }); + + this.addresses = []; + this.walletsNotShowingAddresses.forEach(wallet => { + wallet.addresses.forEach(address => { + if (selectedAddresses.has(address.walletID + '/' + address.printableAddress)) { + address.walletName = wallet.label; + this.addresses.push(address); + } + }); + }); + } + + /** + * Loads the list of transactions. + * @param delayMs Delay before starting to get the data. + */ + private loadTransactions(delayMs: number) { + this.removeTransactionsSubscription(); + + this.loadingTransactions = true; + + // Limit the transactions per address. + let transactionLimitperAddress: TransactionLimits; + if (this.loadingStep === LoadingSteps.Starting) { + transactionLimitperAddress = TransactionLimits.NormalLimit; + } else if (this.loadingStep === LoadingSteps.FirstGroup) { + transactionLimitperAddress = TransactionLimits.ExtraLimit; + } else { + transactionLimitperAddress = TransactionLimits.MaxAllowed; + } + + this.transactionsSubscription = of(1).pipe(delay(delayMs), mergeMap(() => this.historyService.getTransactionsHistory(null, transactionLimitperAddress))).subscribe(response => { + this.allTransactions = response.transactions; + this.addressesWitMoreTransactions = response.addressesWitAdditionalTransactions; + this.transactionsLoadedForTheFirsTime = true; + this.loadingTransactions = false; + + this.loadingStep += 1; + + // Make the page show the new data. + if (this.loadingStep === LoadingSteps.FirstGroup) { + this.showingStep = ShowingSteps.InitialGroup; + } else if (this.loadingStep === LoadingSteps.SecondGroup) { + this.showingStep = ShowingSteps.ExtraGroup; + } else if (this.loadingStep === LoadingSteps.LastGroup) { + this.showingStep = ShowingSteps.All; + } + + // Filter the transactions. + this.showRequestedFilters(); + this.filterTransactions(); + }, + // If there is an error, retry after a short delay. + () => { + this.loadingTransactions = false; + + this.loadTransactions(this.errorUpdatePeriod); + }, + ); + } + + /** + * Updates the list of transactions that the UI will show. + */ + private filterTransactions() { + const selectedfilters: (Wallet|Address)[] = this.form.get('filter').value; + // Removes the selection status of the wallets and addresses. It is updated below, if needed. + this.wallets.forEach(wallet => { + wallet.allAddressesSelected = false; + wallet.addresses.forEach(address => address.showingWholeWallet = false); + }); + + if (selectedfilters.length === 0) { + // If no filter was selected, show all transactions. + this.transactions = this.allTransactions; + + this.someTransactionsWereIgnored = this.addressesWitMoreTransactions.size > 0; + } else { + this.someTransactionsWereIgnored = false; + + // Save all the allowed addresses. + const selectedAddresses = new AddressMap(this.walletsAndAddressesService.formatAddress); + selectedfilters.forEach(currentFilter => { + if ((currentFilter as Wallet).addresses) { + // Update the selection status when a whole wallet was selected. + (currentFilter as Wallet).addresses.forEach(address => { + selectedAddresses.set(address.printableAddress, true); + address.showingWholeWallet = true; + + if (this.addressesWitMoreTransactions.has(address.printableAddress)) { + this.someTransactionsWereIgnored = true; + } + }); + (currentFilter as Wallet).allAddressesSelected = true; + } else { + selectedAddresses.set((currentFilter as Address).printableAddress, true); + + if (this.addressesWitMoreTransactions.has((currentFilter as Address).printableAddress)) { + this.someTransactionsWereIgnored = true; + } + } + }); + + // Filter the transactions. + this.transactions = this.allTransactions.filter(tx => + tx.inputs.some(input => selectedAddresses.has(input.address)) || tx.outputs.some(output => selectedAddresses.has(output.address)), + ); + } + + let maxElementsToShow: number; + if (this.showingStep === ShowingSteps.InitialGroup) { + maxElementsToShow = this.maxInitialElements; + } else if (this.showingStep === ShowingSteps.ExtraGroup) { + maxElementsToShow = this.maxExtraElements; + } + + // Truncate the list, if needed. + this.totalElements = this.transactions.length; + if (this.showingStep !== ShowingSteps.All && this.totalElements > maxElementsToShow) { + this.transactions = this.transactions.slice(0, maxElementsToShow); + this.viewingTruncatedList = true; + } else { + this.viewingTruncatedList = false; + } + } + + /** + * Makes the page show the filters saved on requestedFilters. Does nothing if the page is + * still loading important data. + */ + private showRequestedFilters() { + if (!this.transactionsLoadedForTheFirsTime || !this.wallets || this.wallets.length === 0 || this.requestedFilters === null || this.requestedFilters === undefined) { + return; + } + + if (this.requestedFilters.length > 0) { + const filters: (Wallet|Address)[] = []; + + // Get the requested wallets and addesses. + this.requestedFilters.forEach(currentFilter => { + // The first 2 characters are for knowing if the filter is a complete wallet or + // an address. + const filterContent = currentFilter.substr(2, currentFilter.length - 2); + this.wallets.forEach(wallet => { + if (currentFilter.startsWith('w-')) { + if (filterContent === wallet.id) { + filters.push(wallet); + } + } else if (currentFilter.startsWith('a-')) { + wallet.addresses.forEach(address => { + if (filterContent === address.printableAddress) { + filters.push(address); + } + }); + } + }); + }); + + this.form.get('filter').setValue(filters); + } else { + this.form.get('filter').setValue([]); + } + + this.requestedFilters = null; + + this.prepareWalletsForFiltering(); + } + + private removeTransactionsSubscription() { + if (this.transactionsSubscription) { + this.transactionsSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/change-name/change-name.component.html b/src/gui/static/src/app/components/pages/wallets/change-name/change-name.component.html new file mode 100644 index 0000000..4e0b73f --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/change-name/change-name.component.html @@ -0,0 +1,42 @@ + + + +
+ {{ 'hardware-wallet.added.characters-warning' | translate }} +
+
+ +
+ + +
+
+ +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'wallet.rename.rename-button' | translate }} + +
+
+ + + +
diff --git a/src/gui/static/src/app/components/pages/wallets/change-name/change-name.component.scss b/src/gui/static/src/app/components/pages/wallets/change-name/change-name.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/pages/wallets/change-name/change-name.component.ts b/src/gui/static/src/app/components/pages/wallets/change-name/change-name.component.ts new file mode 100644 index 0000000..dfaabbe --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/change-name/change-name.component.ts @@ -0,0 +1,226 @@ +import { Component, OnInit, Inject, ViewChild, OnDestroy, ChangeDetectorRef } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; + +import { ButtonComponent } from '../../../layout/button/button.component'; +import { MessageIcons } from '../../../layout/hardware-wallet/hw-message/hw-message.component'; +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { processServiceError } from '../../../../utils/errors'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { SoftwareWalletService } from '../../../../services/wallet-operations/software-wallet.service'; +import { WalletBase } from '../../../../services/wallet-operations/wallet-objects'; +import { HardwareWalletService } from '../../../../services/wallet-operations/hardware-wallet.service'; + +/** + * States in which ChangeNameComponent can be. + */ +enum States { + /** + * Showing the form. + */ + Initial = 'Initial', + /** + * Asking the user to confirm the operation on the hw wallet. + */ + WaitingForConfirmation = 'WaitingForConfirmation', +} + +/** + * Settings for ChangeNameComponent. + */ +export class ChangeNameData { + /** + * Wallet whose label will be changed. + */ + wallet: WalletBase; + /** + * New label. If provided, the form for entering the new label will not be shown and the + * procedure will start immediately. NOTE: only for hw wallets. If the operation fails, the + * error will be returned after closing the modal window. + */ + newName: string; +} + +/** + * Response returned if ChangeNameComponent was opened with the new label included in the + * configuration and the operation failed . + */ +export class ChangeNameErrorResponse { + errorMsg: string; +} + +/** + * Modal window for changing the label of a software or hardware wallet. If the label is changed, + * the modal window is closed and the new label is returned in the "afterClosed" event. If the new + * label is provided in the configuration when opening the window, the form is not shown. In that + * case, if there was a problem changing the label the modal window is closed and a + * ChangeNameErrorResponse instance is returned in the "afterClosed" event + */ +@Component({ + selector: 'app-change-name', + templateUrl: './change-name.component.html', + styleUrls: ['./change-name.component.scss'], +}) +export class ChangeNameComponent implements OnInit, OnDestroy { + // Confirmation button. + @ViewChild('button') button: ButtonComponent; + form: FormGroup; + currentState: States = States.Initial; + states = States; + msgIcons = MessageIcons; + maxHwWalletLabelLength = HwWalletService.maxLabelLength; + // Deactivates the form while the system is busy. + working = false; + + // Vars with the validation error messages. + inputErrorMsg = ''; + + private hwConnectionSubscription: SubscriptionLike; + private operationSubscription: SubscriptionLike; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, data: ChangeNameData, smallSize: boolean): MatDialogRef { + const config = new MatDialogConfig(); + config.data = data; + config.autoFocus = true; + config.width = smallSize ? '400px' : '450px'; + + return dialog.open(ChangeNameComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: ChangeNameData, + private formBuilder: FormBuilder, + private hwWalletService: HwWalletService, + private msgBarService: MsgBarService, + private softwareWalletService: SoftwareWalletService, + private hardwareWalletService: HardwareWalletService, + private changeDetector: ChangeDetectorRef, + ) {} + + ngOnInit() { + if (!this.data.newName) { + // If the configuration did not include the new label, show the form so the user + // can enter it. + this.form = this.formBuilder.group({ + label: [this.data.wallet.label], + }); + + this.form.setValidators(this.validateForm.bind(this)); + } else { + // If the configuration included the new label, start the change immediately. + this.finishRenaming(this.data.newName); + } + + if (this.data.wallet.isHardware) { + this.hwConnectionSubscription = this.hwWalletService.walletConnectedAsyncEvent.subscribe(connected => { + if (!connected) { + this.closePopup(); + } + }); + } + } + + ngOnDestroy() { + this.msgBarService.hide(); + if (this.hwConnectionSubscription) { + this.hwConnectionSubscription.unsubscribe(); + } + if (this.operationSubscription) { + this.operationSubscription.unsubscribe(); + } + } + + closePopup() { + this.dialogRef.close(); + } + + // Changes the label with the data entered on the form. + rename() { + if (!this.form.valid || this.button.isLoading()) { + return; + } + + this.msgBarService.hide(); + this.button.setLoading(); + + this.finishRenaming(this.form.value.label); + + this.changeDetector.detectChanges(); + } + + /** + * Performs the procedure for changing the label. + * @param newLabel New label. + */ + private finishRenaming(newLabel: string) { + this.working = true; + + if (!this.data.wallet.isHardware) { + this.operationSubscription = this.softwareWalletService.renameWallet(this.data.wallet, newLabel) + .subscribe(() => { + this.working = false; + this.dialogRef.close(newLabel); + setTimeout(() => this.msgBarService.showDone('common.changes-made')); + }, e => { + this.working = false; + this.msgBarService.showError(e); + if (this.button) { + this.button.resetState(); + } + }); + } else { + this.currentState = States.WaitingForConfirmation; + + this.operationSubscription = this.hardwareWalletService.changeLabel(this.data.wallet, newLabel).subscribe( + () => { + this.working = false; + this.dialogRef.close(newLabel); + + // Don't show a confirmation msg if the new label was included in the configuration. + if (!this.data.newName) { + setTimeout(() => this.msgBarService.showDone('common.changes-made')); + } + }, + err => { + this.working = false; + if (this.data.newName) { + // Return the error to the caller. + const response = new ChangeNameErrorResponse(); + response.errorMsg = processServiceError(err).translatableErrorMsg; + this.dialogRef.close(response); + } else { + // Show the form again. + this.msgBarService.showError(err); + this.currentState = States.Initial; + if (this.button) { + this.button.resetState(); + } + } + }, + ); + } + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.inputErrorMsg = ''; + + let valid = true; + + if (!this.form.get('label').value) { + valid = false; + if (this.form.get('label').touched) { + this.inputErrorMsg = 'wallet.rename.label-error-info'; + } + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.html b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.html new file mode 100644 index 0000000..167168a --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.html @@ -0,0 +1,20 @@ +
+
+ +
+ touch_app + touch_app + {{ emptyText | translate }} +
+ + {{ lastAssistedSeed }} +
{{ 'wallet.new.seed.change-seed' | translate }}
+ +
+ done {{ confirmedText | translate }} +
+
diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.scss b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.scss new file mode 100644 index 0000000..841aa1f --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.scss @@ -0,0 +1,61 @@ +@import '../../../../../../../theme/_variables.scss'; + +$dashed-border-size: 2px; +$gray-dashed-border: $grey-very-light dashed $dashed-border-size; +$white-dashed-border: rgba(255, 255, 255, 0.25) dashed $dashed-border-size; + +.dashed-border { + border: $gray-dashed-border; +} + +.show-pointer { + cursor: pointer; +} + +.non-editable-field { + text-align: center; + padding: 15px; + border-radius: $input-border-radius; + color: $black; + + .text-with-icon-container { + display: inline-flex; + align-items: center; + + mat-icon { + margin-right: 5px; + opacity: 1; + } + } +} + +.transparent-text { + opacity: 0.75; +} + +.normal-seed-field { + font-size: $font-size-standard-plus; +} + +.onboarding-version { + border: $white-dashed-border; + color: $white; +} + +.seed-spinner { + height: 0px; + position: relative; + top: -12px; + left: -12px; + + mat-spinner { + position: absolute; + height: 10px !important; + width: 10px !important; + + ::ng-deep svg { + height: 10px !important; + width: 10px !important; + } + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.ts b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.ts new file mode 100644 index 0000000..8885ca7 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/assisted-seed-field/assisted-seed-field.component.ts @@ -0,0 +1,128 @@ +import { Component, OnDestroy, Input, Output, EventEmitter } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; + +import { SeedWordDialogComponent, WordAskedReasons } from '../../../../../layout/seed-word-dialog/seed-word-dialog.component'; +import { MsgBarService } from '../../../../../../services/msg-bar.service'; +import { WalletUtilsService } from '../../../../../../services/wallet-operations/wallet-utils.service'; + +/** + * Component for entering a seed with the assisted mode, which uses a modal window for entering + * each word independently. + */ +@Component({ + selector: 'app-assisted-seed-field', + templateUrl: './assisted-seed-field.component.html', + styleUrls: ['./assisted-seed-field.component.scss'], +}) +export class AssistedSeedFieldComponent implements OnDestroy { + // If the control is just for confirming a predefined seed (true) or not. + @Input() showConfirmationOnly: boolean; + // Predefined seed to confirm if showConfirmationOnly is true. + @Input() seedToConfirm: string; + // If the component is being shown on the wizard (true) or not (false). + @Input() onboarding: boolean; + // Allows to deactivate the component while the system is busy. + @Input() busy = false; + // Text to be shown if the user has not entered the seed. + @Input() emptyText = ''; + // Text to be shown if showConfirmationOnly is true and the user already confirmed the seed. + @Input() confirmedText = ''; + // How many words the seed must have. + @Input() howManyWords: number; + // Reason for asking the seed. + @Input() reasonForAsking: WordAskedReasons; + // Event emited when the seed entered by the user changes. + @Output() seedChanged = new EventEmitter(); + + /** + * Last seed entered by the user. + */ + lastAssistedSeed = null; + + // Indicates if the component is checking if the seed is valid before accepting it. + checkingSeed = false; + + // Saves the words the user enters while using the assisted mode. + private partialSeed: string[]; + + constructor( + private walletUtilsService: WalletUtilsService, + private dialog: MatDialog, + private msgBarService: MsgBarService, + ) { } + + ngOnDestroy() { + this.seedChanged.complete(); + } + + // Starts the assisted procedure for entering the seed. + enterSeed() { + // Do not continue if trying to confirm an already confirmed seed. + if (!this.showConfirmationOnly || !this.lastAssistedSeed) { + this.askForWord(0); + this.msgBarService.hide(); + } + } + + /** + * Recursively asks the user to enter the words of the seed. + * @param wordIndex Index of the word which is going to be requested on this step. Must be + * 0 when starting to ask for the words. + */ + private askForWord(wordIndex: number) { + if (wordIndex === 0) { + this.partialSeed = []; + } + + // Open the modal window for entering the seed word. + return SeedWordDialogComponent.openDialog(this.dialog, { + reason: this.reasonForAsking, + wordNumber: wordIndex + 1, + }).afterClosed().subscribe(word => { + if (word) { + // If confirming a seed, check if the user entered the requested word. + if (this.showConfirmationOnly) { + const seedToConfirmWords = this.seedToConfirm.split(' '); + if (word !== seedToConfirmWords[wordIndex]) { + this.msgBarService.showError('wallet.new.seed.incorrect-word-error'); + + return; + } + } + + // Add the entered word to the list of words the user already entered. + this.partialSeed[wordIndex] = word; + wordIndex += 1; + + if (wordIndex < this.howManyWords) { + // Ask for the next word. + this.askForWord(wordIndex); + } else { + // Build the seed. + const enteredSeed = this.partialSeed.join(' '); + + if (this.showConfirmationOnly) { + this.lastAssistedSeed = enteredSeed; + this.seedChanged.emit(); + } else { + // Check the seed and use it only if it is valid. + this.checkingSeed = true; + this.walletUtilsService.verifySeed(enteredSeed).subscribe(valid => { + if (valid) { + this.lastAssistedSeed = enteredSeed; + this.seedChanged.emit(); + } else { + this.msgBarService.showError('wallet.new.seed.invalid-seed-error'); + } + + this.checkingSeed = false; + }, () => { + this.msgBarService.showError('wallet.new.seed.invalid-seed-error'); + this.checkingSeed = false; + }); + } + } + } + }); + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.html b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.html new file mode 100644 index 0000000..51fdd97 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.html @@ -0,0 +1,285 @@ + +
+ +
+ +
+ +
+
+ +
+ {{ 'wallet.new.not-available-warning' | translate }} +
+
+ {{ 'wallet.new.skywallet-only-warning' | translate }} +
+
+ + +
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ + + + +
+
+ {{ lastAutogeneratedSeed }} +
+ + +
+ + edit + {{ 'wallet.new.seed.use-custom' | translate }} + +
+
+ + edit + {{ 'wallet.new.seed.use-custom' | translate }} + +
+
+ + + +
+ +
+ + format_list_numbered + {{ 'wallet.new.seed.use-normal' | translate }} + +
+
+ + format_list_numbered + {{ 'wallet.new.seed.use-normal' | translate }} + +
+
+ +

+ {{ 'wallet.new.seed-warning' | translate}} +

+
+
+ + +
+ + +
+ + + +
+ +
+
+ +
+ + + + +
+ +
+ + +
+
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ error +
+
{{ 'wallet.new.passphrase-warning-title' | translate}}
+
{{ 'wallet.new.passphrase-warning' | translate}}
+ + {{ 'common.generic-confirmation-check' | translate}} + +
+
+
+ +
+
+ + + {{ 'wallet.new.encrypt-check' | translate }} + +
+
+
+

+ + {{ ('wallet.new.encrypt-warning' + (!activateXPubField ? '-non' : '') + '-xpub') | translate }} + +

+
+ +
+
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+ error +
+
{{ 'wallet.new.unconventional-seed-title' | translate}}
+
{{ 'wallet.new.unconventional-seed-text' | translate}}
+ + {{ 'wallet.new.unconventional-seed-check' | translate}} + +
+
diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.scss b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.scss new file mode 100644 index 0000000..b3edad4 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.scss @@ -0,0 +1,108 @@ +@import '../../../../../../theme/_variables.scss'; + +$dashed-border-size: 2px; +$gray-dashed-border: $grey-very-light dashed $dashed-border-size; +$white-dashed-border: rgba(255, 255, 255, 0.25) dashed $dashed-border-size; + +.main-container { + font-size: $font-size-standard-minus; +} + +.dashed-border { + border: $gray-dashed-border; +} + +.non-editable-field { + text-align: center; + padding: 15px; + border-radius: $input-border-radius; + color: $black; +} + +.normal-seed-field { + font-size: $font-size-standard-plus; +} + +.seed-type-button { + text-align: right; + + mat-icon { + position: relative; + top: 1px; + } +} + +.onboarding-version { + border: $white-dashed-border; + color: $white; +} + +.transparent-text { + opacity: 0.75; +} + +.disclaimer-box { + padding: 0 10px; + line-height: 1.5; +} + +.-white-text { + color: $white !important; +} + +label[for=seed] { + display: flex; + + > span:last-child { + flex: 1; + } + + .generators { + text-align: right; + + .divider { + padding: 0 5px; + color: $black; + } + } + + .-white-text { + span { + color: $white !important; + } + } +} + +.-passwords { + margin-left: 24px; + + .-info { + margin: 5px 0 15px; + color: $grey; + line-height: 1.5; + } +} + +.seed-spinner { + height: 0px; + position: relative; + top: 2px; + left: 2px; + + mat-spinner { + position: absolute; + height: 10px !important; + width: 10px !important; + + ::ng-deep svg { + height: 10px !important; + width: 10px !important; + } + } +} + +.centered { + text-align: center; + padding: 0 10px; + line-height: 1.5; +} diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.ts b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.ts new file mode 100644 index 0000000..fa21530 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet-form/create-wallet-form.component.ts @@ -0,0 +1,650 @@ +import { switchMap, delay, flatMap } from 'rxjs/operators'; +import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, ChangeDetectorRef, ViewChild } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { SubscriptionLike, Subject, of } from 'rxjs'; +import { MatDialog } from '@angular/material/dialog'; + +import { WordAskedReasons } from '../../../../layout/seed-word-dialog/seed-word-dialog.component'; +import { MsgBarService } from '../../../../../services/msg-bar.service'; +import { ConfirmationParams, ConfirmationComponent, DefaultConfirmationButtons } from '../../../../layout/confirmation/confirmation.component'; +import { OperationError } from '../../../../../utils/operation-error'; +import { processServiceError } from '../../../../../utils/errors'; +import { WalletTypes } from '../../../../../services/wallet-operations/wallet-objects'; +import { AppConfig } from '../../../../../app.config'; +import { WalletUtilsService } from '../../../../../services/wallet-operations/wallet-utils.service'; +import { CoinService } from '../../../../../services/coin.service'; +import { AssistedSeedFieldComponent } from './assisted-seed-field/assisted-seed-field.component'; + +/** + * Data entered in an instance of CreateWalletFormComponent. + */ +export class WalletFormData { + /** + * If the form is for creating a new wallet (true) or loading a walled using a seed (false). + */ + creatingNewWallet: boolean; + /** + * Label for the wallet. + */ + label: string; + /** + * Wallet type. + */ + type: WalletTypes; + /** + * xPub key entered by the user. + */ + xPub: string; + /** + * Passphrase for the wallet. + */ + passphrase: string; + /** + * If set, the wallet must be encrypted with this password. + */ + password: string; + /** + * If true, the seed was entered using the assisted mode. + */ + enterSeedWithAssistance: boolean; + /** + * Last automatically generated seed. + */ + lastAutogeneratedSeed: string; + /** + * Last seed the user entered using the manual mode. + */ + lastCustomSeed: string; + /** + * Last seed the user entered using the assisted mode. + */ + lastAssistedSeed: string; + /** + * If creating a new wallet, how many words the automatically generated seed for the + * assisted mode has. If loading a wallet, how many words the seed entered by the user has. + */ + numberOfWords: number; + /** + * If the user entered a standard seed, if the manual mode was being used. + */ + customSeedIsNormal: boolean; + /** + * If the advanced options panel was open. + */ + advancedOptionsShown: boolean; +} + +/** + * Form for creating or loading a software wallet. + */ +@Component({ + selector: 'app-create-wallet-form', + templateUrl: './create-wallet-form.component.html', + styleUrls: ['./create-wallet-form.component.scss'], +}) +export class CreateWalletFormComponent implements OnInit, OnDestroy { + // Component for entering the seed using the assisted mode. + @ViewChild('assistedSeed') assistedSeed: AssistedSeedFieldComponent; + + // If the form is for creating a new wallet (true) or loading a walled using a seed (false). + @Input() create: boolean; + // If the form is being shown on the wizard (true) or not (false). + @Input() onboarding: boolean; + // Allows to deactivate the form while the system is busy. + @Input() busy = false; + // Emits when the user asks for the wallet ot be created. + @Output() createRequested = new EventEmitter(); + + form: FormGroup; + // If true, there are many coins to select from. + hasManyCoins: boolean; + // If true, the user must enter the ssed using the asisted mode. + enterSeedWithAssistance = true; + // If the user entered a standard seed using the manual mode. + customSeedIsNormal = true; + // If the user entered a non-standard seed using the manual mode and confirmed to use it. + customSeedAccepted = false; + // If the user selected that the wallet must be created encrypted. + encrypt = true; + // Last automatically generated seed. + lastAutogeneratedSeed = ''; + // How many words the last autogenerated seed for the assisted mode has, when creating + // a new wallet. + numberOfAutogeneratedWords = 0; + // If the system is currently checking the custom seed entered by the user. + checkingCustomSeed = false; + // If the advanced options must be shown on the UI. + showAdvancedOptions = false; + // If the passphrase warning must be shown. + showPassphraseWarning = false; + // If the user entered a passphrase and confirmed the desire to use it. + passphraseWarningAccepted = false; + + // Vars with the wallet types the currently selected coin is compatible with. + hardwareWalletsAllowedForCoin = true; + softwareWalletsAllowedForCoin = true; + legacyAllowedForCoin = true; + bip44AllowedForCoin = true; + xPubAllowedForCoin = true; + // If the wallet type options must be shown in the form. + showWalletTypeOptions = true; + + bip44Enabled = AppConfig.bip44Enabled; + xPubEnabled = AppConfig.xPubEnabled; + + walletTypes = WalletTypes; + wordAskedReasons = WordAskedReasons; + + // Emits every time the seed should be checked again, to know if it is a standard seed. + private seed: Subject = new Subject(); + + private defaultWalletType: WalletTypes = this.create && this.bip44Enabled ? WalletTypes.Bip44 : WalletTypes.Deterministic; + + // Vars with the validation error messages. + labelErrorMsg = ''; + seed1ErrorMsg = ''; + seed2ErrorMsg = ''; + xPubErrorMsg = ''; + password1ErrorMsg = ''; + password2ErrorMsg = ''; + + private coinSubscription: SubscriptionLike; + private seedValiditySubscription: SubscriptionLike; + private formSubscriptions: SubscriptionLike[] = []; + + constructor( + private walletUtilsService: WalletUtilsService, + private dialog: MatDialog, + private msgBarService: MsgBarService, + private changeDetector: ChangeDetectorRef, + coinService: CoinService, + ) { + this.hasManyCoins = coinService.coins.length > 1; + + // Check the wallet types the currently selected coin is compatible with. + this.coinSubscription = coinService.currentCoin.subscribe(currentCoin => { + this.hardwareWalletsAllowedForCoin = !!currentCoin.skywalletCoinType; + this.softwareWalletsAllowedForCoin = currentCoin.coinTypeFeatures.softwareWallets; + + let availableTypes = 0; + this.legacyAllowedForCoin = currentCoin.coinTypeFeatures.legacySoftwareWallets; + availableTypes += currentCoin.coinTypeFeatures.legacySoftwareWallets ? 1 : 0; + this.bip44AllowedForCoin = currentCoin.coinTypeFeatures.bip44SoftwareWallets; + availableTypes += currentCoin.coinTypeFeatures.bip44SoftwareWallets && this.bip44Enabled ? 1 : 0; + this.xPubAllowedForCoin = currentCoin.coinTypeFeatures.xPubSoftwareWallets; + availableTypes += currentCoin.coinTypeFeatures.xPubSoftwareWallets && this.xPubEnabled ? 1 : 0; + + this.showWalletTypeOptions = availableTypes > 1; + + this.updateSoftwareWalletTypes(false, this.create); + }); + } + + ngOnInit() { + if (!this.onboarding) { + this.initForm(); + } else { + this.initForm(false, null); + } + } + + ngOnDestroy() { + this.msgBarService.hide(); + this.coinSubscription.unsubscribe(); + this.seedValiditySubscription.unsubscribe(); + this.removeFormSubscriptions(); + this.createRequested.complete(); + } + + // Allows to know if the form is valid. + get isValid(): boolean { + // Check if the basic part of the form is valid. + if (this.form.valid && (!this.activatePassphraseField || !this.showPassphraseWarning || this.passphraseWarningAccepted)) { + // If the user selected a wallet type which needs a seed. + if (!this.activateXPubField) { + // When entering the seed manually, the system must have finished checking the seed and the + // seed must be normal or the user must confirm the usage of a custom seed. When using the + // assisted mode, the user must enter the seed in the appropriate way. + if (!this.checkingCustomSeed) { + if ((!this.enterSeedWithAssistance && (this.customSeedIsNormal || this.customSeedAccepted)) || + (this.enterSeedWithAssistance && this.assistedSeed.lastAssistedSeed)) { + return true; + } + } + } else { + return true; + } + } + + // If none of the previous alternatives was meet, the form is not valid. + return false; + } + + // Allows to know if the passphrase field must be active. + get activatePassphraseField(): boolean { + // Show it only if the user selected the bip44 type. + if (this.form && this.form.get('type').value === WalletTypes.Bip44) { + return true; + } + + return false; + } + + // Allows to know if the xPub field must be active. + get activateXPubField(): boolean { + // Show it only if the user selected the xPub type. + if (this.form && this.form.get('type').value === WalletTypes.XPub) { + return true; + } + + return false; + } + + // Sets if the user has acepted to use a manually entered non-standard seed. + onCustomSeedAcceptance(event) { + this.customSeedAccepted = event.checked; + } + + // Sets if the user has acepted to use a passphrase. + onPassphraseWarningAcceptance(event) { + this.passphraseWarningAccepted = event.checked; + } + + // Sets the user selection regarding whether the wallet must be encrypted or not. + setEncrypt(event) { + this.encrypt = event.checked; + this.form.updateValueAndValidity(); + } + + // Returns the data entered on the form. + getData(): WalletFormData { + return { + creatingNewWallet: this.create, + type: this.form.value.type, + label: this.form.value.label, + lastAssistedSeed: this.assistedSeed.lastAssistedSeed, + xPub: this.form.value.xpub ? (this.form.value.xpub as string).trim() : this.form.value.xpub, + passphrase: this.form.value.passphrase, + password: !this.onboarding && this.encrypt ? this.form.value.password : null, + enterSeedWithAssistance: this.enterSeedWithAssistance, + lastAutogeneratedSeed: this.lastAutogeneratedSeed, + lastCustomSeed: this.form.value.seed, + numberOfWords: !this.create ? this.form.value.number_of_words : this.numberOfAutogeneratedWords, + customSeedIsNormal: this.customSeedIsNormal, + advancedOptionsShown: this.showAdvancedOptions, + }; + } + + // Switches between the assisted mode and the manual mode for entering the seed. + changeSeedType() { + this.msgBarService.hide(); + + if (!this.enterSeedWithAssistance) { + this.enterSeedWithAssistance = true; + this.removeConfirmations(); + } else { + // Ask for confirmation before making the change. + const confirmationParams: ConfirmationParams = { + text: this.create ? 'wallet.new.seed.custom-seed-warning-text' : 'wallet.new.seed.custom-seed-warning-text-recovering', + headerText: 'common.warning-title', + checkboxText: this.create ? 'common.generic-confirmation-check' : null, + defaultButtons: DefaultConfirmationButtons.ContinueCancel, + redTitle: true, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.enterSeedWithAssistance = false; + this.removeConfirmations(); + } + }); + } + } + + /** + * Updates the value of defaultWalletType, taking into account the wallet types + * compatible with the currently selected coin. After that, the fields in the advanced + * options panel are resetted. + * @param updateDefaultOnly If true, the fields in the advanced options panel + * are not resetted. + * @param creatingWallet If the form is being show for creating a new wallet (true) or + * loading a walled using a seed (false). + */ + private updateSoftwareWalletTypes(updateDefaultOnly: boolean, creatingWallet: boolean) { + if (this.form) { + // find a valid default. + if (this.legacyAllowedForCoin && this.bip44AllowedForCoin) { + this.defaultWalletType = creatingWallet && this.bip44Enabled ? WalletTypes.Bip44 : WalletTypes.Deterministic; + } else { + if (this.bip44AllowedForCoin && this.bip44Enabled) { + this.defaultWalletType = WalletTypes.Bip44; + } else { + this.defaultWalletType = WalletTypes.Deterministic; + } + } + + // Update the form. + if (!updateDefaultOnly) { + this.showAdvancedOptions = true; + this.finishTogglingAdvancedOptions(); + } + } + } + + /** + * Inits or resets the form. + * @param create If the form is for creating a new wallet (true) or loading a walled using + * a seed (false). Use null to avoid changing the value set using the html tag. + * @param data Data to populate the form. + */ + initForm(create: boolean = null, data: WalletFormData = null) { + this.msgBarService.hide(); + + create = create !== null ? create : this.create; + + this.lastAutogeneratedSeed = ''; + this.enterSeedWithAssistance = true; + + this.form = new FormGroup({}); + this.form.addControl('label', new FormControl(data ? data.label : '')); + this.form.addControl('seed', new FormControl(data ? data.lastCustomSeed : '')); + this.form.addControl('confirm_seed', new FormControl(data ? data.lastCustomSeed : '')); + this.form.addControl('xpub', new FormControl(data ? data.xPub : '')); + this.form.addControl('type', new FormControl(data ? data.type : '', [Validators.required])); + this.form.addControl('passphrase', new FormControl(data ? data.passphrase : '')); + this.form.addControl('password', new FormControl()); + this.form.addControl('confirm_password', new FormControl()); + this.form.addControl('number_of_words', new FormControl(!this.create && data && data.numberOfWords ? data.numberOfWords : 12)); + + this.form.setValidators(this.validateForm.bind(this)); + + this.removeConfirmations(false); + + // Create a new random seed. + if (create && !data) { + this.generateSeed(128); + } + + this.showAdvancedOptions = false; + this.showPassphraseWarning = false; + + // Use the provided data. + if (data) { + this.enterSeedWithAssistance = data.enterSeedWithAssistance; + this.assistedSeed.lastAssistedSeed = data.lastAssistedSeed; + this.lastAutogeneratedSeed = data.lastAutogeneratedSeed; + this.customSeedAccepted = true; + this.customSeedIsNormal = data.customSeedIsNormal; + + this.showAdvancedOptions = data.advancedOptionsShown; + this.showPassphraseWarning = create && !!data.passphrase; + this.passphraseWarningAccepted = true; + + if (this.create) { + this.numberOfAutogeneratedWords = data.numberOfWords; + } + } + + this.updateSoftwareWalletTypes(!!data, create); + + this.removeFormSubscriptions(); + + this.formSubscriptions = []; + + // Ensure the UI is updated quickly. + this.formSubscriptions.push( + this.form.get('type').statusChanges.subscribe(() => { + setTimeout(() => { + this.changeDetector.detectChanges(); + }); + }), + ); + + // Check the custom seed and invaidate the custom seed confirmation. + this.formSubscriptions.push( + this.form.get('seed').statusChanges.subscribe(() => { + this.customSeedAccepted = false; + this.seed.next(this.form.get('seed').value); + }), + ); + this.formSubscriptions.push( + this.form.get('confirm_seed').statusChanges.subscribe(() => { + this.customSeedAccepted = false; + this.seed.next(this.form.get('seed').value); + }), + ); + + // Cancel the passphrase confirmation and show the warning if needed. + this.formSubscriptions.push( + this.form.get('passphrase').statusChanges.subscribe(() => { + this.passphraseWarningAccepted = false; + this.showPassphraseWarning = this.create && !!this.form.get('passphrase').value; + }), + ); + this.subscribeToSeedValidation(); + } + + // Generates a new random seed for when creating a new wallet. + generateSeed(entropy: number) { + if (entropy === 128) { + this.numberOfAutogeneratedWords = 12; + } else { + this.numberOfAutogeneratedWords = 24; + } + + this.walletUtilsService.generateSeed(entropy).subscribe(seed => { + this.lastAutogeneratedSeed = seed; + this.form.get('seed').setValue(seed); + this.form.get('seed').markAsTouched(); + this.removeConfirmations(); + }); + } + + // Request the wallet to be created or loaded. + requestCreation() { + this.createRequested.emit(); + } + + // Shows or hides the advanced options. + toggleAdvancedOptions() { + // Ask for confirmation if the user made changes and the panel will be closed. + if (this.showAdvancedOptions && (this.form.get('passphrase').value || this.form.get('type').value !== this.defaultWalletType)) { + const confirmationParams: ConfirmationParams = { + text: 'wallet.new.advanced-options-close-warning', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.finishTogglingAdvancedOptions(); + } + }); + } else { + this.finishTogglingAdvancedOptions(); + } + } + + private finishTogglingAdvancedOptions() { + this.showAdvancedOptions = !this.showAdvancedOptions; + // Reset the values. + this.form.get('passphrase').setValue(''); + this.form.get('type').setValue(this.defaultWalletType); + } + + /** + * Removes the confirmations the user could have made for accepting the seed. + * @param cleanSecondSeedField If true, the second field for manually entering a seed (the + * one used for confirming the seed by entering it again) will be cleaned. + */ + private removeConfirmations(cleanSecondSeedField = true) { + this.customSeedAccepted = false; + if (this.assistedSeed) { + this.assistedSeed.lastAssistedSeed = null; + } + this.passphraseWarningAccepted = false; + if (cleanSecondSeedField) { + this.form.get('confirm_seed').setValue(''); + } + this.form.updateValueAndValidity(); + } + + // Makes the component continually check if the user has manually entered a non-standard seed. + private subscribeToSeedValidation() { + if (this.seedValiditySubscription) { + this.seedValiditySubscription.unsubscribe(); + } + + this.seedValiditySubscription = this.seed.asObservable().pipe(switchMap(seed => { + // Verify the seed if it was entered manually and was confirmed. + if ((!this.seedMatchValidator() || !this.create) && !this.enterSeedWithAssistance && seed.length > 0) { + this.checkingCustomSeed = true; + + return of(0).pipe(delay(500), flatMap(() => this.walletUtilsService.verifySeed(seed))); + } else { + return of(true); + } + })).subscribe(valid => { + this.checkingCustomSeed = false; + this.customSeedIsNormal = valid; + }, (error: OperationError) => { + this.checkingCustomSeed = false; + // If the node said the seed is not standard, ask the user for confirmation before + // allowing to use it. + error = processServiceError(error); + if (error && error.originalError && error.originalError.status === 422) { + this.customSeedIsNormal = false; + } else { + this.customSeedIsNormal = true; + this.msgBarService.showWarning('wallet.new.seed-checking-error'); + } + this.subscribeToSeedValidation(); + }); + } + + private seedsAreEqual(): boolean { + if (this.form && this.form.get('seed') && this.form.get('confirm_seed')) { + return this.form.get('seed').value === this.form.get('confirm_seed').value; + } + + this.customSeedIsNormal = true; + + return false; + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.labelErrorMsg = ''; + this.seed1ErrorMsg = ''; + this.seed2ErrorMsg = ''; + this.xPubErrorMsg = ''; + this.password1ErrorMsg = ''; + this.password2ErrorMsg = ''; + + let valid = true; + + // Check if the currently selected coin is compatible with software wallets. + if (!this.softwareWalletsAllowedForCoin) { + valid = false; + } + + // Validate the label. + if (!this.form.get('label').value) { + valid = false; + if (this.form.get('label').touched) { + this.labelErrorMsg = 'wallet.new.name-error-info'; + } + } + + // Validate custom seeds. + if (!this.enterSeedWithAssistance && !this.activateXPubField) { + let enteredSeeds = true; + if (!this.form.get('seed').value) { + valid = false; + enteredSeeds = false; + this.customSeedIsNormal = true; + if (this.form.get('seed').touched) { + this.seed1ErrorMsg = 'wallet.new.seed-error-info'; + } + } + + if (this.create) { + if (!this.form.get('confirm_seed').value) { + valid = false; + enteredSeeds = false; + this.customSeedIsNormal = true; + if (this.form.get('confirm_seed').touched) { + this.seed2ErrorMsg = 'wallet.new.seed-error-info'; + } + } + + if (enteredSeeds) { + if (!this.seed2ErrorMsg && !this.seedsAreEqual()) { + valid = false; + this.customSeedIsNormal = true; + this.seed2ErrorMsg = 'wallet.new.confirm-seed-error-info'; + } + } + } + } + + // validate the xPub field. + if (this.activateXPubField) { + if (!this.form.get('xpub').value) { + valid = false; + if (this.form.get('xpub').touched) { + this.xPubErrorMsg = 'wallet.new.xpub-error-info'; + } + } + } + + // Validate password. + if (this.encrypt && !this.onboarding) { + let enteredPasswords = true; + + if (!this.form.get('password').value) { + valid = false; + enteredPasswords = false; + if (this.form.get('password').touched) { + this.password1ErrorMsg = 'password.password-error-info'; + } + } + + if (!this.form.get('confirm_password').value) { + valid = false; + enteredPasswords = false; + if (this.form.get('confirm_password').touched) { + this.password2ErrorMsg = 'password.password-error-info'; + } + } + + if (enteredPasswords) { + if (!this.password2ErrorMsg && this.form.get('password').value !== this.form.get('confirm_password').value) { + valid = false; + this.password2ErrorMsg = 'password.confirm-error-info'; + } + } + } + + return valid ? null : { Invalid: true }; + } + + // Validator that checks if the manually entered seeds match, if the assisted mode is + // not activated and the selected wallet type is not xPub. + private seedMatchValidator() { + if (this.enterSeedWithAssistance || this.activateXPubField) { + return null; + } + + if (this.form && this.form.get('seed') && this.form.get('confirm_seed')) { + return this.form.get('seed').value === this.form.get('confirm_seed').value ? null : { NotEqual: true }; + } else { + return { NotEqual: true }; + } + } + + private removeFormSubscriptions() { + this.formSubscriptions.forEach(s => s.unsubscribe()); + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet.component.html b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet.component.html new file mode 100644 index 0000000..f99cc13 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet.component.html @@ -0,0 +1,19 @@ + + + + +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'common.' + (data.create ? 'create' : 'load') + '-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet.component.scss b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet.component.ts b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet.component.ts new file mode 100644 index 0000000..458e426 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/create-wallet/create-wallet.component.ts @@ -0,0 +1,160 @@ +import { Component, Inject, ViewChild, OnDestroy, ChangeDetectorRef } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; + +import { ButtonComponent } from '../../../layout/button/button.component'; +import { CreateWalletFormComponent } from './create-wallet-form/create-wallet-form.component'; +import { BlockchainService } from '../../../../services/blockchain.service'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { AppConfig } from '../../../../app.config'; +import { ConfirmationParams, ConfirmationComponent, DefaultConfirmationButtons } from '../../../layout/confirmation/confirmation.component'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; +import { WalletTypes } from '../../../../services/wallet-operations/wallet-objects'; +import { CreateWalletArgs } from '../../../../services/coin-specific/wallets-and-addresses-operator'; + +/** + * Settings for CreateWalletComponent. + */ +export class CreateWalletParams { + /** + * If the modal window is for creating a new wallet (true) or for loading a wallet + * using a seed (false). + */ + create: boolean; +} + +/** + * Modal window for creating a new software wallet or loading a software wallet using a seed. + */ +@Component({ + selector: 'app-create-wallet', + templateUrl: './create-wallet.component.html', + styleUrls: ['./create-wallet.component.scss'], +}) +export class CreateWalletComponent implements OnDestroy { + @ViewChild('formControl') formControl: CreateWalletFormComponent; + @ViewChild('createButton') createButton: ButtonComponent; + @ViewChild('cancelButton') cancelButton: ButtonComponent; + + // If the normal ways for closing the modal window must be deactivated. + disableDismiss = false; + // Deactivates the form while the system is busy. + busy = false; + + // If the blockchain is synchronized. + private synchronized = true; + private blockchainSubscription: SubscriptionLike; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, params: CreateWalletParams): MatDialogRef { + const config = new MatDialogConfig(); + config.data = params; + config.autoFocus = true; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(CreateWalletComponent, config); + } + + constructor( + @Inject(MAT_DIALOG_DATA) public data, + public dialogRef: MatDialogRef, + private dialog: MatDialog, + private msgBarService: MsgBarService, + private walletsAndAddressesService: WalletsAndAddressesService, + private changeDetector: ChangeDetectorRef, + blockchainService: BlockchainService, + ) { + this.blockchainSubscription = blockchainService.progress.subscribe(response => this.synchronized = response.synchronized); + } + + ngOnDestroy() { + this.blockchainSubscription.unsubscribe(); + this.msgBarService.hide(); + } + + closePopup() { + this.dialogRef.close(); + } + + // Checks if the blockchain is synchronized before creating the wallet. If it is synchronized, + // it continues creating the wallet, if not, the user must confirm the operation first. + checkAndCreateWallet() { + if (!this.formControl.isValid || this.busy) { + return; + } + + this.msgBarService.hide(); + + if (this.data.create && this.formControl.getData().type !== WalletTypes.XPub) { + const confirmationParams: ConfirmationParams = { + headerText: 'wizard.confirm.title', + redTitle: true, + text: 'wizard.confirm.desc', + checkboxText: 'wizard.confirm.checkbox', + confirmButtonText: 'common.continue-button', + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.continueCreating(); + } + }); + } else if (this.data.create || this.synchronized) { + this.continueCreating(); + } else { + const confirmationParams: ConfirmationParams = { + headerText: 'common.warning-title', + text: 'wallet.new.synchronizing-warning-text', + defaultButtons: DefaultConfirmationButtons.ContinueCancel, + redTitle: true, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.continueCreating(); + } + }); + } + + this.changeDetector.detectChanges(); + } + + // Creates the wallet with the data entered on the form. + private continueCreating() { + this.busy = true; + const data = this.formControl.getData(); + + this.createButton.resetState(); + this.createButton.setLoading(); + this.cancelButton.setDisabled(); + this.disableDismiss = true; + + const args: CreateWalletArgs = { + isHardwareWallet: false, + softwareWalletArgs: { + label: data.label, + type: data.type, + seed: data.enterSeedWithAssistance ? data.lastAssistedSeed : data.lastCustomSeed, + password: data.password, + passphrase: data.passphrase, + xPub: data.xPub, + }, + }; + + this.walletsAndAddressesService.createWallet(args) + .subscribe(() => { + this.busy = false; + setTimeout(() => this.msgBarService.showDone('wallet.new.wallet-created')); + this.dialogRef.close(); + }, e => { + this.busy = false; + this.msgBarService.showError(e); + this.createButton.resetState(); + this.cancelButton.setEnabled(); + this.disableDismiss = false; + }); + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/number-of-addresses/number-of-addresses.html b/src/gui/static/src/app/components/pages/wallets/number-of-addresses/number-of-addresses.html new file mode 100644 index 0000000..2692744 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/number-of-addresses/number-of-addresses.html @@ -0,0 +1,27 @@ + + +
+
+ + +
+
+ +
+ + {{ 'common.cancel-button' | translate }} + + + {{ 'common.create-button' | translate }} + +
+
diff --git a/src/gui/static/src/app/components/pages/wallets/number-of-addresses/number-of-addresses.scss b/src/gui/static/src/app/components/pages/wallets/number-of-addresses/number-of-addresses.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/app/components/pages/wallets/number-of-addresses/number-of-addresses.ts b/src/gui/static/src/app/components/pages/wallets/number-of-addresses/number-of-addresses.ts new file mode 100644 index 0000000..a89e19d --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/number-of-addresses/number-of-addresses.ts @@ -0,0 +1,70 @@ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormControl } from '@angular/forms'; +import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog'; + +/** + * Modal window for entering how many addresses to add to a wallet. It does not add the + * addresses. If the user does not cancel the operation, the modal window is closed and + * number of addresses is returned in the "afterClosed" event. + */ +@Component({ + selector: 'app-number-of-addresses', + templateUrl: './number-of-addresses.html', + styleUrls: ['./number-of-addresses.scss'], +}) +export class NumberOfAddressesComponent implements OnInit { + form: FormGroup; + + // Vars with the validation error messages. + inputErrorMsg = ''; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = true; + config.width = '450px'; + + return dialog.open(NumberOfAddressesComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + ) {} + + ngOnInit() { + this.form = new FormGroup({}); + this.form.addControl('quantity', new FormControl(1)); + + this.form.setValidators(this.validateForm.bind(this)); + } + + closePopup() { + this.dialogRef.close(); + } + + continue() { + this.dialogRef.close(this.form.value.quantity); + } + + /** + * Validates the form and updates the vars with the validation errors. + */ + validateForm() { + this.inputErrorMsg = ''; + + let valid = true; + + // The number must be an integer from 1 to 100. + const value = this.form.get('quantity').value as number; + if (!value || value < 1 || value > 100 || value !== Math.round(value)) { + valid = false; + if (this.form.get('quantity').touched) { + this.inputErrorMsg = 'wallet.add-addresses.quantity-error-info'; + } + } + + return valid ? null : { Invalid: true }; + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.html b/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.html new file mode 100644 index 0000000..34cc388 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.html @@ -0,0 +1,81 @@ + +
+
+ + {{ 'wallet.' + (hideEmpty ? 'show' : 'hide') + '-empty-button' | translate }} + +
+
+
+ + {{ 'wallet.wallet-options.title' | translate }} + +
+
+ + + +
+ +
{{ i + 1 }}
+ +
+ + + +

+ {{ address.printableAddress }} + + + {{ 'wallet.address.copy' | translate }} + +

+
+ + +

+ {{ address.printableAddress }} + + {{ 'wallet.address.show' | translate }} + + +

+
+
+ +
+ {{ (address.coins ? address.coins : 0) | amount:true:'first' }} + warning +
+
+ {{ (address.hours ? address.hours : 0) | amount:false:'first' }} + warning +
+ +
+ more_vert + + + + + + +
+
+
diff --git a/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.scss b/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.scss new file mode 100644 index 0000000..81873ca --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.scss @@ -0,0 +1,183 @@ +@import '../../../../../theme/variables'; + +.-record { + display: flex; + font-size: $font-size-standard; + padding: 21px 0 16px $main-containers-small-padding; + align-items: center; + color: $black; + + &:not(:last-of-type) { + border-bottom: 1px solid $grey-very-light; + } + + .address-column { + color: $grey; + display: flex; + align-items: center; + + app-qr-code-button { + margin-right: 10px; + } + + p { + margin: 0; + word-break: break-all; + + &:hover .copy-label { + opacity: .999 !important; + } + } + } + + .small-preview { + max-width: 60px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + display: inline-block; + vertical-align: middle; + } + + .options-column { + display: flex; + justify-content: flex-end; + flex-shrink: 0; + padding-right: $main-containers-small-padding !important; + + mat-icon { + cursor: pointer; + color: lighten($grey, 30%); + } + } +} + +.-actions { + background-color: $white; + display: flex; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.03) !important; + z-index: 100; + + .-button { + padding-right: 20px; + padding-left: 0px; + cursor: pointer; + + &:first-child { + padding-left: 5px; + } + + span { + color: lighten($color: $grey, $amount: 40%); + font-size: $font-size-standard-minus; + height: 60px; + margin: 0 5px; + display: flex; + align-items: center; + + &.-img::before { + content: ''; + height: $normal-icon-size; + width: $normal-icon-size; + margin-right: 5px; + background-repeat: no-repeat; + background-size: $normal-icon-size $normal-icon-size; + } + + &.-options::before { + background-image: url('/assets/img/list-grey.png'); + } + + &.-hide-empty::before { + background-image: url('/assets/img/minus-grey.png'); + } + + &.-show-empty::before { + background-image: url('/assets/img/plus-grey.png'); + } + + &:active { + opacity: 1; + } + } + + &:hover { + span { + color: $grey; + opacity: 0.8; + + &.-options::before { + background-image: url('/assets/img/list-blue.png'); + } + + &.-hide-empty::before { + background-image: url('/assets/img/minus-red.png'); + } + + &.-show-empty::before { + background-image: url('/assets/img/plus-green.png'); + } + } + } + } +} + +@keyframes floatup { + 50% { + opacity: 1; + } + + 100% { + transform: translateY(-20px); + opacity: 0; + } +} + +.copy-label { + opacity: 0; + font-size: $font-size-standard-minus; + position: relative; + padding-left: 10px; + + &::after { + content: attr(data-label); + position: absolute; + white-space: nowrap; + top: 0; + left: 4px; + opacity: 0; + line-height: 1; + } +} + +.unconfirmed-label { + opacity: 0.5 !important; +} + +.copying .copy-label::after { + animation: floatup .5s ease-in-out; +} + +.mat-menu-item { + font-size: $font-size-standard; + height: 35px; + line-height: 35px; +} + +.click-to-copy { + cursor: pointer; + + mat-spinner { + display: inline-block; + height: 12px !important; + width: 12px !important; + margin-left: 7px !important; + position: relative; + top: 2px; + + ::ng-deep svg { + height: 12px !important; + width: 12px !important; + } + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.ts b/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.ts new file mode 100644 index 0000000..6cc34b1 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallet-detail/wallet-detail.component.ts @@ -0,0 +1,138 @@ +import { Component, Input, OnDestroy } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; + +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { copyTextToClipboard } from '../../../../utils/general-utils'; +import { HwConfirmAddressDialogComponent, AddressConfirmationParams } from '../../../layout/hardware-wallet/hw-confirm-address-dialog/hw-confirm-address-dialog.component'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { WalletWithBalance, AddressWithBalance, AddressMap } from '../../../../services/wallet-operations/wallet-objects'; +import { WalletsComponent } from '../wallets.component'; +import { WalletOptionsComponent } from '../wallet-options/wallet-options.component'; +import { CoinService } from '../../../../services/coin.service'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; + +/** + * Shows the option buttons and address list of a wallet on the wallet list. + */ +@Component({ + selector: 'app-wallet-detail', + templateUrl: './wallet-detail.component.html', + styleUrls: ['./wallet-detail.component.scss'], +}) +export class WalletDetailComponent implements OnDestroy { + @Input() wallet: WalletWithBalance; + + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + // Index of the address currently being confirmed. Used for showing the loading animation + // on the UI. + confirmingIndex = null; + // If all addresses without coins must be hidden on the address list. + hideEmpty = false; + // Allows to know which addresses are being copied, so the UI can show an indication. + copying = new AddressMap(this.walletsAndAddressesService.formatAddress); + + // Vars for showing only the options available for the current coin. + showOutputsOption: boolean; + + private confirmSubscription: SubscriptionLike; + + constructor( + private dialog: MatDialog, + private msgBarService: MsgBarService, + private hwWalletService: HwWalletService, + private walletsAndAddressesService: WalletsAndAddressesService, + coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.showOutputsOption = coinService.currentCoinInmediate.coinTypeFeatures.outputs; + } + + ngOnDestroy() { + this.msgBarService.hide(); + if (this.confirmSubscription) { + this.confirmSubscription.unsubscribe(); + } + } + + // Opens wallet options modal window. + openWalletOptions() { + if (WalletsComponent.busy) { + this.msgBarService.showError('wallet.busy-error'); + + return; + } + + WalletOptionsComponent.openDialog(this.dialog, {wallet: this.wallet}); + } + + // Switches between showing and hiding the addresses without balance. + toggleEmpty() { + this.hideEmpty = !this.hideEmpty; + } + + /** + * Shows a modal window for the user to confirm if the address shown on the UI is equal to + * the one stored on the device. + * @param wallet Wallet with the address toc be confirmed. + * @param addressIndex Index of the address on the wallet. + * @param showCompleteConfirmation Must be true if the address has not been donfirmed yet, to + * show a longer success message after the user confirms the address. + */ + confirmAddress(wallet: WalletWithBalance, addressIndex: number, showCompleteConfirmation: boolean) { + if (this.confirmingIndex !== null) { + return; + } + + if (WalletsComponent.busy) { + this.msgBarService.showError('wallet.busy-error'); + + return; + } + + WalletsComponent.busy = true; + this.confirmingIndex = addressIndex; + this.msgBarService.hide(); + + if (this.confirmSubscription) { + this.confirmSubscription.unsubscribe(); + } + + // Check if the correct device is connected. + this.confirmSubscription = this.hwWalletService.checkIfCorrectHwConnected(this.wallet).subscribe(() => { + const data = new AddressConfirmationParams(); + data.wallet = wallet; + data.addressIndex = addressIndex; + data.showCompleteConfirmation = showCompleteConfirmation; + + HwConfirmAddressDialogComponent.openDialog(this.dialog, data); + + WalletsComponent.busy = false; + this.confirmingIndex = null; + }, err => { + this.msgBarService.showError(err); + WalletsComponent.busy = false; + this.confirmingIndex = null; + }); + } + + // Copies an address to the clipboard and shows it as being copied for the time set on + // the "duration" param. + copyAddress(event, address: AddressWithBalance, duration = 500) { + event.stopPropagation(); + + if (this.copying.has(address.printableAddress)) { + return; + } + + copyTextToClipboard(address.printableAddress); + this.copying.set(address.printableAddress, true); + + setTimeout(() => { + if (this.copying.has(address.printableAddress)) { + this.copying.delete(address.printableAddress); + } + }, duration); + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.html b/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.html new file mode 100644 index 0000000..f256063 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.html @@ -0,0 +1,64 @@ + + + +
+ + + + + + + + + + + + + + +
+
diff --git a/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.scss b/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.scss new file mode 100644 index 0000000..96ebd45 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.scss @@ -0,0 +1,18 @@ +@import '../../../../../theme/variables'; + +.content { + display: flex; + align-items: center; + + img { + height: $normal-icon-size; + width: $normal-icon-size; + margin-right: 5px; + } + + span { + font-size: $font-size-standard; + line-height: 1.7; + color: $black; + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.ts b/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.ts new file mode 100644 index 0000000..519e4a5 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallet-options/wallet-options.component.ts @@ -0,0 +1,452 @@ +import { Component, Inject, OnDestroy } from '@angular/core'; +import { MatDialogRef, MatDialog, MatDialogConfig, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { TranslateService } from '@ngx-translate/core'; +import { Router } from '@angular/router'; +import { Subscription, Observable } from 'rxjs'; +import { mergeMap, first } from 'rxjs/operators'; + +import { AppConfig } from '../../../../app.config'; +import { WalletTypes, WalletBase, AddressBase } from '../../../../services/wallet-operations/wallet-objects'; +import { ChangeNameData, ChangeNameComponent } from '../change-name/change-name.component'; +import { MsgBarService } from '../../../../services/msg-bar.service'; +import { HwWalletService } from '../../../../services/hw-wallet.service'; +import { SoftwareWalletService } from '../../../../services/wallet-operations/software-wallet.service'; +import { HardwareWalletService } from '../../../../services/wallet-operations/hardware-wallet.service'; +import { ConfirmationParams, DefaultConfirmationButtons, ConfirmationComponent } from '../../../../components/layout/confirmation/confirmation.component'; +import { NumberOfAddressesComponent } from '../number-of-addresses/number-of-addresses'; +import { HistoryService } from '../../../../services/wallet-operations/history.service'; +import { PasswordDialogComponent, PasswordDialogParams, PasswordSubmitEvent } from '../../../../components/layout/password-dialog/password-dialog.component'; +import { WalletsAndAddressesService } from '../../../../services/wallet-operations/wallets-and-addresses.service'; +import { BlockchainService } from '../../../../services/blockchain.service'; + +/** + * Settings for WalletOptionsComponent. + */ +export interface WalletOptionsParams { + /** + * Wallet for which the options will be shown. + */ + wallet: WalletBase; + /** + * If true, the options list will not be shown and the modal window will just start the + * process for adding addresses to the wallet. + */ + automaticallyAddAddresses?: boolean; +} + +/** + * Modal window for the wallet options. If the user selects an option, the modal window makes + * the operation. + */ +@Component({ + selector: 'app-wallet-options', + templateUrl: './wallet-options.component.html', + styleUrls: ['./wallet-options.component.scss'], +}) +export class WalletOptionsComponent implements OnDestroy { + walletTypes = WalletTypes; + + loading = false; + wallet: WalletBase; + + // If the blockchain is synchronized. + private synchronized = true; + private operationSubscription: Subscription; + private blockchainSubscription: Subscription; + + /** + * Opens the modal window. Please use this function instead of opening the window "by hand". + */ + public static openDialog(dialog: MatDialog, wallet: WalletOptionsParams): MatDialogRef { + const config = new MatDialogConfig(); + config.autoFocus = false; + config.data = wallet; + config.width = AppConfig.mediumModalWidth; + + return dialog.open(WalletOptionsComponent, config); + } + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: WalletOptionsParams, + private dialog: MatDialog, + private translateService: TranslateService, + private router: Router, + private msgBarService: MsgBarService, + private hwWalletService: HwWalletService, + private softwareWalletService: SoftwareWalletService, + private hardwareWalletService: HardwareWalletService, + private historyService: HistoryService, + private walletsAndAddressesService: WalletsAndAddressesService, + blockchainService: BlockchainService, + ) { + this.wallet = data.wallet; + this.blockchainSubscription = blockchainService.progress.subscribe(response => this.synchronized = response.synchronized); + + if (data.automaticallyAddAddresses) { + this.loading = true; + // Small delay for better UX. + setTimeout(() => this.addAddresses(), 300); + } + } + + ngOnDestroy() { + this.removeOperationSubscription(); + this.blockchainSubscription.unsubscribe(); + } + + closePopup() { + this.dialogRef.close(); + } + + // Opens the address history page. + showAddressHistory() { + this.router.navigate(['/addresses', { id: this.wallet.id }]); + this.closePopup(); + } + + // Checks the wallet before opening the modal window for changing its label. + renameWallet() { + this.msgBarService.hide(); + + if (this.wallet.isHardware) { + this.loading = true; + + this.removeOperationSubscription(); + // Check if the correct device is connected. + this.operationSubscription = this.hwWalletService.checkIfCorrectHwConnected(this.wallet) + // Check if the device still has the label this app knows. + .pipe(mergeMap(() => this.hardwareWalletService.getFeaturesAndUpdateData(this.wallet))).subscribe( + response => { + this.loading = false; + + this.continueRenameWallet(); + + // Inform if a different label was detected while checking the device. + if (response.walletNameUpdated) { + setTimeout(() => this.msgBarService.showWarning('hardware-wallet.general.name-updated')); + } + }, + err => { + this.loading = false; + this.msgBarService.showError(err); + }, + ); + } else { + // No checks needed for software wallets. + this.continueRenameWallet(); + } + } + + // Adds addresses to the wallet. If the wallet is a software wallet, the user can select + // how many addresses to add. + addAddresses() { + // Don't allow more than the max number of addresses on a hw wallet. + if (this.wallet.isHardware && this.wallet.addresses.length >= AppConfig.maxHardwareWalletAddresses) { + const confirmationParams: ConfirmationParams = { + text: 'wallet.max-hardware-wallets-error', + headerText: 'common.error', + defaultButtons: DefaultConfirmationButtons.Close, + }; + ConfirmationComponent.openDialog(this.dialog, confirmationParams); + + return; + } + + this.msgBarService.hide(); + + if (!this.wallet.isHardware) { + // Open the modal window for knowing how many addresses to add. + const numberOfAddressesDialog = NumberOfAddressesComponent.openDialog(this.dialog); + + const maxAddressesGap = AppConfig.maxAddressesGap; + // When the user requests the creation of the addresses, check if there will be a big + // gap of unused addresses, before completing the operation. + numberOfAddressesDialog.afterClosed().subscribe(howManyAddresses => { + if (!howManyAddresses) { + if (!this.data.automaticallyAddAddresses) { + this.loading = false; + this.msgBarService.showError('wallet.wallet-options.cancelled-error'); + } else { + this.closePopup(); + } + + return; + } + + this.loading = true; + + // Create an array excluding change addresses. + const relevantAddresses: AddressBase[] = []; + this.wallet.addresses.forEach(address => { + if (!address.isChangeAddress) { + relevantAddresses.push(address); + } + }); + + let lastWithBalance = 0; + relevantAddresses.forEach((address, i) => { + if (address['coins'] && address['coins'].isGreaterThan(0)) { + lastWithBalance = i; + } + }); + + // Try to use the current known balance (if the provided wallet object has that info) to + // check if the new addresses will create a gap of unused addresses bigger than the + // aceptable one. This is just a quick check which is fast but could fail, as the code + // must detect a gap of unused addresses, not one of addresses without balance. + if ((relevantAddresses.length - (lastWithBalance + 1)) + howManyAddresses < maxAddressesGap) { + this.continueNewAddress(howManyAddresses); + + // If the previous check failed, use the real transaction history to be sure. + } else { + this.removeOperationSubscription(); + // Check which addresses have been used. + this.operationSubscription = this.historyService.getIfAddressesUsed(this.wallet).subscribe(AddressesWithTxs => { + // Get the index of the last address with transaction history. + let lastWithTxs = 0; + relevantAddresses.forEach((address, i) => { + if (AddressesWithTxs.has(address.printableAddress) && AddressesWithTxs.get(address.printableAddress)) { + lastWithTxs = i; + } + }); + + if ((relevantAddresses.length - (lastWithTxs + 1)) + howManyAddresses < maxAddressesGap) { + // Continue normally. + this.continueNewAddress(howManyAddresses); + } else { + // Tell the user that the gap could cause problems and ask for confirmation. + const confirmationParams: ConfirmationParams = { + text: 'wallet.add-many-confirmation', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.continueNewAddress(howManyAddresses); + } else { + if (!this.data.automaticallyAddAddresses) { + this.loading = false; + this.msgBarService.showError('wallet.wallet-options.cancelled-error'); + } else { + this.closePopup(); + } + } + }); + } + }, err => { + if (!this.data.automaticallyAddAddresses) { + this.loading = false; + } else { + this.closePopup(); + } + + setTimeout(() => this.msgBarService.showError(err)); + }); + } + }); + } else { + // Hw wallets are limited to add one address at a time, for performance reasons. + this.loading = true; + this.continueNewAddress(1); + } + } + + // If the wallet is not encrypted, encrypts it. If the wallet is encrypted, removes + // the encryption. + toggleEncryption() { + this.msgBarService.hide(); + + const params: PasswordDialogParams = { + confirm: !this.wallet.encrypted, + title: this.wallet.encrypted ? 'wallet.wallet-options.decrypt' : 'wallet.wallet-options.encrypt', + warning: this.wallet.encrypted, + wallet: this.wallet.encrypted ? this.wallet : null, + }; + + if (this.wallet.encrypted) { + params.description = 'wallet.wallet-options.decrypt-warning'; + } else { + params.description = 'wallet.new.encrypt-warning' + (this.wallet.walletType !== WalletTypes.XPub ? '-non' : '') + '-xpub'; + } + + // Ask for the current password or the new one. + const dialogRef = PasswordDialogComponent.openDialog(this.dialog, params, false); + dialogRef.componentInstance.passwordSubmit.subscribe(passwordDialog => { + // Make the operation. + this.removeOperationSubscription(); + this.operationSubscription = this.softwareWalletService.toggleEncryption(this.wallet, passwordDialog.password).subscribe(() => { + passwordDialog.close(); + setTimeout(() => this.msgBarService.showDone('common.changes-made')); + }, e => passwordDialog.error(e)); + }); + } + + // Makes the preparations for asking the node to scan the addresses of the wallet again, + // to add to it the addresses with transactions which have not been added to the addresses + // list. Only for software wallets. + scanAddresses() { + this.msgBarService.hide(); + + // Check if the blockchain is synchronized. + if (this.synchronized) { + // Ask for the password if the wallet is encrypted and continue the process. + if (!this.wallet.isHardware && this.wallet.encrypted) { + const dialogRef = PasswordDialogComponent.openDialog(this.dialog, { wallet: this.wallet }); + dialogRef.componentInstance.passwordSubmit.subscribe(passwordDialog => this.continueScanningAddresses(passwordDialog)); + } else { + this.continueScanningAddresses(); + } + } else { + const confirmationParams: ConfirmationParams = { + headerText: 'common.warning-title', + text: 'wallet.scan-addresses.synchronizing-warning-text', + defaultButtons: DefaultConfirmationButtons.YesNo, + redTitle: true, + }; + + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + // Ask for the password if the wallet is encrypted and continue the process. + if (!this.wallet.isHardware && this.wallet.encrypted) { + const dialogRef = PasswordDialogComponent.openDialog(this.dialog, { wallet: this.wallet }); + dialogRef.componentInstance.passwordSubmit.subscribe(passwordDialog => this.continueScanningAddresses(passwordDialog)); + } else { + this.continueScanningAddresses(); + } + } + }); + } + } + + // Deletes a hw wallet. + deleteHwWallet() { + this.msgBarService.hide(); + + const confirmationParams: ConfirmationParams = { + text: this.translateService.instant('wallet.delete-confirmation', {name: this.wallet.label}), + checkboxText: 'wallet.delete-confirmation-check', + defaultButtons: DefaultConfirmationButtons.YesNo, + }; + + // Ask for confirmation. + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + this.closePopup(); + this.walletsAndAddressesService.deleteWallet(this.wallet.id); + setTimeout(() => this.msgBarService.showDone('common.changes-made')); + + // If there are no more wallets left, go to the wizard. + this.walletsAndAddressesService.allWallets.pipe(first()).subscribe(wallets => { + if (wallets.length === 0) { + setTimeout(() => this.router.navigate(['/wizard']), 500); + } + }); + } + }); + } + + // Asks the node to scan the addresses of the wallet again. + private continueScanningAddresses(passwordSubmitEvent?: PasswordSubmitEvent) { + const password = passwordSubmitEvent ? passwordSubmitEvent.password : null; + + // If the password modal window is being shown. the loading animation is not needed on this + // modal window. + if (!passwordSubmitEvent) { + this.loading = true; + } + + this.removeOperationSubscription(); + this.operationSubscription = this.walletsAndAddressesService.scanAddresses(this.wallet, password).subscribe(result => { + if (passwordSubmitEvent) { + passwordSubmitEvent.close(); + } + + setTimeout(() => { + if (result) { + this.msgBarService.showDone('wallet.scan-addresses.done-with-new-addresses'); + } else { + this.msgBarService.showWarning('wallet.scan-addresses.done-without-new-addresses'); + } + }); + + this.loading = false; + }, err => { + if (passwordSubmitEvent) { + passwordSubmitEvent.error(err); + } else { + this.msgBarService.showError(err); + this.loading = false; + } + }); + } + + // Opens the modal window for renaming the wallet. + private continueRenameWallet() { + const data = new ChangeNameData(); + data.wallet = this.wallet; + ChangeNameComponent.openDialog(this.dialog, data, false); + } + + // Finish adding addresses to the wallet. + private continueNewAddress(howManyAddresses: number) { + if (!this.wallet.isHardware && this.wallet.encrypted) { + // Small delay to avoid a negative impact on the UX. + setTimeout(() => { + // Ask for the password and continue. + const dialogRef = PasswordDialogComponent.openDialog(this.dialog, { wallet: this.wallet }); + dialogRef.afterClosed().subscribe(() => { + // If loading is still true, it means the user closed the password window. + if (this.loading) { + if (!this.data.automaticallyAddAddresses) { + this.loading = false; + this.msgBarService.showError('wallet.wallet-options.cancelled-error'); + } else { + this.closePopup(); + } + } + }); + dialogRef.componentInstance.passwordSubmit.subscribe(passwordDialog => { + this.removeOperationSubscription(); + this.operationSubscription = this.walletsAndAddressesService.addAddressesToWallet(this.wallet, howManyAddresses, passwordDialog.password).subscribe(() => { + this.loading = false; + passwordDialog.close(); + this.closePopup(); + setTimeout(() => this.msgBarService.showDone('common.changes-made')); + }, error => passwordDialog.error(error)); + }); + }, 300); + } else { + let procedure: Observable; + + if (this.wallet.isHardware) { + // Continue after checking the device. + procedure = this.hwWalletService.checkIfCorrectHwConnected(this.wallet).pipe(mergeMap( + () => this.walletsAndAddressesService.addAddressesToWallet(this.wallet, howManyAddresses), + )); + } else { + procedure = this.walletsAndAddressesService.addAddressesToWallet(this.wallet, howManyAddresses); + } + + this.removeOperationSubscription(); + this.operationSubscription = procedure.subscribe(() => { + this.closePopup(); + setTimeout(() => this.msgBarService.showDone('common.changes-made')); + }, err => { + if (!this.data.automaticallyAddAddresses) { + this.loading = false; + } else { + this.closePopup(); + } + + setTimeout(() => this.msgBarService.showError(err)); + }); + } + } + + private removeOperationSubscription() { + if (this.operationSubscription) { + this.operationSubscription.unsubscribe(); + } + } +} diff --git a/src/gui/static/src/app/components/pages/wallets/wallets.component.html b/src/gui/static/src/app/components/pages/wallets/wallets.component.html new file mode 100644 index 0000000..7b61b34 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallets.component.html @@ -0,0 +1,97 @@ +
+ + +
+ + +
+ + +
+
{{ (i === 0 ? 'wallet.hardware-wallet-table-label' : 'wallet.wallet-table-label') | translate }}
+
+
{{ 'coinSymbol' | commonText }}
+
{{ 'hours' | commonText }}
+
+
+ + +
+
+
+ +
+
{{ wallet.label }}
+ +
+ + {{ 'wallet.legacy-small-label' | translate }} + help + +
+ +
+ + {{ 'wallet.xpub-small-label' | translate }} + help + +
+
+ +
+
+
+
+
+ +
+ {{ (wallet.coins ? wallet.coins : 0) | amount:true:'first' }} + warning +
+
+ {{ (wallet.hours ? wallet.hours : 0) | amount:false:'first' }} + warning +
+
+ + + + + +
+
+ + +
+
+
+
+ + +
+ + + +
+
+
diff --git a/src/gui/static/src/app/components/pages/wallets/wallets.component.scss b/src/gui/static/src/app/components/pages/wallets/wallets.component.scss new file mode 100644 index 0000000..90fa3b9 --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallets.component.scss @@ -0,0 +1,132 @@ +@import '../../../../theme/variables'; + +.-width-85 { + padding-right: $main-containers-small-padding !important; +} + +.-width-250 { + padding-left: $main-containers-small-padding !important; + + @media (max-width: $max-sm-width) { + width: 200px; + flex-shrink: 0; + } +} + +.-headers { + > div { + padding: 0px; + } +} + +.-body { + margin-bottom: 10px; + color: $black; + background-color: transparent !important; + + .-row { + font-size: $font-size-standard; + line-height: 60px; + height: 60px; + background-color: $white; + cursor: pointer; + + > div { + padding: 0px; + } + + .-label { + line-height: 1.3; + + .-wallet-type-label { + color: $red; + font-size: $font-size-micro; + margin-top: 2px; + + mat-icon { + vertical-align: text-bottom; + } + } + } + + .-hours { + color: $grey; + text-align: right; + } + + .-coins { + text-align: right; + } + + .-encryption { + padding-left: 20px !important; + + > div { + border-radius: 50%; + background-color: $grey-lightest; + display: inline-block; + height: 38px; + width: 38px; + + img { + height: 38px; + padding: 3px; + width: 38px; + } + } + } + + .-expand { + display: flex; + justify-content: flex-end; + + img { + width: $normal-icon-size; + height: $normal-icon-size; + opacity: 0.7; + } + + button { + opacity: 0.5; + + mat-icon { + position: relative; + top: -2px; + } + + &:hover { + opacity: 1; + } + } + } + + &:hover { + background-color: $white-hover; + + .-expand img { + opacity: 1; + } + + .-encryption > div { + background-color: darken($grey-lightest, 1%); + } + } + } +} + +.action-buttons { + padding: 40px 0; + text-align: center; + + button { + margin: 0 5px; + } +} + +.rotate-90 { + transform: rotate(90deg); +} + +.rotate-270 { + transform: rotate(270deg); +} diff --git a/src/gui/static/src/app/components/pages/wallets/wallets.component.ts b/src/gui/static/src/app/components/pages/wallets/wallets.component.ts new file mode 100644 index 0000000..0fb9c4f --- /dev/null +++ b/src/gui/static/src/app/components/pages/wallets/wallets.component.ts @@ -0,0 +1,181 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { SubscriptionLike } from 'rxjs'; +import { first } from 'rxjs/operators'; +import { Router } from '@angular/router'; + +import { CreateWalletComponent } from './create-wallet/create-wallet.component'; +import { HwOptionsDialogComponent } from '../../layout/hardware-wallet/hw-options-dialog/hw-options-dialog.component'; +import { HwWalletService } from '../../../services/hw-wallet.service'; +import { ConfirmationParams, ConfirmationComponent, DefaultConfirmationButtons } from '../../layout/confirmation/confirmation.component'; +import { WalletsAndAddressesService } from '../../../services/wallet-operations/wallets-and-addresses.service'; +import { BalanceAndOutputsService } from '../../../services/wallet-operations/balance-and-outputs.service'; +import { WalletWithBalance, WalletTypes } from '../../../services/wallet-operations/wallet-objects'; +import { QrDialogConfig, QrCodeComponent } from '../../layout/qr-code/qr-code.component'; +import { WalletOptionsComponent } from './wallet-options/wallet-options.component'; +import { CoinService } from '../../../services/coin.service'; + +/** + * Shows the wallet list and options related to it. + */ +@Component({ + selector: 'app-wallets', + templateUrl: './wallets.component.html', + styleUrls: ['./wallets.component.scss'], +}) +export class WalletsComponent implements OnInit, OnDestroy { + /** + * Allow to know if the page is busy preparing an operation and no other operation must + * be stated before finishing it. + */ + static busy = false; + + // If true, the currently selected coin includes coin hours. + coinHasHours = false; + // Software wallets to show on the list. + wallets: WalletWithBalance[] = []; + // Hardware wallets to show on the list. + hardwareWallets: WalletWithBalance[] = []; + // Saves which wallet panels are open. + walletsOpenedState = new Map(); + // True if wallets shown by the component don't have the same value on the walletType param. + hasVariousWalletTypes = false; + + walletTypes = WalletTypes; + + // Vars for showing only the options available for the current coin. + showHwWalletOptions: boolean; + showSwWalletOptions: boolean; + + private subscription: SubscriptionLike; + + constructor( + private hwWalletService: HwWalletService, + private dialog: MatDialog, + private router: Router, + private walletsAndAddressesService: WalletsAndAddressesService, + private balanceAndOutputsService: BalanceAndOutputsService, + coinService: CoinService, + ) { + this.coinHasHours = coinService.currentCoinInmediate.coinTypeFeatures.coinHours; + this.showHwWalletOptions = this.hwWalletService.hwWalletCompatibilityActivated && !!coinService.currentCoinInmediate.skywalletCoinType; + this.showSwWalletOptions = coinService.currentCoinInmediate.coinTypeFeatures.softwareWallets; + + // Keep the wallet list updated. + this.subscription = this.balanceAndOutputsService.walletsWithBalance.subscribe(wallets => { + this.wallets = []; + this.hardwareWallets = []; + + const typeOfTheFirstWallet = wallets.length > 0 ? wallets[0].walletType : null; + this.hasVariousWalletTypes = false; + + // Create a map with the wallets and put each wallet on the appropiate array. + const walletsMap = new Map(); + wallets.forEach(value => { + walletsMap.set(value.id, true); + + if (!value.isHardware) { + this.wallets.push(value); + } else { + this.hardwareWallets.push(value); + } + + if (value.walletType !== typeOfTheFirstWallet) { + this.hasVariousWalletTypes = true; + } + + // If it is a new wallet, set it as closed. + if (!this.walletsOpenedState.has(value.id)) { + this.walletsOpenedState.set(value.id, false); + } + }); + + // Remove from walletsOpenedState all the deleted wallets. + const walletsToRemove: string[] = []; + this.walletsOpenedState.forEach((value, key) => { + if (!walletsMap.has(key)) { + walletsToRemove.push(key); + } + }); + walletsToRemove.forEach(walletToRemove => { + this.walletsOpenedState.delete(walletToRemove); + }); + }); + } + + ngOnInit(): void { + // Open the hw wallet options if it was requested before opening the page. + if (this.hwWalletService.showOptionsWhenPossible) { + setTimeout(() => { + this.hwWalletService.showOptionsWhenPossible = false; + this.adminHwWallet(); + }); + } + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + WalletsComponent.busy = false; + } + + // Opens the create wallet modal window, for creating a new wallet (create === true) or loading + // an old one. + addWallet(create: boolean) { + CreateWalletComponent.openDialog(this.dialog, { create }); + } + + // Opens the hw wallet options modal window. + adminHwWallet() { + HwOptionsDialogComponent.openDialog(this.dialog, false).afterClosed().subscribe(() => { + // Check if there are still wallets on the wallet list. If not, go to the wizard. + this.walletsAndAddressesService.allWallets.pipe(first()).subscribe(wallets => { + if (wallets.length === 0) { + setTimeout(() => this.router.navigate(['/wizard']), 500); + } + }); + }); + } + + // If the wallet is deterministic, opens or closes a wallet panel. If the wallet is BIP44 + // or xPub, opens the modal window for receiving coins. + toggleWallet(wallet: WalletWithBalance) { + if (wallet.walletType === WalletTypes.Deterministic) { + if (wallet.isHardware && wallet.hasHwSecurityWarnings && !wallet.stopShowingHwSecurityPopup && !this.walletsOpenedState.get(wallet.id)) { + const confirmationParams: ConfirmationParams = { + headerText: 'hardware-wallet.security-warning.title', + text: 'hardware-wallet.security-warning.text', + checkboxText: 'common.generic-confirmation-check', + defaultButtons: DefaultConfirmationButtons.ContinueCancel, + linkText: 'hardware-wallet.security-warning.link', + linkFunction: this.adminHwWallet.bind(this), + }; + + // If there are security warnings related to the hw wallet, ask for confirmation before opening the panel. + ConfirmationComponent.openDialog(this.dialog, confirmationParams).afterClosed().subscribe(confirmationResult => { + if (confirmationResult) { + // Do not show the warning in the future and open the panel. + wallet.stopShowingHwSecurityPopup = true; + this.walletsAndAddressesService.informValuesUpdated(wallet); + this.walletsOpenedState.set(wallet.id, true); + } + }); + } else { + // Open or close the panel. + this.walletsOpenedState.set(wallet.id, !this.walletsOpenedState.get(wallet.id)); + } + } else { + const config: QrDialogConfig = { + showSpecificAddress: false, + wallet: wallet, + }; + + QrCodeComponent.openDialog(this.dialog, config); + } + } + + config(event, wallet: WalletWithBalance) { + event.stopPropagation(); + + WalletOptionsComponent.openDialog(this.dialog, {wallet: wallet}); + } +} diff --git a/src/gui/static/src/app/directives/dontsavepassword.directive.ts b/src/gui/static/src/app/directives/dontsavepassword.directive.ts new file mode 100644 index 0000000..fd36c34 --- /dev/null +++ b/src/gui/static/src/app/directives/dontsavepassword.directive.ts @@ -0,0 +1,20 @@ +import { Directive, ElementRef, HostListener } from '@angular/core'; + +/** + * Tries to make an input avoid the "save password" feature of most browsers. + */ +@Directive({ + selector: '[appDontSavePassword]', +}) +export class DontsavepasswordDirective { + constructor( + private el: ElementRef, + ) { + el.nativeElement.autocomplete = 'new-password'; + el.nativeElement.readOnly = true; + } + + @HostListener('focus') onFocus() { + this.el.nativeElement.readOnly = false; + } +} diff --git a/src/gui/static/src/app/directives/form-field-error.directive.ts b/src/gui/static/src/app/directives/form-field-error.directive.ts new file mode 100644 index 0000000..79b1ead --- /dev/null +++ b/src/gui/static/src/app/directives/form-field-error.directive.ts @@ -0,0 +1,74 @@ +import { Directive, ElementRef, Renderer2, Input, ViewContainerRef, NgZone, Inject, Optional } from '@angular/core'; +import { MatTooltip, MAT_TOOLTIP_SCROLL_STRATEGY, MAT_TOOLTIP_DEFAULT_OPTIONS, MatTooltipDefaultOptions } from '@angular/material/tooltip'; +import { Overlay, ScrollDispatcher } from '@angular/cdk/overlay'; +import { Platform } from '@angular/cdk/platform'; +import { AriaDescriber, FocusMonitor } from '@angular/cdk/a11y'; +import { Directionality } from '@angular/cdk/bidi'; +import { TranslateService } from '@ngx-translate/core'; + +/** + * Makes a form field show red boders and text, as well as a tooltip, if there is a + * validation error. For making it work, set a valid error msg (may be a var for translation) + * using the directive like this: '[appFormFieldError]="Msg"'. + */ +@Directive({ + selector: '[appFormFieldError]', +}) +export class FormFieldErrorDirective extends MatTooltip { + // Error msg. + @Input() set appFormFieldError(val: string) { + if (val) { + this.message = this.translate.instant(val); + } else { + this.message = null; + } + + this.updateField(); + } + + constructor( + private translate: TranslateService, + private renderer: Renderer2, + private elementRef: ElementRef, + overlay: Overlay, + scrollDispatcher: ScrollDispatcher, + viewContainerRef: ViewContainerRef, + ngZone: NgZone, + platform: Platform, + ariaDescriber: AriaDescriber, + focusMonitor: FocusMonitor, + @Inject(MAT_TOOLTIP_SCROLL_STRATEGY) scrollStrategy: any, + @Optional() dir: Directionality, + @Optional() @Inject(MAT_TOOLTIP_DEFAULT_OPTIONS) defaultOptions: MatTooltipDefaultOptions, + ) { + super( + overlay, + elementRef, + scrollDispatcher, + viewContainerRef, + ngZone, + platform, + ariaDescriber, + focusMonitor, + scrollStrategy, + dir, + defaultOptions, + ); + + this.tooltipClass = 'error-tooltip'; + } + + // Activates or disables the highlight effect. + private updateField() { + if (this.message) { + this.renderer.addClass(this.elementRef.nativeElement, 'red-field'); + + // If the fied is focussed, show the tooltip, enven if the mouse cursor is not over the field. + if (document.activeElement === this.elementRef.nativeElement) { + this.show(); + } + } else { + this.renderer.removeClass(this.elementRef.nativeElement, 'red-field'); + } + } +} diff --git a/src/gui/static/src/app/directives/styling/image-color.directive.ts b/src/gui/static/src/app/directives/styling/image-color.directive.ts new file mode 100644 index 0000000..9fadc2d --- /dev/null +++ b/src/gui/static/src/app/directives/styling/image-color.directive.ts @@ -0,0 +1,49 @@ +import { Directive, ElementRef, Renderer2, OnInit, OnDestroy, RendererStyleFlags2, Input, HostListener } from '@angular/core'; +import { SubscriptionLike } from 'rxjs'; + +import { CoinService } from '../../services/coin.service'; + +/** + * Add filters to an element with a black icon, so that the icon is shown using the + * current main color. If used as '[appImageColor]="true"', the secondary color is used. + */ +@Directive({ + selector: '[appImageColor]', +}) +export class ColorImageDirective implements OnInit, OnDestroy { + // If true, the secondary color is used. + private showSecondaryColor = false; + @Input() set appImageColor(val: boolean) { + this.showSecondaryColor = val; + this.updateColor(); + } + + // Current filters. + private mainColorFilter: string; + private secondaryColorFilter: string; + private subscription: SubscriptionLike; + + constructor( + private el: ElementRef, + private renderer: Renderer2, + private coinService: CoinService, + ) { } + + ngOnInit(): void { + // Get the filters. + this.subscription = this.coinService.currentCoin.subscribe(coin => { + this.mainColorFilter = coin.styleConfig.mainColorImagesFilter; + this.secondaryColorFilter = coin.styleConfig.secondaryColorImagesFilter; + this.updateColor(); + }); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } + + // Updates the css property. + private updateColor() { + this.renderer.setStyle(this.el.nativeElement, 'filter', this.showSecondaryColor ? this.secondaryColorFilter : this.mainColorFilter); + } +} diff --git a/src/gui/static/src/app/directives/styling/main-color-form-element.directive.ts b/src/gui/static/src/app/directives/styling/main-color-form-element.directive.ts new file mode 100644 index 0000000..6b93f78 --- /dev/null +++ b/src/gui/static/src/app/directives/styling/main-color-form-element.directive.ts @@ -0,0 +1,87 @@ +import { Directive, ElementRef, Renderer2, OnDestroy, RendererStyleFlags2, AfterViewInit } from '@angular/core'; +import { SubscriptionLike } from 'rxjs'; + +import { CoinService } from '../../services/coin.service'; + +/** + * Makes a form element use the current main color. It is currently compatible with: + * + * - mat-checkbox + * - mat-option + * - mat-slider + * - mat-spinner + */ +@Directive({ + selector: '[appMainColorFormElement]', +}) +export class MainColorFormElementDirective implements OnDestroy, AfterViewInit { + // Allows to detect changes in the DOM, to update the properties. + private mutationObserver: MutationObserver; + // Current main color. + private currentColor = ''; + private subscription: SubscriptionLike; + + constructor( + private el: ElementRef, + private renderer: Renderer2, + private coinService: CoinService, + ) { } + + ngAfterViewInit() { + // Update the properties if there are changes in the DOM. + this.mutationObserver = new MutationObserver(() => this.updateColor()); + const config = { attributes: true, subtree: true }; + this.mutationObserver.observe(this.el.nativeElement, config); + + // Get the main color. + this.subscription = this.coinService.currentCoin.subscribe(coin => { + this.currentColor = coin.styleConfig.mainColor; + this.updateColor(); + }); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + this.mutationObserver.disconnect(); + } + + // Updates the css properties. + private updateColor() { + // For mat-spinner. + const circle = this.el.nativeElement.querySelector('circle'); + if (circle) { + this.renderer.setStyle(circle, 'stroke', this.currentColor); + } + + // For mat-slider. + const sliderThumb = this.el.nativeElement.querySelector('.mat-slider-thumb'); + if (sliderThumb) { + this.renderer.setStyle(sliderThumb, 'background-color', this.currentColor); + } + const sliderThumbLabel = this.el.nativeElement.querySelector('.mat-slider-thumb-label'); + if (sliderThumbLabel) { + this.renderer.setStyle(sliderThumbLabel, 'background-color', this.currentColor); + } + + // For mat-option. + const pseudoCheckboxChecked = this.el.nativeElement.querySelector('.mat-pseudo-checkbox-checked'); + const pseudoCheckbox = this.el.nativeElement.querySelector('.mat-pseudo-checkbox'); + if (pseudoCheckboxChecked) { + this.renderer.setStyle(pseudoCheckboxChecked, 'background', this.currentColor); + } else if (pseudoCheckbox) { + this.renderer.setStyle(pseudoCheckbox, 'background', null); + } + + // For mat-checkbox. + const checkboxCheckmarkPath = this.el.nativeElement.querySelector('.mat-checkbox-checkmark-path'); + if (checkboxCheckmarkPath) { + // tslint:disable-next-line:no-bitwise + this.renderer.setStyle(checkboxCheckmarkPath, 'stroke', this.currentColor, RendererStyleFlags2.DashCase | RendererStyleFlags2.Important); + + const rippleElements = this.el.nativeElement.querySelectorAll('.mat-ripple-element'); + rippleElements.forEach(element => { + this.renderer.setStyle(element, 'background', this.currentColor); + }); + } + } +} diff --git a/src/gui/static/src/app/directives/styling/theme-color-text.directive.ts b/src/gui/static/src/app/directives/styling/theme-color-text.directive.ts new file mode 100644 index 0000000..5241191 --- /dev/null +++ b/src/gui/static/src/app/directives/styling/theme-color-text.directive.ts @@ -0,0 +1,78 @@ +import { Directive, ElementRef, Renderer2, OnInit, OnDestroy, RendererStyleFlags2, Input, HostListener } from '@angular/core'; +import { SubscriptionLike } from 'rxjs'; + +import { CoinService } from '../../services/coin.service'; + +/** + * Sets the 'color' css property of the element to the current main or secondary color. + * If used as '[appThemeColorText]="true"', the secondary color is used. If you use + * '[showOnlyIfMouseOver]="true"', the color property will be set only when the mouse + * cursor is over the element, and will be set to null when it is not. + */ +@Directive({ + selector: '[appThemeColorText]', +}) +export class ThemeColorTextDirective implements OnInit, OnDestroy { + // If true, the color will be used only if the mouse cursor is over the element. + private showOnlyIfMouseOverInternal = false; + @Input() set showOnlyIfMouseOver(val: boolean) { + this.showOnlyIfMouseOverInternal = val; + this.updateColor(); + } + + // If true, the secondary color is used. + private showSecondaryColor = false; + @Input() set appThemeColorText(val: boolean) { + this.showSecondaryColor = val; + this.updateColor(); + } + + // If the mouse is over the element. + private mouseOver = false; + // Current colors. + private currentMainColor = ''; + private currentSecondaryColor = ''; + private subscription: SubscriptionLike; + + constructor( + private el: ElementRef, + private renderer: Renderer2, + private coinService: CoinService, + ) { } + + ngOnInit(): void { + // Get the colors. + this.subscription = this.coinService.currentCoin.subscribe(coin => { + this.currentMainColor = coin.styleConfig.mainColor; + this.currentSecondaryColor = coin.styleConfig.secondaryColor; + this.updateColor(); + }); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } + + // Mouse events. + @HostListener('mouseenter') onMouseEnter() { + this.mouseOver = true; + this.updateColor(); + } + @HostListener('mouseleave') onMouseLeave() { + this.mouseOver = false; + this.updateColor(); + } + + // Updates the css property. + private updateColor() { + if (!this.showOnlyIfMouseOverInternal || this.mouseOver) { + const color = this.showSecondaryColor ? this.currentSecondaryColor : this.currentMainColor; + // Use the color. + // tslint:disable-next-line:no-bitwise + this.renderer.setStyle(this.el.nativeElement, 'color', color, RendererStyleFlags2.DashCase | RendererStyleFlags2.Important); + } else { + // Unset the color property. + this.renderer.setStyle(this.el.nativeElement, 'color', null); + } + } +} diff --git a/src/gui/static/src/app/pipes/amount.pipe.ts b/src/gui/static/src/app/pipes/amount.pipe.ts new file mode 100644 index 0000000..67b81f9 --- /dev/null +++ b/src/gui/static/src/app/pipes/amount.pipe.ts @@ -0,0 +1,61 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { BigNumber } from 'bignumber.js'; + +import { CoinService } from '../services/coin.service'; +import { NodeService } from '../services/node.service'; + +/** + * Converts a number into a coin or hour amount. The resulting string is formatted with the + * correct max number of decimals and the small name of the coin or the full name of the + * coin hours at the end. It expects a number, numeric string or BigNumber instance as argument. + * Also, the pipe can receive 2 optional arguments: the first one is a boolean value indicating + * if the provided number must be converted to a coin amount (true) or an hour amount (false); + * while the second one is a string which can be 'first', for the pipe to return only the first part + * of the amount (the fometted number without the coin name), or 'last', for the pipe to return + * only the last part of the amount (the coin or hours name). + */ +@Pipe({ + name: 'amount', + pure: false, +}) +export class AmountPipe implements PipeTransform { + + constructor( + private nodeService: NodeService, + private coinService: CoinService, + ) { } + + transform(value: any, showingCoins = true, partToReturn = '') { + const convertedVal = new BigNumber(value).decimalPlaces(showingCoins ? this.nodeService.currentMaxDecimals : 0); + + let response = ''; + + // Add the numeric part. + if (partToReturn !== 'last') { + if (convertedVal.isNaN()) { + response = 'NaN'; + } else { + response = convertedVal.toFormat(); + } + + if (partToReturn !== 'first') { + response += ' '; + } + } + + // Add the name. + if (partToReturn !== 'first') { + if (showingCoins) { + response += this.coinService.currentCoinInmediate.coinSymbol; + } else { + if (this.coinService.currentCoinInmediate.hoursNameSingular && convertedVal.absoluteValue().isEqualTo(1)) { + response += this.coinService.currentCoinInmediate.hoursNameSingular; + } else if (this.coinService.currentCoinInmediate.hoursName) { + response += this.coinService.currentCoinInmediate.hoursName; + } + } + } + + return response; + } +} diff --git a/src/gui/static/src/app/pipes/common-text.pipe.ts b/src/gui/static/src/app/pipes/common-text.pipe.ts new file mode 100644 index 0000000..ce2be9a --- /dev/null +++ b/src/gui/static/src/app/pipes/common-text.pipe.ts @@ -0,0 +1,33 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +import { CoinService } from '../services/coin.service'; + +/** + * Returns the name of a commonly used element. The posible values are: + * hours: returns the name of the coin hours. + * coin: returns the short name of the coin, like 'SKY' for Skycoin. + * coinFull: returns the full name of the coin, like 'Skycoin'. + * The pipe expect the value to be exactly one of the previously listed strings. + */ +@Pipe({ + name: 'commonText', + pure: false, +}) +export class CommonTextPipe implements PipeTransform { + + constructor( + private coinService: CoinService, + ) { } + + transform(value: string) { + if (value === 'hours' && this.coinService.currentCoinInmediate.hoursName) { + return this.coinService.currentCoinInmediate.hoursName; + } else if (value === 'coinSymbol') { + return this.coinService.currentCoinInmediate.coinSymbol; + } else if (value === 'coinFull') { + return this.coinService.currentCoinInmediate.coinName; + } + + return ''; + } +} diff --git a/src/gui/static/src/app/pipes/date-from-now.pipe.ts b/src/gui/static/src/app/pipes/date-from-now.pipe.ts new file mode 100644 index 0000000..548318f --- /dev/null +++ b/src/gui/static/src/app/pipes/date-from-now.pipe.ts @@ -0,0 +1,38 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import * as moment from 'moment'; +import { TranslateService } from '@ngx-translate/core'; + +/** + * Takes an Unix date (UTC seconds since the Epoch) and returns a translated string indicating + * how much time has passed since that moment. It expects a number or a numeric string as + * argument. + */ +@Pipe({ + name: 'dateFromNow', + pure: false, +}) +export class DateFromNowPipe implements PipeTransform { + constructor( + public translateService: TranslateService, + ) { } + + transform(value: number) { + const diff: number = moment().unix() - value; + + if (diff < 60) { + return this.translateService.instant('time-from-now.few-seconds'); + } else if (diff < 120) { + return this.translateService.instant('time-from-now.minute'); + } else if (diff < 3600) { + return this.translateService.instant('time-from-now.minutes', { time: Math.floor(diff / 60) }); + } else if (diff < 7200) { + return this.translateService.instant('time-from-now.hour'); + } else if (diff < 86400) { + return this.translateService.instant('time-from-now.hours', { time: Math.floor(diff / 3600) }); + } else if (diff < 172800) { + return this.translateService.instant('time-from-now.day'); + } + + return this.translateService.instant('time-from-now.days', { time: Math.floor(diff / 86400) }); + } +} diff --git a/src/gui/static/src/app/pipes/date-time.pipe.ts b/src/gui/static/src/app/pipes/date-time.pipe.ts new file mode 100644 index 0000000..79895e7 --- /dev/null +++ b/src/gui/static/src/app/pipes/date-time.pipe.ts @@ -0,0 +1,16 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import * as moment from 'moment'; + +/** + * Takes an Unix date (UTC seconds since the Epoch) and converts it to a readable date-time + * string. Even as Unix dates are UTC-based, the returned string is in local time. It expects + * a number or a numeric string as argument. + */ +@Pipe({ + name: 'dateTime', +}) +export class DateTimePipe implements PipeTransform { + transform(value: number) { + return moment.unix(value).format('YYYY-MM-DD HH:mm'); + } +} diff --git a/src/gui/static/src/app/pipes/teller-status.pipe.ts b/src/gui/static/src/app/pipes/teller-status.pipe.ts new file mode 100644 index 0000000..33b4145 --- /dev/null +++ b/src/gui/static/src/app/pipes/teller-status.pipe.ts @@ -0,0 +1,20 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +/** + * Returns the variable, on the translation file, to display the name of one of the states + * returned by the teller service, using the translate pipe. It expects the value to be a + * string with one of the known states, or a variable for indicating that the state is unknown + * is returned. + */ +@Pipe({ + name: 'tellerStatus', +}) +export class TellerStatusPipe implements PipeTransform { + private statuses = ['done', 'waiting_confirm', 'waiting_deposit', 'waiting_send']; + + transform(value: any): any { + return this.statuses.find(status => status === value) + ? 'teller.' + value.replace('_', '-') + : 'teller.unknown'; + } +} diff --git a/src/gui/static/src/app/services/api/blockbook-api.service.ts b/src/gui/static/src/app/services/api/blockbook-api.service.ts new file mode 100644 index 0000000..60b0684 --- /dev/null +++ b/src/gui/static/src/app/services/api/blockbook-api.service.ts @@ -0,0 +1,84 @@ +import { throwError as observableThrowError, Observable } from 'rxjs'; +import { catchError } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +import { processServiceError } from '../../utils/errors'; +import { OperationError } from '../../utils/operation-error'; + +/** + * Allows to make request to the Blockbook api with ease. Check the API documentation for + * information about the API endpoints. + */ +@Injectable() +export class BlockbookApiService { + constructor( + private http: HttpClient, + ) { } + + /** + * Sends a GET request to the API. + * @param url URL to access Blockbook. + * @param endpointUrl URL to send the request to. + * @param params Object with the key/value pairs to be sent to the API as part of + * the querystring. + */ + get(url: string, endpointUrl: string, params: any = null): Observable { + return this.http.get(this.getUrl(url, endpointUrl, params)).pipe( + catchError((error: any) => this.processConnectionError(error))); + } + + /** + * Encodes a list of params as a query string, for being used for sending data + * in a request. + * @param parameters Object with the key/value pairs that will be used for + * creating the querystring. + */ + private getQueryString(parameters: any = null): string { + if (!parameters) { + return ''; + } + + return Object.keys(parameters).reduce((array, key) => { + array.push(key + '=' + encodeURIComponent(parameters[key])); + + return array; + }, []).join('&'); + } + + /** + * Get the complete URL needed for making a request to the API. + * @param url URL to access Blockbook. + * @param endpointUrl URL to send the request to. + * @param params Object with the key/value pairs to be sent to the API as part of + * the querystring. + */ + private getUrl(url: string, endpointUrl: string, params: any): string { + // Sanitize the URLs. + if (!url.endsWith('/api/')) { + if (url.endsWith('/')) { + url = url.substr(0, url.length - 1); + } + + url += '/api/'; + } + + if (endpointUrl.startsWith('/')) { + endpointUrl = endpointUrl.substr(1, endpointUrl.length - 1); + } + + // The '/api' endpoint must not be preceded by '/v2/'. + const response = url + (!endpointUrl.includes('api') ? 'v2/' : '') + endpointUrl; + const urlParams = this.getQueryString(params); + + return response + (urlParams ? '?' + this.getQueryString(params) : ''); + } + + /** + * Takes an error returned by the API and converts it to an instance of OperationError. + * @param error Error obtained while triying to connect to the API. + */ + private processConnectionError(error: any): Observable { + return observableThrowError(processServiceError(error)); + } +} diff --git a/src/gui/static/src/app/services/api/btc-api.service.ts b/src/gui/static/src/app/services/api/btc-api.service.ts new file mode 100644 index 0000000..4269ba4 --- /dev/null +++ b/src/gui/static/src/app/services/api/btc-api.service.ts @@ -0,0 +1,60 @@ +import { throwError as observableThrowError, Observable, of } from 'rxjs'; +import { mergeMap, catchError } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; + +import { processServiceError } from '../../utils/errors'; + +/** + * Allows to make request to the bitcoind node api with ease. Check the node API documentation for + * information about the API endpoints. + */ +@Injectable() +export class BtcApiService { + constructor( + private http: HttpClient, + ) { } + + /** + * Calls a RPC method of the bitcoind node. If the call returns an error in the "error" field of + * the RPC response, an error is thrown. + * @param nodeUrl URL of the node. + * @param methodName Name of the RPC method to call. + * @param params Params to send while calling the method. + * @returns Response obtained after calling the method. Only the "result" part of the RPC + * response is returned. + */ + callRpcMethod(nodeUrl: string, methodName: string, params: any = null): Observable { + // Populate the RPC fields. + const requestBody = { + jsonrpc: '2.0', + method: methodName, + id: '0', + }; + + if (params) { + requestBody['params'] = params; + } + + // Add the auth credentials. + const requestOptions: any = {}; + requestOptions.headers = new HttpHeaders(); + requestOptions.headers = requestOptions.headers.append('Authorization', 'Basic dXNlcjoxMjM='); + + // Send the request and process the errors. + // TODO: error processing could be better. It would be good to add better information + // for known errors. + return this.http.post(nodeUrl, JSON.stringify(requestBody), requestOptions).pipe( + catchError((error: any) => { + return observableThrowError(processServiceError(error)); + }), + mergeMap((response: any) => { + if (response.error) { + return observableThrowError(processServiceError(response.error)); + } + + return of(response.result); + }), + ); + } +} diff --git a/src/gui/static/src/app/services/api/eth-api.service.ts b/src/gui/static/src/app/services/api/eth-api.service.ts new file mode 100644 index 0000000..73acc56 --- /dev/null +++ b/src/gui/static/src/app/services/api/eth-api.service.ts @@ -0,0 +1,60 @@ +import { throwError as observableThrowError, Observable, of } from 'rxjs'; +import { mergeMap, catchError } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; + +import { processServiceError } from '../../utils/errors'; + +/** + * Allows to make request to the Ethereum node api with ease. Check the node API documentation for + * information about the API endpoints. + */ +@Injectable() +export class EthApiService { + constructor( + private http: HttpClient, + ) { } + + /** + * Calls a RPC method of the Ethereum node. If the call returns an error in the "error" field of + * the RPC response, an error is thrown. + * @param nodeUrl URL of the node. + * @param methodName Name of the RPC method to call. + * @param params Params to send while calling the method. + * @returns Response obtained after calling the method. Only the "result" part of the RPC + * response is returned. + */ + callRpcMethod(nodeUrl: string, methodName: string, params: any = null): Observable { + // Populate the RPC fields. + const requestBody = { + jsonrpc: '2.0', + method: methodName, + id: '0', + }; + + if (params) { + requestBody['params'] = params; + } + + // Add the required headers. + const requestOptions: any = {}; + requestOptions.headers = new HttpHeaders(); + requestOptions.headers = requestOptions.headers.append('Content-Type', 'application/json'); + + // Send the request and process the errors. + // TODO: error processing could be better. It would be good to add better information + // for known errors. + return this.http.post(nodeUrl, JSON.stringify(requestBody), requestOptions).pipe( + catchError((error: any) => { + return observableThrowError(processServiceError(error)); + }), + mergeMap((response: any) => { + if (response.error) { + return observableThrowError(processServiceError(response.error)); + } + + return of(response.result); + }), + ); + } +} diff --git a/src/gui/static/src/app/services/api/fiber-api.service.ts b/src/gui/static/src/app/services/api/fiber-api.service.ts new file mode 100644 index 0000000..65a473a --- /dev/null +++ b/src/gui/static/src/app/services/api/fiber-api.service.ts @@ -0,0 +1,186 @@ +import { throwError as observableThrowError, Observable, of } from 'rxjs'; +import { first, map, mergeMap, catchError } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; + +import { processServiceError } from '../../utils/errors'; +import { OperationError } from '../../utils/operation-error'; + +// IMPORTANT: AFTER MAKING MODIFICATIONS TO THIS INTERFACE YOU MUST ALSO +// MAKE APPROPIATE CHANGES TO THE createDefaultRequestOptions +// FUNCTION INSIDE FiberApiService. +/** + * Options for configuring the requests to the Fiber node API. + */ +export interface FiberNodeApiRequestOptions { + /** + * If true, the request will be sent to the API v2 and not to the v1. + */ + useV2?: boolean; + /** + * If true, the data will be sent to the node encoded as JSON. This only makes sense for POST + * request while using the v1, as GET request only send the data as params on the URL and the + * data is always sent encoded as JSON when using the API v2. + */ + sendDataAsJson?: boolean; +} + +/** + * Allows to make request to the Fiber node api with ease. Check the node API documentation for + * information about the API endpoints. + */ +@Injectable() +export class FiberApiService { + constructor( + private http: HttpClient, + ) { } + + /** + * Sends a GET request to the node API. + * @param nodeUrl URL of the node. + * @param endpointUrl URL to send the request to. + * @param params Object with the key/value pairs to be sent to the node as part of + * the querystring. + * @param options Request options. + */ + get(nodeUrl: string, endpointUrl: string, params: any = null, options: FiberNodeApiRequestOptions = null): Observable { + if (!options) { + options = this.createDefaultRequestOptions(); + } else { + options = Object.assign(this.createDefaultRequestOptions(), options); + } + + return this.http.get(this.getUrl(nodeUrl, endpointUrl, params, options.useV2), this.returnRequestOptions(options, null)).pipe( + catchError((error: any) => this.processConnectionError(error))); + } + + /** + * Sends a POST request to the node API. + * @param nodeUrl URL of the node. + * @param endpointUrl URL to send the request to. + * @param params Object with the key/value pairs to be sent to the node as + * x-www-form-urlencoded or JSON, as defined in the options param. + * @param options Request options. + */ + post(nodeUrl: string, endpointUrl: string, params: any = null, options: FiberNodeApiRequestOptions = null): Observable { + if (!options) { + options = this.createDefaultRequestOptions(); + } else { + options = Object.assign(this.createDefaultRequestOptions(), options); + } + + return this.getCsrf(nodeUrl).pipe(first(), mergeMap(csrf => { + // V2 always needs the data to be sent encoded as JSON. + if (options.useV2) { + options.sendDataAsJson = true; + } + + return this.http.post( + this.getUrl(nodeUrl, endpointUrl, null, options.useV2), + options.sendDataAsJson ? (params ? JSON.stringify(params) : '') : this.getQueryString(params), + this.returnRequestOptions(options, csrf), + ).pipe( + catchError((error: any) => this.processConnectionError(error))); + })); + } + + /** + * Creates a FiberNodeApiRequestOptions instance with the default values. + */ + private createDefaultRequestOptions(): FiberNodeApiRequestOptions { + return { + useV2: false, + sendDataAsJson: false, + }; + } + + /** + * Gets a csrf token from the node, to be able to make a post request to the node API. + * @param nodeUrl URL of the node. + */ + private getCsrf(nodeUrl: string): Observable { + return this.get(nodeUrl, 'csrf').pipe( + catchError((error: any) => { + error = processServiceError(error); + + // If the node returns a 404 error, the csrf protection is disabled on the node. + if (error && error.originalError && (error.originalError as HttpErrorResponse).status === 404) { + return of({csrf_token: null}); + } + + return error; + }), + map(response => response.csrf_token), + ); + } + + /** + * Returns the options object requiered by HttpClient for sending a request. + * @param options Options that will be used for making the request. + * @param csrfToken Csrf token to be added on a header, for being able to make + * POST requests. + */ + private returnRequestOptions(options: FiberNodeApiRequestOptions, csrfToken: string): any { + const requestOptions: any = {}; + + requestOptions.headers = new HttpHeaders(); + requestOptions.headers = requestOptions.headers.append('Content-Type', options.sendDataAsJson ? 'application/json' : 'application/x-www-form-urlencoded'); + + if (csrfToken) { + requestOptions.headers = requestOptions.headers.append('X-CSRF-Token', csrfToken); + } + + return requestOptions; + } + + /** + * Encodes a list of params as a query string, for being used for sending data + * in a request. + * @param parameters Object with the key/value pairs that will be used for + * creating the querystring. + */ + private getQueryString(parameters: any = null): string { + if (!parameters) { + return ''; + } + + return Object.keys(parameters).reduce((array, key) => { + array.push(key + '=' + encodeURIComponent(parameters[key])); + + return array; + }, []).join('&'); + } + + /** + * Get the complete URL needed for making a request to the node API. + * @param nodeUrl URL of the node. + * @param endpointUrl URL to send the request to. + * @param params Object with the key/value pairs to be sent to the node as part of + * the querystring. + * @param useV2 If the returned URL must point to the API v2 (true) or v1 (false). + */ + private getUrl(nodeUrl: string, endpointUrl: string, params: any = null, useV2 = false): string { + // Sanitize the node URLs. + if (!nodeUrl.endsWith('/api/')) { + if (nodeUrl.endsWith('/')) { + nodeUrl = nodeUrl.substr(0, nodeUrl.length - 1); + } + + nodeUrl += '/api/'; + } + + if (endpointUrl.startsWith('/')) { + endpointUrl = endpointUrl.substr(1, endpointUrl.length - 1); + } + + return nodeUrl + (useV2 ? 'v2/' : 'v1/') + endpointUrl + '?' + this.getQueryString(params); + } + + /** + * Takes an error returned by the node and converts it to an instance of OperationError. + * @param error Error obtained while triying to connect to the node API. + */ + private processConnectionError(error: any): Observable { + return observableThrowError(processServiceError(error)); + } +} diff --git a/src/gui/static/src/app/services/app-update.service.ts b/src/gui/static/src/app/services/app-update.service.ts new file mode 100644 index 0000000..ba24d75 --- /dev/null +++ b/src/gui/static/src/app/services/app-update.service.ts @@ -0,0 +1,68 @@ +import { delay, retryWhen, mergeMap } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { of } from 'rxjs'; + +import { shouldUpgradeVersion } from '../utils/general-utils'; +import { AppConfig } from '../app.config'; +import { FiberApiService } from './api/fiber-api.service'; +import { environment } from '../../environments/environment'; + +/** + * Allows check if there is an update available. + */ +@Injectable() +export class AppUpdateService { + /** + * Version number of the app. Empty while getting the data. Empty while getting the data. + */ + get appVersion() { + return this.appVersionInternal; + } + private appVersionInternal = ''; + + /** + * Indicates if there is an update for this app available for download. False while getting + * the data. + */ + get updateAvailable(): boolean { + return this.updateAvailableInternal; + } + private updateAvailableInternal = false; + + /** + * Number of the lastest version available for download of this app. Empty while getting + * the data. + */ + get lastestVersion(): string { + return this.lastestVersionInternal; + } + private lastestVersionInternal = ''; + + constructor( + private fiberApiService: FiberApiService, + private http: HttpClient, + ) { } + + initialize() { + // Get the current version of the app. + this.fiberApiService.get(environment.nodeUrl, 'health').pipe(mergeMap(response => { + this.appVersionInternal = response.version.version; + + // Get the lastest version available for download. + if (AppConfig.urlForVersionChecking) { + return this.http.get(AppConfig.urlForVersionChecking, { responseType: 'text' }); + } else { + return of('0.0.0'); + } + }), + retryWhen(errors => errors.pipe(delay(30000))), + ).subscribe((response: string) => { + this.lastestVersionInternal = response.trim(); + if (this.lastestVersionInternal.startsWith('v')) { + this.lastestVersionInternal = this.lastestVersionInternal.substr(1); + } + this.updateAvailableInternal = shouldUpgradeVersion(this.appVersionInternal, this.lastestVersionInternal); + }); + } +} diff --git a/src/gui/static/src/app/services/bip39-word-list.service.ts b/src/gui/static/src/app/services/bip39-word-list.service.ts new file mode 100644 index 0000000..dcdc20b --- /dev/null +++ b/src/gui/static/src/app/services/bip39-word-list.service.ts @@ -0,0 +1,80 @@ +import { Injectable } from '@angular/core'; +import { debounceTime, map } from 'rxjs/operators'; +import { Subject, Observable, from } from 'rxjs'; + +/** + * Allows to access the BIP39 word list. + */ +@Injectable() +export class Bip39WordListService { + + /** + * Emits the results of the searches requested by calling the setSearchTerm function. + */ + get searchResults(): Observable { + // Filter the emissions to avoid making very frecuent calculations while the user writes. + return this.searchRequestSubject.asObservable().pipe(debounceTime(100), map(searchTerm => { + if (searchTerm.length > 1 && this.wordList) { + return this.wordList.filter(option => option.startsWith(searchTerm)); + } else { + return []; + } + })); + } + + private lastSearchTerm = ''; + private searchRequestSubject: Subject = new Subject(); + /** + * Array with all the BIP39 words. + */ + private wordList: string[]; + /** + * Map with all the BIP39 words, used mainly to know if a word is on the list. + */ + private wordMap: Map = new Map(); + + initialize() { + // Load the word list. + const name = 'bip39-word-list'; + from(import(`../../assets/${name}.json`)).subscribe(result => { + this.wordList = result.list; + this.wordList.forEach(word => { + this.wordMap.set(word, true); + }); + + // If a search was requested before loading the word list, the search is done again. + this.searchRequestSubject.next(this.lastSearchTerm); + }); + } + + /** + * Asks the service to search for all the BIP39 words which start with the provided + * string. The service will search for the words and the result will be emited by + * the searchResults observable. + * @param value String used to search for the BIP39 words. + */ + setSearchTerm(value: string) { + this.lastSearchTerm = value; + if (this.wordList) { + this.searchRequestSubject.next(value); + } + } + + /** + * Checks if a string is a valid BIP39 word. + * @param word Word to check. + * @returns True or false, depending on whether the provided word is a valid BIP39 + * word. If the service is still loading the word list, this function returns null. + */ + validateWord(word: string): boolean | null { + if (this.wordList) { + if (!this.wordMap.has(word)) { + return false; + } + + return true; + } else { + return null; + } + } +} diff --git a/src/gui/static/src/app/services/blockchain.service.ts b/src/gui/static/src/app/services/blockchain.service.ts new file mode 100644 index 0000000..271a4e8 --- /dev/null +++ b/src/gui/static/src/app/services/blockchain.service.ts @@ -0,0 +1,84 @@ +import { Observable } from 'rxjs'; +import { Injectable } from '@angular/core'; + +import { BlockchainOperator } from './coin-specific/blockchain-operator'; +import { OperatorService } from './operators.service'; + +/** + * Data about the current state of the blockchain in the node. + */ +export interface BlockchainState { + lastBlock: BasicBlockInfo; + /** + * Null if there is no info available. + */ + coinSupply: CoinSupply; +} +/** + * Basic info of the last block added to the blockchain. + */ +export interface BasicBlockInfo { + seq: number; + timestamp: number; + hash: string; +} + +/** + * Data about the current and max coin supply. + */ +export interface CoinSupply { + currentSupply: string; + totalSupply: string; + currentCoinhourSupply?: string; + totalCoinhourSupply?: string; +} + +/** + * Info about the current synchronization state of the blockchain. Not all coins provide + * information about the current blocks, specially if the blockchain is + * already synchronized. + */ +export interface ProgressEvent { + currentBlock: number; + highestBlock: number; + synchronized: boolean; +} + +/** + * Allows to check the current state of the blockchain. + */ +@Injectable() +export class BlockchainService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: BlockchainOperator; + + /** + * Allows to know the current synchronization state of the blockchain. It is updated over time. + */ + get progress(): Observable { + return this.operator.progress; + } + + constructor(private operatorService: OperatorService) { } + + initialize() { + // Maintain the operator updated. + this.operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.blockchainOperator; + } else { + this.operator = null; + } + }); + } + + /** + * Gets the basic info of the last block and the coin supply of the blockchain . + */ + getBlockchainState(): Observable { + return this.operator.getBlockchainState(); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/README.md b/src/gui/static/src/app/services/coin-specific/README.md new file mode 100644 index 0000000..83c98f1 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/README.md @@ -0,0 +1,48 @@ +# Coin Specific Operators + +This folder contains classes which are in charge of performing most of the general operations which would normally be +in a service but are dependant on the currently selected coin. Those clases are called "operators" in the context of +this applications simply as a way to identify them and make clear their purpose. + + + +- [Purpose of the operators](#purpose-of-the-operators) +- [Contents of this folder](#contents-of-this-folder) +- [Considerations about the operators](#considerations-about-the-operators) + + + +## Purpose of the operators + +This app has several services which allows to perform multiple operations which are different depending on the blockchain +type the currently selected coin uses. Having the code for each blockchain type in a separate operator instead of including it +directly in the service has the obvious advantage of allowing to create a much more maintanable code, but also helps when part of +the state of the services must be resetted after the active coin is changed: instead of having to reset most of the properties +of the services after the active coin is changed, which is not only tedious but also error prone, services can simply create a +new instance of the appropiate operator, which will come with a fresh state and will not touch any of the properties inside +the service. + +## Contents of this folder + +This folder contains several files with interfaces which the public functions and properties the operators must have. The +implementations must be added inside subfolders. + +## Considerations about the operators + +Every operator must work as a temporal helper instance, which can be created and destroyed at any moment if the user +decides to change the active coin. OperatorService is responsible for creating and deleting the operators as needed, so +the operators must not check the changes in the active coin and try to react to them. + +When the active coin is changed the main app component removes all the content from the UI and creates it again after several +frames, giving time for the operators to be removed and created again without having the UI trying to interact with them and +ensuring that the new UI instances will use the services when the new operators are in place (not the ones corresponding to the +old coin). + +It is important to keep in mind that removing the UI only gives protection agains race conditions to the UI +itself, it would be posible for the services and operators to continue running, which may be problematic. Because of that, +operators must not depend on services which depend on other oeprators. This is because an operator could take a lot of time to +complete an operation, specially when remote calls are involved. If the service is used only after a previous remote operation +is completed, the coin could have been changed at that moment, so calling the service will make the operation to be performed +for the new coin. Instead, just after being created, the operators must use OperatorService to get the set of operators active +at that very moment and use the requiered operators directly. This way, if the coin changes, the operator itself will continue +using the operator set it obtained when created. diff --git a/src/gui/static/src/app/services/coin-specific/balance-and-outputs-operator.ts b/src/gui/static/src/app/services/coin-specific/balance-and-outputs-operator.ts new file mode 100644 index 0000000..28a3992 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/balance-and-outputs-operator.ts @@ -0,0 +1,30 @@ +import { Observable } from 'rxjs'; + +import { WalletWithBalance, WalletBase, WalletWithOutputs } from '../wallet-operations/wallet-objects'; +import { Output } from '../wallet-operations/transaction-objects'; + +/** + * Interface with the elements the operators for BalanceAndOutputsService must have. + * Much of it is similar to BalanceAndOutputsService, so you can find more info in that class. + */ +export interface BalanceAndOutputsOperator { + // Properties for getting access to general info. Documented on the service. + lastBalancesUpdateTime: Observable; + walletsWithBalance: Observable; + hasPendingTransactions: Observable; + firstFullUpdateMade: Observable; + hadErrorRefreshingBalance: Observable; + refreshingBalance: Observable; + outputsWithWallets: Observable; + + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(): void; + + // Functions related to the balance and the outputs. Documented on the service. + getOutputs(addresses: string): Observable; + getWalletUnspentOutputs(wallet: WalletBase): Observable; + refreshBalance(): void; +} diff --git a/src/gui/static/src/app/services/coin-specific/blockchain-operator.ts b/src/gui/static/src/app/services/coin-specific/blockchain-operator.ts new file mode 100644 index 0000000..11f30dd --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/blockchain-operator.ts @@ -0,0 +1,21 @@ +import { Observable } from 'rxjs'; + +import { ProgressEvent, BlockchainState } from '../blockchain.service'; + +/** + * Interface with the elements the operators for BlockchainService must have. + * Much of it is similar to BlockchainService, so you can find more info in that class. + */ +export interface BlockchainOperator { + // Properties. Documented on the service. + progress: Observable; + + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(); + + // Functions related to the state of the blockchain. Documented on the service. + getBlockchainState(): Observable; +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-balance-and-outputs-operator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-balance-and-outputs-operator.ts new file mode 100644 index 0000000..2fd8515 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-balance-and-outputs-operator.ts @@ -0,0 +1,628 @@ +import { of, Observable, ReplaySubject, Subscription, BehaviorSubject, forkJoin, Subject } from 'rxjs'; +import { NgZone, Injector } from '@angular/core'; +import { mergeMap, map, switchMap, delay, tap, first, filter } from 'rxjs/operators'; +import BigNumber from 'bignumber.js'; + +import { WalletWithBalance, walletWithBalanceFromBase, WalletBase, WalletWithOutputs, walletWithOutputsFromBase, AddressMap, AddressBase } from '../../wallet-operations/wallet-objects'; +import { Output } from '../../wallet-operations/transaction-objects'; +import { Coin } from '../../../coins/coin'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; +import { getOutputId } from './utils/btc-history-utils'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; +import { BtcCoinConfig } from '../../../coins/coin-type-configs/btc.coin-config'; + +/** + * Balance of a wallet, for internal use. + */ +class WalletBalance { + current = new BigNumber(0); + predicted = new BigNumber(0); + available = new BigNumber(0); + addresses: AddressMap; + + constructor(walletsAndAddressesOperator: WalletsAndAddressesOperator) { + this.addresses = new AddressMap(walletsAndAddressesOperator.formatAddress); + } +} + +/** + * Balance of an address, for internal use. + */ +class AddressBalance { + current = new BigNumber(0); + predicted = new BigNumber(0); + available = new BigNumber(0); +} + +/** + * Operator for BalanceAndOutputsService to be used with btc-like coins. + * + * You can find more information about the functions and properties this class implements by + * checking BalanceAndOutputsOperator and BalanceAndOutputsService. + */ +export class BtcBalanceAndOutputsOperator implements BalanceAndOutputsOperator { + // The list of wallets with balance and the subject used for informing when the list has been modified. + private walletsWithBalanceList: WalletWithBalance[]; + private walletsWithBalanceSubject: ReplaySubject = new ReplaySubject(1); + + // Subject for providing information in the getters below. + private lastBalancesUpdateTimeSubject: ReplaySubject = new ReplaySubject(1); + private hasPendingTransactionsSubject: BehaviorSubject = new BehaviorSubject(false); + private firstFullUpdateMadeSubject: BehaviorSubject = new BehaviorSubject(false); + private hadErrorRefreshingBalanceSubject: BehaviorSubject = new BehaviorSubject(false); + private refreshingBalanceSubject: BehaviorSubject = new BehaviorSubject(false); + + private dataRefreshSubscription: Subscription; + private walletsSubscription: Subscription; + private operatorsSubscription: Subscription; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 10 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 2 * 1000; + + /** + * After the service retrieves the balance of each wallet, the balance and outputs returned + * by the backend for each wallet is saved here, accessible via the wallet id. + */ + private savedBalanceData = new Map(); + /** + * Allows to know when the value of savedBalanceData has been updated. + */ + private savedBalanceDataSubject: Subject = new Subject(); + /** + * Temporal map for updating savedBalanceData only after retrieving the data of all wallets, + * to avoid problems when the balance update procedure is cancelled early. + */ + private temporalSavedBalanceData = new Map(); + /** + * Saves the lastest, most up to date, wallet list obtained from the wallets service. + */ + private savedWalletsList: WalletBase[]; + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services and operators used by this operator. + private blockbookApiService: BlockbookApiService; + private ngZone: NgZone; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.blockbookApiService = injector.get(BlockbookApiService); + this.ngZone = injector.get(NgZone); + + // Intervals for updating the data must be longer if connecting to a remote backend. + if (!currentCoin.isLocal) { + this.updatePeriod = 600 * 1000; + this.errorUpdatePeriod = 60 * 1000; + } + + // Get the operators and only then start using them. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + + // Update the balance immediately each time the wallets are updated. + this.walletsSubscription = this.walletsAndAddressesOperator.currentWallets.subscribe(wallets => { + this.savedWalletsList = wallets; + this.startDataRefreshSubscription(0, true); + }); + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + if (this.walletsSubscription) { + this.walletsSubscription.unsubscribe(); + } + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + this.lastBalancesUpdateTimeSubject.complete(); + this.walletsWithBalanceSubject.complete(); + this.hasPendingTransactionsSubject.complete(); + this.firstFullUpdateMadeSubject.complete(); + this.hadErrorRefreshingBalanceSubject.complete(); + this.refreshingBalanceSubject.complete(); + this.savedBalanceDataSubject.complete(); + } + + get lastBalancesUpdateTime(): Observable { + return this.lastBalancesUpdateTimeSubject.asObservable(); + } + + get walletsWithBalance(): Observable { + return this.walletsWithBalanceSubject.asObservable(); + } + + get hasPendingTransactions(): Observable { + return this.hasPendingTransactionsSubject.asObservable(); + } + + get firstFullUpdateMade(): Observable { + return this.firstFullUpdateMadeSubject.asObservable(); + } + + get hadErrorRefreshingBalance(): Observable { + return this.hadErrorRefreshingBalanceSubject.asObservable(); + } + + get refreshingBalance(): Observable { + return this.refreshingBalanceSubject.asObservable(); + } + + get outputsWithWallets(): Observable { + // Run each time the wallet list changes. + return this.walletsWithBalance.pipe(switchMap(wallets => { + const addresses: string[] = []; + wallets.forEach(wallet => wallet.addresses.forEach(address => addresses.push(address.printableAddress))); + + // Get the unspent outputs of the list of addresses. + return this.recursivelyGetOutputs(addresses, false); + }), map(outputs => { + // Build the response. + const walletsList: WalletWithOutputs[] = []; + this.walletsWithBalanceList.forEach(wallet => { + const newWallet = walletWithOutputsFromBase(wallet); + walletsList.push(newWallet); + + newWallet.addresses.forEach(address => { + address.outputs = outputs.filter(output => address.compareAddress(output.address)); + }); + }); + + return walletsList; + })); + } + + getOutputs(addresses: string): Observable { + const addressesArray = addresses.split(','); + for (let i = 0; i < addressesArray.length; i++) { + addressesArray[i] = addressesArray[i].trim(); + } + + return this.recursivelyGetOutputs(addressesArray, true); + } + + /** + * Gets the unspent outputs of the addresses in the provided address list. + * @param addresses Addresses to check. The list will be altered by the function. + * @param confirmedOnly If true, only confirmed outputs will be returned. + * @param currentElements Already obtained outputs. For internal use. + * @returns Array with all the unspent outputs related to the provided address list. + */ + private recursivelyGetOutputs(addresses: string[], confirmedOnly: boolean, currentElements: Output[] = []): Observable { + if (addresses.length === 0) { + return of(currentElements); + } + + // Value which will allow to get the value in coins, instead of sats. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as BtcCoinConfig).decimals); + + // Get the outputs of the address. + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'utxo/' + addresses[addresses.length - 1], {confirmed: confirmedOnly}) + .pipe(mergeMap((response) => { + + // Process the outputs. + (response as any[]).forEach(output => { + if (!confirmedOnly || (output.confirmations && output.confirmations >= this.currentCoin.confirmationsNeeded)) { + const processedOutput: Output = { + address: this.walletsAndAddressesOperator.formatAddress(addresses[addresses.length - 1]), + coins: new BigNumber(output.value).dividedBy(decimalsCorrector), + hash: getOutputId(output.txid, output.vout), + confirmations: output.confirmations ? output.confirmations : 0, + transactionId: output.txid, + indexInTransaction: output.vout, + }; + + currentElements.push(processedOutput); + } + }); + + addresses.pop(); + + if (addresses.length === 0) { + return of(currentElements); + } + + // Continue to the next step. + return this.recursivelyGetOutputs(addresses, confirmedOnly, currentElements); + })); + } + + getWalletUnspentOutputs(wallet: WalletBase): Observable { + const addresses: string[] = []; + wallet.addresses.forEach(address => addresses.push(address.printableAddress)); + + return this.recursivelyGetOutputs(addresses, true); + } + + refreshBalance() { + this.startDataRefreshSubscription(0, false); + } + + /** + * Makes the service start updating the balance periodically. If this function was called + * before, the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the balance. + * @param updateWalletsFirst If true, after the delay the function will inmediatelly update + * the wallet list with the data on savedWalletsList and using the last balance data obtained + * from the backend (or will set all the wallets to 0, if no data exists) and only after that + * will try to get the balance data from the backend and update the wallet list again. This + * allows to inmediatelly reflect changes made to the wallet list, without having to wait for + * the backend to respond. + */ + private startDataRefreshSubscription(delayMs: number, updateWalletsFirst: boolean) { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + if (this.savedWalletsList) { + this.ngZone.runOutsideAngular(() => { + this.dataRefreshSubscription = of(0).pipe(delay(delayMs), mergeMap(() => { + // Inform the balance is being updated. + this.ngZone.run(() => { + this.refreshingBalanceSubject.next(true); + }); + + // Update the wallet list with the last saved data, if requested. + if (updateWalletsFirst) { + return this.refreshBalances(this.savedWalletsList, true); + } else { + return of(0); + } + }), mergeMap(() => { + // Refresh the balance. + return this.refreshBalances(this.savedWalletsList, false); + })).subscribe( + () => { + this.ngZone.run(() => { + this.hadErrorRefreshingBalanceSubject.next(false); + this.refreshingBalanceSubject.next(false); + }); + + // Repeat the operation after a delay. + this.startDataRefreshSubscription(this.updatePeriod, false); + }, + () => { + this.ngZone.run(() => { + this.hadErrorRefreshingBalanceSubject.next(true); + this.refreshingBalanceSubject.next(false); + }); + + // Repeat the operation after a delay. + this.startDataRefreshSubscription(this.errorUpdatePeriod, false); + }, + ); + }); + } + } + + /** + * Refreshes the wallets on walletsWithBalanceList and their balances. + * @param wallets The current wallet lists. + * @param forceQuickCompleteArrayUpdate If true, the balance data saved on savedBalanceData + * will be used to set the balance of the wallet list, instead of getting the data from + * the backend. If false, the balance data is obtained from the backend and savedBalanceData is + * updated. + */ + private refreshBalances(wallets: WalletBase[], forceQuickCompleteArrayUpdate: boolean): Observable { + // Create a copy of the wallet list. + const temporalWallets: WalletWithBalance[] = []; + wallets.forEach(wallet => { + temporalWallets.push(walletWithBalanceFromBase(wallet)); + }); + + // This will help to update savedBalanceData when finishing the procedure. + if (!forceQuickCompleteArrayUpdate) { + this.temporalSavedBalanceData = new Map(); + } + + let procedure: Observable; + if (wallets.length > 0) { + if (!forceQuickCompleteArrayUpdate) { + procedure = this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api').pipe(mergeMap(response => { + // Get the balance of each wallet. + return forkJoin(temporalWallets.map(wallet => this.retrieveWalletBalance(wallet, response.blockbook.bestHeight, forceQuickCompleteArrayUpdate))); + })); + } else { + procedure = forkJoin(temporalWallets.map(wallet => this.retrieveWalletBalance(wallet, 0, forceQuickCompleteArrayUpdate))); + } + } else { + // Create a fake response, as there are no wallets. + procedure = of([false]); + } + + // Calculate the balance of each wallet. + return procedure.pipe(tap(walletHasPendingTx => { + this.hasPendingTransactionsSubject.next(walletHasPendingTx.some(value => value)); + + if (!forceQuickCompleteArrayUpdate) { + this.ngZone.run(() => { + this.lastBalancesUpdateTimeSubject.next(new Date()); + }); + } + + if (!this.walletsWithBalanceList || forceQuickCompleteArrayUpdate || this.walletsWithBalanceList.length !== temporalWallets.length) { + // Update the whole list. + this.walletsWithBalanceList = temporalWallets; + this.informDataUpdated(); + } else { + // If there is a change in the IDs of the wallet list, update the whole list. + let changeDetected = false; + this.walletsWithBalanceList.forEach((currentWallet, i) => { + if (currentWallet.id !== temporalWallets[i].id) { + changeDetected = true; + } + }); + + if (changeDetected) { + this.walletsWithBalanceList = temporalWallets; + this.informDataUpdated(); + } else { + // Update only the balances with changes. This allows to show updated data without + // having to completelly replace the wallet array. + this.walletsWithBalanceList.forEach((currentWallet, i) => { + if (!currentWallet.coins.isEqualTo(temporalWallets[i].coins) || !currentWallet.confirmedCoins.isEqualTo(temporalWallets[i].confirmedCoins)) { + currentWallet.coins = temporalWallets[i].coins; + currentWallet.confirmedCoins = temporalWallets[i].confirmedCoins; + currentWallet.availableCoins = temporalWallets[i].availableCoins; + currentWallet.hasPendingCoins = temporalWallets[i].hasPendingCoins; + + changeDetected = true; + } + + if (currentWallet.addresses.length !== temporalWallets[i].addresses.length) { + currentWallet.addresses = temporalWallets[i].addresses; + changeDetected = true; + } else { + currentWallet.addresses.forEach((currentAddress, j) => { + if (!currentAddress.coins.isEqualTo(temporalWallets[i].addresses[j].coins) || !currentAddress.confirmedCoins.isEqualTo(temporalWallets[i].addresses[j].confirmedCoins)) { + currentAddress.coins = temporalWallets[i].addresses[j].coins; + currentAddress.confirmedCoins = temporalWallets[i].addresses[j].confirmedCoins; + currentAddress.availableCoins = temporalWallets[i].addresses[j].availableCoins; + currentAddress.hasPendingCoins = temporalWallets[i].addresses[j].hasPendingCoins; + + changeDetected = true; + } + }); + } + }); + + // If any of the balances changed, inform that there were changes. + if (changeDetected) { + this.informDataUpdated(); + } + } + } + + if (!forceQuickCompleteArrayUpdate) { + this.savedBalanceData = this.temporalSavedBalanceData; + this.ngZone.run(() => this.savedBalanceDataSubject.next()); + if (!this.firstFullUpdateMadeSubject.value) { + // Inform that the service already obtained the balance from the backend for the + // first time. + this.ngZone.run(() => { + this.firstFullUpdateMadeSubject.next(true); + }); + } + } + })); + } + + /** + * Gets from the backend the balance of a wallet and uses the retrieved data to update an + * instamce of WalletWithBalance. It also saves the retrieved data on temporalSavedBalanceData. + * @param wallet Wallet to update. + * @param lastBlock Number of the last block on the blockchain. Used only if + * useSavedBalanceData is true. + * @param useSavedBalanceData If true, the balance data saved on savedBalanceData + * will be used instead of retrieving the data from the backend. + * @returns True if there are one or more pending transactions that will affect the balance of + * the provided walled, false otherwise. If useSavedBalanceData is true, the value of + * hasPendingTransactionsSubject will be returned. + */ + private retrieveWalletBalance(wallet: WalletWithBalance, lastBlock: number, useSavedBalanceData: boolean): Observable { + let query: Observable; + + let hasUnconfirmedTxs = false; + + if (!useSavedBalanceData) { + // Get the balance of all addresses. + const addresses = wallet.addresses.map(a => a.printableAddress); + query = this.recursivelyGetBalances(addresses, lastBlock).pipe(mergeMap(result => { + const response = new WalletBalance(this.walletsAndAddressesOperator); + + result.forEach((addressBalance, address) => { + // Add the values to the balance of the wallet. + response.addresses.set(address, addressBalance); + response.current = response.current.plus(addressBalance.current); + response.predicted = response.predicted.plus(addressBalance.predicted); + response.available = response.available.plus(addressBalance.available); + + if (!addressBalance.current.isEqualTo(addressBalance.predicted)) { + hasUnconfirmedTxs = true; + } + }); + + return of(response); + })); + } else { + // Get the balance from the saved data, if possible. + if (this.savedBalanceData.has(wallet.id)) { + query = of(this.savedBalanceData.get(wallet.id)); + } else { + query = of(new WalletBalance(this.walletsAndAddressesOperator)); + } + } + + // Add the values to the wallet object. + return query.pipe(map(balance => { + this.temporalSavedBalanceData.set(wallet.id, balance); + + wallet.coins = balance.predicted; + wallet.confirmedCoins = balance.current; + wallet.availableCoins = balance.available; + wallet.hasPendingCoins = !wallet.coins.isEqualTo(wallet.confirmedCoins); + + wallet.addresses.forEach(address => { + if (balance.addresses.has(address.printableAddress)) { + address.coins = balance.addresses.get(address.printableAddress).predicted; + address.confirmedCoins = balance.addresses.get(address.printableAddress).current; + address.availableCoins = balance.addresses.get(address.printableAddress).available; + address.hasPendingCoins = !address.coins.isEqualTo(address.confirmedCoins); + } else { + address.coins = new BigNumber(0); + address.confirmedCoins = new BigNumber(0); + address.availableCoins = new BigNumber(0); + address.hasPendingCoins = false; + } + }); + + if (!useSavedBalanceData) { + return hasUnconfirmedTxs; + } else { + return this.hasPendingTransactionsSubject.value; + } + })); + } + + /** + * Gets the balance of the addresses in the provided address list. + * @param addresses Addresses to check. The list will be altered by the function. + * @param lastBlock Number of the last block on the blockchain. + * @param currentElements Already obtained balance. For internal use. + * @returns Array with all the balance of the provided address list. + */ + private recursivelyGetBalances( + addresses: string[], + lastBlock: number, + currentElements = new AddressMap(this.walletsAndAddressesOperator.formatAddress), + ): Observable> { + + if (addresses.length === 0) { + return of(currentElements); + } + + const requestParams = { + details: 'txslight', + }; + + // When requesting the balance, the transactions of the blocks considered unconfirmed + // will be obtained too, to consider the balance moved in them as pending. This is + // because Blockbook only considers as pending the balance in the transactions which + // are still in the mempool. + if (this.currentCoin.confirmationsNeeded > 1) { + const lastUnconfirmedBlock = lastBlock - (this.currentCoin.confirmationsNeeded - 2); + requestParams['from'] = lastUnconfirmedBlock; + } else { + // Get only the transactions in the mempool, as only 1 confirmation is needed. + requestParams['from'] = -1; + } + + // Get the balance of the address. + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'address/' + addresses[addresses.length - 1], requestParams).pipe(mergeMap((response) => { + // Save the predicted balance with all unconfirmed transactions. Blockbook returns in the + // "balance" property the balance considering all the transactions already in a block and + // in the "unconfirmedBalance" property the variance in the balance after confirming the + // transactions currently in the mempool. NOTE: the "unconfirmedBalance" property will be + // 0 if the "to" param has a value set when calling the "/address" API endpoint. + const predicted = response.balance ? new BigNumber(response.balance).plus(response.unconfirmedBalance) : new BigNumber(0); + + // If the response has transactions, the balance in those transactions is + // considered as unconfirmed. + const unconfirmed = this.calculateBalanceFromTransactions(response.transactions, addresses[addresses.length - 1]); + // Calculate the currently confirmed balance. + const balance = predicted.minus(unconfirmed); + + // Calculate how many coins are entering the address in the pending transactions. + const incomingBalance = this.calculateBalanceFromTransactions(response.transactions, addresses[addresses.length - 1], true); + // The available balance is all the confirmed coins minus all coins going out. + let available = predicted.minus(incomingBalance); + // This prevents problems if the address sends coins to itself. + if (available.isLessThan(0)) { + available = new BigNumber(0); + } + + // Value which will allow to get the value in coins, instead of sats. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as BtcCoinConfig).decimals); + + // Create the response object. + currentElements.set(addresses[addresses.length - 1], { + current: balance.dividedBy(decimalsCorrector), + predicted: predicted.dividedBy(decimalsCorrector), + available: available.dividedBy(decimalsCorrector), + }); + + addresses.pop(); + + if (addresses.length === 0) { + return of(currentElements); + } + + // Continue to the next step. + return this.recursivelyGetBalances(addresses, lastBlock, currentElements); + })); + } + + /** + * Calculates the final balance of an address after several transactions, assuming that the + * initial balance is 0. + * @param transactions Transactions to check. Must be the array returned by Blockbook when + * calling the "address/" API endpoint. Can be null, as the api may not return any value. + * @param address Address to check. + * @param onlyIncoming If true, only the balance entering the address will be taken + * into account. + */ + private calculateBalanceFromTransactions(transactions: any[], address: string, onlyIncoming = false): BigNumber { + let balance = new BigNumber(0); + const addressObject = AddressBase.create(this.walletsAndAddressesOperator.formatAddress, address); + + if (transactions && transactions.length > 0) { + transactions.forEach(transaction => { + // Remove the balance in the inputs related to the current address. + if (!onlyIncoming && transaction.vin && (transaction.vin as any[]).length > 0) { + (transaction.vin as any[]).forEach(input => { + if (input.isAddress && input.addresses && (input.addresses as any[]).length === 1 && addressObject.compareAddress((input.addresses as any[])[0])) { + if (input.value) { + balance = balance.minus(input.value); + } + } + }); + } + + // Add the balance in the outputs related to the current address. + if (transaction.vout && (transaction.vout as any[]).length > 0) { + (transaction.vout as any[]).forEach(output => { + if (output.isAddress && output.addresses && (output.addresses as any[]).length === 1 && addressObject.compareAddress((output.addresses as any[])[0])) { + if (output.value) { + balance = balance.plus(output.value); + } + } + }); + } + }); + } + + return balance; + } + + /** + * Makes walletsWithBalanceSubject emit, to inform that the wallet list has been updated. + */ + private informDataUpdated() { + this.ngZone.run(() => { + this.walletsWithBalanceSubject.next(this.walletsWithBalanceList); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-blockchain-operator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-blockchain-operator.ts new file mode 100644 index 0000000..5631ba4 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-blockchain-operator.ts @@ -0,0 +1,177 @@ +import { Subscription, of, Observable, ReplaySubject } from 'rxjs'; +import { delay, map, mergeMap, filter, first } from 'rxjs/operators'; +import { NgZone, Injector } from '@angular/core'; +import BigNumber from 'bignumber.js'; + +import * as moment from 'moment'; + +import { Coin } from '../../../coins/coin'; +import { ProgressEvent, BlockchainState } from '../../blockchain.service'; +import { BlockchainOperator } from '../blockchain-operator'; +import { environment } from '../../../../environments/environment'; +import { BtcCoinConfig } from '../../../coins/coin-type-configs/btc.coin-config'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; + +/** + * Operator for BlockchainService to be used with btc-like coins.. + * + * You can find more information about the functions and properties this class implements by + * checking BlockchainService and BlockchainOperator. + */ +export class BtcBlockchainOperator implements BlockchainOperator { + private progressSubject: ReplaySubject = new ReplaySubject(1); + + private dataSubscription: Subscription; + private operatorsSubscription: Subscription; + + /** + * If the node was synchronized the last time it was checked. + */ + private nodeSynchronized = false; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 2 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 2 * 1000; + + get progress(): Observable { + return this.progressSubject.asObservable(); + } + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services and operators used by this operator. + private blockbookApiService: BlockbookApiService; + private ngZone: NgZone; + private balanceAndOutputsOperator: BalanceAndOutputsOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.blockbookApiService = injector.get(BlockbookApiService); + this.ngZone = injector.get(NgZone); + + // Intervals for updating the data must be longer if connecting to a remote backend. + if (!currentCoin.isLocal) { + this.updatePeriod = 120 * 1000; + this.errorUpdatePeriod = 30 * 1000; + } + + this.currentCoin = currentCoin; + + // Get the operators and only then start using them. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.balanceAndOutputsOperator = operators.balanceAndOutputsOperator; + + // Start checking the state of the blockchain. + this.startDataRefreshSubscription(0); + }); + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + + this.progressSubject.complete(); + } + + getBlockchainState(): Observable { + // Get the basic info from Blockbook. + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api').pipe(map(result => { + let currentBlock = result.blockbook.bestHeight; + let currentSupply = new BigNumber(0); + let reward = new BigNumber((this.currentCoin.config as BtcCoinConfig).initialMiningReward); + + // Calculate how many coins have been mined. + while (currentBlock > 0) { + if (currentBlock < (this.currentCoin.config as BtcCoinConfig).halvingBlocks) { + currentSupply = currentSupply.plus(reward.multipliedBy(currentBlock)); + currentBlock = 0; + } else { + currentSupply = currentSupply.plus(reward.multipliedBy((this.currentCoin.config as BtcCoinConfig).halvingBlocks)); + currentBlock -= (this.currentCoin.config as BtcCoinConfig).halvingBlocks; + reward = reward.dividedBy(2); + } + } + + return { + lastBlock: { + seq: result.blockbook.bestHeight, + timestamp: moment(result.blockbook.lastBlockTime).unix(), + hash: result.backend.bestBlockHash, + }, + coinSupply: { + currentSupply: currentSupply.toString(), + totalSupply: (this.currentCoin.config as BtcCoinConfig).totalSupply.toString(), + }, + }; + })); + } + + /** + * Makes the operator start periodically checking the synchronization state of the blockchain. + * If this function was called before, the previous procedure is cancelled. + * @param delayMs Delay before starting to check the data. + */ + private startDataRefreshSubscription(delayMs: number) { + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + + this.ngZone.runOutsideAngular(() => { + this.dataSubscription = of(0).pipe( + delay(delayMs), + mergeMap(() => { + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api'); + }), + ).subscribe(result => { + this.ngZone.run(() => { + // If Blockbook and the node are out of sync but only by 1 or 2 blocks, retry after a + // small delay. + const blockbookBlocksBehind = new BigNumber(result.backend.blocks).minus(result.blockbook.bestHeight); + if (blockbookBlocksBehind.isGreaterThan(0) && blockbookBlocksBehind.isLessThanOrEqualTo(2)) { + this.startDataRefreshSubscription(10000); + + return; + } + + // Consider the blockchain out of sync if the last block is very old. + let synchronized = environment.ignoreNonFiberNetworIssues ? true : + Date.now() - (moment(result.blockbook.lastBlockTime).unix() * 1000) < (this.currentCoin.config as BtcCoinConfig).outOfSyncMinutes * 60000; + + // If Blockbook and the node are more than 2 blocks appart, consider everything + // out of sync. + if (blockbookBlocksBehind.isGreaterThan(2)) { + synchronized = false; + } + + this.progressSubject.next({ + currentBlock: 0, + highestBlock: 0, + synchronized: synchronized, + }); + + // If the node was out of sync and now it is not, refresh the balance. + if (synchronized && !this.nodeSynchronized) { + this.balanceAndOutputsOperator.refreshBalance(); + } + + this.nodeSynchronized = synchronized; + + // Refresh faster if the node is out of sync. + this.startDataRefreshSubscription(synchronized ? this.updatePeriod : this.errorUpdatePeriod); + }); + }, () => { + this.startDataRefreshSubscription(this.errorUpdatePeriod); + }); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-history-operator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-history-operator.ts new file mode 100644 index 0000000..6ab01e9 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-history-operator.ts @@ -0,0 +1,170 @@ +import { of, Observable, Subscription } from 'rxjs'; +import { first, mergeMap, filter, map } from 'rxjs/operators'; +import { Injector } from '@angular/core'; +import BigNumber from 'bignumber.js'; + +import { StorageService } from '../../storage.service'; +import { WalletBase, AddressMap } from '../../wallet-operations/wallet-objects'; +import { Coin } from '../../../coins/coin'; +import { getTransactionsHistory, recursivelyGetTransactions } from './utils/btc-history-utils'; +import { PendingTransactionsResponse, AddressesHistoryResponse, PendingTransactionData, TransactionHistory, TransactionLimits } from '../../wallet-operations/history.service'; +import { HistoryOperator } from '../history-operator'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; +import { OperatorService } from '../../operators.service'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; +import { BtcCoinConfig } from '../../../coins/coin-type-configs/btc.coin-config'; +import { AppConfig } from '../../../app.config'; + +/** + * Operator for HistoryService to be used with btc-like coins. + * + * NOTE: still under heavy development. + * + * You can find more information about the functions and properties this class implements by + * checking HistoryOperator and HistoryService. + */ +export class BtcHistoryOperator implements HistoryOperator { + // Coin the current instance will work with. + private currentCoin: Coin; + + private operatorsSubscription: Subscription; + + // Services and operators used by this operator. + private blockbookApiService: BlockbookApiService; + private storageService: StorageService; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.storageService = injector.get(StorageService); + this.blockbookApiService = injector.get(BlockbookApiService); + + // Get the operators. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + } + + getIfAddressesUsed(wallet: WalletBase): Observable> { + const addresses = wallet.addresses.map(address => address.printableAddress); + + return this.recursivelyGetIfAddressesUsed(addresses); + } + + /** + * Checks the provided addresses and returns a map indicating which ones have been used, + * defined as having received coins. + * @param addresses Addresses to check. The list will be altered by the function. + * @param currentElements Already obtained data. For internal use. + */ + private recursivelyGetIfAddressesUsed(addresses: string[], currentElements = new AddressMap(this.walletsAndAddressesOperator.formatAddress)): Observable> { + if (addresses.length === 0) { + return of(currentElements); + } + + // Get the information of the address. + this.blockbookApiService.get(this.currentCoin.indexerUrl, 'address/' + addresses[addresses.length - 1], {details: 'basic'}) + .pipe(mergeMap((response) => { + // Check is the address has received coins. + currentElements.set(addresses[addresses.length - 1], response.totalReceived && new BigNumber(response.totalReceived).isGreaterThan(0)); + + addresses.pop(); + + if (addresses.length === 0) { + return of(currentElements); + } + + // Continue to the next step. + return this.recursivelyGetIfAddressesUsed(addresses, currentElements); + })); + } + + getTransactionsHistory(wallet: WalletBase|null, transactionLimitperAddress: TransactionLimits): Observable { + // Use the provided wallet or get all wallets. + let initialRequest: Observable; + if (wallet) { + initialRequest = of([wallet]); + } else { + initialRequest = this.walletsAndAddressesOperator.currentWallets; + } + + // Get the history. + return initialRequest.pipe(first(), mergeMap(wallets => { + return getTransactionsHistory(this.currentCoin, wallets, transactionLimitperAddress, this.blockbookApiService, this.storageService, this.walletsAndAddressesOperator); + })); + } + + getPendingTransactions(): Observable { + let wallets: WalletBase[]; + + return this.walletsAndAddressesOperator.currentWallets.pipe(first(), mergeMap(response => { + wallets = response; + + // Get the basic backend info to know the number of the lastest block. + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api'); + }), mergeMap(generalData => { + // Allows to avoid repeating addresses. + const addressMap = new AddressMap(this.walletsAndAddressesOperator.formatAddress); + + // Get all the addresses of the wallets. + const addresses: string[] = []; + wallets.forEach(w => { + w.addresses.map(add => { + if (!addressMap.has(add.printableAddress)) { + addresses.push(add.printableAddress); + addressMap.set(add.printableAddress, true); + } + }); + }); + + // Calculate how many transactions to get per address. + const hasManyAddresses = addresses.length > AppConfig.fewAddressesLimit; + const transactionsToGet = hasManyAddresses ? AppConfig.maxTxPerAddressIfManyAddresses : AppConfig.maxTxPerAddressIfFewAddresses; + + // Determine the initial block to get only the pending transactions. + const startingBlock = generalData.blockbook.bestHeight - (this.currentCoin.confirmationsNeeded - 1); + + // Get the history. + return recursivelyGetTransactions(this.currentCoin, this.blockbookApiService, this.walletsAndAddressesOperator, addresses, transactionsToGet, startingBlock); + }), map(response => { + // Security measure for race conditions, as 2 request were made. + response.transactions = response.transactions.filter(tx => !tx.confirmations || tx.confirmations < this.currentCoin.confirmationsNeeded); + + return { + user: response.transactions.map(tx => this.processTransactionData(tx)).sort((a, b) => b.confirmations - a.confirmations), + all: [], + }; + })); + } + + getAddressesHistory(wallet: WalletBase): Observable { + return null; + } + + /** + * Converts a pending transaction returned by the server to a PendingTransactionData instance. + * @param transaction Transaction returned by the server. + */ + private processTransactionData(transaction: any): PendingTransactionData { + // Value which will allow to get the value in coins, instead of sats. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as BtcCoinConfig).decimals); + + let coins = new BigNumber('0'); + transaction.vout.map(output => { + coins = coins.plus(new BigNumber(output.value).dividedBy(decimalsCorrector)); + }); + + return { + coins: coins.toString(), + timestamp: transaction.blockTime ? transaction.blockTime : null, + id: transaction.txid, + confirmations: transaction.confirmations ? transaction.confirmations : 0, + }; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-network-operator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-network-operator.ts new file mode 100644 index 0000000..a2b7b7b --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-network-operator.ts @@ -0,0 +1,94 @@ +import { mergeMap, delay } from 'rxjs/operators'; +import { NgZone, Injector } from '@angular/core'; +import { Observable, of, Subscription } from 'rxjs'; + +import { NetworkOperator, Connection } from '../network-operator'; +import { Coin } from '../../../coins/coin'; +import { BtcApiService } from '../../api/btc-api.service'; +import { environment } from '../../../../environments/environment'; + +/** + * Operator for NetworkService to be used with btc-like coins. + * + * NOTE: only for knowing if the node is connected to other nodes. Remote nodes data not + * available for this coin type. + * + * You can find more information about the functions and properties this class implements by + * checking NetworkService and NetworkOperator. + */ +export class BtcNetworkOperator implements NetworkOperator { + get noConnections(): boolean { + return this.noConnectionsInternal; + } + noConnectionsInternal = false; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 5 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 5 * 1000; + + private dataRefreshSubscription: Subscription; + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private btcApiService: BtcApiService; + private ngZone: NgZone; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.btcApiService = injector.get(BtcApiService); + this.ngZone = injector.get(NgZone); + + this.currentCoin = currentCoin; + + // Intervals for updating the data must be longer if connecting to a remote node. + if (!currentCoin.isLocal) { + this.updatePeriod = 120 * 1000; + this.errorUpdatePeriod = 30 * 1000; + } + + // Start updating the data periodically. + this.startDataRefreshSubscription(0); + } + + dispose() { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + } + + connections(): Observable { + // Data not available for this coin type + return of(null); + } + + /** + * Makes the operator start updating the data periodically. If this function was called + * before, the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the data. + */ + private startDataRefreshSubscription(delayMs: number) { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + this.ngZone.runOutsideAngular(() => { + this.dataRefreshSubscription = of(0).pipe(delay(delayMs), mergeMap(() => { + return this.btcApiService.callRpcMethod(this.currentCoin.nodeUrl, 'getconnectioncount'); + })).subscribe(result => { + this.ngZone.run(() => { + this.noConnectionsInternal = environment.ignoreNonFiberNetworIssues ? false : result < 1; + }); + + // Repeat the operation after an appropiate delay. + this.startDataRefreshSubscription(this.updatePeriod); + }, () => this.startDataRefreshSubscription(this.errorUpdatePeriod)); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-node-operator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-node-operator.ts new file mode 100644 index 0000000..60f9403 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-node-operator.ts @@ -0,0 +1,82 @@ +import { delay, mergeMap } from 'rxjs/operators'; +import { BigNumber } from 'bignumber.js'; +import { Subscription, of, Observable, BehaviorSubject } from 'rxjs'; +import { Injector } from '@angular/core'; + +import { NodeOperator } from '../node-operator'; +import { Coin } from '../../../coins/coin'; +import { BtcCoinConfig } from '../../../coins/coin-type-configs/btc.coin-config'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; + +/** + * Operator for NodeService to be used with btc-like coins. + * + * You can find more information about the functions and properties this class implements by + * checking NodeService and NodeOperator. + */ +export class BtcNodeOperator implements NodeOperator { + get remoteNodeDataUpdated(): Observable { + return this.remoteNodeDataUpdatedInternal.asObservable(); + } + private remoteNodeDataUpdatedInternal = new BehaviorSubject(false); + + get nodeVersion() { + return this.nodeVersionInternal; + } + private nodeVersionInternal = ''; + + get currentMaxDecimals() { + return (this.currentCoin.config as BtcCoinConfig).decimals; + } + + get burnRate() { + return this.burnRateInternal; + } + private burnRateInternal = new BigNumber(1); + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private blockbookApiService: BlockbookApiService; + + private basicInfoSubscription: Subscription; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.blockbookApiService = injector.get(BlockbookApiService); + + this.currentCoin = currentCoin; + + this.updateData(0); + } + + dispose() { + if (this.basicInfoSubscription) { + this.basicInfoSubscription.unsubscribe(); + } + + this.remoteNodeDataUpdatedInternal.complete(); + } + + /** + * Connects to the node to get the data. + */ + private updateData(delayMs: number) { + if (this.basicInfoSubscription) { + this.basicInfoSubscription.unsubscribe(); + } + + this.basicInfoSubscription = of(1).pipe( + delay(delayMs), + mergeMap(() => this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api')), + ).subscribe(response => { + this.nodeVersionInternal = response.backend.version; + + this.remoteNodeDataUpdatedInternal.next(true); + }, () => { + // If there is an error, retry after a delay. + this.updateData(this.currentCoin.isLocal ? 2000 : 15000); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-operators-generator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-operators-generator.ts new file mode 100644 index 0000000..9001879 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-operators-generator.ts @@ -0,0 +1,33 @@ +import { Injector } from '@angular/core'; + +import { OperatorSet } from '../../operators.service'; +import { Coin } from '../../../coins/coin'; +import { OperatorsGenerator } from '../operators-generator'; +import { FiberSoftwareWalletOperator } from '../fiber/fiber-software-wallet-operator'; +import { BtcNodeOperator } from './btc-node-operator'; +import { BtcWalletsAndAddressesOperator } from './btc-wallets-and-addresses-operator'; +import { BtcBalanceAndOutputsOperator } from './btc-balance-and-outputs-operator'; +import { BtcBlockchainOperator } from './btc-blockchain-operator'; +import { BtcNetworkOperator } from './btc-network-operator'; +import { BtcHistoryOperator } from './btc-history-operator'; +import { BtcSpendingOperator } from './btc-spending-operator'; +import { BtcWalletUtilsOperator } from './btc-wallet-utils-operator'; + +/** + * Generates the complete set of operators for btc-like coins. + */ +export class BtcOperatorsGenerator implements OperatorsGenerator { + generate(coin: Coin, injector: Injector): OperatorSet { + return { + balanceAndOutputsOperator: new BtcBalanceAndOutputsOperator(injector, coin), + blockchainOperator: new BtcBlockchainOperator(injector, coin), + historyOperator: new BtcHistoryOperator(injector, coin), + networkOperator: new BtcNetworkOperator(injector, coin), + nodeOperator: new BtcNodeOperator(injector, coin), + softwareWalletOperator: new FiberSoftwareWalletOperator(injector, coin), + spendingOperator: new BtcSpendingOperator(injector, coin), + walletUtilsOperator: new BtcWalletUtilsOperator(injector, coin), + walletsAndAddressesOperator: new BtcWalletsAndAddressesOperator(injector, coin), + }; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-spending-operator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-spending-operator.ts new file mode 100644 index 0000000..ccb98ba --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-spending-operator.ts @@ -0,0 +1,595 @@ +import { throwError as observableThrowError, of, Observable, Subscription, concat } from 'rxjs'; +import { delay, retryWhen, take, mergeMap, catchError, map, filter, first } from 'rxjs/operators'; +import { Injector } from '@angular/core'; +import { BigNumber } from 'bignumber.js'; +import { TranslateService } from '@ngx-translate/core'; + +import { HwWalletService, HwOutput, HwBtcInput, OperationResult, HwBtcOutput } from '../../hw-wallet.service'; +import { StorageService, StorageType } from '../../storage.service'; +import { WalletBase, AddressMap } from '../../wallet-operations/wallet-objects'; +import { GeneratedTransaction, Output, Input } from '../../wallet-operations/transaction-objects'; +import { Coin } from '../../../coins/coin'; +import { TransactionDestination, HoursDistributionOptions, RecommendedFees } from '../../wallet-operations/spending.service'; +import { SpendingOperator } from '../spending-operator'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; +import { BtcApiService } from '../../api/btc-api.service'; +import { BtcCoinConfig } from '../../../coins/coin-type-configs/btc.coin-config'; +import { BtcInput, BtcOutput, BtcTxEncoder } from './utils/btc-tx-encoder'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; + +/** + * Operator for SpendingService to be used with btc-like coins. + * + * NOTE: still under heavy development. + * + * You can find more information about the functions and properties this class implements by + * checking SpendingOperator and SpendingService. + */ +export class BtcSpendingOperator implements SpendingOperator { + private readonly aproxP2pkhInputSize = 150; + private readonly aproxOutputSize = 34; + + // Coin the current instance will work with. + private currentCoin: Coin; + + private operatorsSubscription: Subscription; + + // Services and operators used by this operator. + private btcApiService: BtcApiService; + private hwWalletService: HwWalletService; + private translate: TranslateService; + private storageService: StorageService; + private balanceAndOutputsOperator: BalanceAndOutputsOperator; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.btcApiService = injector.get(BtcApiService); + this.hwWalletService = injector.get(HwWalletService); + this.translate = injector.get(TranslateService); + this.storageService = injector.get(StorageService); + + // Get the operators. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.balanceAndOutputsOperator = operators.balanceAndOutputsOperator; + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + } + + createTransaction( + wallet: WalletBase|null, + addresses: string[]|null, + unspents: Output[]|null, + destinations: TransactionDestination[], + hoursDistributionOptions: HoursDistributionOptions, + changeAddress: string|null, + password: string|null, + unsigned: boolean, + fee: string): Observable { + + // TODO: more validations are needed. + + // Create a string indicating where the coins come from. + let senderString = ''; + if (wallet) { + senderString = wallet.label; + } else { + if (addresses) { + senderString = addresses.map(add => this.walletsAndAddressesOperator.formatAddress(add)).join(', '); + } else if (unspents) { + senderString = unspents.map(output => output.hash).join(', '); + } + } + + let response: Observable; + + // Get the locking scripts for the destination addresses. + const addressesToCheck = destinations.map(destination => destination.address); + let destinationLockingScripts: AddressMap; + response = this.recursivelyGetAddressesScripts(addressesToCheck).pipe(map(result => { + // If it was not possible to get the script for an address, the address is not valid. + const invalidAddresses: string[] = []; + result.forEach((val, key) => { + if (!val) { + invalidAddresses.push(key); + } + }); + + // If there are invalid addresses, show an error. + if (invalidAddresses.length > 0) { + let errorString = this.translate.instant('send.invalid-address' + (invalidAddresses.length > 1 ? 'es' : '')); + errorString += invalidAddresses.join(', '); + throw new Error(errorString); + } + + // Save the scripts in a map. + destinationLockingScripts = result; + })); + + // Get a list with available outputs for the transaction. + if (unspents) { + response = response.pipe(map(() => unspents)); + } else { + // Get all the outputs of the provided wallet or address list. + let AddressesToCheck_: string[] = []; + if (addresses) { + AddressesToCheck_ = addresses; + } else { + wallet.addresses.forEach(address => AddressesToCheck_.push(address.printableAddress)); + } + + response = response.pipe(mergeMap(() => this.balanceAndOutputsOperator.getOutputs(AddressesToCheck_.join(',')))); + } + + // How many coins will be sent. + let amountToSend = new BigNumber(0); + // Transaction fee. + let calculatedFee = new BigNumber(0); + // Inputs in the format needed; + let processedInputs: Input[]; + // Outputs in the format needed; + const processedOutputs: Output[] = []; + + response = response.pipe(mergeMap((availableOutputs: Output[]) => { + // Order the available outputs from lowest to highest according to the amount of coins. + const outputsToChoseFrom: Output[] = availableOutputs.map(output => output).sort((a, b) => a.coins.minus(b.coins).toNumber()); + // Calculate how many coins are going to be sent (without considering the fee). + destinations.forEach(destination => amountToSend = amountToSend.plus(destination.coins)); + + // Select the inputs for the operation. + const inputs: Output[] = this.recursivelySelectOutputs(outputsToChoseFrom, amountToSend, destinations.length, new BigNumber(fee)); + // Calculate how many coins the inputs have. + let coinsInInputs = new BigNumber(0); + inputs.forEach(input => coinsInInputs = coinsInInputs.plus(input.coins)); + + // If not specific change address was selected, select the one on the first input, which + // is the one with most coins. + if (!changeAddress) { + changeAddress = inputs[0].address; + } + + // Add the fee to the amount of coins needed. The calculation ignores the fee needed for + // the change output, if the selected inputs have more coins than neeed. This is to avoid + // overcomplicating the available balance calculation in the UI. + calculatedFee = this.calculateFinalFee(inputs.length, destinations.length, new BigNumber(fee), null); + const amountNeeded = amountToSend.plus(calculatedFee); + + // Convert the inputs to the correct object type. + processedInputs = inputs.map(input => { + return { + hash: input.hash, + address: this.walletsAndAddressesOperator.formatAddress(input.address), + coins: input.coins, + transactionId: input.transactionId, + indexInTransaction: input.indexInTransaction, + }; + }); + + calculatedFee = coinsInInputs; + + // Convert the outputs to the format needed. The coins of each output + // are removed from the fee. + destinations.forEach(destination => { + processedOutputs.push({ + hash: '', + address: this.walletsAndAddressesOperator.formatAddress(destination.address), + coins: new BigNumber(destination.coins), + lockingScript: destinationLockingScripts.get(destination.address), + }); + + calculatedFee = calculatedFee.minus(destination.coins); + }); + + // Create an extra output for the remaining coins. + if (coinsInInputs.minus(amountNeeded).isGreaterThan(0)) { + processedOutputs.push({ + hash: '', + address: this.walletsAndAddressesOperator.formatAddress(changeAddress), + coins: coinsInInputs.minus(amountNeeded), + lockingScript: '', + returningCoins: true, + }); + + calculatedFee = calculatedFee.minus(coinsInInputs.minus(amountNeeded)); + } + + // Return an error if using a hw wallet and the transaction has too many inputs or outputs. + if (wallet && wallet.isHardware) { + if (processedInputs.length > 8) { + throw new Error(this.translate.instant('hardware-wallet.errors.too-many-inputs-outputs')); + } + if (processedOutputs.length > 8) { + throw new Error(this.translate.instant('hardware-wallet.errors.too-many-inputs-outputs')); + } + } + + // If an extra output was created for the remaining coins, the script needed for that + // output is obtained. + if (coinsInInputs.minus(amountNeeded).isGreaterThan(0)) { + return this.recursivelyGetAddressesScripts([changeAddress]); + } else { + return of(null); + } + }), map((changeAddressData: AddressMap) => { + // Set the script for the output created for the remaining coins, if any. + if (changeAddressData) { + processedOutputs[processedOutputs.length - 1].lockingScript = changeAddressData.get(changeAddress); + } + + // Create the transaction object. + const tx: GeneratedTransaction = { + inputs: processedInputs, + outputs: processedOutputs, + coinsToSend: amountToSend, + fee: calculatedFee, + from: senderString, + to: destinations.map(destination => this.walletsAndAddressesOperator.formatAddress(destination.address)).join(', '), + wallet: wallet, + encoded: '', + innerHash: '', + }; + + return tx; + })); + + // If required, append to the response the steps needed for signing the transaction. + if (wallet && !unsigned) { + let unsignedTx: GeneratedTransaction; + + response = response.pipe(mergeMap(transaction => { + unsignedTx = transaction; + + return this.signTransaction(wallet, null, transaction); + })).pipe(map(encodedSignedTx => { + unsignedTx.encoded = encodedSignedTx; + + return unsignedTx; + })); + } + + return response; + } + + /** + * Selects the outputs that should be used as inputs for a transaction. The function will + * try to use as few outputs as possible, prefering the ones with less coins. However, the + * function may add an additional input if the solution with the least amount of inputs + * would require to create a change output with so few coins that it would not be convenient + * to send it due to the fees. + * @param outputs List with the outputs available to be used. Must be ordered from lowest + * to highest according to the amount of coins. The list will be altered by the function. + * @param amountToSend How many coins are going to be sent in the transaction. + * @param destinations How many destinations the transaction will have. + * @param feePerUnit Approximate amount of sats per byte that will be paid as fee. Note: the + * function ignores the fee needed for the change output, if the selected inputs have more + * coins than neeed. This is to avoid overcomplicating the available balance calculation in + * the UI. + * @param currentlySelectedBalance Coins in the already selected outputs. For internal use. + * @param currentlySelectedOutputs Already selected outputs. For internal use. + */ + private recursivelySelectOutputs( + outputs: Output[], + amountToSend: BigNumber, + destinations: number, + feePerUnit: BigNumber, + currentlySelectedBalance = new BigNumber(0), + currentlySelectedOutputs: Output[] = [], + ): Output[] { + + if (outputs.length < 1) { + return currentlySelectedOutputs; + } + + // Check the outputs in ascending order (according to the coins). + for (let i = 0; i < outputs.length; i++) { + // How many coins the procedure would have with the inputs selected in the previous steps + // of the recursive procedure and the one being checked right now. + const potentinalNewSelectedBalance = currentlySelectedBalance.plus(outputs[i].coins); + + if (potentinalNewSelectedBalance.isGreaterThan(amountToSend)) { + // Add the fee to the amount of coins needed. + const calculatedFee = this.calculateFinalFee(currentlySelectedOutputs.length + 1, destinations, feePerUnit, null); + const totalAmountNeeded = amountToSend.plus(calculatedFee); + + // Check if no more coins are needed. + if (potentinalNewSelectedBalance.isGreaterThanOrEqualTo(totalAmountNeeded)) { + // Add the output to the list of the ones that have been selected. + currentlySelectedOutputs.push(outputs[i]); + + // Needed for converting from sats to coins. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as BtcCoinConfig).decimals); + + // Check how many coins will have to be added to a change output and how much would + // it cost to use that change output in a future transaction if using the current fee. + const remainingCoins = potentinalNewSelectedBalance.minus(totalAmountNeeded); + const aproxChangeOutputCost = new BigNumber(this.aproxP2pkhInputSize).multipliedBy(feePerUnit).dividedBy(decimalsCorrector); + + // If the change output is needed but it would cost more than 10% of its value to + // send it in a future transaction, try to add another input. + if (!remainingCoins.isEqualTo(0) && remainingCoins.isLessThan(aproxChangeOutputCost.multipliedBy(10))) { + for (let j = 0; j < outputs.length; j++) { + if (j !== i) { + // Check the amounts that would be obtained after adding the new input. + const balanceWithAdditionalInput = potentinalNewSelectedBalance.plus(outputs[j].coins); + const calculatedFeeWithAdditionalInput = this.calculateFinalFee(currentlySelectedOutputs.length + 1, destinations, feePerUnit, null); + const totalAmountNeededWithAdditionalInput = amountToSend.plus(calculatedFeeWithAdditionalInput); + const remainingCoinsWithAdditionalInput = balanceWithAdditionalInput.minus(totalAmountNeededWithAdditionalInput); + + // If the new input causes the change output to be spendable without having + // to pay more than 10% of its value in fees, use it. + if (remainingCoinsWithAdditionalInput.isGreaterThanOrEqualTo(aproxChangeOutputCost.multipliedBy(10))) { + currentlySelectedOutputs.push(outputs[j]); + + break; + } + } + } + } + + return currentlySelectedOutputs; + } + } + } + + // If no output in this pass of the recursive procedure was able sum the coins needed, + // add the output with most coins to the selected list and go to the next step. + currentlySelectedOutputs.push(outputs[outputs.length - 1]); + currentlySelectedBalance = currentlySelectedBalance.plus(outputs[outputs.length - 1].coins); + outputs.pop(); + + return this.recursivelySelectOutputs(outputs, amountToSend, destinations, feePerUnit, currentlySelectedBalance, currentlySelectedOutputs); + } + + /** + * Gets the locking scripts needed to send coins to the provided addresses. + * @param addresses Addresses to check. The list will be altered by the function. + * @param currentElements Already obtained data. For internal use. + * @returns Map with the scripts of each address. If an address is invalid, the script is null. + */ + private recursivelyGetAddressesScripts(addresses: string[], currentElements = new AddressMap(this.walletsAndAddressesOperator.formatAddress)): Observable> { + if (addresses.length === 0) { + return of(currentElements); + } + + // Get the data of the last address. + return this.btcApiService.callRpcMethod(this.currentCoin.nodeUrl, 'validateaddress', [addresses[addresses.length - 1]]).pipe(mergeMap(response => { + if (!response.isvalid || !response.scriptPubKey) { + // Do not accept invalid addresses. + currentElements.set(addresses[addresses.length - 1], null); + } else { + currentElements.set(addresses[addresses.length - 1], response.scriptPubKey); + } + + addresses.pop(); + + if (addresses.length === 0) { + return of(currentElements); + } + + // Continue to the next step. + return this.recursivelyGetAddressesScripts(addresses, currentElements); + })); + } + + calculateFinalFee(howManyInputs: number, howManyOutputs: number, feePerUnit: BigNumber, maxUnits: BigNumber): BigNumber { + // Maultiply the inputs and outputs by their aproximate size. + const inputsSize = new BigNumber(howManyInputs).multipliedBy(this.aproxP2pkhInputSize); + const outputsSize = new BigNumber(howManyOutputs).multipliedBy(this.aproxOutputSize); + + const otherDataSize = new BigNumber(10); + + // Needed for returning the value in coins and not satoshis. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as BtcCoinConfig).decimals); + + return inputsSize.plus(outputsSize).plus(otherDataSize).multipliedBy(feePerUnit).dividedBy(decimalsCorrector); + } + + signTransaction( + wallet: WalletBase, + password: string|null, + transaction: GeneratedTransaction, + rawTransactionString = ''): Observable { + + if (rawTransactionString) { + throw new Error('Raw transactions not allowed.'); + } + + // Convert the inputs to the format the encoder needs. + const inputs: BtcInput[] = []; + transaction.inputs.forEach((input, i) => { + const processedInput = new BtcInput(); + processedInput.transaction = input.transactionId; + processedInput.vout = input.indexInTransaction; + processedInput.script = ''; + + inputs.push(processedInput); + }); + + // Needed for converting the coin amounts to sats. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as BtcCoinConfig).decimals); + + // Convert the outputs to the format the encoder needs. + const outputs: BtcOutput[] = []; + transaction.outputs.forEach(output => { + const processedOutput = new BtcOutput(); + + if (!output.lockingScript) { + throw new Error('Locking script not found.'); + } + + processedOutput.satsValue = output.coins.multipliedBy(decimalsCorrector); + processedOutput.script = output.lockingScript; + + outputs.push(processedOutput); + }); + + // Will return the signatures. + let signaturesGenerationProcedure: Observable; + + // Procedure for getting the signatures with a software wallet. + if (!wallet.isHardware) { + const signatures: string[] = []; + + // Temporal test method. + transaction.inputs.forEach((input, i) => { + signatures.push(this.getP2pkhSignature(i)); + }); + + signaturesGenerationProcedure = of(signatures); + + // Procedure for getting the signatures with a hardware wallet. + } else { + const hwOutputs: HwBtcOutput[] = []; + const hwInputs: HwBtcInput[] = []; + + const addressMap = new AddressMap(this.walletsAndAddressesOperator.formatAddress); + wallet.addresses.forEach((address, i) => addressMap.set(address.printableAddress, i)); + + // Convert all inputs and outputs to the format used by the hw wallet. + transaction.outputs.forEach(output => { + hwOutputs.push({ + address: output.address, + coins: output.coins.decimalPlaces(6).toString(10), + }); + + // This makes de device consider the output as the one used for returning the remaining coins. + if (output.returningCoins && addressMap.has(output.address)) { + hwOutputs[hwOutputs.length - 1].address_index = addressMap.get(output.address); + } + }); + transaction.inputs.forEach(input => { + hwInputs.push({ + prev_hash: input.transactionId, + index: addressMap.get(input.address), + }); + }); + + // Make the device sign the transaction. + signaturesGenerationProcedure = this.hwWalletService.signTransaction(hwInputs, hwOutputs).pipe(map((result: OperationResult) => (result.rawResponse as string[]))); + } + + return signaturesGenerationProcedure.pipe(map(signatures => { + if (signatures.length !== inputs.length) { + throw new Error('Invalid number of signatures.'); + } + + transaction.inputs.forEach((input, i) => { + // TODO: currently the signature is added as the script, but more data may be needed + // after the changes for making the hw wallet return valid signatures are made. + inputs[i].script = signatures[i]; + }); + + return BtcTxEncoder.encode(inputs, outputs); + })); + } + + /** + * Temporal function, only for testing, for getting the signature for unlocking an input. For + * using it, you must add the script inside the code. + * @param index Index of the input inside the transaction that is being created. + */ + private getP2pkhSignature(index: number) { + return ''; + } + + injectTransaction(encodedTx: string, note: string|null): Observable { + // Send the transaction. + return this.btcApiService.callRpcMethod(this.currentCoin.nodeUrl, 'sendrawtransaction', [encodedTx, 0]).pipe( + mergeMap(txId => { + // Refresh the balance after a small delay. + setTimeout(() => this.balanceAndOutputsOperator.refreshBalance(), 200); + + if (!note) { + return of(false); + } else { + // Save the note. Retry 3 times if an error is found. + return this.storageService.store(StorageType.NOTES, txId, note).pipe( + retryWhen(errors => concat(errors.pipe(delay(1000), take(3)), observableThrowError(-1))), + catchError(err => err === -1 ? of(-1) : err), + map(result => result === -1 ? false : true)); + } + })); + } + + getCurrentRecommendedFees(): Observable { + let veryLow: BigNumber; + let low: BigNumber; + let normal: BigNumber; + let thereWereProblems = false; + + // Get the recommended fee from the node. + return this.btcApiService.callRpcMethod(this.currentCoin.nodeUrl, 'estimatesmartfee', [20]).pipe(mergeMap(result => { + // The node returns the recommended sats per kb (using 1000 bytes instead of 1024 per kb). + if (!result.errors) { + veryLow = this.returnUsableFee(new BigNumber(result).dividedBy(1000)); + } else { + veryLow = this.returnUsableFee(new BigNumber(1)); + thereWereProblems = true; + } + + return this.btcApiService.callRpcMethod(this.currentCoin.nodeUrl, 'estimatesmartfee', [10]); + }), mergeMap(result => { + if (!result.errors) { + low = this.returnUsableFee(new BigNumber(result).dividedBy(1000)); + } else { + low = this.returnUsableFee(new BigNumber(1)); + thereWereProblems = true; + } + + return this.btcApiService.callRpcMethod(this.currentCoin.nodeUrl, 'estimatesmartfee', [5]); + }), mergeMap(result => { + if (!result.errors) { + normal = this.returnUsableFee(new BigNumber(result).dividedBy(1000)); + } else { + normal = this.returnUsableFee(new BigNumber(1)); + thereWereProblems = true; + } + + return this.btcApiService.callRpcMethod(this.currentCoin.nodeUrl, 'estimatesmartfee', [1]); + }), map(result => { + let high: BigNumber; + let veryHigh: BigNumber; + if (!result.errors) { + high = this.returnUsableFee(new BigNumber(result).dividedBy(1000)); + veryHigh = high.multipliedBy(1.1); + } else { + high = this.returnUsableFee(new BigNumber(1)); + veryHigh = this.returnUsableFee(new BigNumber(1)); + thereWereProblems = true; + } + + return { + recommendedBtcFees: { + veryHigh: veryHigh, + high: high, + normal: normal, + low: low, + veryLow: veryLow, + gasLimit: null, + }, + recommendedEthFees: null, + thereWereProblems: thereWereProblems, + }; + }), retryWhen(errors => errors.pipe(delay(5000)))); + } + + /** + * Checks if the provided fee is lower than the minimum accepted by the node. If the fee is + * lower, the minimum fee is returned, otherwise the provided fee is returned. + * @param fee Fee to check. + */ + private returnUsableFee(fee: BigNumber) { + if (fee.isLessThan((this.currentCoin.config as BtcCoinConfig).minFee)) { + return (this.currentCoin.config as BtcCoinConfig).minFee; + } + + return fee; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-wallet-utils-operator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-wallet-utils-operator.ts new file mode 100644 index 0000000..4399d4b --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-wallet-utils-operator.ts @@ -0,0 +1,51 @@ +import { of, Observable, throwError } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; +import { Injector } from '@angular/core'; + +import { Coin } from '../../../coins/coin'; +import { FiberApiService } from '../../api/fiber-api.service'; +import { WalletUtilsOperator } from '../wallet-utils-operator'; +import { BtcApiService } from '../../api/btc-api.service'; +import { OperationError, OperationErrorTypes } from 'app/utils/operation-error'; +import { processServiceError } from 'app/utils/errors'; + +/** + * Operator for WalletUtilsService to be used with btc-like coins. + * + * You can find more information about the functions and properties this class implements by + * checking WalletUtilsOperator and WalletUtilsService. + */ +export class BtcWalletUtilsOperator implements WalletUtilsOperator { + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private fiberApiService: FiberApiService; + private btcApiService: BtcApiService; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + this.btcApiService = injector.get(BtcApiService); + + this.currentCoin = currentCoin; + } + + dispose() { } + + verifyAddress(address: string): Observable { + return this.btcApiService.callRpcMethod(this.currentCoin.nodeUrl, 'validateaddress', [address]).pipe( + map(result => result.isvalid === true), + catchError((err: OperationError) => { + err = processServiceError(err); + + // Return false in case of error, but not if the error was for a connection problem. + if (err.type !== OperationErrorTypes.NoInternet) { + return of(false); + } else { + return throwError(err); + } + }), + ); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/btc-wallets-and-addresses-operator.ts b/src/gui/static/src/app/services/coin-specific/btc/btc-wallets-and-addresses-operator.ts new file mode 100644 index 0000000..69c02f1 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/btc-wallets-and-addresses-operator.ts @@ -0,0 +1,474 @@ +import { of, Observable, Subscription, ReplaySubject, throwError } from 'rxjs'; +import { mergeMap, map } from 'rxjs/operators'; +import { Injector } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import BigNumber from 'bignumber.js'; + +import { HwWalletService } from '../../hw-wallet.service'; +import { WalletBase, AddressBase, duplicateWalletBase, WalletTypes, AddressMap } from '../../wallet-operations/wallet-objects'; +import { redirectToErrorPage, processServiceError } from '../../../utils/errors'; +import { StorageService, StorageType } from '../../storage.service'; +import { Coin } from '../../../coins/coin'; +import { WalletsAndAddressesOperator, LastAddress, CreateWalletArgs } from '../wallets-and-addresses-operator'; +import { AppConfig } from '../../../app.config'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; + +/** + * Operator for WalletsAndAddressesService to be used with btc-like coins. + * + * NOTE: still under heavy development. + * + * You can find more information about the functions and properties this class implements by + * checking WalletsAndAddressesOperator and WalletsAndAddressesService. + */ +export class BtcWalletsAndAddressesOperator implements WalletsAndAddressesOperator { + /** + * Key used for saving the hw wallet list in persistent storage. NOTE: the value is changed + * in the code to make it unique for the current coin. + */ + private hwWalletsDataStorageKey = 'hw-wallets'; + /** + * Key used for saving the software wallet list in persistent storage. At this state it is only + * for testing. NOTE: the value is changed in the code to make it unique for the current coin. + */ + private swWalletsDataStorageKey = 'sw-wallets'; + + // List with all the wallets of all coins and the subject used for informing when the list + // has been modified. + private walletsList: WalletBase[]; + private walletsSubject: ReplaySubject = new ReplaySubject(1); + // List with the wallets of the currently selected coin. + private currentWalletsList: WalletBase[]; + private currentWalletsSubject: ReplaySubject = new ReplaySubject(1); + + private walletsSubscription: Subscription; + private savingHwWalletDataSubscription: Subscription; + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private hwWalletService: HwWalletService; + private storageService: StorageService; + private blockbookApiService: BlockbookApiService; + private translate: TranslateService; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.hwWalletService = injector.get(HwWalletService); + this.storageService = injector.get(StorageService); + this.blockbookApiService = injector.get(BlockbookApiService); + this.translate = injector.get(TranslateService); + + // Save the coin which will be used by this operator and change the persistent storage vars + // to correspond to the selected coin. + this.currentCoin = currentCoin; + this.hwWalletsDataStorageKey = this.hwWalletsDataStorageKey + '-' + currentCoin.coinName; + this.swWalletsDataStorageKey = this.swWalletsDataStorageKey + '-' + currentCoin.coinName; + } + + initialize(wallets: WalletBase[]) { + this.walletsList = wallets; + + // When the list with all the wallets is updated, the list with the wallets for the current + // coin is updated too. + this.walletsSubscription = this.walletsSubject.subscribe(() => { + this.currentWalletsList = this.walletsList.filter(wallet => wallet.coin === this.currentCoin.coinName); + this.currentWalletsSubject.next(this.currentWalletsList); + }); + + this.informDataUpdated(); + } + + dispose() { + if (this.savingHwWalletDataSubscription) { + this.savingHwWalletDataSubscription.unsubscribe(); + } + if (this.walletsSubscription) { + this.walletsSubscription.unsubscribe(); + } + + this.walletsSubject.complete(); + this.currentWalletsSubject.complete(); + } + + get allWallets(): Observable { + return this.walletsSubject.asObservable(); + } + + get currentWallets(): Observable { + return this.currentWalletsSubject.asObservable(); + } + + addAddressesToWallet(wallet: WalletBase, num: number, password?: string): Observable { + return of(null); + } + + scanAddresses(wallet: WalletBase, password?: string): Observable { + return of(null); + } + + getNextAddressAndUpdateWallet(wallet: WalletBase, password?: string): Observable { + return of(null); + } + + getLastAddressAndUpdateWallet(wallet: WalletBase, checkUnused: boolean): Observable { + return of(null); + } + + updateWallet(wallet: WalletBase): Observable { + return of(null); + } + + informValuesUpdated(wallet: WalletBase) { + const affectedWalletIndex = this.walletsList.findIndex(w => w.id === wallet.id); + if (affectedWalletIndex === -1) { + return; + } + if (this.walletsList[affectedWalletIndex].coin !== this.currentCoin.coinName) { + return; + } + + // Create a duplicate of the provided wallet and save it on the wallet list. + const newWallet = duplicateWalletBase(wallet, true); + this.walletsList[affectedWalletIndex] = newWallet; + + // Save if needed and inform the changes. + if (wallet.isHardware) { + this.saveHardwareWalletsAndInformUpdate(); + } else { + this.informDataUpdated(); + } + } + + createWallet(args: CreateWalletArgs): Observable { + if (!args.isHardwareWallet) { + // Not implemented. + return of(null); + } else { + return this.createHardwareWallet(); + } + } + + /** + * Adds a new hardware wallet to the wallets list, with the data of the currently connected device. + * @returns The newly created wallet. + */ + private createHardwareWallet(): Observable { + let addresses: string[]; + let id: string; + + // Ask the device to return as many addresses as set on AppConfig.maxHardwareWalletAddresses. + return this.hwWalletService.getAddresses(AppConfig.maxHardwareWalletAddresses, 0, this.currentCoin.skywalletCoinType).pipe(mergeMap(response => { + addresses = response.rawResponse; + id = this.getHwWalletID(addresses[0]); + + // Throw an error if any wallet has the same ID. + let walletAlreadyExists = false; + this.walletsList.forEach(wallet => { + if (wallet.id === id) { + walletAlreadyExists = true; + } + }); + if (walletAlreadyExists) { + return throwError(processServiceError('The wallet already exists')); + } + + // Create a copy of the address list and check if any of them already has transactions. + const addressesToCheck = addresses.map(a => a); + + return this.recursivelyGetIfUsed(addressesToCheck); + }), map(response => { + // Get the index of the last address of the list with transaction. + let lastAddressWithTx = 0; + addresses.forEach((address, i) => { + if (response.get(address)) { + lastAddressWithTx = i; + } + }); + + const newWallet = this.createHardwareWalletData( + this.translate.instant('hardware-wallet.general.default-wallet-name'), + addresses.slice(0, lastAddressWithTx + 1).map(add => { + const newAddress = AddressBase.create(this.formatAddress, add); + newAddress.confirmed = false; + + return newAddress; + }), true, false, + ); + + newWallet.id = id; + + // Add the wallet just after the last hw wallet of the wallet list. + let lastHardwareWalletIndex = this.walletsList.length - 1; + for (let i = 0; i < this.walletsList.length; i++) { + if (!this.walletsList[i].isHardware) { + lastHardwareWalletIndex = i - 1; + break; + } + } + this.walletsList.splice(lastHardwareWalletIndex + 1, 0, newWallet); + this.saveHardwareWalletsAndInformUpdate(); + + return newWallet; + })); + } + + /** + * Checks if the provided addresses have been used (received coins). + * @param addresses Addresses to check. The list will be altered by the function. + * @param currentElements Already obtained data. For internal use. + * @returns A map with the addresses as key and a value indicating if the address has + * already been used. + */ + private recursivelyGetIfUsed(addresses: string[], currentElements = new AddressMap(this.formatAddress)): Observable> { + if (addresses.length === 0) { + return of(currentElements); + } + + // Get the basic state of the address. + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'address/' + addresses[addresses.length - 1], {details: 'basic'}) + .pipe(mergeMap((response) => { + // Check if the addresses has received coins. + const received = response.totalReceived ? new BigNumber(response.totalReceived) : new BigNumber(0); + currentElements.set(addresses[addresses.length - 1], received.isGreaterThan(0)); + + addresses.pop(); + + if (addresses.length === 0) { + return of(currentElements); + } + + // Continue to the next step. + return this.recursivelyGetIfUsed(addresses, currentElements); + })); + } + + deleteWallet(walletId: string) { + const index = this.walletsList.findIndex(w => w.id === walletId); + if (index === -1 || !this.walletsList[index].isHardware) { + return; + } + + this.walletsList.splice(index, 1); + this.saveHardwareWalletsAndInformUpdate(); + } + + /** + * Saves on persistent storage the data of the hw wallets on the wallet list for the current + * coin. It overwrites the previously saved data. It also calls informDataUpdated(). + */ + private saveHardwareWalletsAndInformUpdate() { + const hardwareWallets: WalletBase[] = []; + + this.walletsList.map(wallet => { + if (wallet.coin === this.currentCoin.coinName && wallet.isHardware) { + hardwareWallets.push(this.createHardwareWalletData( + wallet.label, + wallet.addresses.map(address => { + const newAddress = AddressBase.create(this.formatAddress, address.printableAddress); + newAddress.confirmed = address.confirmed; + + return newAddress; + }), + wallet.hasHwSecurityWarnings, + wallet.stopShowingHwSecurityPopup, + )); + } + }); + + // Cancel any previous saving operation. + if (this.savingHwWalletDataSubscription) { + this.savingHwWalletDataSubscription.unsubscribe(); + } + + // The data is saved as a JSON string. + this.savingHwWalletDataSubscription = + this.storageService.store(StorageType.CLIENT, this.hwWalletsDataStorageKey, JSON.stringify(hardwareWallets)) + .subscribe({ + next: null, + error: () => redirectToErrorPage(3), + }); + + this.informDataUpdated(); + } + + /** + * Helper function for creating a WalletBase object for a hw wallet. + */ + private createHardwareWalletData(label: string, addresses: AddressBase[], hasHwSecurityWarnings: boolean, stopShowingHwSecurityPopup: boolean): WalletBase { + return { + label: label, + id: '', + hasHwSecurityWarnings: hasHwSecurityWarnings, + stopShowingHwSecurityPopup: stopShowingHwSecurityPopup, + addresses: addresses, + encrypted: false, + isHardware: true, + walletType: WalletTypes.Deterministic, + coin: this.currentCoin.coinName, + }; + } + + loadWallets(): Observable { + let wallets: WalletBase[] = []; + + // Get the software wallets. + return this.loadSoftwareWallets().pipe(mergeMap((response: any[]) => { + wallets = response; + + // Get the hardware wallets. + if (this.hwWalletService.hwWalletCompatibilityActivated) { + return this.loadHardwareWallets(); + } + + return of([]); + }), map((hardwareWallets: WalletBase[]) => { + // Hw wallets are first on the list. + return hardwareWallets.concat(wallets); + })); + } + + /** + * Loads all the hw wallets saved on persistent storage. + * @returns The list of hw wallets. + */ + private loadHardwareWallets(): Observable { + return this.storageService.get(StorageType.CLIENT, this.hwWalletsDataStorageKey).pipe( + map(storedWallets => { + if (storedWallets) { + const loadedWallets: WalletBase[] = JSON.parse(storedWallets); + + // Prepare to remove all unexpected properties, which could have been saved in a + // previous version of the app. + const knownPropertiesMap = new Map(); + const referenceObject = new WalletBase(); + Object.keys(referenceObject).forEach(property => { + knownPropertiesMap.set(property, true); + }); + + loadedWallets.forEach(wallet => { + // Remove all unexpected properties. + const propertiesToRemove: string[] = []; + Object.keys(wallet).forEach(property => { + if (!knownPropertiesMap.has(property)) { + propertiesToRemove.push(property); + } + }); + propertiesToRemove.forEach(property => { + delete wallet[property]; + }); + + // The wallet must be identified as a hw wallet and have at least one address. + // This is just a precaution. + wallet.isHardware = true; + if (!wallet.addresses) { + const newAddress = AddressBase.create(this.formatAddress, 'invalid'); + newAddress.confirmed = false; + wallet.addresses = [newAddress]; + } + + for (let i = 0; i < wallet.addresses.length; i++) { + const confirmed = wallet.addresses[i].confirmed; + const isChangeAddress = wallet.addresses[i].isChangeAddress; + + // Convert the saved address to the expected format. + if (wallet.addresses[i]['address']) { + // If the address was saved with the old format. + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['address']); + } else if (wallet.addresses[i]['printableAddressInternal']) { + // If the address was saved with the current format. + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['printableAddressInternal']); + } else { + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['invalid']); + } + + wallet.addresses[i].confirmed = confirmed; + wallet.addresses[i].isChangeAddress = isChangeAddress; + } + + // If the value was not retrieved, it means that the wallet was saved with a previous + // version of the app, which only used the Deterministic type for hw wallets. + if (!wallet.walletType) { + wallet.walletType = WalletTypes.Deterministic; + } + + wallet.coin = this.currentCoin.coinName; + + wallet.id = this.getHwWalletID(wallet.addresses[0].printableAddress); + }); + + return loadedWallets; + } + + return []; + }), + ); + } + + /** + * Loads all the software wallets saved on the persistent storage. At this state is only + * for testing. + */ + private loadSoftwareWallets(): Observable { + return this.storageService.get(StorageType.CLIENT, this.swWalletsDataStorageKey).pipe( + map(storedWallets => { + if (storedWallets) { + let loadedWallets: WalletBase[] = JSON.parse(storedWallets); + + loadedWallets = loadedWallets.filter(wallet => wallet.coin === this.currentCoin.coinName); + loadedWallets.forEach(wallet => { + // The wallet must be identified as a software wallet and have at least one address. + // This is just a precaution. + wallet.isHardware = false; + if (!wallet.addresses) { + const newAddress = AddressBase.create(this.formatAddress, 'invalid'); + newAddress.confirmed = true; + wallet.addresses = [newAddress]; + } + + // If an address was saved with the old format, convert it to the new one. + for (let i = 0; i < wallet.addresses.length; i++) { + if (wallet.addresses[i]['address']) { + const confirmed = wallet.addresses[i].confirmed; + const isChangeAddress = wallet.addresses[i].isChangeAddress; + + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['address']); + wallet.addresses[i].confirmed = confirmed; + wallet.addresses[i].isChangeAddress = isChangeAddress; + } + } + }); + + return loadedWallets; + } + + return []; + }), + ); + } + + /** + * Returns the ID a hw wallet must use. + * @param firstAddress First address of the wallet. + */ + private getHwWalletID(firstAddress: string): string { + return this.currentCoin.coinName + '-' + firstAddress; + } + + /** + * Makes walletsSubject emit, to inform that the wallet list has been updated. + */ + private informDataUpdated() { + this.walletsSubject.next(this.walletsList); + } + + formatAddress(address: string): string { + address = address.trim(); + if (address.toLowerCase().startsWith('bc1') || address.toLowerCase().startsWith('tb1')) { + address = address.toLowerCase(); + } + + return address; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/utils/btc-history-utils.ts b/src/gui/static/src/app/services/coin-specific/btc/utils/btc-history-utils.ts new file mode 100644 index 0000000..00ff063 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/utils/btc-history-utils.ts @@ -0,0 +1,260 @@ +import { Observable, of } from 'rxjs'; +import { mergeMap, map } from 'rxjs/operators'; +import { BigNumber } from 'bignumber.js'; + +import { WalletBase, AddressMap } from '../../../wallet-operations/wallet-objects'; +import { OldTransaction, OldTransactionTypes, Output } from '../../../wallet-operations/transaction-objects'; +import { StorageService, StorageType } from '../../../storage.service'; +import { calculateGeneralData } from '../../../../utils/history-utils'; +import { Coin } from '../../../../coins/coin'; +import { BlockbookApiService } from '../../../../services/api/blockbook-api.service'; +import { BtcCoinConfig } from '../../../../coins/coin-type-configs/btc.coin-config'; +import { TransactionHistory, TransactionLimits } from '../../../../services/wallet-operations/history.service'; +import { AppConfig } from '../../../../app.config'; +import { WalletsAndAddressesOperator } from '../../wallets-and-addresses-operator'; + +/** + * Gets the transaction history of a wallet list. + * @param wallets Wallets to consult. + */ +export function getTransactionsHistory( + currentCoin: Coin, + wallets: WalletBase[], + transactionLimitperAddress: TransactionLimits, + blockbookApiService: BlockbookApiService, + storageService: StorageService, + walletsAndAddressesOperator: WalletsAndAddressesOperator, +): Observable { + + let transactions: OldTransaction[]; + /** + * Allows to easily know which addresses are part of the wallets and also to know + * which wallet the address belong to. + */ + const addressMap = new AddressMap(walletsAndAddressesOperator.formatAddress); + + // Get all the addresses of the wallets. + const addresses: string[] = []; + wallets.forEach(w => { + w.addresses.map(add => { + if (!addressMap.has(add.printableAddress)) { + addresses.push(add.printableAddress); + } + // There could be more than one wallet with the address. This would happen if the wallet is repeated + // (like when using the same seed for a software and a hardware wallet). In that case, the wallet + // with most addresses is considered "the most complete one" and is used. + if (!addressMap.has(add.printableAddress) || addressMap.get(add.printableAddress).addresses.length < w.addresses.length) { + addressMap.set(add.printableAddress, w); + } + }); + }); + + // Value which will allow to get the value in coins, instead of sats. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((currentCoin.config as BtcCoinConfig).decimals); + + // Addresses for which transactions were ignored due to transactionLimitperAddres. + let addressesWitMoreTransactions: AddressMap; + // Calculate how many transactions to get per address. + const hasManyAddresses = addresses.length > AppConfig.fewAddressesLimit; + let transactionsToGet = hasManyAddresses ? AppConfig.maxTxPerAddressIfManyAddresses : AppConfig.maxTxPerAddressIfFewAddresses; + if (transactionLimitperAddress === TransactionLimits.ExtraLimit) { + transactionsToGet = transactionsToGet * AppConfig.maxTxPerAddressMultiplier; + } else if (transactionLimitperAddress === TransactionLimits.MaxAllowed) { + transactionsToGet = AppConfig.maxTxPerAddressAllowedByBackend; + } + + // Get the transactions of all addresses. + return recursivelyGetTransactions(currentCoin, blockbookApiService, walletsAndAddressesOperator, addresses, transactionsToGet).pipe(mergeMap((response: TransactionsResponse) => { + addressesWitMoreTransactions = response.addressesWitMoreTransactions; + + // Process the response and convert it into a known object type. Some values are temporal. + transactions = response.transactions.map(transaction => { + // Build the output list, ignoring data outputs. + const outputs: Output[] = []; + (transaction.vout as any[]).forEach(output => { + if (output.value && output.value !== '0') { + outputs.push({ + hash: getOutputId(transaction.txid, output.n), + address: (output.addresses as string[]).map(add => walletsAndAddressesOperator.formatAddress(add)).join(', '), + coins: new BigNumber(output.value).dividedBy(decimalsCorrector), + transactionId: transaction.txid, + indexInTransaction: output.n, + }); + } + }); + + // Build the transaction object. + const processedTx: OldTransaction = { + relevantAddresses: [], + balance: new BigNumber(0), + fee: new BigNumber(0), + confirmed: transaction.confirmations ? (transaction.confirmations >= currentCoin.confirmationsNeeded) : false, + confirmations: transaction.confirmations ? transaction.confirmations : 0, + timestamp: transaction.blockTime ? transaction.blockTime : -1, + id: transaction.txid, + inputs: (transaction.vin as any[]).map(input => { + return { + hash: !input.isAddress ? '' : getOutputId(input.txid, input.vout), + address: !input.isAddress ? null : (input.addresses as string[]).map(add => walletsAndAddressesOperator.formatAddress(add)).join(', '), + coins: !input.isAddress ? new BigNumber(0) : new BigNumber(input.value).dividedBy(decimalsCorrector), + }; + }), + outputs: outputs, + involvedLocalWallets: '', + numberOfInvolvedLocalWallets: 0, + type: OldTransactionTypes.MixedOrUnknown, + failed: false, + }; + + // Calculate the fee. + let inputsCoins = new BigNumber('0'); + (transaction.vin as any[]).forEach(input => { + if (input.value) { + inputsCoins = inputsCoins.plus(input.value); + } + }); + let outputsCoins = new BigNumber('0'); + (transaction.vout as any[]).forEach(output => { + if (output.value) { + outputsCoins = outputsCoins.plus(output.value); + } + }); + processedTx.fee = inputsCoins.minus(outputsCoins).dividedBy(decimalsCorrector); + if (processedTx.fee.isLessThan(0)) { + processedTx.fee = new BigNumber(0); + } + + return processedTx; + }); + + // Get the transaction notes. + return storageService.get(StorageType.NOTES, null); + }), map(notes => { + if (!notes) { + notes = {}; + } + + const notesMap: Map = new Map(); + Object.keys(notes).forEach(key => { + notesMap.set(key, notes[key]); + }); + + transactions = transactions + // Sort the transactions by date. + .sort((a, b) => { + if (b.timestamp >= 0 && a.timestamp >= 0) { + return b.timestamp - a.timestamp; + } else if (a.timestamp >= 0) { + return 1; + } else if (b.timestamp >= 0) { + return -1; + } else { + return 0; + } + }) + .map(transaction => { + // Add to the transaction object the type, balance and the involved wallets and addresses. + calculateGeneralData(transaction, addressMap, false, walletsAndAddressesOperator); + + // Add the note. + const txNote = notesMap.get(transaction.id); + if (txNote) { + transaction.note = txNote; + } + + return transaction; + }); + + const finalResponse: TransactionHistory = { + transactions: transactions, + addressesWitAdditionalTransactions: addressesWitMoreTransactions, + }; + + return finalResponse; + })); +} + +/** + * Object returned by the recursivelyGetTransactions function. + */ +export interface TransactionsResponse { + transactions: any[]; + /** + * List with the addresses for which transactions were ignored due to the value sent in the + * maxPerAddress param. + */ + addressesWitMoreTransactions: AddressMap; +} + +/** + * Gets the transaction history of the addresses in the provided address list. + * @param addresses Addresses to check. The list will be altered by the function. + * @param maxPerAddress Max number of transactions to return per address. + * @param startingBlock Block from which to start looking for transactions. + * @param currentElements Already obtained transactions. For internal use. + * @param addressesWitMoreTransactions Addresses with transactions which were ignored. + * For internal use. + * @returns Array with all the transactions related to the provided address list, in the + * format returned by the backend. + */ +export function recursivelyGetTransactions( + currentCoin: Coin, + blockbookApiService: BlockbookApiService, + walletsAndAddressesOperator: WalletsAndAddressesOperator, + addresses: string[], + maxPerAddress: number, + startingBlock: number = null, + currentElements = new Map(), + addressesWitMoreTransactions = new AddressMap(walletsAndAddressesOperator.formatAddress), +): Observable { + const requestParams = { + pageSize: maxPerAddress, + details: 'txslight', + }; + + if (startingBlock) { + requestParams['from'] = startingBlock; + } + + return blockbookApiService.get(currentCoin.indexerUrl, 'address/' + addresses[addresses.length - 1], requestParams) + .pipe(mergeMap((response) => { + // Save the transactions. A map is used to avoid repeating transactions. + if (response.transactions) { + (response.transactions as any[]).forEach(transaction => { + currentElements.set(transaction.txid, transaction); + }); + } + + // Check if some transactions were ignored. + if (response.totalPages && response.totalPages > 1) { + addressesWitMoreTransactions.set(addresses[addresses.length - 1], true); + } + + addresses.pop(); + + // If there are no more addresses, build and return the final response. + if (addresses.length === 0) { + const transactionsForResponse: any[] = []; + currentElements.forEach(tx => { + transactionsForResponse.push(tx); + }); + + const finalResponse: TransactionsResponse = { + transactions: transactionsForResponse, + addressesWitMoreTransactions: addressesWitMoreTransactions, + }; + + return of(finalResponse); + } + + // Continue to the next step. + return recursivelyGetTransactions(currentCoin, blockbookApiService, walletsAndAddressesOperator, addresses, maxPerAddress, startingBlock, currentElements, addressesWitMoreTransactions); + })); +} + +/** + * Returns the ID of an output. It is just txId + '/' + outputIndex; + */ +export function getOutputId(txId: string, outputIndex: number): string { + return (txId + '') + '/' + (outputIndex + ''); +} diff --git a/src/gui/static/src/app/services/coin-specific/btc/utils/btc-tx-encoder.ts b/src/gui/static/src/app/services/coin-specific/btc/utils/btc-tx-encoder.ts new file mode 100644 index 0000000..a660c33 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/btc/utils/btc-tx-encoder.ts @@ -0,0 +1,274 @@ +import BigNumber from 'bignumber.js'; + +/** + * Input for a BTC transaction. + */ +export class BtcInput { + /** + * Hex string with the ID of the transaction were the input was created. + */ + transaction: string; + /** + * Number of the input in the outputs list of the transaction were it was created. + */ + vout: number; + /** + * Script, hex encoded. + */ + script: string; +} + +/** + * Output for a BTC transaction. + */ +export class BtcOutput { + /** + * Coin value, in sats. + */ + satsValue: BigNumber; + /** + * Script, hex encoded. + */ + script: string; +} + +/** + * Allows to encode BTC transactions, to be able to send them to the network. + */ +export class BtcTxEncoder { + /** + * Creates an encoded transaction using the Bitcoin format. + * @param inputs List of all inputs. + * @param outputs List of all outputs. + */ + static encode(inputs: BtcInput[], outputs: BtcOutput[]): string { + // Calculate the size of the transaction and initialize the object used + // for writting the byte data. + const transactionSize = this.encodeSizeTransaction(inputs, outputs).toNumber(); + const buffer = new ArrayBuffer(transactionSize); + const dataView = new DataView(buffer); + let currentPos = 0; + + // Tx version. + dataView.setUint32(currentPos, 1, true); + currentPos += 4; + + // How many inputs the transaction has. + currentPos = this.insertVariableSizeInt(dataView, currentPos, new BigNumber(inputs.length)); + + inputs.forEach(input => { + if (input.transaction.length % 2 !== 0) { + throw new Error('Invalid hex string.'); + } + + // Reverse the transaction hash, as needed for the BTC transaction. + let reversedTxHash = ''; + for (let i = 0; i < input.transaction.length; i += 2) { + reversedTxHash = input.transaction.substr(i, 2) + reversedTxHash; + } + + // Tx hash. + const txHashBytes = this.convertToBytes(reversedTxHash); + txHashBytes.forEach(number => { + dataView.setUint8(currentPos, number); + currentPos += 1; + }); + + // Output index. + dataView.setUint32(currentPos, input.vout, true); + currentPos += 4; + + // Length of the script. + const scriptSize = new BigNumber(input.script.length).dividedBy(2).decimalPlaces(0, BigNumber.ROUND_CEIL); + currentPos = this.insertVariableSizeInt(dataView, currentPos, scriptSize); + + // Script. + const scriptBytes = this.convertToBytes(input.script); + scriptBytes.forEach(number => { + dataView.setUint8(currentPos, number); + currentPos += 1; + }); + + // Sequence (ffffffff). + dataView.setUint32(currentPos, 4294967295, true); + currentPos += 4; + }); + + // How many outputs the transaction has. + currentPos = this.insertVariableSizeInt(dataView, currentPos, new BigNumber(outputs.length)); + + outputs.forEach(output => { + // Coins. + currentPos = this.setUint64(dataView, currentPos, output.satsValue); + + // Length of the script. + const scriptSize = new BigNumber(output.script.length).dividedBy(2).decimalPlaces(0, BigNumber.ROUND_CEIL); + currentPos = this.insertVariableSizeInt(dataView, currentPos, scriptSize); + + // Script. + const scriptBytes = this.convertToBytes(output.script); + scriptBytes.forEach(number => { + dataView.setUint8(currentPos, number); + currentPos += 1; + }); + }); + + // Lock time. + dataView.setUint32(currentPos, 0, true); + currentPos += 4; + + // + + return this.convertToHex(buffer); + } + + /** + * Calculates the final size, in bytes, that an encoded transaction will have. + * @param inputs List of all inputs. + * @param outputs List of all outputs. + */ + private static encodeSizeTransaction(inputs: BtcInput[], outputs: BtcOutput[]): BigNumber { + let size = new BigNumber(0); + + // Tx version. + size = size.plus(4); + + // How many bytes will be needed for saving how many inputs the transaction has. + size = size.plus(BtcTxEncoder.calculateVariableIntSize(new BigNumber(inputs.length))); + + inputs.forEach(input => { + // Transaction hash, output index and sequence number. + size = size.plus(40); + + // How many bytes will be needed for saving the length of the script and the script itself. + const scriptSize = new BigNumber(input.script.length).dividedBy(2).decimalPlaces(0, BigNumber.ROUND_CEIL); + size = size.plus(BtcTxEncoder.calculateVariableIntSize(scriptSize)); + size = size.plus(scriptSize); + }); + + // How many bytes will be needed for saving how many outputs the transaction has. + size = size.plus(BtcTxEncoder.calculateVariableIntSize(new BigNumber(outputs.length))); + + outputs.forEach(output => { + // Coin value. + size = size.plus(8); + + // How many bytes will be needed for saving the length of the script and the script. + const scriptSize = new BigNumber(output.script.length).dividedBy(2).decimalPlaces(0, BigNumber.ROUND_CEIL); + size = size.plus(BtcTxEncoder.calculateVariableIntSize(scriptSize)); + size = size.plus(scriptSize); + }); + + // Lock time. + size = size.plus(4); + + return size; + } + + /** + * Calculates how many bytes are needed for storing an int number. No more than 2 bytes + * must be needed. + */ + private static calculateVariableIntSize(int: BigNumber): BigNumber { + const size = new BigNumber(int.toString(16).length).dividedBy(2).decimalPlaces(0, BigNumber.ROUND_CEIL); + + if (size.isGreaterThan(2)) { + throw new Error('Invalid variable size int.'); + } + + return size; + } + + /** + * Writes an int number on a DataView using only as many bytes as needed. No more than 2 bytes + * must be needed. + * @param dataView DataView in which the value will be written. + * @param currentPos Position inside the DataView in which the value will be written. + * @param int Value to write. + * @returns The position in which the next value will have to be written on the DataView. + */ + private static insertVariableSizeInt(dataView: DataView, currentPos: number, int: BigNumber): number { + // How many bytes will be needed for saving the value. + const bytesForInputsNumber = BtcTxEncoder.calculateVariableIntSize(int); + + // Write the value. + if (bytesForInputsNumber.isEqualTo(1)) { + dataView.setUint8(currentPos, int.toNumber()); + + return currentPos + 1; + } else if (bytesForInputsNumber.isEqualTo(1)) { + dataView.setUint16(currentPos, int.toNumber(), true); + + return currentPos + 2; + } else { + throw new Error('Invalid variable size int.'); + } + } + + /** + * Writes an Uint64 value on a DataView. + * @param dataView DataView in which the value will be written. + * @param currentPos Position inside the DataView in which the value will be written. + * @param value Value to be written. + * @returns The position in which the next value will have to be written on the DataView. + */ + private static setUint64(dataView: DataView, currentPos: number, value: BigNumber): number { + let hex = value.toString(16); + // Make sure the hex string has an even number of characters. + if (hex.length % 2 !== 0) { + hex = '0' + hex; + } + + const bytes = this.convertToBytes(hex); + for (let i = bytes.length - 1; i >= 0; i--) { + dataView.setUint8(currentPos, bytes[i]); + currentPos += 1; + } + + // Add zeros to fill the remaining space. + for (let i = 0; i < 8 - bytes.length; i++) { + dataView.setUint8(currentPos, 0); + currentPos += 1; + } + + return currentPos; + } + + /** + * Converts a hex string to a byte array. + * @param hexString String to convert. + */ + private static convertToBytes(hexString: string): number[] { + if (hexString.length % 2 !== 0) { + throw new Error('Invalid hex string.'); + } + + const result: number[] = []; + + for (let i = 0; i < hexString.length; i += 2) { + result.push(parseInt(hexString.substr(i, 2), 16)); + } + + return result; + } + + /** + * Converts an ArrayBuffer to a hex string. + * @param buffer ArrayBuffer to convert. + */ + private static convertToHex(buffer: ArrayBuffer) { + let result = ''; + + (new Uint8Array(buffer)).forEach((v) => { + let val = v.toString(16); + if (val.length === 0) { + val = '00'; + } else if (val.length === 1) { + val = '0' + val; + } + result += val; + }); + + return result; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/eth-balance-and-outputs-operator.ts b/src/gui/static/src/app/services/coin-specific/eth/eth-balance-and-outputs-operator.ts new file mode 100644 index 0000000..0788042 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/eth-balance-and-outputs-operator.ts @@ -0,0 +1,570 @@ +import { of, Observable, ReplaySubject, Subscription, BehaviorSubject, forkJoin } from 'rxjs'; +import { NgZone, Injector } from '@angular/core'; +import { mergeMap, map, delay, tap, first, filter } from 'rxjs/operators'; +import BigNumber from 'bignumber.js'; + +import { WalletWithBalance, walletWithBalanceFromBase, WalletBase, WalletWithOutputs, AddressMap, AddressBase } from '../../wallet-operations/wallet-objects'; +import { Output } from '../../wallet-operations/transaction-objects'; +import { Coin } from '../../../coins/coin'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; +import { EthCoinConfig } from '../../../coins/coin-type-configs/eth.coin-config'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; + +/** + * Balance of a wallet, for internal use. + */ +class WalletBalance { + current = new BigNumber(0); + predicted = new BigNumber(0); + available = new BigNumber(0); + addresses: AddressMap; + + constructor(walletsAndAddressesOperator: WalletsAndAddressesOperator) { + this.addresses = new AddressMap(walletsAndAddressesOperator.formatAddress); + } +} + +/** + * Balance of an address, for internal use. + */ +class AddressBalance { + current = new BigNumber(0); + predicted = new BigNumber(0); + available = new BigNumber(0); +} + +/** + * Operator for BalanceAndOutputsService to be used with eth-like coins. + * + * NOTE: eth-like coins don't use outputs. + * + * You can find more information about the functions and properties this class implements by + * checking BalanceAndOutputsOperator and BalanceAndOutputsService. + */ +export class EthBalanceAndOutputsOperator implements BalanceAndOutputsOperator { + // The list of wallets with balance and the subject used for informing when the list has been modified. + private walletsWithBalanceList: WalletWithBalance[]; + private walletsWithBalanceSubject: ReplaySubject = new ReplaySubject(1); + + // Subject for providing information in the getters below. + private lastBalancesUpdateTimeSubject: ReplaySubject = new ReplaySubject(1); + private hasPendingTransactionsSubject: BehaviorSubject = new BehaviorSubject(false); + private firstFullUpdateMadeSubject: BehaviorSubject = new BehaviorSubject(false); + private hadErrorRefreshingBalanceSubject: BehaviorSubject = new BehaviorSubject(false); + private refreshingBalanceSubject: BehaviorSubject = new BehaviorSubject(false); + + private dataRefreshSubscription: Subscription; + private walletsSubscription: Subscription; + private operatorsSubscription: Subscription; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 10 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 2 * 1000; + + /** + * After the service retrieves the balance of each wallet, the balance returned + * by the backend for each wallet is saved here, accessible via the wallet id. + */ + private savedBalanceData = new Map(); + /** + * Temporal map for updating savedBalanceData only after retrieving the data of all wallets, + * to avoid problems when the balance update procedure is cancelled early. + */ + private temporalSavedBalanceData = new Map(); + /** + * Saves the lastest, most up to date, wallet list obtained from the wallets service. + */ + private savedWalletsList: WalletBase[]; + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services and operators used by this operator. + private blockbookApiService: BlockbookApiService; + private ngZone: NgZone; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.blockbookApiService = injector.get(BlockbookApiService); + this.ngZone = injector.get(NgZone); + + // Intervals for updating the data must be longer if connecting to a remote backend. + if (!currentCoin.isLocal) { + this.updatePeriod = 600 * 1000; + this.errorUpdatePeriod = 60 * 1000; + } + + // Get the operators and only then start using them. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + + // Update the balance immediately each time the wallets are updated. + this.walletsSubscription = operators.walletsAndAddressesOperator.currentWallets.subscribe(wallets => { + this.savedWalletsList = wallets; + this.startDataRefreshSubscription(0, true); + }); + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + if (this.walletsSubscription) { + this.walletsSubscription.unsubscribe(); + } + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + this.lastBalancesUpdateTimeSubject.complete(); + this.walletsWithBalanceSubject.complete(); + this.hasPendingTransactionsSubject.complete(); + this.firstFullUpdateMadeSubject.complete(); + this.hadErrorRefreshingBalanceSubject.complete(); + this.refreshingBalanceSubject.complete(); + } + + get lastBalancesUpdateTime(): Observable { + return this.lastBalancesUpdateTimeSubject.asObservable(); + } + + get walletsWithBalance(): Observable { + return this.walletsWithBalanceSubject.asObservable(); + } + + get hasPendingTransactions(): Observable { + return this.hasPendingTransactionsSubject.asObservable(); + } + + get firstFullUpdateMade(): Observable { + return this.firstFullUpdateMadeSubject.asObservable(); + } + + get hadErrorRefreshingBalance(): Observable { + return this.hadErrorRefreshingBalanceSubject.asObservable(); + } + + get refreshingBalance(): Observable { + return this.refreshingBalanceSubject.asObservable(); + } + + get outputsWithWallets(): Observable { + return of([]); + } + + getOutputs(addresses: string): Observable { + return of([]); + } + + getWalletUnspentOutputs(wallet: WalletBase): Observable { + return of([]); + } + + refreshBalance() { + this.startDataRefreshSubscription(0, false); + } + + /** + * Makes the service start updating the balance periodically. If this function was called + * before, the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the balance. + * @param updateWalletsFirst If true, after the delay the function will inmediatelly update + * the wallet list with the data on savedWalletsList and using the last balance data obtained + * from the backend (or will set all the wallets to 0, if no data exists) and only after that + * will try to get the balance data from the backend and update the wallet list again. This + * allows to inmediatelly reflect changes made to the wallet list, without having to wait for + * the backend to respond. + */ + private startDataRefreshSubscription(delayMs: number, updateWalletsFirst: boolean) { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + if (this.savedWalletsList) { + this.ngZone.runOutsideAngular(() => { + this.dataRefreshSubscription = of(0).pipe(delay(delayMs), mergeMap(() => { + // Inform the balance is being updated. + this.ngZone.run(() => { + this.refreshingBalanceSubject.next(true); + }); + + // Update the wallet list with the last saved data, if requested. + if (updateWalletsFirst) { + return this.refreshBalances(this.savedWalletsList, true); + } else { + return of(0); + } + }), mergeMap(() => { + // Refresh the balance. + return this.refreshBalances(this.savedWalletsList, false); + })).subscribe( + () => { + this.ngZone.run(() => { + this.hadErrorRefreshingBalanceSubject.next(false); + this.refreshingBalanceSubject.next(false); + }); + + // Repeat the operation after a delay. + this.startDataRefreshSubscription(this.updatePeriod, false); + }, + () => { + this.ngZone.run(() => { + this.hadErrorRefreshingBalanceSubject.next(true); + this.refreshingBalanceSubject.next(false); + }); + + // Repeat the operation after a delay. + this.startDataRefreshSubscription(this.errorUpdatePeriod, false); + }, + ); + }); + } + } + + /** + * Refreshes the wallets on walletsWithBalanceList and their balances. + * @param wallets The current wallet lists. + * @param forceQuickCompleteArrayUpdate If true, the balance data saved on savedBalanceData + * will be used to set the balance of the wallet list, instead of getting the data from + * the backend. If false, the balance data is obtained from the backend and savedBalanceData is + * updated. + */ + private refreshBalances(wallets: WalletBase[], forceQuickCompleteArrayUpdate: boolean): Observable { + // Create a copy of the wallet list. + const temporalWallets: WalletWithBalance[] = []; + wallets.forEach(wallet => { + temporalWallets.push(walletWithBalanceFromBase(wallet)); + }); + + // This will help to update savedBalanceData when finishing the procedure. + if (!forceQuickCompleteArrayUpdate) { + this.temporalSavedBalanceData = new Map(); + } + + let procedure: Observable; + if (wallets.length > 0) { + if (!forceQuickCompleteArrayUpdate) { + procedure = this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api').pipe(mergeMap(response => { + // Get the balance of each wallet. + return forkJoin(temporalWallets.map(wallet => this.retrieveWalletBalance(wallet, response.blockbook.bestHeight, forceQuickCompleteArrayUpdate))); + })); + } else { + procedure = forkJoin(temporalWallets.map(wallet => this.retrieveWalletBalance(wallet, 0, forceQuickCompleteArrayUpdate))); + } + } else { + // Create a fake response, as there are no wallets. + procedure = of([false]); + } + + // Calculate the balance of each wallet. + return procedure.pipe(tap(walletHasPendingTx => { + this.hasPendingTransactionsSubject.next(walletHasPendingTx.some(value => value)); + + if (!forceQuickCompleteArrayUpdate) { + this.ngZone.run(() => { + this.lastBalancesUpdateTimeSubject.next(new Date()); + }); + } + + if (!this.walletsWithBalanceList || forceQuickCompleteArrayUpdate || this.walletsWithBalanceList.length !== temporalWallets.length) { + // Update the whole list. + this.walletsWithBalanceList = temporalWallets; + this.informDataUpdated(); + } else { + // If there is a change in the IDs of the wallet list, update the whole list. + let changeDetected = false; + this.walletsWithBalanceList.forEach((currentWallet, i) => { + if (currentWallet.id !== temporalWallets[i].id) { + changeDetected = true; + } + }); + + if (changeDetected) { + this.walletsWithBalanceList = temporalWallets; + this.informDataUpdated(); + } else { + // Update only the balances with changes. This allows to show updated data without + // having to completelly replace the wallet array. + this.walletsWithBalanceList.forEach((currentWallet, i) => { + if (!currentWallet.coins.isEqualTo(temporalWallets[i].coins) || !currentWallet.confirmedCoins.isEqualTo(temporalWallets[i].confirmedCoins)) { + currentWallet.coins = temporalWallets[i].coins; + currentWallet.confirmedCoins = temporalWallets[i].confirmedCoins; + currentWallet.availableCoins = temporalWallets[i].availableCoins; + currentWallet.hasPendingCoins = temporalWallets[i].hasPendingCoins; + + changeDetected = true; + } + + if (currentWallet.addresses.length !== temporalWallets[i].addresses.length) { + currentWallet.addresses = temporalWallets[i].addresses; + changeDetected = true; + } else { + currentWallet.addresses.forEach((currentAddress, j) => { + if (!currentAddress.coins.isEqualTo(temporalWallets[i].addresses[j].coins) || !currentAddress.confirmedCoins.isEqualTo(temporalWallets[i].addresses[j].confirmedCoins)) { + currentAddress.coins = temporalWallets[i].addresses[j].coins; + currentAddress.confirmedCoins = temporalWallets[i].addresses[j].confirmedCoins; + currentAddress.availableCoins = temporalWallets[i].addresses[j].availableCoins; + currentAddress.hasPendingCoins = temporalWallets[i].addresses[j].hasPendingCoins; + + changeDetected = true; + } + }); + } + }); + + // If any of the balances changed, inform that there were changes. + if (changeDetected) { + this.informDataUpdated(); + } + } + } + + if (!forceQuickCompleteArrayUpdate) { + this.savedBalanceData = this.temporalSavedBalanceData; + if (!this.firstFullUpdateMadeSubject.value) { + // Inform that the service already obtained the balance from the backend for the + // first time. + this.ngZone.run(() => { + this.firstFullUpdateMadeSubject.next(true); + }); + } + } + })); + } + + /** + * Gets from the backend the balance of a wallet and uses the retrieved data to update an + * instamce of WalletWithBalance. It also saves the retrieved data on temporalSavedBalanceData. + * @param wallet Wallet to update. + * @param lastBlock Number of the last block on the blockchain. Used only if + * useSavedBalanceData is true. + * @param useSavedBalanceData If true, the balance data saved on savedBalanceData + * will be used instead of retrieving the data from the backend. + * @returns True if there are one or more pending transactions that will affect the balance of + * the provided walled, false otherwise. If useSavedBalanceData is true, the value of + * hasPendingTransactionsSubject will be returned. + */ + private retrieveWalletBalance(wallet: WalletWithBalance, lastBlock: number, useSavedBalanceData: boolean): Observable { + let query: Observable; + + if (!useSavedBalanceData) { + // Get the balance of all addresses. + const addresses = wallet.addresses.map(a => a.printableAddress); + query = this.recursivelyGetBalances(addresses, lastBlock).pipe(mergeMap(result => { + const response = new WalletBalance(this.walletsAndAddressesOperator); + + result.forEach((addressBalance, address) => { + // Add the values to the balance of the wallet. + response.addresses.set(address, addressBalance); + response.current = response.current.plus(addressBalance.current); + response.predicted = response.predicted.plus(addressBalance.predicted); + response.available = response.available.plus(addressBalance.available); + }); + + return of(response); + })); + } else { + // Get the balance from the saved data, if possible. + if (this.savedBalanceData.has(wallet.id)) { + query = of(this.savedBalanceData.get(wallet.id)); + } else { + query = of(new WalletBalance(this.walletsAndAddressesOperator)); + } + } + + // Add the values to the wallet object. + return query.pipe(map(balance => { + this.temporalSavedBalanceData.set(wallet.id, balance); + + wallet.coins = balance.predicted; + wallet.confirmedCoins = balance.current; + wallet.availableCoins = balance.available; + wallet.hasPendingCoins = !wallet.coins.isEqualTo(wallet.confirmedCoins); + + wallet.addresses.forEach(address => { + if (balance.addresses.has(address.printableAddress)) { + address.coins = balance.addresses.get(address.printableAddress).predicted; + address.confirmedCoins = balance.addresses.get(address.printableAddress).current; + address.availableCoins = balance.addresses.get(address.printableAddress).available; + address.hasPendingCoins = !address.coins.isEqualTo(address.confirmedCoins); + } else { + address.coins = new BigNumber(0); + address.confirmedCoins = new BigNumber(0); + address.availableCoins = new BigNumber(0); + address.hasPendingCoins = false; + } + }); + + if (!useSavedBalanceData) { + return !balance.current.isEqualTo(balance.predicted); + } else { + return this.hasPendingTransactionsSubject.value; + } + })); + } + + /** + * Gets the balances of the addresses in the provided address list. + * @param addresses Addresses to check. The list will be altered by the function. + * @param lastBlock Number of the last block on the blockchain. + * @param currentElements Already obtained balances. For internal use. + * @returns Map with the balances of the provided address list. + */ + private recursivelyGetBalances( + addresses: string[], + lastBlock: number, + currentElements = new AddressMap(this.walletsAndAddressesOperator.formatAddress), + ): Observable> { + + if (addresses.length === 0) { + return of(currentElements); + } + + const requestParams = { + details: 'txslight', + }; + + // When requesting the balance, the transactions of the blocks considered unconfirmed + // will be obtained too, to consider the balance moved in them as pending. This is + // because Blockbook only considers as pending the balance in the transactions which + // are still in the mempool. + if (this.currentCoin.confirmationsNeeded > 1) { + const lastUnconfirmedBlock = lastBlock - (this.currentCoin.confirmationsNeeded - 2); + requestParams['from'] = lastUnconfirmedBlock; + } else { + // Get only the transactions in the mempool, as only 1 confirmation is needed. + requestParams['from'] = -1; + } + + // Get the balance of the address. + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'address/' + addresses[addresses.length - 1], requestParams).pipe(mergeMap((response) => { + // Blockbook returns in the "balance" property the balance considering all the transactions + // already in a block and the "unconfirmedBalance" property should contain the variance + // in the balance after confirming the transactions currently in the mempool, but this last + // property does not work well for ETH. Because of this the balnce of the transaction + // currently in mempool is calculated here. + let transactionsInMempool: any[] = []; + if (response.transactions && (response.transactions as any[]).length > 0) { + transactionsInMempool = (response.transactions as any[]).filter(transactions => transactions.confirmations === 0); + } + const mempoolBalance = this.calculateBalanceFromTransactions(transactionsInMempool, addresses[addresses.length - 1]); + + // The mempool balance is added to the balance in the transactions already in blocks. + const predicted = response.balance ? new BigNumber(response.balance).plus(mempoolBalance) : new BigNumber(0); + + // If the response has transactions, the balance in those transactions is + // considered as unconfirmed. + const unconfirmed = this.calculateBalanceFromTransactions(response.transactions, addresses[addresses.length - 1]); + // Calculate the currently confirmed balance. + const balance = predicted.minus(unconfirmed); + + // Calculate how many coins are entering the address in the pending transactions. + const incomingBalance = this.calculateBalanceFromTransactions(response.transactions, addresses[addresses.length - 1], true); + // The available balance is all the confirmed coins minus all coins going out. + let available = predicted.minus(incomingBalance); + // This prevents problems if the address sends coins to itself. + if (available.isLessThan(0)) { + available = new BigNumber(0); + } + + // Value which will allow to get the balances in coins, instead of wei. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as EthCoinConfig).decimals); + + // Create the response object. + currentElements.set(addresses[addresses.length - 1], { + current: balance.dividedBy(decimalsCorrector), + predicted: predicted.dividedBy(decimalsCorrector), + available: available.dividedBy(decimalsCorrector), + }); + + addresses.pop(); + + if (addresses.length === 0) { + return of(currentElements); + } + + // Continue to the next step. + return this.recursivelyGetBalances(addresses, lastBlock, currentElements); + })); + } + + /** + * Calculates the final balance of an address after several transactions, assuming that the + * initial balance is 0. + * @param transactions Transactions to check. Must be the array returned by Blockbook when + * calling the "address/" API endpoint. Can be null, as the api may not return any value. + * @param address Address to check. + * @param onlyIncoming If true, only the balance entering the address will be taken + * into account. + */ + private calculateBalanceFromTransactions(transactions: any[], address: string, onlyIncoming = false): BigNumber { + let balance = new BigNumber(0); + const addressObject = AddressBase.create(this.walletsAndAddressesOperator.formatAddress, address); + + if (transactions && transactions.length > 0) { + transactions.forEach(transaction => { + // If the input is from the current address, consider the output and fee as outgoing coins. + if (!onlyIncoming && transaction.vin && (transaction.vin as any[]).length === 1 && (transaction.vin as any[])[0].isAddress) { + if ((transaction.vin as any[])[0].addresses.length === 1 && addressObject.compareAddress((transaction.vin as any[])[0].addresses[0])) { + // Only compute the balance is the transaction did not fail. + if (transaction.ethereumSpecific.status !== 0) { + balance = balance.minus(this.getOutputValue(transaction)); + } + + // gasUsed is not available if the transaction is still in the mempool. + const gas = transaction.ethereumSpecific.gasUsed ? transaction.ethereumSpecific.gasUsed : transaction.ethereumSpecific.gasLimit; + if (gas && transaction.ethereumSpecific.gasPrice) { + balance = balance.minus(new BigNumber(gas).multipliedBy(transaction.ethereumSpecific.gasPrice)); + } + } + } + + // If the output is for the current address, consider the output as incoming coins. + // Only compute the balance is the transaction did not fail. + if (transaction.ethereumSpecific.status !== 0) { + balance = balance.plus(this.getOutputValue(transaction, addressObject)); + } + }); + } + + return balance; + } + + /** + * Checks a transaction and returns the value of the output. + * @param transaction Transaction to check. Must be an object returned by Blockbook when + * calling the "address/" API endpoint. + * @param addressFilter If provided, the value of the output will be returned only if the + * output is for the provided address. If the output is for another address, the returned + * value is 0. + */ + private getOutputValue(transaction: any, addressFilter: AddressBase = null): BigNumber { + if (transaction.vout && (transaction.vout as any[]).length === 1 && (transaction.vout as any[])[0].isAddress) { + if (!addressFilter || ((transaction.vout as any[])[0].addresses.length === 1 && addressFilter.compareAddress((transaction.vout as any[])[0].addresses[0]))) { + if ((transaction.vout as any[])[0].value) { + return new BigNumber((transaction.vout as any[])[0].value); + } + } + } + + return new BigNumber(0); + } + + /** + * Makes walletsWithBalanceSubject emit, to inform that the wallet list has been updated. + */ + private informDataUpdated() { + this.ngZone.run(() => { + this.walletsWithBalanceSubject.next(this.walletsWithBalanceList); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/eth-blockchain-operator.ts b/src/gui/static/src/app/services/coin-specific/eth/eth-blockchain-operator.ts new file mode 100644 index 0000000..fce5e42 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/eth-blockchain-operator.ts @@ -0,0 +1,188 @@ +import { Subscription, of, Observable, ReplaySubject } from 'rxjs'; +import { delay, map, mergeMap, filter, first } from 'rxjs/operators'; +import { NgZone, Injector } from '@angular/core'; +import BigNumber from 'bignumber.js'; + +import { Coin } from '../../../coins/coin'; +import { ProgressEvent, BlockchainState } from '../../blockchain.service'; +import { BlockchainOperator } from '../blockchain-operator'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; +import { EthApiService } from '../../api/eth-api.service'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; + +/** + * Operator for BlockchainService to be used with eth-like coins. + * + * You can find more information about the functions and properties this class implements by + * checking BlockchainService and BlockchainOperator. + */ +export class EthBlockchainOperator implements BlockchainOperator { + private progressSubject: ReplaySubject = new ReplaySubject(1); + + private dataSubscription: Subscription; + private operatorsSubscription: Subscription; + + /** + * If the node was synchronized the last time it was checked. + */ + private nodeSynchronized = false; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 2 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 2 * 1000; + + get progress(): Observable { + return this.progressSubject.asObservable(); + } + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services and operators used by this operator. + private blockbookApiService: BlockbookApiService; + private ethApiService: EthApiService; + private ngZone: NgZone; + private balanceAndOutputsOperator: BalanceAndOutputsOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.blockbookApiService = injector.get(BlockbookApiService); + this.ethApiService = injector.get(EthApiService); + this.ngZone = injector.get(NgZone); + + // Intervals for updating the data must be longer if connecting to a remote node. + if (!currentCoin.isLocal) { + this.updatePeriod = 120 * 1000; + this.errorUpdatePeriod = 30 * 1000; + } + + // Get the operators and only then start using them. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.balanceAndOutputsOperator = operators.balanceAndOutputsOperator; + + // Start checking the state of the blockchain. + this.startDataRefreshSubscription(0); + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + + this.progressSubject.complete(); + } + + getBlockchainState(): Observable { + // Get the last block info. + return this.ethApiService.callRpcMethod(this.currentCoin.nodeUrl, 'eth_getBlockByNumber', ['latest', false]).pipe(map(result => { + return { + lastBlock: { + seq: new BigNumber((result.number as string).substr(2), 16).toNumber(), + timestamp: new BigNumber((result.timestamp as string).substr(2), 16).toNumber(), + hash: result.hash, + }, + coinSupply: null, + }; + })); + } + + /** + * Makes the operator start periodically checking the synchronization state of the blockchain. + * If this function was called before, the previous procedure is cancelled. + * @param delayMs Delay before starting to check the data. + */ + private startDataRefreshSubscription(delayMs: number) { + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + + let blockbookData: any; + + this.ngZone.runOutsideAngular(() => { + this.dataSubscription = of(0).pipe( + delay(delayMs), + mergeMap(() => { + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api'); + }), + mergeMap(result => { + blockbookData = result; + + return this.ethApiService.callRpcMethod(this.currentCoin.nodeUrl, 'eth_syncing'); + }), + ).subscribe(result => { + this.ngZone.run(() => { + let synchronized = false; + + // If Blockbook and the node are out of sync but only by 1 or 2 blocks, retry after a + // small delay. + const blockbookBlocksBehind = new BigNumber(blockbookData.backend.blocks).minus(blockbookData.blockbook.bestHeight); + if (blockbookBlocksBehind.isGreaterThan(0) && blockbookBlocksBehind.isLessThanOrEqualTo(2)) { + this.startDataRefreshSubscription(10000); + + return; + } + + // If the result is false, the blockchain is synchronized. + if (result === false) { + // If Blockbook and the node are more than 2 block2 appart, consider everything + // out of sync. + if (blockbookBlocksBehind.isGreaterThan(2)) { + this.progressSubject.next({ + currentBlock: blockbookData.blockbook.bestHeight, + highestBlock: blockbookData.backend.blocks, + synchronized: false, + }); + } else { + this.progressSubject.next({ + currentBlock: 0, + highestBlock: 0, + synchronized: true, + }); + + synchronized = true; + } + } else { + const currentBlock = new BigNumber((result.currentBlock as string).substr(2), 16); + const highestBlock = new BigNumber((result.highestBlock as string).substr(2), 16); + + // If the node is out of sync but only by 1 or 2 blocks, retry after a small delay. + const blocksBehind = new BigNumber(highestBlock).minus(currentBlock); + if (blocksBehind.isGreaterThan(0) && blocksBehind.isLessThanOrEqualTo(2)) { + this.startDataRefreshSubscription(10000); + + return; + } + + this.progressSubject.next({ + currentBlock: currentBlock.toNumber(), + highestBlock: highestBlock.toNumber(), + synchronized: false, + }); + } + + // If the node was out of sync and now it is not, refresh the balance. + if (synchronized && !this.nodeSynchronized) { + this.balanceAndOutputsOperator.refreshBalance(); + } + + this.nodeSynchronized = synchronized; + + // Refresh faster if the node is out of sync. + this.startDataRefreshSubscription(synchronized ? this.updatePeriod : this.errorUpdatePeriod); + }); + }, () => { + this.startDataRefreshSubscription(this.errorUpdatePeriod); + }); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/eth-history-operator.ts b/src/gui/static/src/app/services/coin-specific/eth/eth-history-operator.ts new file mode 100644 index 0000000..f77adc5 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/eth-history-operator.ts @@ -0,0 +1,170 @@ +import { of, Observable, Subscription } from 'rxjs'; +import { first, mergeMap, filter, map } from 'rxjs/operators'; +import { Injector } from '@angular/core'; +import BigNumber from 'bignumber.js'; + +import { StorageService } from '../../storage.service'; +import { WalletBase, AddressMap } from '../../wallet-operations/wallet-objects'; +import { Coin } from '../../../coins/coin'; +import { PendingTransactionsResponse, AddressesHistoryResponse, PendingTransactionData, TransactionHistory, TransactionLimits } from '../../wallet-operations/history.service'; +import { HistoryOperator } from '../history-operator'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; +import { OperatorService } from '../../operators.service'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; +import { recursivelyGetTransactions, getTransactionsHistory } from './utils/eth-history-utils'; +import { EthCoinConfig } from '../../../coins/coin-type-configs/eth.coin-config'; +import { AppConfig } from '../../../app.config'; + +/** + * Operator for HistoryService to be used with eth-like coins. + * + * NOTE: still under heavy development. + * + * You can find more information about the functions and properties this class implements by + * checking HistoryOperator and HistoryService. + */ +export class EthHistoryOperator implements HistoryOperator { + // Coin the current instance will work with. + private currentCoin: Coin; + + private operatorsSubscription: Subscription; + + // Services and operators used by this operator. + private blockbookApiService: BlockbookApiService; + private storageService: StorageService; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.blockbookApiService = injector.get(BlockbookApiService); + this.storageService = injector.get(StorageService); + + // Get the operators. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + } + + getIfAddressesUsed(wallet: WalletBase): Observable> { + const addresses = wallet.addresses.map(address => address.printableAddress); + + return this.recursivelyGetIfAddressesUsed(addresses); + } + + /** + * Checks the provided addresses and returns a map indicating which ones have been used, + * defined as having received coins. + * @param addresses Addresses to check. The list will be altered by the function. + * @param currentElements Already obtained data. For internal use. + */ + private recursivelyGetIfAddressesUsed(addresses: string[], currentElements = new AddressMap(this.walletsAndAddressesOperator.formatAddress)): Observable> { + if (addresses.length === 0) { + return of(currentElements); + } + + // Get the information of the address. + this.blockbookApiService.get(this.currentCoin.indexerUrl, 'address/' + addresses[addresses.length - 1], {details: 'basic'}) + .pipe(mergeMap((response) => { + // Check is the address has received coins. + currentElements.set(addresses[addresses.length - 1], response.totalReceived && new BigNumber(response.totalReceived).isGreaterThan(0)); + + addresses.pop(); + + if (addresses.length === 0) { + return of(currentElements); + } + + // Continue to the next step. + return this.recursivelyGetIfAddressesUsed(addresses, currentElements); + })); + } + + getTransactionsHistory(wallet: WalletBase|null, transactionLimitperAddress: TransactionLimits): Observable { + // Use the provided wallet or get all wallets. + let initialRequest: Observable; + if (wallet) { + initialRequest = of([wallet]); + } else { + initialRequest = this.walletsAndAddressesOperator.currentWallets; + } + + // Get the history. + return initialRequest.pipe(first(), mergeMap(wallets => { + return getTransactionsHistory(this.currentCoin, wallets, transactionLimitperAddress, this.blockbookApiService, this.storageService, this.walletsAndAddressesOperator); + })); + } + + getPendingTransactions(): Observable { + let wallets: WalletBase[]; + + return this.walletsAndAddressesOperator.currentWallets.pipe(first(), mergeMap(response => { + wallets = response; + + // Get the basic backend info to know the number of the lastest block. + return this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api'); + }), mergeMap(generalData => { + // Allows to avoid repeating addresses. + const addressMap = new AddressMap(this.walletsAndAddressesOperator.formatAddress); + + // Get all the addresses of the wallets. + const addresses: string[] = []; + wallets.forEach(w => { + w.addresses.map(add => { + if (!addressMap.has(add.printableAddress)) { + addresses.push(add.printableAddress); + addressMap.set(add.printableAddress, true); + } + }); + }); + + // Calculate how many transactions to get per address. + const hasManyAddresses = addresses.length > AppConfig.fewAddressesLimit; + const transactionsToGet = hasManyAddresses ? AppConfig.maxTxPerAddressIfManyAddresses : AppConfig.maxTxPerAddressIfFewAddresses; + + // Determine the initial block to get only the pending transactions. + const startingBlock = generalData.blockbook.bestHeight - (this.currentCoin.confirmationsNeeded - 1); + + // Get the history. + return recursivelyGetTransactions(this.currentCoin, this.blockbookApiService, this.walletsAndAddressesOperator, addresses, transactionsToGet, startingBlock); + }), map(response => { + // Security measure for race conditions, as 2 request were made. + response.transactions = response.transactions.filter(tx => !tx.confirmations || tx.confirmations < this.currentCoin.confirmationsNeeded); + + return { + user: response.transactions.map(tx => this.processTransactionData(tx)).sort((a, b) => b.confirmations - a.confirmations), + all: [], + }; + })); + } + + getAddressesHistory(wallet: WalletBase): Observable { + return null; + } + + /** + * Converts a pending transaction returned by the server to a PendingTransactionData instance. + * @param transaction Transaction returned by the server. + */ + private processTransactionData(transaction: any): PendingTransactionData { + // Value which will allow to get the value in coins, instead of sats. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as EthCoinConfig).decimals); + + let coins = new BigNumber('0'); + transaction.vout.map(output => { + coins = coins.plus(new BigNumber(output.value).dividedBy(decimalsCorrector)); + }); + + return { + coins: coins.toString(), + timestamp: transaction.blockTime ? transaction.blockTime : null, + id: transaction.txid, + confirmations: transaction.confirmations ? transaction.confirmations : 0, + }; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/eth-network-operator.ts b/src/gui/static/src/app/services/coin-specific/eth/eth-network-operator.ts new file mode 100644 index 0000000..d313704 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/eth-network-operator.ts @@ -0,0 +1,95 @@ +import { mergeMap, delay } from 'rxjs/operators'; +import { NgZone, Injector } from '@angular/core'; +import { Observable, of, Subscription } from 'rxjs'; +import BigNumber from 'bignumber.js'; + +import { NetworkOperator, Connection } from '../network-operator'; +import { Coin } from '../../../coins/coin'; +import { environment } from '../../../../environments/environment'; +import { EthApiService } from '../../api/eth-api.service'; + +/** + * Operator for NetworkService to be used with eth-like coins. + * + * NOTE: only for knowing if the node is connected to other nodes. Remote nodes data not + * available for this coin type. + * + * You can find more information about the functions and properties this class implements by + * checking NetworkService and NetworkOperator. + */ +export class EthNetworkOperator implements NetworkOperator { + get noConnections(): boolean { + return this.noConnectionsInternal; + } + noConnectionsInternal = false; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 5 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 5 * 1000; + + private dataRefreshSubscription: Subscription; + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private ethApiService: EthApiService; + private ngZone: NgZone; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.ethApiService = injector.get(EthApiService); + this.ngZone = injector.get(NgZone); + + this.currentCoin = currentCoin; + + // Intervals for updating the data must be longer if connecting to a remote node. + if (!currentCoin.isLocal) { + this.updatePeriod = 120 * 1000; + this.errorUpdatePeriod = 30 * 1000; + } + + // Start updating the data periodically. + this.startDataRefreshSubscription(0); + } + + dispose() { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + } + + connections(): Observable { + // Data not available for this coin type + return of(null); + } + + /** + * Makes the operator start updating the data periodically. If this function was called + * before, the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the data. + */ + private startDataRefreshSubscription(delayMs: number) { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + this.ngZone.runOutsideAngular(() => { + this.dataRefreshSubscription = of(0).pipe(delay(delayMs), mergeMap(() => { + return this.ethApiService.callRpcMethod(this.currentCoin.nodeUrl, 'net_peerCount'); + })).subscribe(result => { + this.ngZone.run(() => { + this.noConnectionsInternal = environment.ignoreNonFiberNetworIssues ? false : new BigNumber((result as string).substr(2), 16).isLessThan(1); + }); + + // Repeat the operation after an appropiate delay. + this.startDataRefreshSubscription(this.updatePeriod); + }, () => this.startDataRefreshSubscription(this.errorUpdatePeriod)); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/eth-node-operator.ts b/src/gui/static/src/app/services/coin-specific/eth/eth-node-operator.ts new file mode 100644 index 0000000..1c59c5b --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/eth-node-operator.ts @@ -0,0 +1,82 @@ +import { delay, mergeMap } from 'rxjs/operators'; +import { BigNumber } from 'bignumber.js'; +import { Subscription, of, Observable, BehaviorSubject } from 'rxjs'; +import { Injector } from '@angular/core'; + +import { NodeOperator } from '../node-operator'; +import { Coin } from '../../../coins/coin'; +import { EthCoinConfig } from '../../../coins/coin-type-configs/eth.coin-config'; +import { BlockbookApiService } from '../../api/blockbook-api.service'; + +/** + * Operator for NodeService to be used with eth-like coins. + * + * You can find more information about the functions and properties this class implements by + * checking NodeService and NodeOperator. + */ +export class EthNodeOperator implements NodeOperator { + get remoteNodeDataUpdated(): Observable { + return this.remoteNodeDataUpdatedInternal.asObservable(); + } + private remoteNodeDataUpdatedInternal = new BehaviorSubject(false); + + get nodeVersion() { + return this.nodeVersionInternal; + } + private nodeVersionInternal = ''; + + get currentMaxDecimals() { + return (this.currentCoin.config as EthCoinConfig).decimals; + } + + get burnRate() { + return this.burnRateInternal; + } + private burnRateInternal = new BigNumber(1); + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private blockbookApiService: BlockbookApiService; + + private basicInfoSubscription: Subscription; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.blockbookApiService = injector.get(BlockbookApiService); + + this.currentCoin = currentCoin; + + this.updateData(0); + } + + dispose() { + if (this.basicInfoSubscription) { + this.basicInfoSubscription.unsubscribe(); + } + + this.remoteNodeDataUpdatedInternal.complete(); + } + + /** + * Connects to the node to get the data. + */ + private updateData(delayMs: number) { + if (this.basicInfoSubscription) { + this.basicInfoSubscription.unsubscribe(); + } + + this.basicInfoSubscription = of(1).pipe( + delay(delayMs), + mergeMap(() => this.blockbookApiService.get(this.currentCoin.indexerUrl, 'api')), + ).subscribe(response => { + this.nodeVersionInternal = response.backend.version; + + this.remoteNodeDataUpdatedInternal.next(true); + }, () => { + // If there is an error, retry after a delay. + this.updateData(this.currentCoin.isLocal ? 2000 : 15000); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/eth-operators-generator.ts b/src/gui/static/src/app/services/coin-specific/eth/eth-operators-generator.ts new file mode 100644 index 0000000..519c87f --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/eth-operators-generator.ts @@ -0,0 +1,33 @@ +import { Injector } from '@angular/core'; + +import { OperatorSet } from '../../operators.service'; +import { Coin } from '../../../coins/coin'; +import { OperatorsGenerator } from '../operators-generator'; +import { FiberSoftwareWalletOperator } from '../fiber/fiber-software-wallet-operator'; +import { FiberWalletUtilsOperator } from '../fiber/fiber-wallet-utils-operator'; +import { EthNetworkOperator } from './eth-network-operator'; +import { EthNodeOperator } from './eth-node-operator'; +import { EthWalletsAndAddressesOperator } from './eth-wallets-and-addresses-operator'; +import { EthBlockchainOperator } from './eth-blockchain-operator'; +import { EthBalanceAndOutputsOperator } from './eth-balance-and-outputs-operator'; +import { EthHistoryOperator } from './eth-history-operator'; +import { EthSpendingOperator } from './eth-spending-operator'; + +/** + * Generates the complete set of operators for eth-like coins. + */ +export class EthOperatorsGenerator implements OperatorsGenerator { + generate(coin: Coin, injector: Injector): OperatorSet { + return { + balanceAndOutputsOperator: new EthBalanceAndOutputsOperator(injector, coin), + blockchainOperator: new EthBlockchainOperator(injector, coin), + historyOperator: new EthHistoryOperator(injector, coin), + networkOperator: new EthNetworkOperator(injector, coin), + nodeOperator: new EthNodeOperator(injector, coin), + softwareWalletOperator: new FiberSoftwareWalletOperator(injector, coin), + spendingOperator: new EthSpendingOperator(injector, coin), + walletUtilsOperator: new FiberWalletUtilsOperator(injector, coin), + walletsAndAddressesOperator: new EthWalletsAndAddressesOperator(injector, coin), + }; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/eth-spending-operator.ts b/src/gui/static/src/app/services/coin-specific/eth/eth-spending-operator.ts new file mode 100644 index 0000000..e6b1123 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/eth-spending-operator.ts @@ -0,0 +1,221 @@ +import { throwError as observableThrowError, of, Observable, Subscription } from 'rxjs'; +import { concat, delay, retryWhen, take, mergeMap, catchError, map, filter, first } from 'rxjs/operators'; +import { Injector } from '@angular/core'; +import { BigNumber } from 'bignumber.js'; +import { TranslateService } from '@ngx-translate/core'; + +import { HwWalletService } from '../../hw-wallet.service'; +import { StorageService, StorageType } from '../../storage.service'; +import { WalletBase } from '../../wallet-operations/wallet-objects'; +import { GeneratedTransaction, Output, Input } from '../../wallet-operations/transaction-objects'; +import { Coin } from '../../../coins/coin'; +import { TransactionDestination, HoursDistributionOptions, RecommendedFees } from '../../wallet-operations/spending.service'; +import { SpendingOperator } from '../spending-operator'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; +import { EthApiService } from '../../api/eth-api.service'; +import { EthCoinConfig } from '../../../coins/coin-type-configs/eth.coin-config'; +import { EthTransactionData, EthTxEncoder } from './utils/eth-tx-encoder'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; + +/** + * Operator for SpendingService to be used with eth-like coins. + * + * NOTE: still under heavy development. + * + * You can find more information about the functions and properties this class implements by + * checking SpendingOperator and SpendingService. + */ +export class EthSpendingOperator implements SpendingOperator { + // Coin the current instance will work with. + private currentCoin: Coin; + + private operatorsSubscription: Subscription; + + // Services and operators used by this operator. + private ethApiService: EthApiService; + private hwWalletService: HwWalletService; + private translate: TranslateService; + private storageService: StorageService; + private balanceAndOutputsOperator: BalanceAndOutputsOperator; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.ethApiService = injector.get(EthApiService); + this.hwWalletService = injector.get(HwWalletService); + this.translate = injector.get(TranslateService); + this.storageService = injector.get(StorageService); + + // Get the operators. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.balanceAndOutputsOperator = operators.balanceAndOutputsOperator; + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + } + + createTransaction( + wallet: WalletBase|null, + addresses: string[]|null, + unspents: Output[]|null, + destinations: TransactionDestination[], + hoursDistributionOptions: HoursDistributionOptions, + changeAddress: string|null, + password: string|null, + unsigned: boolean, + fee: string): Observable { + + // The transaction can only have one source and destination. + if (destinations.length !== 1) { + throw new Error('Only one destination is allowed.'); + } + // Only one input address is used. + // TODO: prevent problems related to this. + if (addresses) { + addresses = [addresses[0]]; + } + + // Get the gas price (first part of the fee string) and max gas (second part). + const feeParts = fee.split('/'); + if (feeParts.length !== 2) { + throw new Error('Invalid fee format.'); + } + // Aproximate transaction fee. + const calculatedFee = this.calculateFinalFee(0, 0, new BigNumber(feeParts[0]), new BigNumber(feeParts[1])); + + // Create a string indicating where the coins come from. + let senderString = ''; + if (wallet) { + senderString = wallet.label; + } else if (addresses) { + senderString = this.walletsAndAddressesOperator.formatAddress(addresses[0]); + } + + const txInputs: Input[] = [{ + address: addresses ? this.walletsAndAddressesOperator.formatAddress(addresses[0]) : wallet.addresses[0].printableAddress, + coins: new BigNumber(0), + hash: '', + }]; + + const txOutputs: Output[] = [{ + address: this.walletsAndAddressesOperator.formatAddress(destinations[0].address), + coins: new BigNumber(destinations[0].coins), + hash: '', + }]; + + const tx: GeneratedTransaction = { + inputs: txInputs, + outputs: txOutputs, + coinsToSend: new BigNumber(destinations[0].coins), + fee: calculatedFee, + from: senderString, + to: this.walletsAndAddressesOperator.formatAddress(destinations[0].address), + wallet: wallet, + encoded: '', + innerHash: '', + }; + + // Get how many transactions the address has, for using it as nonce. + let response = this.ethApiService.callRpcMethod(this.currentCoin.nodeUrl, 'eth_getTransactionCount', [addresses[0], 'pending']).pipe(map((result: string) => { + // Needed for calculating the value in wei. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as EthCoinConfig).decimals); + + // Encode the transaction. + const txForEncoding: EthTransactionData = { + data: '', + destinationAddress: destinations[0].address, + value: new BigNumber(destinations[0].coins).multipliedBy(decimalsCorrector), + gasPriceInWei: new BigNumber(feeParts[0]).multipliedBy(1000000000), + gasLimit: new BigNumber(feeParts[1]), + nonce: new BigNumber(result.substr(2), 16), + chainId: new BigNumber((this.currentCoin.config as EthCoinConfig).chainId), + }; + tx.encoded = EthTxEncoder.encodeUnsigned(txForEncoding); + + return tx; + })); + + // If required, append to the response the steps needed for signing the transaction. + if (!unsigned) { + let unsignedTx: GeneratedTransaction; + + response = response.pipe(mergeMap(transaction => { + unsignedTx = transaction; + + return this.signTransaction(wallet, null, transaction); + })).pipe(map(encodedSignedTx => { + unsignedTx.encoded = encodedSignedTx; + + return unsignedTx; + })); + } + + return response; + } + + calculateFinalFee(howManyInputs: number, howManyOutputs: number, feePerUnit: BigNumber, maxUnits: BigNumber): BigNumber { + // Needed for returning the value in coins, not wei. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((this.currentCoin.config as EthCoinConfig).decimals); + + // feePerUnit is in gwei, so it has to be multiplied by 1000000000. + return maxUnits.multipliedBy(feePerUnit.multipliedBy(1000000000)).dividedBy(decimalsCorrector); + } + + signTransaction( + wallet: WalletBase, + password: string|null, + transaction: GeneratedTransaction, + rawTransactionString = ''): Observable { + + const tx = rawTransactionString ? rawTransactionString : transaction.encoded; + + // Get the test signature. + const signature = this.getSignature(); + const r = signature.substr(0, 64); + const s = signature.substr(64); + + return of(EthTxEncoder.addSignatureToRawTx(tx, new BigNumber((this.currentCoin.config as EthCoinConfig).chainId), r, s, 0)); + } + + /** + * Temporal function, only for testing, for getting a signature for signing a transaction. For + * using it, you must add the signature inside the code. + */ + private getSignature() { + return '13b0dbb70d09a3665ec693aec1b1b1a3b2aaefdf3c57f963a0229c83d1883c386b2171092d7e8f3d0087d01832e389392223993e0d14440ad6f0295f8e5e219d'; + } + + injectTransaction(encodedTx: string, note: string|null): Observable { + return this.ethApiService.callRpcMethod(this.currentCoin.nodeUrl, 'eth_sendRawTransaction', [encodedTx]).pipe(map(() => { + return true; + })); + } + + getCurrentRecommendedFees(): Observable { + // Get the recommended fee from the node. + return this.ethApiService.callRpcMethod(this.currentCoin.nodeUrl, 'eth_gasPrice').pipe(map(result => { + let gasPrice = new BigNumber((result as string).substr(2), 16).dividedBy(1000000000); + if (gasPrice.isLessThan((this.currentCoin.config as EthCoinConfig).minFee)) { + gasPrice = (this.currentCoin.config as EthCoinConfig).minFee; + } + + return { + recommendedEthFees: { + // The response is converted from Wei to Gwei. + gasPrice: gasPrice, + // Default gas limit for normal coin sending transactions. + gasLimit: new BigNumber(21000), + }, + recommendedBtcFees: null, + thereWereProblems: false, + }; + + }), retryWhen(errors => errors.pipe(delay(5000)))); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/eth-wallets-and-addresses-operator.ts b/src/gui/static/src/app/services/coin-specific/eth/eth-wallets-and-addresses-operator.ts new file mode 100644 index 0000000..f1385a9 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/eth-wallets-and-addresses-operator.ts @@ -0,0 +1,362 @@ +import { of, Observable, Subscription, ReplaySubject } from 'rxjs'; +import { mergeMap, map } from 'rxjs/operators'; +import { Injector } from '@angular/core'; + +import { HwWalletService } from '../../hw-wallet.service'; +import { WalletBase, AddressBase, duplicateWalletBase, WalletTypes } from '../../wallet-operations/wallet-objects'; +import { redirectToErrorPage } from '../../../utils/errors'; +import { StorageService, StorageType } from '../../storage.service'; +import { Coin } from '../../../coins/coin'; +import { WalletsAndAddressesOperator, LastAddress, CreateWalletArgs } from '../wallets-and-addresses-operator'; + +/** + * Operator for WalletsAndAddressesService to be used with eth-like coins. + * + * NOTE: still under heavy development. + * + * You can find more information about the functions and properties this class implements by + * checking WalletsAndAddressesOperator and WalletsAndAddressesService. + */ +export class EthWalletsAndAddressesOperator implements WalletsAndAddressesOperator { + /** + * Key used for saving the hw wallet list in persistent storage. NOTE: the value is changed + * in the code to make it unique for the current coin. + */ + private hwWalletsDataStorageKey = 'hw-wallets'; + /** + * Key used for saving the software wallet list in persistent storage. At this state it is only + * for testing. NOTE: the value is changed in the code to make it unique for the current coin. + */ + private swWalletsDataStorageKey = 'sw-wallets'; + + // List with all the wallets of all coins and the subject used for informing when the list + // has been modified. + private walletsList: WalletBase[]; + private walletsSubject: ReplaySubject = new ReplaySubject(1); + // List with the wallets of the currently selected coin. + private currentWalletsList: WalletBase[]; + private currentWalletsSubject: ReplaySubject = new ReplaySubject(1); + + private walletsSubscription: Subscription; + private savingHwWalletDataSubscription: Subscription; + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private hwWalletService: HwWalletService; + private storageService: StorageService; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.hwWalletService = injector.get(HwWalletService); + this.storageService = injector.get(StorageService); + + // Save the coin which will be used by this operator and change the persistent storage vars + // to correspond to the selected coin. + this.currentCoin = currentCoin; + this.hwWalletsDataStorageKey = this.hwWalletsDataStorageKey + '-' + currentCoin.coinName; + this.swWalletsDataStorageKey = this.swWalletsDataStorageKey + '-' + currentCoin.coinName; + } + + initialize(wallets: WalletBase[]) { + this.walletsList = wallets; + + // When the list with all the wallets is updated, the list with the wallets for the current + // coin is updated too. + this.walletsSubscription = this.walletsSubject.subscribe(() => { + this.currentWalletsList = this.walletsList.filter(wallet => wallet.coin === this.currentCoin.coinName); + this.currentWalletsSubject.next(this.currentWalletsList); + }); + + this.informDataUpdated(); + } + + dispose() { + if (this.savingHwWalletDataSubscription) { + this.savingHwWalletDataSubscription.unsubscribe(); + } + if (this.walletsSubscription) { + this.walletsSubscription.unsubscribe(); + } + + this.walletsSubject.complete(); + this.currentWalletsSubject.complete(); + } + + get allWallets(): Observable { + return this.walletsSubject.asObservable(); + } + + get currentWallets(): Observable { + return this.currentWalletsSubject.asObservable(); + } + + addAddressesToWallet(wallet: WalletBase, num: number, password?: string): Observable { + return of(null); + } + + scanAddresses(wallet: WalletBase, password?: string): Observable { + return of(null); + } + + getNextAddressAndUpdateWallet(wallet: WalletBase, password?: string): Observable { + return of(null); + } + + getLastAddressAndUpdateWallet(wallet: WalletBase, checkUnused: boolean): Observable { + return of(null); + } + + updateWallet(wallet: WalletBase): Observable { + return of(null); + } + + informValuesUpdated(wallet: WalletBase) { + const affectedWalletIndex = this.walletsList.findIndex(w => w.id === wallet.id); + if (affectedWalletIndex === -1) { + return; + } + if (this.walletsList[affectedWalletIndex].coin !== this.currentCoin.coinName) { + return; + } + + // Create a duplicate of the provided wallet and save it on the wallet list. + const newWallet = duplicateWalletBase(wallet, true); + this.walletsList[affectedWalletIndex] = newWallet; + + // Save if needed and inform the changes. + if (wallet.isHardware) { + this.saveHardwareWalletsAndInformUpdate(); + } else { + this.informDataUpdated(); + } + } + + createWallet(args: CreateWalletArgs): Observable { + return of(null); + } + + deleteWallet(walletId: string) { + const index = this.walletsList.findIndex(w => w.id === walletId); + if (index === -1 || !this.walletsList[index].isHardware) { + return; + } + + this.walletsList.splice(index, 1); + this.saveHardwareWalletsAndInformUpdate(); + } + + /** + * Saves on persistent storage the data of the hw wallets on the wallet list for the current + * coin. It overwrites the previously saved data. It also calls informDataUpdated(). + */ + private saveHardwareWalletsAndInformUpdate() { + const hardwareWallets: WalletBase[] = []; + + this.walletsList.map(wallet => { + if (wallet.coin === this.currentCoin.coinName && wallet.isHardware) { + hardwareWallets.push(this.createHardwareWalletData( + wallet.label, + wallet.addresses.map(address => { + const newAddress = AddressBase.create(this.formatAddress, address.printableAddress); + newAddress.confirmed = address.confirmed; + + return newAddress; + }), + wallet.hasHwSecurityWarnings, + wallet.stopShowingHwSecurityPopup, + )); + } + }); + + // Cancel any previous saving operation. + if (this.savingHwWalletDataSubscription) { + this.savingHwWalletDataSubscription.unsubscribe(); + } + + // The data is saved as a JSON string. + this.savingHwWalletDataSubscription = + this.storageService.store(StorageType.CLIENT, this.hwWalletsDataStorageKey, JSON.stringify(hardwareWallets)) + .subscribe({ + next: null, + error: () => redirectToErrorPage(3), + }); + + this.informDataUpdated(); + } + + /** + * Helper function for creating a WalletBase object for a hw wallet. + */ + private createHardwareWalletData(label: string, addresses: AddressBase[], hasHwSecurityWarnings: boolean, stopShowingHwSecurityPopup: boolean): WalletBase { + return { + label: label, + id: '', + hasHwSecurityWarnings: hasHwSecurityWarnings, + stopShowingHwSecurityPopup: stopShowingHwSecurityPopup, + addresses: addresses, + encrypted: false, + isHardware: true, + walletType: WalletTypes.Deterministic, + coin: this.currentCoin.coinName, + }; + } + + loadWallets(): Observable { + let wallets: WalletBase[] = []; + + // Get the software wallets. + return this.loadSoftwareWallets().pipe(mergeMap((response: any[]) => { + wallets = response; + + // Get the hardware wallets. + if (this.hwWalletService.hwWalletCompatibilityActivated) { + return this.loadHardwareWallets(); + } + + return of([]); + }), map((hardwareWallets: WalletBase[]) => { + // Hw wallets are first on the list. + return hardwareWallets.concat(wallets); + })); + } + + /** + * Loads all the hw wallets saved on persistent storage. + * @returns The list of hw wallets. + */ + private loadHardwareWallets(): Observable { + return this.storageService.get(StorageType.CLIENT, this.hwWalletsDataStorageKey).pipe( + map(storedWallets => { + if (storedWallets) { + const loadedWallets: WalletBase[] = JSON.parse(storedWallets); + + // Prepare to remove all unexpected properties, which could have been saved in a + // previous version of the app. + const knownPropertiesMap = new Map(); + const referenceObject = new WalletBase(); + Object.keys(referenceObject).forEach(property => { + knownPropertiesMap.set(property, true); + }); + + loadedWallets.forEach(wallet => { + // Remove all unexpected properties. + const propertiesToRemove: string[] = []; + Object.keys(wallet).forEach(property => { + if (!knownPropertiesMap.has(property)) { + propertiesToRemove.push(property); + } + }); + propertiesToRemove.forEach(property => { + delete wallet[property]; + }); + + // The wallet must be identified as a hw wallet and have at least one address. + // This is just a precaution. + wallet.isHardware = true; + if (!wallet.addresses) { + const newAddress = AddressBase.create(this.formatAddress, 'invalid'); + newAddress.confirmed = false; + wallet.addresses = [newAddress]; + } + + for (let i = 0; i < wallet.addresses.length; i++) { + const confirmed = wallet.addresses[i].confirmed; + const isChangeAddress = wallet.addresses[i].isChangeAddress; + + // Convert the saved address to the expected format. + if (wallet.addresses[i]['address']) { + // If the address was saved with the old format. + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['address']); + } else if (wallet.addresses[i]['printableAddressInternal']) { + // If the address was saved with the current format. + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['printableAddressInternal']); + } else { + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['invalid']); + } + + wallet.addresses[i].confirmed = confirmed; + wallet.addresses[i].isChangeAddress = isChangeAddress; + } + + // If the value was not retrieved, it means that the wallet was saved with a previous + // version of the app, which only used the Deterministic type for hw wallets. + if (!wallet.walletType) { + wallet.walletType = WalletTypes.Deterministic; + } + + wallet.coin = this.currentCoin.coinName; + + wallet.id = this.getHwWalletID(wallet.addresses[0].printableAddress); + }); + + return loadedWallets; + } + + return []; + }), + ); + } + + /** + * Loads all the software wallets saved on the persistent storage. At this state is only + * for testing. + */ + private loadSoftwareWallets(): Observable { + return this.storageService.get(StorageType.CLIENT, this.swWalletsDataStorageKey).pipe( + map(storedWallets => { + if (storedWallets) { + let loadedWallets: WalletBase[] = JSON.parse(storedWallets); + + loadedWallets = loadedWallets.filter(wallet => wallet.coin === this.currentCoin.coinName); + loadedWallets.forEach(wallet => { + // The wallet must be identified as a software wallet and have at least one address. + // This is just a precaution. + wallet.isHardware = false; + if (!wallet.addresses) { + const newAddress = AddressBase.create(this.formatAddress, 'invalid'); + newAddress.confirmed = true; + wallet.addresses = [newAddress]; + } + + // If an address was saved with the old format, convert it to the new one. + for (let i = 0; i < wallet.addresses.length; i++) { + if (wallet.addresses[i]['address']) { + const confirmed = wallet.addresses[i].confirmed; + const isChangeAddress = wallet.addresses[i].isChangeAddress; + + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['address']); + wallet.addresses[i].confirmed = confirmed; + wallet.addresses[i].isChangeAddress = isChangeAddress; + } + } + }); + + return loadedWallets; + } + + return []; + }), + ); + } + + /** + * Returns the ID a hw wallet must use. + * @param firstAddress First address of the wallet. + */ + private getHwWalletID(firstAddress: string): string { + return this.currentCoin.coinName + '-' + firstAddress; + } + + /** + * Makes walletsSubject emit, to inform that the wallet list has been updated. + */ + private informDataUpdated() { + this.walletsSubject.next(this.walletsList); + } + + formatAddress(address: string): string { + return address.trim().toLowerCase(); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/utils/eth-history-utils.ts b/src/gui/static/src/app/services/coin-specific/eth/utils/eth-history-utils.ts new file mode 100644 index 0000000..f5cd706 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/utils/eth-history-utils.ts @@ -0,0 +1,231 @@ +import { Observable, of } from 'rxjs'; +import { mergeMap, map } from 'rxjs/operators'; +import { BigNumber } from 'bignumber.js'; + +import { WalletBase, AddressMap } from '../../../wallet-operations/wallet-objects'; +import { OldTransaction, OldTransactionTypes, Output } from '../../../wallet-operations/transaction-objects'; +import { StorageService, StorageType } from '../../../storage.service'; +import { calculateGeneralData } from '../../../../utils/history-utils'; +import { Coin } from '../../../../coins/coin'; +import { BlockbookApiService } from '../../../../services/api/blockbook-api.service'; +import { EthCoinConfig } from '../../../../coins/coin-type-configs/eth.coin-config'; +import { TransactionHistory, TransactionLimits } from '../../../../services/wallet-operations/history.service'; +import { AppConfig } from '../../../../app.config'; +import { WalletsAndAddressesOperator } from '../../wallets-and-addresses-operator'; + +/** + * Gets the transaction history of a wallet list. + * @param wallets Wallets to consult. + */ +export function getTransactionsHistory( + currentCoin: Coin, + wallets: WalletBase[], + transactionLimitperAddress: TransactionLimits, + blockbookApiService: BlockbookApiService, + storageService: StorageService, + walletsAndAddressesOperator: WalletsAndAddressesOperator, +): Observable { + + let transactions: OldTransaction[]; + /** + * Allows to easily know which addresses are part of the wallets and also to know + * which wallet the address belong to. + */ + const addressMap = new AddressMap(walletsAndAddressesOperator.formatAddress); + + // Get all the addresses of the wallets. + const addresses: string[] = []; + wallets.forEach(w => { + w.addresses.map(add => { + if (!addressMap.has(add.printableAddress)) { + addresses.push(add.printableAddress); + } + // There could be more than one wallet with the address. This would happen if the wallet is repeated + // (like when using the same seed for a software and a hardware wallet). In that case, the wallet + // with most addresses is considered "the most complete one" and is used. + if (!addressMap.has(add.printableAddress) || addressMap.get(add.printableAddress).addresses.length < w.addresses.length) { + addressMap.set(add.printableAddress, w); + } + }); + }); + + // Value which will allow to get amounts in coins, instead of wei. + const decimalsCorrector = new BigNumber(10).exponentiatedBy((currentCoin.config as EthCoinConfig).decimals); + + // Addresses for which transactions were ignored due to transactionLimitperAddres. + let addressesWitMoreTransactions: AddressMap; + // Calculate how many transactions to get per address. + const hasManyAddresses = addresses.length > AppConfig.fewAddressesLimit; + let transactionsToGet = hasManyAddresses ? AppConfig.maxTxPerAddressIfManyAddresses : AppConfig.maxTxPerAddressIfFewAddresses; + if (transactionLimitperAddress === TransactionLimits.ExtraLimit) { + transactionsToGet = transactionsToGet * AppConfig.maxTxPerAddressMultiplier; + } else if (transactionLimitperAddress === TransactionLimits.MaxAllowed) { + transactionsToGet = AppConfig.maxTxPerAddressAllowedByBackend; + } + + // Get the transactions of all addresses. + return recursivelyGetTransactions(currentCoin, blockbookApiService, walletsAndAddressesOperator, addresses, transactionsToGet).pipe(mergeMap((response: TransactionsResponse) => { + addressesWitMoreTransactions = response.addressesWitMoreTransactions; + + // Process the response and convert it into a known object type. Some values are temporal. + transactions = response.transactions.map(transaction => { + // Build the output list. + const outputs: Output[] = []; + (transaction.vout as any[]).forEach(output => { + outputs.push({ + hash: '', + address: (output.addresses as string[]).map(add => walletsAndAddressesOperator.formatAddress(add)).join(', '), + coins: new BigNumber(output.value).dividedBy(decimalsCorrector), + }); + }); + + // Build the transaction object. + const processedTx: OldTransaction = { + relevantAddresses: [], + balance: new BigNumber(0), + fee: new BigNumber(transaction.ethereumSpecific.gasUsed).multipliedBy(transaction.ethereumSpecific.gasPrice).dividedBy(decimalsCorrector), + confirmed: transaction.confirmations ? (transaction.confirmations >= currentCoin.confirmationsNeeded) : false, + confirmations: transaction.confirmations ? transaction.confirmations : 0, + timestamp: transaction.blockTime ? transaction.blockTime : -1, + id: transaction.txid, + inputs: (transaction.vin as any[]).map(input => { + return { + hash: '', + address: (input.addresses as string[]).map(add => walletsAndAddressesOperator.formatAddress(add)).join(', '), + coins: new BigNumber(0), + }; + }), + outputs: outputs, + involvedLocalWallets: '', + numberOfInvolvedLocalWallets: 0, + type: OldTransactionTypes.MixedOrUnknown, + failed: transaction.ethereumSpecific.status === 0, + }; + + return processedTx; + }); + + // Get the transaction notes. + return storageService.get(StorageType.NOTES, null); + }), map(notes => { + if (!notes) { + notes = {}; + } + + const notesMap: Map = new Map(); + Object.keys(notes).forEach(key => { + notesMap.set(key, notes[key]); + }); + + transactions = transactions + // Sort the transactions by date. + .sort((a, b) => { + if (b.timestamp >= 0 && a.timestamp >= 0) { + return b.timestamp - a.timestamp; + } else if (a.timestamp >= 0) { + return 1; + } else if (b.timestamp >= 0) { + return -1; + } else { + return 0; + } + }) + .map(transaction => { + // Add to the transaction object the type, balance and the involved wallets and addresses. + calculateGeneralData(transaction, addressMap, false, walletsAndAddressesOperator); + + // Add the note. + const txNote = notesMap.get(transaction.id); + if (txNote) { + transaction.note = txNote; + } + + return transaction; + }); + + const finalResponse: TransactionHistory = { + transactions: transactions, + addressesWitAdditionalTransactions: addressesWitMoreTransactions, + }; + + return finalResponse; + })); +} + +/** + * Object returned by the recursivelyGetTransactions function. + */ +export interface TransactionsResponse { + transactions: any[]; + /** + * List with the addresses for which transactions were ignored due to the value sent in the + * maxPerAddress param. + */ + addressesWitMoreTransactions: AddressMap; +} + +/** + * Gets the transaction history of the addresses in the provided address list. + * @param addresses Addresses to check. The list will be altered by the function. + * @param maxPerAddress Max number of transactions to return per address. + * @param startingBlock Block from which to start looking for transactions. + * @param currentElements Already obtained transactions. For internal use. + * @param addressesWitMoreTransactions Addresses with transactions which were ignored. + * For internal use. + * @returns Array with all the transactions related to the provided address list, in the + * format returned by the backend. + */ +export function recursivelyGetTransactions( + currentCoin: Coin, + blockbookApiService: BlockbookApiService, + walletsAndAddressesOperator: WalletsAndAddressesOperator, + addresses: string[], + maxPerAddress: number, + startingBlock: number = null, + currentElements = new Map(), + addressesWitMoreTransactions = new AddressMap(walletsAndAddressesOperator.formatAddress), +): Observable { + const requestParams = { + pageSize: maxPerAddress, + details: 'txslight', + }; + + if (startingBlock) { + requestParams['from'] = startingBlock; + } + + return blockbookApiService.get(currentCoin.indexerUrl, 'address/' + addresses[addresses.length - 1], requestParams) + .pipe(mergeMap((response) => { + // Save the transactions. A map is used to avoid repeating transactions. + if (response.transactions) { + (response.transactions as any[]).forEach(transaction => { + currentElements.set(transaction.txid, transaction); + }); + } + + // Check if some transactions were ignored. + if (response.totalPages && response.totalPages > 1) { + addressesWitMoreTransactions.set(addresses[addresses.length - 1], true); + } + + addresses.pop(); + + // If there are no more addresses, build and return the final response. + if (addresses.length === 0) { + const transactionsForResponse: any[] = []; + currentElements.forEach(tx => { + transactionsForResponse.push(tx); + }); + + const finalResponse: TransactionsResponse = { + transactions: transactionsForResponse, + addressesWitMoreTransactions: addressesWitMoreTransactions, + }; + + return of(finalResponse); + } + + // Continue to the next step. + return recursivelyGetTransactions(currentCoin, blockbookApiService, walletsAndAddressesOperator, addresses, maxPerAddress, startingBlock, currentElements, addressesWitMoreTransactions); + })); +} diff --git a/src/gui/static/src/app/services/coin-specific/eth/utils/eth-tx-encoder.ts b/src/gui/static/src/app/services/coin-specific/eth/utils/eth-tx-encoder.ts new file mode 100644 index 0000000..a625a09 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/eth/utils/eth-tx-encoder.ts @@ -0,0 +1,173 @@ +import BigNumber from 'bignumber.js'; + +/** + * Data for creating an encoded unsigned transaction. + */ +export interface EthTransactionData { + nonce: BigNumber; + gasPriceInWei: BigNumber; + gasLimit: BigNumber; + destinationAddress: string; + value: BigNumber; + data: string; + chainId: BigNumber; +} + +/** + * Allows to encode ETH transactions, to be able to send them to the network. + */ +export class EthTxEncoder { + /** + * Creates an encoded transaction using the Ethereum format. + * @param transactionData Data for creating the transaction. + */ + static encodeUnsigned(transactionData: EthTransactionData): string { + let response = ''; + + // Nonce. + const nonce = EthTxEncoder.convertToValidRplHex(transactionData.nonce); + response += EthTxEncoder.getRplHexSize(nonce) + nonce; + + // Gas price. + const gasPrice = EthTxEncoder.convertToValidRplHex(transactionData.gasPriceInWei); + response += EthTxEncoder.getRplHexSize(gasPrice) + gasPrice; + + // Gas limit. + const gasLimit = EthTxEncoder.convertToValidRplHex(transactionData.gasLimit); + response += EthTxEncoder.getRplHexSize(gasLimit) + gasLimit; + + // Destination address, without the '0x' part. + if (transactionData.destinationAddress.startsWith('0x') || transactionData.destinationAddress.startsWith('0X')) { + transactionData.destinationAddress = transactionData.destinationAddress.substr(2); + } + response += EthTxEncoder.getRplHexSize(transactionData.destinationAddress) + transactionData.destinationAddress; + + // Value. + const value = EthTxEncoder.convertToValidRplHex(transactionData.value); + response += EthTxEncoder.getRplHexSize(value) + value; + + // Data + response += EthTxEncoder.getRplHexSize(transactionData.data) + transactionData.data; + + // V, in unsigned transactions it is just the chain ID. + const v = EthTxEncoder.convertToValidRplHex(transactionData.chainId); + response += EthTxEncoder.getRplHexSize(v) + v; + + // R and s, empty in unsigned transactions. + response += 8080; + + // RPL payload size. + response = EthTxEncoder.getRplHexSize(response, true) + response; + + return '0x' + response; + } + + /** + * Adds a signature to an unsigned raw transaction. + * @param rawTX Raw transaction, generated with encodeUnsigned. + * @param chainId Chain ID. + * @param r R part of the signature, as a hex string. + * @param s S part of the signature, as a hex string. + * @param recoveryValue Recovery value for the signature. 0 if V = 26 or 1 if V = 27. + */ + static addSignatureToRawTx(rawTX: string, chainId: BigNumber, r: string, s: string, recoveryValue: number): string { + if (r.length !== 64 || s.length !== 64) { + throw new Error('Invalid signature length.'); + } + + // Calculate the v value the unsigned raw transaction should have. + let expectedVString = EthTxEncoder.convertToValidRplHex(chainId); + expectedVString = EthTxEncoder.getRplHexSize(expectedVString) + expectedVString; + + // Remove everything after the v value. + const VPosition = rawTX.lastIndexOf(expectedVString); + if (VPosition === -1) { + throw new Error('Invalid encoded transaction.'); + } + rawTX = rawTX.substr(0, VPosition); + + // Calculate the new V value, using EIP-155. + const newV = EthTxEncoder.convertToValidRplHex(chainId.multipliedBy(2).plus(35).plus(recoveryValue)); + + // Add the signature. + rawTX += EthTxEncoder.getRplHexSize(newV) + newV; + rawTX += EthTxEncoder.getRplHexSize(r) + r; + rawTX += EthTxEncoder.getRplHexSize(s) + s; + + // Remove the 0x part. + rawTX = rawTX.substr(2); + + // Remove the RPL payload size, using the rules of the RPL format. + const oldTransactionSize = new BigNumber(rawTX.substr(0, 2), 16); + if (oldTransactionSize.isLessThanOrEqualTo('f7', 16)) { + rawTX = rawTX.substr(2); + } else { + const transactionSizeBytes = oldTransactionSize.minus('f7', 16); + rawTX = rawTX.substr(transactionSizeBytes.multipliedBy(2).plus(2).toNumber()); + } + + // Add the new RPL payload size. + rawTX = EthTxEncoder.getRplHexSize(rawTX, true) + rawTX; + + return '0x' + rawTX; + } + + /** + * Gets the size, in bytes, of a hex value, in the format neede for a RPL string. + * @param data Hex string to check. + * @param isTotalPayload If false, the value will be returned in the format needed for generic + * values inside the RPL payload. If true, the format will be the one nedded for indicating the + * size of the full RPL payload. + */ + private static getRplHexSize(data: string, isTotalPayload = false): string { + if (!data) { + data = ''; + } + + // 0 is considered an empty value. + if (new BigNumber(data).isEqualTo(0)) { + return '80'; + } + + // Small values do not need size. + if (!isTotalPayload && (data.length === 1 || data.length === 2)) { + const val = new BigNumber(data, 16); + if (val.isLessThan(128)) { + return ''; + } + } + + const bytes = new BigNumber(data.length).dividedBy(2).decimalPlaces(0, BigNumber.ROUND_CEIL); + if (bytes.isLessThanOrEqualTo(55)) { + const baseVaue = new BigNumber(isTotalPayload ? 'c0' : '80', 16); + + return bytes.plus(baseVaue).toString(16); + } else { + const bytesString = EthTxEncoder.convertToValidRplHex(bytes); + const lengthBytes = new BigNumber(bytesString.length).dividedBy(2); + + const baseVaue = new BigNumber(isTotalPayload ? 'f7' : 'b7', 16); + + return EthTxEncoder.convertToValidRplHex(lengthBytes.plus(baseVaue)) + bytesString; + } + } + + /** + * Converts a number into a hex string valid for a RPL string. + * @param value Value to convert. + */ + private static convertToValidRplHex(value: BigNumber): string { + // 0 is considered an empty value. + if (value.isEqualTo(0)) { + return ''; + } + + let response = value.toString(16); + // The length must be even. + if (response.length % 2 !== 0) { + response = '0' + response; + } + + return response; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-balance-and-outputs-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-balance-and-outputs-operator.ts new file mode 100644 index 0000000..cb0f2a7 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-balance-and-outputs-operator.ts @@ -0,0 +1,538 @@ +import { forkJoin as observableForkJoin, of, Observable, ReplaySubject, Subscription, BehaviorSubject } from 'rxjs'; +import { mergeMap, map, switchMap, tap, delay, filter, first } from 'rxjs/operators'; +import { NgZone, Injector } from '@angular/core'; +import { BigNumber } from 'bignumber.js'; + +import { WalletWithBalance, walletWithBalanceFromBase, WalletBase, walletWithOutputsFromBase, WalletWithOutputs, AddressMap } from '../../wallet-operations/wallet-objects'; +import { Output } from '../../wallet-operations/transaction-objects'; +import { FiberWalletsAndAddressesOperator } from './fiber-wallets-and-addresses-operator'; +import { Coin } from '../../../coins/coin'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { FiberApiService } from '../../api/fiber-api.service'; +import { OperatorService } from '../../operators.service'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; + +/** + * Operator for BalanceAndOutputsService to be used with Fiber coins. + * + * NOTE: The compatibility with coins not being managed by the local node is extremely limited + * at this time. + * + * You can find more information about the functions and properties this class implements by + * checking BalanceAndOutputsOperator and BalanceAndOutputsService. + */ +export class FiberBalanceAndOutputsOperator implements BalanceAndOutputsOperator { + // The list of wallets with balance and the subject used for informing when the list has been modified. + private walletsWithBalanceList: WalletWithBalance[]; + private walletsWithBalanceSubject: ReplaySubject = new ReplaySubject(1); + + // Subject for providing information in the getters below. + private lastBalancesUpdateTimeSubject: ReplaySubject = new ReplaySubject(1); + private hasPendingTransactionsSubject: BehaviorSubject = new BehaviorSubject(false); + private firstFullUpdateMadeSubject: BehaviorSubject = new BehaviorSubject(false); + private hadErrorRefreshingBalanceSubject: BehaviorSubject = new BehaviorSubject(false); + private refreshingBalanceSubject: BehaviorSubject = new BehaviorSubject(false); + + private dataRefreshSubscription: Subscription; + private walletsSubscription: Subscription; + private operatorsSubscription: Subscription; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 10 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 2 * 1000; + + /** + * After the service retrieves the balance of each wallet, the response returned by the node for each + * wallet is saved here, accessible via the wallet id. + */ + private savedBalanceData = new Map(); + /** + * Temporal map for updating savedBalanceData only after retrieving the data of all wallets, to avoid + * problems when the balance update procedure is cancelled early. + */ + private temporalSavedBalanceData = new Map(); + /** + * Saves the lastest, most up to date, wallet list obtained from the wallets service. + */ + private savedWalletsList: WalletBase[]; + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services and operators used by this operator. + private fiberApiService: FiberApiService; + private ngZone: NgZone; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + this.ngZone = injector.get(NgZone); + + // Intervals for updating the data must be longer if connecting to a remote node. + if (!currentCoin.isLocal) { + this.updatePeriod = 600 * 1000; + this.errorUpdatePeriod = 60 * 1000; + } + + // Get the operators and only then start using them. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + + // Update the balance immediately each time the wallets are updated. + this.walletsSubscription = this.walletsAndAddressesOperator.currentWallets.subscribe(wallets => { + this.savedWalletsList = wallets; + this.startDataRefreshSubscription(0, true); + }); + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + if (this.walletsSubscription) { + this.walletsSubscription.unsubscribe(); + } + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + this.lastBalancesUpdateTimeSubject.complete(); + this.walletsWithBalanceSubject.complete(); + this.hasPendingTransactionsSubject.complete(); + this.firstFullUpdateMadeSubject.complete(); + this.hadErrorRefreshingBalanceSubject.complete(); + this.refreshingBalanceSubject.complete(); + } + + get lastBalancesUpdateTime(): Observable { + return this.lastBalancesUpdateTimeSubject.asObservable(); + } + + get walletsWithBalance(): Observable { + return this.walletsWithBalanceSubject.asObservable(); + } + + get hasPendingTransactions(): Observable { + return this.hasPendingTransactionsSubject.asObservable(); + } + + get firstFullUpdateMade(): Observable { + return this.firstFullUpdateMadeSubject.asObservable(); + } + + get hadErrorRefreshingBalance(): Observable { + return this.hadErrorRefreshingBalanceSubject.asObservable(); + } + + get refreshingBalance(): Observable { + return this.refreshingBalanceSubject.asObservable(); + } + + get outputsWithWallets(): Observable { + // Run each time the wallet list changes. + return this.walletsWithBalance.pipe(switchMap(wallets => { + const addresses = wallets.map(wallet => wallet.addresses.map(address => address.printableAddress).join(',')).join(','); + + // Get the unspent outputs of the list of addresses. + return this.obtainOutputsList(addresses, false); + }), map(outputs => { + // Build the response. + const walletsList: WalletWithOutputs[] = []; + this.walletsWithBalanceList.forEach(wallet => { + const newWallet = walletWithOutputsFromBase(wallet); + walletsList.push(newWallet); + + newWallet.addresses.forEach(address => { + address.outputs = outputs.filter(output => address.compareAddress(output.address)); + }); + }); + + return walletsList; + })); + } + + getOutputs(addresses: string): Observable { + return this.obtainOutputsList(addresses, true); + } + + /** + * Gets the list of unspent outputs owned by any of the addresses passed in the addresses param. + * @param addresses List of addresses, comma separated. + * @param confirmedOnly If true, only confirmed outputs will be returned. + * @returns Array with all the unspent outputs owned by any of the provide addresses. + */ + private obtainOutputsList(addresses: string, confirmedOnly: boolean): Observable { + if (!addresses) { + return of([]); + } else { + // Get the outputs from the node and process the response. + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'outputs', { addrs: addresses }).pipe(map((response) => { + const outputs: Output[] = []; + + let outputsToUse: any[]; + if (confirmedOnly) { + outputsToUse = response.head_outputs; + } else { + outputsToUse = (response.head_outputs as any[]).concat(response.incoming_outputs); + } + + outputsToUse.forEach(output => { + const processedOutput: Output = { + address: this.walletsAndAddressesOperator.formatAddress(output.address), + coins: new BigNumber(output.coins), + hash: output.hash, + hours: new BigNumber(output.calculated_hours), + }; + + outputs.push(processedOutput); + }); + + return outputs; + })); + } + } + + getWalletUnspentOutputs(wallet: WalletBase): Observable { + const addresses = wallet.addresses.map(a => a.printableAddress).join(','); + + return this.obtainOutputsList(addresses, true); + } + + refreshBalance() { + this.startDataRefreshSubscription(0, false); + } + + /** + * Makes the service start updating the balance periodically. If it detects that the wallet + * address have been changed in the node (if apply), it will update the wallet data first. If + * this function was called before, the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the balance. + * @param updateWalletsFirst If true, after the delay the function will inmediatelly update + * the wallet list with the data on savedWalletsList and using the last balance data obtained + * from the node (or will set all the wallets to 0, if no data exists) and only after that will + * try to get the balance data from the node and update the wallet list again. This allows to + * inmediatelly reflect changes made to the wallet list, without having to wait for the node + * to respond. + */ + private startDataRefreshSubscription(delayMs: number, updateWalletsFirst: boolean) { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + // If the address list of one or more wallets has been changed in the node. + let addressesChanged = false; + + if (this.savedWalletsList) { + this.ngZone.runOutsideAngular(() => { + this.dataRefreshSubscription = of(0).pipe(delay(delayMs), mergeMap(() => { + // Inform the balance is being updated. + this.ngZone.run(() => { + this.refreshingBalanceSubject.next(true); + }); + + // Update the wallet list with the last saved data, if requested. + if (updateWalletsFirst) { + return this.refreshBalances(this.savedWalletsList, true); + } else { + return of(0); + } + }), mergeMap(() => { + // Get the current state of the wallet list in the node. + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'wallets'); + }), mergeMap(response => { + // Get the wallet list as it is in the node. + const nodeWallets: Map = new Map(); + response.forEach(wallet => { + const processedWallet = FiberWalletsAndAddressesOperator.processWallet(wallet, this.currentCoin.coinName, this.walletsAndAddressesOperator.formatAddress); + nodeWallets.set(processedWallet.id, processedWallet); + }); + + // Check if the address list of any of the saved wallets has changed in the node. + const outdatedWallets: WalletBase[] = []; + for (let i = 0; i < this.savedWalletsList.length; i++) { + // The case of wallets removed from the node is not considered. + if (nodeWallets.has(this.savedWalletsList[i].id)) { + if (nodeWallets.get(this.savedWalletsList[i].id).addresses.length !== this.savedWalletsList[i].addresses.length) { + addressesChanged = true; + outdatedWallets.push(this.savedWalletsList[i]); + } + } + } + + // If there was a change in the node, instead of refreshing the balance, the wallet + // is updated. This method will be called immediately after that for refreshing + // the balance. + if (addressesChanged) { + return this.recursivelyUpdateWallets(outdatedWallets); + } else { + return this.refreshBalances(this.savedWalletsList, false); + } + })).subscribe( + () => { + this.ngZone.run(() => { + this.hadErrorRefreshingBalanceSubject.next(false); + this.refreshingBalanceSubject.next(false); + }); + + // Repeat the operation after a delay. + this.startDataRefreshSubscription(addressesChanged ? 0 : this.updatePeriod, false); + }, + () => { + this.ngZone.run(() => { + this.hadErrorRefreshingBalanceSubject.next(true); + this.refreshingBalanceSubject.next(false); + }); + + // Repeat the operation after a delay. + this.startDataRefreshSubscription(this.errorUpdatePeriod, false); + }, + ); + }); + } + } + + /** + * Recursively updates the address list of the provided wallets, with the data stored on + * the node. + * @param outdatedWallets Wallets to update. + * @returns An observable for updating all the wallets. + */ + private recursivelyUpdateWallets(outdatedWallets: WalletBase[]): Observable { + let response = this.walletsAndAddressesOperator.updateWallet(outdatedWallets[outdatedWallets.length - 1]); + if (outdatedWallets.length > 1) { + outdatedWallets.pop(); + + response = response.pipe(mergeMap(() => this.recursivelyUpdateWallets(outdatedWallets))); + } + + return response; + } + + /** + * Refreshes the wallets on walletsWithBalanceList and their balances. + * @param wallets The current wallet lists. + * @param forceQuickCompleteArrayUpdate If true, the balance data saved on savedBalanceData + * will be used to set the balance of the wallet list, instead of getting the data from + * the node. If false, the balance data is obtained from the node and savedBalanceData is + * updated. + */ + private refreshBalances(wallets: WalletBase[], forceQuickCompleteArrayUpdate: boolean): Observable { + // Create a copy of the wallet list. + const temporalWallets: WalletWithBalance[] = []; + wallets.forEach(wallet => { + temporalWallets.push(walletWithBalanceFromBase(wallet)); + }); + + // This will help to update savedBalanceData when finishing the procedure. + if (!forceQuickCompleteArrayUpdate) { + this.temporalSavedBalanceData = new Map(); + } + + let procedure: Observable; + if (wallets.length > 0) { + // Get the balance of each wallet. + procedure = observableForkJoin(temporalWallets.map(wallet => this.retrieveWalletBalance(wallet, forceQuickCompleteArrayUpdate))); + } else { + // Create a fake response, as there are no wallets. + procedure = of([false]); + } + + // Calculate the balance of each wallet. + return procedure.pipe(tap(walletHasPendingTx => { + this.hasPendingTransactionsSubject.next(walletHasPendingTx.some(value => value)); + + if (!forceQuickCompleteArrayUpdate) { + this.ngZone.run(() => { + this.lastBalancesUpdateTimeSubject.next(new Date()); + }); + } + + if (!this.walletsWithBalanceList || forceQuickCompleteArrayUpdate || this.walletsWithBalanceList.length !== temporalWallets.length) { + // Update the whole list. + this.walletsWithBalanceList = temporalWallets; + this.informDataUpdated(); + } else { + // If there is a change in the IDs of the wallet list, update the whole list. + let changeDetected = false; + this.walletsWithBalanceList.forEach((currentWallet, i) => { + if (currentWallet.id !== temporalWallets[i].id) { + changeDetected = true; + } + }); + + if (changeDetected) { + this.walletsWithBalanceList = temporalWallets; + this.informDataUpdated(); + } else { + // Update only the balances with changes. This allows to show updated data without + // having to completelly replace the wallet array. + this.walletsWithBalanceList.forEach((currentWallet, i) => { + if ( + !currentWallet.coins.isEqualTo(temporalWallets[i].coins) || + !currentWallet.confirmedCoins.isEqualTo(temporalWallets[i].confirmedCoins) || + !currentWallet.hours.isEqualTo(temporalWallets[i].hours) || + !currentWallet.confirmedHours.isEqualTo(temporalWallets[i].confirmedHours) + ) { + currentWallet.coins = temporalWallets[i].coins; + currentWallet.confirmedCoins = temporalWallets[i].confirmedCoins; + currentWallet.availableCoins = temporalWallets[i].availableCoins; + currentWallet.hours = temporalWallets[i].hours; + currentWallet.confirmedHours = temporalWallets[i].confirmedHours; + currentWallet.availableHours = temporalWallets[i].availableHours; + currentWallet.hasPendingCoins = temporalWallets[i].hasPendingCoins; + currentWallet.hasPendingHours = temporalWallets[i].hasPendingHours; + + changeDetected = true; + } + + if (currentWallet.addresses.length !== temporalWallets[i].addresses.length) { + currentWallet.addresses = temporalWallets[i].addresses; + changeDetected = true; + } else { + currentWallet.addresses.forEach((currentAddress, j) => { + if ( + !currentAddress.coins.isEqualTo(temporalWallets[i].addresses[j].coins) || + !currentAddress.confirmedCoins.isEqualTo(temporalWallets[i].addresses[j].confirmedCoins) || + !currentAddress.hours.isEqualTo(temporalWallets[i].addresses[j].hours) || + !currentAddress.confirmedHours.isEqualTo(temporalWallets[i].addresses[j].confirmedHours) + ) { + currentAddress.coins = temporalWallets[i].addresses[j].coins; + currentAddress.confirmedCoins = temporalWallets[i].addresses[j].confirmedCoins; + currentAddress.availableCoins = temporalWallets[i].addresses[j].availableCoins; + currentAddress.hours = temporalWallets[i].addresses[j].hours; + currentAddress.confirmedHours = temporalWallets[i].addresses[j].confirmedHours; + currentAddress.availableHours = temporalWallets[i].addresses[j].availableHours; + currentAddress.hasPendingCoins = temporalWallets[i].addresses[j].hasPendingCoins; + currentAddress.hasPendingHours = temporalWallets[i].addresses[j].hasPendingHours; + + changeDetected = true; + } + }); + } + }); + + // If any of the balances changed, inform that there were changes. + if (changeDetected) { + this.informDataUpdated(); + } + } + } + + if (!forceQuickCompleteArrayUpdate) { + this.savedBalanceData = this.temporalSavedBalanceData; + if (!this.firstFullUpdateMadeSubject.value) { + // Inform that the service already obtained the balance from the node for the first time. + this.ngZone.run(() => { + this.firstFullUpdateMadeSubject.next(true); + }); + } + } + })); + } + + /** + * Gets from the node the balance of a wallet and used the retrieved data to update an instamce + * of WalletWithBalance. It also saves the retrieved data on temporalSavedBalanceData. + * @param wallet Wallet to update. + * @param useSavedBalanceData If true, the balance data saved on savedBalanceData + * will be used instead of retrieving the data from the node. + * @returns True if there are one or more pending transactions that will affect the balance of + * the provided walled, false otherwise. If useSavedBalanceData is true, the value of + * hasPendingTransactionsSubject will be returned. + */ + private retrieveWalletBalance(wallet: WalletWithBalance, useSavedBalanceData: boolean): Observable { + let query: Observable; + + if (!useSavedBalanceData) { + if (!wallet.isHardware) { + query = this.fiberApiService.get(this.currentCoin.nodeUrl, 'wallet/balance', { id: wallet.id }); + } else { + const addressesList = wallet.addresses.map(a => a.printableAddress).join(','); + query = this.fiberApiService.post(this.currentCoin.nodeUrl, 'balance', { addrs: addressesList }); + } + } else { + if (this.savedBalanceData.has(wallet.id)) { + query = of(this.savedBalanceData.get(wallet.id)); + } else { + query = of({ addresses: [] }); + } + } + + return query.pipe(map(balance => { + this.temporalSavedBalanceData.set(wallet.id, balance); + + const addressMap = new AddressMap(this.walletsAndAddressesOperator.formatAddress); + const addresses = Object.keys(balance.addresses); + addresses.forEach(address => { + addressMap.set(address, balance.addresses[address]); + }); + + // TODO: the available balance should be all the confirmed coins or hours minus all + // coins or hours going out. + + if (balance.confirmed) { + wallet.coins = new BigNumber(balance.predicted.coins).dividedBy(1000000); + wallet.hours = new BigNumber(balance.predicted.hours); + wallet.confirmedCoins = new BigNumber(balance.confirmed.coins).dividedBy(1000000); + wallet.confirmedHours = new BigNumber(balance.confirmed.hours); + wallet.availableCoins = wallet.coins; + wallet.availableHours = wallet.hours; + wallet.hasPendingCoins = !wallet.coins.isEqualTo(wallet.confirmedCoins); + wallet.hasPendingHours = !wallet.hours.isEqualTo(wallet.confirmedHours); + } else { + wallet.coins = new BigNumber(0); + wallet.hours = new BigNumber(0); + wallet.confirmedCoins = new BigNumber(0); + wallet.confirmedHours = new BigNumber(0); + wallet.availableCoins = wallet.coins; + wallet.availableHours = wallet.hours; + wallet.hasPendingCoins = false; + wallet.hasPendingHours = false; + } + + wallet.addresses.forEach(address => { + if (addressMap.has(address.printableAddress)) { + address.coins = new BigNumber(addressMap.get(address.printableAddress).predicted.coins).dividedBy(1000000); + address.hours = new BigNumber(addressMap.get(address.printableAddress).predicted.hours); + address.confirmedCoins = new BigNumber(addressMap.get(address.printableAddress).confirmed.coins).dividedBy(1000000); + address.confirmedHours = new BigNumber(addressMap.get(address.printableAddress).confirmed.hours); + address.availableCoins = address.coins; + address.availableHours = address.hours; + address.hasPendingCoins = !address.coins.isEqualTo(address.confirmedCoins); + address.hasPendingHours = !address.hours.isEqualTo(address.confirmedHours); + } else { + address.coins = new BigNumber(0); + address.hours = new BigNumber(0); + address.confirmedCoins = new BigNumber(0); + address.confirmedHours = new BigNumber(0); + address.availableCoins = address.coins; + address.availableHours = address.hours; + address.hasPendingCoins = false; + address.hasPendingHours = false; + } + }); + + if (!useSavedBalanceData) { + return !wallet.confirmedCoins.isEqualTo(wallet.coins) || !wallet.confirmedHours.isEqualTo(wallet.hours); + } else { + return this.hasPendingTransactionsSubject.value; + } + })); + } + + /** + * Makes walletsWithBalanceSubject emit, to inform that the wallet list has been updated. + */ + private informDataUpdated() { + this.ngZone.run(() => { + this.walletsWithBalanceSubject.next(this.walletsWithBalanceList); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-blockchain-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-blockchain-operator.ts new file mode 100644 index 0000000..d158d6d --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-blockchain-operator.ts @@ -0,0 +1,170 @@ +import { Subscription, of, Observable, ReplaySubject } from 'rxjs'; +import { delay, map, mergeMap, filter, first } from 'rxjs/operators'; +import { NgZone, Injector } from '@angular/core'; + +import { Coin } from '../../../coins/coin'; +import { BasicBlockInfo, ProgressEvent, BlockchainState } from '../../blockchain.service'; +import { BlockchainOperator } from '../blockchain-operator'; +import { FiberApiService } from '../../api/fiber-api.service'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; + +/** + * Operator for BlockchainService to be used with Fiber coins. + * + * You can find more information about the functions and properties this class implements by + * checking BlockchainService and BlockchainOperator. + */ +export class FiberBlockchainOperator implements BlockchainOperator { + private progressSubject: ReplaySubject = new ReplaySubject(1); + /** + * The current block reported the last time the current synchronization state was checked. + */ + private lastCurrentBlock = 0; + /** + * The last block reported the last time the current synchronization state was checked. + */ + private lastHighestBlock = 0; + /** + * If the node was synchronized the last time it was checked. + */ + private nodeSynchronized = false; + /** + * Allows the service to update the balance the first time the blockchain state is updated. + */ + private refreshedBalance = false; + + private dataSubscription: Subscription; + private operatorsSubscription: Subscription; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 2 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 2 * 1000; + + get progress(): Observable { + return this.progressSubject.asObservable(); + } + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services and operators used by this operator. + private fiberApiService: FiberApiService; + private ngZone: NgZone; + private balanceAndOutputsOperator: BalanceAndOutputsOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + this.ngZone = injector.get(NgZone); + + // Intervals for updating the data must be longer if connecting to a remote node. + if (!currentCoin.isLocal) { + this.updatePeriod = 120 * 1000; + this.errorUpdatePeriod = 30 * 1000; + } + + // Get the operators and only then start using them. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.balanceAndOutputsOperator = operators.balanceAndOutputsOperator; + + // Start checking the state of the blockchain. + this.startDataRefreshSubscription(0); + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + + this.progressSubject.complete(); + } + + getBlockchainState(): Observable { + let lastBlock: BasicBlockInfo; + + // Get the last block info. + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'last_blocks', { num: 1 }).pipe(mergeMap(blocks => { + lastBlock = { + seq: blocks.blocks[0].header.seq, + timestamp: blocks.blocks[0].header.timestamp, + hash: blocks.blocks[0].header.block_hash, + }; + + // Get the coin supply info. + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'coinSupply'); + }), map(supply => { + return { + lastBlock: lastBlock, + coinSupply: { + currentSupply: supply.current_supply, + totalSupply: supply.total_supply, + currentCoinhourSupply: supply.current_coinhour_supply, + totalCoinhourSupply: supply.total_coinhour_supply, + }, + }; + })); + } + + /** + * Makes the operator start periodically checking the synchronization state of the blockchain. + * If this function was called before, the previous procedure is cancelled. + * @param delayMs Delay before starting to check the data. + */ + private startDataRefreshSubscription(delayMs: number) { + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + + this.ngZone.runOutsideAngular(() => { + this.dataSubscription = of(0).pipe(delay(delayMs), mergeMap(() => { + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'blockchain/progress'); + })).subscribe((response: any) => { + this.ngZone.run(() => { + // Stop if a value is not valid. + if (!response || !response.current || !response.highest || response.highest === 0 || response.current < this.lastCurrentBlock || response.highest < this.lastHighestBlock) { + this.startDataRefreshSubscription(this.errorUpdatePeriod); + + return; + } + + this.lastCurrentBlock = response.current; + this.lastHighestBlock = response.highest; + + if (response.current === response.highest && !this.nodeSynchronized) { + this.nodeSynchronized = true; + this.balanceAndOutputsOperator.refreshBalance(); + this.refreshedBalance = true; + } else if (response.current !== response.highest && this.nodeSynchronized) { + this.nodeSynchronized = false; + } + + // Refresh the balance the first time the info is retrieved. + if (!this.refreshedBalance) { + this.balanceAndOutputsOperator.refreshBalance(); + this.refreshedBalance = true; + } + + this.progressSubject.next({ + currentBlock: this.lastCurrentBlock, + highestBlock: this.lastHighestBlock, + synchronized: this.nodeSynchronized, + }); + + this.startDataRefreshSubscription(this.updatePeriod); + }); + }, () => { + this.startDataRefreshSubscription(this.errorUpdatePeriod); + }); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-history-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-history-operator.ts new file mode 100644 index 0000000..bbd9a65 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-history-operator.ts @@ -0,0 +1,201 @@ +import { of, Observable, throwError, Subscription } from 'rxjs'; +import { first, mergeMap, map, filter, switchMap } from 'rxjs/operators'; +import { Injector } from '@angular/core'; +import { BigNumber } from 'bignumber.js'; + +import * as moment from 'moment'; + +import { StorageService } from '../../storage.service'; +import { WalletBase, WalletWithBalance, WalletTypes, AddressMap } from '../../wallet-operations/wallet-objects'; +import { Coin } from '../../../coins/coin'; +import { getTransactionsHistory, getIfAddressesUsed } from './utils/fiber-history-utils'; +import { PendingTransactionsResponse, AddressesHistoryResponse, AddressesState, PendingTransactionData, TransactionHistory, TransactionLimits } from '../../wallet-operations/history.service'; +import { HistoryOperator } from '../history-operator'; +import { FiberApiService } from '../../api/fiber-api.service'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; + +/** + * Operator for HistoryService to be used with Fiber coins. + * + * NOTE: The compatibility with coins not being managed by the local node is extremely limited + * at this time. + * + * You can find more information about the functions and properties this class implements by + * checking HistoryOperator and HistoryService. + */ +export class FiberHistoryOperator implements HistoryOperator { + // Coin the current instance will work with. + private currentCoin: Coin; + + private operatorsSubscription: Subscription; + + // Services and operators used by this operator. + private fiberApiService: FiberApiService; + private storageService: StorageService; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + private balanceAndOutputsOperator: BalanceAndOutputsOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + this.storageService = injector.get(StorageService); + + // Get the operators. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + this.balanceAndOutputsOperator = operators.balanceAndOutputsOperator; + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + } + + getIfAddressesUsed(wallet: WalletBase): Observable> { + return getIfAddressesUsed(this.currentCoin, wallet, this.fiberApiService, this.storageService, this.walletsAndAddressesOperator); + } + + getTransactionsHistory(wallet: WalletBase|null, transactionLimitperAddress: TransactionLimits): Observable { + // Use the provided wallet or get all wallets. + let initialRequest: Observable; + if (wallet) { + initialRequest = of([wallet]); + } else { + initialRequest = this.walletsAndAddressesOperator.currentWallets; + } + + // Get the history. + return initialRequest.pipe(first(), mergeMap(wallets => { + return getTransactionsHistory(this.currentCoin, wallets, this.fiberApiService, this.storageService, this.walletsAndAddressesOperator); + }), map(transactions => { + const response: TransactionHistory = { + transactions: transactions, + // This operator always returns the complete history. + addressesWitAdditionalTransactions: new AddressMap(this.walletsAndAddressesOperator.formatAddress), + }; + + return response; + })); + } + + getPendingTransactions(): Observable { + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'pendingTxs', { verbose: true }).pipe( + mergeMap((transactions: any[]) => { + // Default response if no transactions were found. + if (transactions.length === 0) { + return of({ + user: [], + all: [], + }); + } + + return this.walletsAndAddressesOperator.currentWallets.pipe(first(), map((wallets: WalletBase[]) => { + const addressMap = new AddressMap(this.walletsAndAddressesOperator.formatAddress); + wallets.forEach(wallet => { + wallet.addresses.forEach(address => addressMap.set(address.printableAddress, true)); + }); + + // Build an array with the transactions affecting the user. + const userTransactions = transactions.filter(tran => { + return tran.transaction.inputs.some(input => addressMap.has(input.owner)) || tran.transaction.outputs.some(output => addressMap.has(output.dst)); + }); + + return { + user: userTransactions.map(tx => this.processTransactionData(tx)).sort((a, b) => b.timestamp - a.timestamp), + all: transactions.map(tx => this.processTransactionData(tx)).sort((a, b) => b.timestamp - a.timestamp), + }; + })); + })); + } + + getAddressesHistory(wallet: WalletBase): Observable { + if (wallet.walletType === WalletTypes.Deterministic) { + return throwError('Invalid wallet.'); + } + + // Local object with the data of the requested wallet and its balance. + let currentWallet: WalletWithBalance; + // Response returned by the node when asked for the details of the requested wallet. + let nodeWallet; + + // Get data about the wallet. + return this.balanceAndOutputsOperator.firstFullUpdateMade.pipe(filter(response => response), switchMap(() => { + return this.balanceAndOutputsOperator.walletsWithBalance; + }), switchMap(response => { + currentWallet = response.find(w => w.id === wallet.id); + if (!currentWallet) { + return throwError('Invalid wallet.'); + } + + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'wallet', { id: wallet.id }); + }), switchMap(response => { + nodeWallet = response; + if (!nodeWallet || !nodeWallet.entries) { + return throwError('Invalid wallet.'); + } + + return this.getIfAddressesUsed(wallet); + }), map(usedMap => { + // Create a map with all the addresses the node says the wallet has. + const nodeAddressMap = new AddressMap(this.walletsAndAddressesOperator.formatAddress); + (nodeWallet.entries as any[]).forEach(currentAddress => { + nodeAddressMap.set(currentAddress.address, currentAddress); + }); + + const finalResponse: AddressesHistoryResponse = { + externalAddresses: [], + changeAddresses: [], + omitedAddresses: false, + }; + + currentWallet.addresses.forEach(currentAddress => { + // Create a response object for the current address. + const processedAddress: AddressesState = { + address: currentAddress, + indexInWallet: nodeAddressMap.has(currentAddress.printableAddress) ? nodeAddressMap.get(currentAddress.printableAddress).child_number : 0, + alreadyUsed: usedMap.has(currentAddress.printableAddress) && usedMap.get(currentAddress.printableAddress), + }; + + // Add the address to the appropiate array. + if (nodeAddressMap.has(currentAddress.printableAddress)) { + if (!nodeAddressMap.get(currentAddress.printableAddress).change || nodeAddressMap.get(currentAddress.printableAddress).change === 0) { + finalResponse.externalAddresses.push(processedAddress); + } else if (nodeAddressMap.get(currentAddress.printableAddress).change === 1) { + finalResponse.changeAddresses.push(processedAddress); + } else { + finalResponse.omitedAddresses = true; + } + } else { + finalResponse.omitedAddresses = true; + } + }); + + return finalResponse; + })); + } + + /** + * Converts a pending transaction returned by the server to a PendingTransactionData instance. + * @param transaction Transaction returned by the server. + */ + private processTransactionData(transaction: any): PendingTransactionData { + let coins = new BigNumber('0'); + let hours = new BigNumber('0'); + transaction.transaction.outputs.map(output => { + coins = coins.plus(output.coins); + hours = hours.plus(output.hours); + }); + + return { + coins: coins.toString(), + hours: hours.toString(), + timestamp: moment(transaction.received).unix(), + id: transaction.transaction.txid, + confirmations: 0, + }; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-network-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-network-operator.ts new file mode 100644 index 0000000..4db69d4 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-network-operator.ts @@ -0,0 +1,133 @@ +import { mergeMap, delay } from 'rxjs/operators'; +import { NgZone, Injector } from '@angular/core'; +import { Subject, BehaviorSubject, Observable, of, Subscription } from 'rxjs'; + +import { NetworkOperator, Connection, ConnectionSources } from '../network-operator'; +import { Coin } from '../../../coins/coin'; +import { FiberApiService } from '../../api/fiber-api.service'; + +/** + * Operator for NetworkService to be used with Fiber coins. + * + * You can find more information about the functions and properties this class implements by + * checking NetworkService and NetworkOperator. + */ +export class FiberNetworkOperator implements NetworkOperator { + get noConnections(): boolean { + return this.noConnectionsInternal; + } + noConnectionsInternal = false; + + /** + * Time interval in which periodic data updates will be made. + */ + private updatePeriod = 5 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private errorUpdatePeriod = 5 * 1000; + + /** + * List of default addresses to which the node will always try connect to when started. + */ + private trustedAddresses: string[]; + + private dataRefreshSubscription: Subscription; + + /** + * Emits the lists of remote nodes to which the node is currently connected. + */ + private connectionsSubject: Subject = new BehaviorSubject([]); + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private fiberApiService: FiberApiService; + private ngZone: NgZone; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + this.ngZone = injector.get(NgZone); + + this.currentCoin = currentCoin; + + // Intervals for updating the data must be longer if connecting to a remote node. + if (!currentCoin.isLocal) { + this.updatePeriod = 120 * 1000; + this.errorUpdatePeriod = 30 * 1000; + } + + // Start updating the data periodically. + this.startDataRefreshSubscription(0); + } + + dispose() { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + this.connectionsSubject.complete(); + } + + connections(): Observable { + return this.connectionsSubject.asObservable(); + } + + /** + * Makes the operator start updating the data periodically. If this function was called + * before, the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the data. + */ + private startDataRefreshSubscription(delayMs: number) { + if (this.dataRefreshSubscription) { + this.dataRefreshSubscription.unsubscribe(); + } + + this.ngZone.runOutsideAngular(() => { + this.dataRefreshSubscription = of(0).pipe(delay(delayMs), mergeMap(() => { + // Get the list of default remote nodes, but only if the list has not been + // obtained before. + if (!this.trustedAddresses) { + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'network/defaultConnections'); + } else { + return of(this.trustedAddresses); + } + }), mergeMap(defaultConnectionsResponse => { + this.trustedAddresses = defaultConnectionsResponse; + + // Get the list of current connections. + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'network/connections'); + })).subscribe(connectionsResponse => { + if (connectionsResponse.connections === null || connectionsResponse.connections.length === 0) { + this.noConnectionsInternal = true; + this.ngZone.run(() => this.connectionsSubject.next([])); + this.startDataRefreshSubscription(this.updatePeriod); + + return; + } + + this.noConnectionsInternal = false; + + // Process the obtained remote connections and convert them to a known object type. + const currentConnections = (connectionsResponse.connections as any[]).map(connection => { + return { + address: connection.address, + listenPort: connection.listen_port, + outgoing: connection.outgoing, + height: connection.height, + lastSent: connection.last_sent, + lastReceived: connection.last_received, + source: this.trustedAddresses.find(trustedAddress => trustedAddress === connection.address) ? ConnectionSources.Default : ConnectionSources.Exchange, + }; + }).sort((a, b) => a.address.localeCompare(b.address)); + + this.ngZone.run(() => this.connectionsSubject.next(currentConnections)); + + // Repeat the operation after an appropiate delay. + this.startDataRefreshSubscription(this.updatePeriod); + }, () => this.startDataRefreshSubscription(this.errorUpdatePeriod)); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-node-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-node-operator.ts new file mode 100644 index 0000000..fd4fa82 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-node-operator.ts @@ -0,0 +1,81 @@ +import { delay, mergeMap } from 'rxjs/operators'; +import { BigNumber } from 'bignumber.js'; +import { Subscription, of, Observable, BehaviorSubject } from 'rxjs'; +import { Injector } from '@angular/core'; + +import { NodeOperator } from '../node-operator'; +import { Coin } from '../../../coins/coin'; +import { FiberApiService } from '../../api/fiber-api.service'; + +/** + * Operator for NodeService to be used with Fiber coins. + * + * You can find more information about the functions and properties this class implements by + * checking NodeService and NodeOperator. + */ +export class FiberNodeOperator implements NodeOperator { + get remoteNodeDataUpdated(): Observable { + return this.remoteNodeDataUpdatedInternal.asObservable(); + } + private remoteNodeDataUpdatedInternal = new BehaviorSubject(false); + + get nodeVersion() { + return this.nodeVersionInternal; + } + private nodeVersionInternal = ''; + + get currentMaxDecimals() { + return this.currentMaxDecimalsInternal; + } + private currentMaxDecimalsInternal = 100; + + get burnRate() { + return this.burnRateInternal; + } + private burnRateInternal = new BigNumber(2); + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private fiberApiService: FiberApiService; + + private basicInfoSubscription: Subscription; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + + this.currentCoin = currentCoin; + + this.updateData(0); + } + + dispose() { + if (this.basicInfoSubscription) { + this.basicInfoSubscription.unsubscribe(); + } + + this.remoteNodeDataUpdatedInternal.complete(); + } + + /** + * Connects to the node to get the data. + */ + private updateData(delayMs: number) { + if (this.basicInfoSubscription) { + this.basicInfoSubscription.unsubscribe(); + } + + this.basicInfoSubscription = of(1).pipe(delay(delayMs), mergeMap(() => this.fiberApiService.get(this.currentCoin.nodeUrl, 'health'))).subscribe(response => { + this.nodeVersionInternal = response.version.version; + this.burnRateInternal = new BigNumber(response.user_verify_transaction.burn_factor); + this.currentMaxDecimalsInternal = response.user_verify_transaction.max_decimals; + + this.remoteNodeDataUpdatedInternal.next(true); + }, () => { + // If there is an error, retry after a delay. + this.updateData(this.currentCoin.isLocal ? 2000 : 15000); + }); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-operators-generator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-operators-generator.ts new file mode 100644 index 0000000..4fddb86 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-operators-generator.ts @@ -0,0 +1,33 @@ +import { Injector } from '@angular/core'; + +import { OperatorSet } from '../../operators.service'; +import { Coin } from '../../../coins/coin'; +import { OperatorsGenerator } from '../operators-generator'; +import { FiberBalanceAndOutputsOperator } from './fiber-balance-and-outputs-operator'; +import { FiberBlockchainOperator } from './fiber-blockchain-operator'; +import { FiberHistoryOperator } from './fiber-history-operator'; +import { FiberNetworkOperator } from './fiber-network-operator'; +import { FiberNodeOperator } from './fiber-node-operator'; +import { FiberSoftwareWalletOperator } from './fiber-software-wallet-operator'; +import { FiberSpendingOperator } from './fiber-spending-operator'; +import { FiberWalletUtilsOperator } from './fiber-wallet-utils-operator'; +import { FiberWalletsAndAddressesOperator } from './fiber-wallets-and-addresses-operator'; + +/** + * Generates the complete set of operators for fiber coins. + */ +export class FiberOperatorsGenerator implements OperatorsGenerator { + generate(coin: Coin, injector: Injector): OperatorSet { + return { + balanceAndOutputsOperator: new FiberBalanceAndOutputsOperator(injector, coin), + blockchainOperator: new FiberBlockchainOperator(injector, coin), + historyOperator: new FiberHistoryOperator(injector, coin), + networkOperator: new FiberNetworkOperator(injector, coin), + nodeOperator: new FiberNodeOperator(injector, coin), + softwareWalletOperator: new FiberSoftwareWalletOperator(injector, coin), + spendingOperator: new FiberSpendingOperator(injector, coin), + walletUtilsOperator: new FiberWalletUtilsOperator(injector, coin), + walletsAndAddressesOperator: new FiberWalletsAndAddressesOperator(injector, coin), + }; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-software-wallet-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-software-wallet-operator.ts new file mode 100644 index 0000000..930a198 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-software-wallet-operator.ts @@ -0,0 +1,88 @@ +import { Observable, Subscription } from 'rxjs'; +import { map, filter, first } from 'rxjs/operators'; +import { Injector } from '@angular/core'; + +import { WalletBase } from '../../wallet-operations/wallet-objects'; +import { Coin } from '../../../coins/coin'; +import { SoftwareWalletOperator } from '../software-wallet-operator'; +import { SeedResponse } from '../../wallet-operations/software-wallet.service'; +import { FiberApiService } from '../../api/fiber-api.service'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; +import { OperatorService } from '../../operators.service'; + +/** + * Operator for SoftwareWalletService to be used with Fiber coins. + * + * NOTE: The compatibility with coins not being managed by the local node is extremely limited + * at this time. + * + * You can find more information about the functions and properties this class implements by + * checking SoftwareWalletOperator and SoftwareWalletService. + */ +export class FiberSoftwareWalletOperator implements SoftwareWalletOperator { + // Coin the current instance will work with. + private currentCoin: Coin; + + private operatorsSubscription: Subscription; + + // Services and operators used by this operator. + private fiberApiService: FiberApiService; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + + // Get the operators. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + } + + renameWallet(wallet: WalletBase, label: string): Observable { + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'wallet/update', { id: wallet.id, label: label }).pipe(map(() => { + wallet.label = label; + this.walletsAndAddressesOperator.informValuesUpdated(wallet); + })); + } + + toggleEncryption(wallet: WalletBase, password: string): Observable { + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'wallet/' + (wallet.encrypted ? 'decrypt' : 'encrypt'), { id: wallet.id, password }).pipe(map(w => { + wallet.encrypted = w.meta.encrypted; + this.walletsAndAddressesOperator.informValuesUpdated(wallet); + })); + } + + resetPassword(wallet: WalletBase, seed: string, password: string, passphrase: string): Observable { + const params = new Object(); + params['id'] = wallet.id; + params['seed'] = seed; + if (password) { + params['password'] = password; + } + if (passphrase) { + params['seed_passphrase'] = passphrase; + } + + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'wallet/recover', params, {useV2: true}).pipe(map(w => { + wallet.encrypted = w.data.meta.encrypted; + this.walletsAndAddressesOperator.informValuesUpdated(wallet); + })); + } + + getWalletSeed(wallet: WalletBase, password: string): Observable { + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'wallet/seed', { id: wallet.id, password }).pipe(map(response => { + return { + seed: response.seed, + passphrase: response.seed_passphrase, + walletType: wallet.walletType, + }; + })); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-spending-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-spending-operator.ts new file mode 100644 index 0000000..974dc74 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-spending-operator.ts @@ -0,0 +1,300 @@ +import { throwError as observableThrowError, of, Observable, Subscription, concat } from 'rxjs'; +import { delay, retryWhen, take, mergeMap, catchError, map, filter, first } from 'rxjs/operators'; +import { Injector } from '@angular/core'; +import { BigNumber } from 'bignumber.js'; +import { TranslateService } from '@ngx-translate/core'; + +import { HwWalletService, HwOutput, HwInput } from '../../hw-wallet.service'; +import { StorageService, StorageType } from '../../storage.service'; +import { FiberTxEncoder } from './utils/fiber-tx-encoder'; +import { WalletBase, AddressBase, AddressMap } from '../../wallet-operations/wallet-objects'; +import { GeneratedTransaction, Output } from '../../wallet-operations/transaction-objects'; +import { Coin } from '../../../coins/coin'; +import { TransactionDestination, HoursDistributionOptions, RecommendedFees } from '../../wallet-operations/spending.service'; +import { SpendingOperator } from '../spending-operator'; +import { FiberApiService } from '../../api/fiber-api.service'; +import { BalanceAndOutputsOperator } from '../balance-and-outputs-operator'; +import { OperatorService } from '../../operators.service'; +import { WalletsAndAddressesOperator } from '../wallets-and-addresses-operator'; + +/** + * Operator for SpendingService to be used with Fiber coins. + * + * NOTE: The compatibility with coins not being managed by the local node is extremely limited + * at this time. + * + * You can find more information about the functions and properties this class implements by + * checking SpendingOperator and SpendingService. + */ +export class FiberSpendingOperator implements SpendingOperator { + // Coin the current instance will work with. + private currentCoin: Coin; + + private operatorsSubscription: Subscription; + + // Services and operators used by this operator. + private fiberApiService: FiberApiService; + private hwWalletService: HwWalletService; + private translate: TranslateService; + private storageService: StorageService; + private balanceAndOutputsOperator: BalanceAndOutputsOperator; + private walletsAndAddressesOperator: WalletsAndAddressesOperator; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + this.hwWalletService = injector.get(HwWalletService); + this.translate = injector.get(TranslateService); + this.storageService = injector.get(StorageService); + + // Get the operators. + this.operatorsSubscription = injector.get(OperatorService).currentOperators.pipe(filter(operators => !!operators), first()).subscribe(operators => { + this.balanceAndOutputsOperator = operators.balanceAndOutputsOperator; + this.walletsAndAddressesOperator = operators.walletsAndAddressesOperator; + }); + + this.currentCoin = currentCoin; + } + + dispose() { + this.operatorsSubscription.unsubscribe(); + } + + createTransaction( + wallet: WalletBase|null, + addresses: string[]|null, + unspents: Output[]|null, + destinations: TransactionDestination[], + hoursDistributionOptions: HoursDistributionOptions, + changeAddress: string|null, + password: string|null, + unsigned: boolean, + fee: string): Observable { + + let unspentOutputHashes: string[]; + if (unspents) { + unspentOutputHashes = unspents.map(output => output.hash); + } + + // Create a string indicating where the coins come from. + let senderString = ''; + if (wallet) { + senderString = wallet.label; + } else { + if (addresses) { + senderString = addresses.join(', '); + } else if (unspentOutputHashes) { + senderString = unspentOutputHashes.join(', '); + } + } + + // Ignore the source addresses if specific source outputs were provided. + if (unspentOutputHashes) { + addresses = null; + } + + const useUnsignedTxEndpoint = !wallet || !!wallet.isHardware; + + const params = { + hours_selection: hoursDistributionOptions, + wallet_id: !useUnsignedTxEndpoint ? wallet.id : null, + password: password, + addresses: addresses, + unspents: unspentOutputHashes, + to: destinations, + change_address: changeAddress, + }; + if (!useUnsignedTxEndpoint) { + params['unsigned'] = unsigned; + } + + // Make the node create the transaction by using the appropiate URL and sending the + // previously defined params. + let response: Observable = this.fiberApiService.post( + this.currentCoin.nodeUrl, + useUnsignedTxEndpoint ? 'transaction' : 'wallet/transaction', + params, + { + sendDataAsJson: true, + useV2: useUnsignedTxEndpoint, + }, + ).pipe(map(transaction => { + const data = useUnsignedTxEndpoint ? transaction.data : transaction; + + // Return an error if using a hw wallet and the transaction has too many inputs or outputs. + if (wallet && wallet.isHardware) { + if (data.transaction.inputs.length > 8) { + throw new Error(this.translate.instant('hardware-wallet.errors.too-many-inputs-outputs')); + } + if (data.transaction.outputs.length > 8) { + throw new Error(this.translate.instant('hardware-wallet.errors.too-many-inputs-outputs')); + } + } + + // Calculate how many coins and hours are being sent. + let amountToSend = new BigNumber(0); + destinations.map(destination => amountToSend = amountToSend.plus(destination.coins)); + + let hoursToSend = new BigNumber(0); + data.transaction.outputs + .filter(o => destinations.map(dest => AddressBase.create(this.walletsAndAddressesOperator.formatAddress, dest.address)).find(addr => addr.compareAddress(o.address))) + .map(o => hoursToSend = hoursToSend.plus(new BigNumber(o.hours))); + + // Process the node response and create a known object. + const tx: GeneratedTransaction = { + inputs: (data.transaction.inputs as any[]).map(input => { + return { + hash: input.uxid, + address: this.walletsAndAddressesOperator.formatAddress(input.address), + coins: new BigNumber(input.coins), + hours: new BigNumber(input.calculated_hours), + }; + }), + outputs: (data.transaction.outputs as any[]).map(output => { + return { + hash: output.uxid, + address: this.walletsAndAddressesOperator.formatAddress(output.address), + coins: new BigNumber(output.coins), + hours: new BigNumber(output.hours), + }; + }), + coinsToSend: amountToSend, + hoursToSend: hoursToSend, + fee: new BigNumber(data.transaction.fee), + from: senderString, + to: destinations.map(destination => this.walletsAndAddressesOperator.formatAddress(destination.address)).join(', '), + wallet: wallet, + encoded: data.encoded_transaction, + innerHash: data.transaction.inner_hash, + }; + + if (wallet && wallet.isHardware && tx.outputs.length !== destinations.length) { + // If the transaction has an output for returning any remaining coins, the node puts it + // at the end. This helps to avoid asking for confirmation for the returning coins. + tx.outputs[tx.outputs.length - 1].returningCoins = true; + } + + return tx; + })); + + // If required, append to the response the steps needed for signing the transaction with the hw wallet. + if (wallet && wallet.isHardware && !unsigned) { + let unsignedTx: GeneratedTransaction; + + response = response.pipe(mergeMap(transaction => { + unsignedTx = transaction; + + return this.signTransaction(wallet, null, transaction); + })).pipe(map(encodedSignedTx => { + unsignedTx.encoded = encodedSignedTx; + + return unsignedTx; + })); + } + + return response; + } + + calculateFinalFee(howManyInputs: number, howManyOutputs: number, feePerUnit: BigNumber, maxUnits: BigNumber): BigNumber { + return new BigNumber(0); + } + + signTransaction( + wallet: WalletBase, + password: string|null, + transaction: GeneratedTransaction, + rawTransactionString = ''): Observable { + + // Code for signing a software wallet. The node is responsible for making the operation. + if (!wallet.isHardware) { + return this.fiberApiService.post( + this.currentCoin.nodeUrl, + 'wallet/transaction/sign', + { + wallet_id: wallet.id, + password: password, + encoded_transaction: rawTransactionString ? rawTransactionString : transaction.encoded, + }, + { + useV2: true, + }, + ).pipe(map(response => { + return response.data.encoded_transaction; + })); + + // Code for signing a hardware wallet. + } else { + if (rawTransactionString) { + throw new Error('Raw transactions not allowed.'); + } + + const hwOutputs: HwOutput[] = []; + const hwInputs: HwInput[] = []; + + const addressMap = new AddressMap(this.walletsAndAddressesOperator.formatAddress); + wallet.addresses.forEach((address, i) => addressMap.set(address.printableAddress, i)); + + // Convert all inputs and outputs to the format used by the hw wallet. + transaction.outputs.forEach(output => { + hwOutputs.push({ + address: output.address, + coins: new BigNumber(output.coins).toString(), + hours: new BigNumber(output.hours).toFixed(0), + }); + + // This makes de device consider the output as the one used for returning the remaining coins. + if (output.returningCoins && addressMap.has(output.address)) { + hwOutputs[hwOutputs.length - 1].address_index = addressMap.get(output.address); + } + }); + transaction.inputs.forEach(input => { + hwInputs.push({ + hash: input.hash, + index: addressMap.get(input.address), + }); + }); + + // Make the device sign the transaction. + return this.hwWalletService.signTransaction(hwInputs, hwOutputs).pipe(map(signatures => { + const rawTransaction = FiberTxEncoder.encode( + hwInputs, + hwOutputs, + signatures.rawResponse, + transaction.innerHash, + ); + + return rawTransaction; + })); + } + } + + /** + * Sends a signed transaction to the network, to efectivelly send the coins. + * @param encodedTx Transaction to send. + * @param note Optional local note for the transaction. + * @returns If the note was saved or not. + */ + injectTransaction(encodedTx: string, note: string|null): Observable { + // Send the transaction. + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'injectTransaction', { rawtx: encodedTx }, { sendDataAsJson: true }).pipe( + mergeMap(txId => { + // Refresh the balance after a small delay. + setTimeout(() => this.balanceAndOutputsOperator.refreshBalance(), 32); + + if (!note) { + return of(false); + } else { + // Save the note. Retry 3 times if an error is found. + return this.storageService.store(StorageType.NOTES, txId, note).pipe( + retryWhen(errors => concat(errors.pipe(delay(1000), take(3)), observableThrowError(-1))), + catchError(err => err === -1 ? of(-1) : err), + map(result => result === -1 ? false : true)); + } + })); + } + + // Not needed for Fiber coins. + getCurrentRecommendedFees(): Observable { + return null; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-wallet-utils-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-wallet-utils-operator.ts new file mode 100644 index 0000000..dd26f0d --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-wallet-utils-operator.ts @@ -0,0 +1,51 @@ +import { of, Observable, throwError } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; +import { Injector } from '@angular/core'; + +import { Coin } from '../../../coins/coin'; +import { FiberApiService } from '../../api/fiber-api.service'; +import { WalletUtilsOperator } from '../wallet-utils-operator'; +import { processServiceError } from 'app/utils/errors'; +import { OperationError, OperationErrorTypes } from 'app/utils/operation-error'; + +/** + * Operator for WalletUtilsService to be used with Fiber coins. + * + * NOTE: The compatibility with coins not being managed by the local node is extremely limited + * at this time. + * + * You can find more information about the functions and properties this class implements by + * checking WalletUtilsOperator and WalletUtilsService. + */ +export class FiberWalletUtilsOperator implements WalletUtilsOperator { + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private fiberApiService: FiberApiService; + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + + this.currentCoin = currentCoin; + } + + dispose() { } + + verifyAddress(address: string): Observable { + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'address/verify', { address }, {useV2: true}).pipe( + map(() => true), + catchError((err: OperationError) => { + err = processServiceError(err); + + // Return false in case of error, but not if the error was for a connection problem. + if (err.type !== OperationErrorTypes.NoInternet) { + return of(false); + } else { + return throwError(err); + } + }), + ); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/fiber-wallets-and-addresses-operator.ts b/src/gui/static/src/app/services/coin-specific/fiber/fiber-wallets-and-addresses-operator.ts new file mode 100644 index 0000000..a23ee19 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/fiber-wallets-and-addresses-operator.ts @@ -0,0 +1,804 @@ +import { of, Observable, throwError as observableThrowError, Subscription, ReplaySubject } from 'rxjs'; +import { mergeMap, map } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; +import { Injector } from '@angular/core'; + +import { HwWalletService } from '../../hw-wallet.service'; +import { AppConfig } from '../../../app.config'; +import { WalletBase, AddressBase, duplicateWalletBase, WalletTypes, AddressMap } from '../../wallet-operations/wallet-objects'; +import { processServiceError, redirectToErrorPage } from '../../../utils/errors'; +import { StorageService, StorageType } from '../../storage.service'; +import { Coin } from '../../../coins/coin'; +import { WalletsAndAddressesOperator, LastAddress, CreateWalletArgs, CreateSoftwareWalletArgs } from '../wallets-and-addresses-operator'; +import { getIfAddressesUsed } from './utils/fiber-history-utils'; +import { FiberApiService } from '../../api/fiber-api.service'; + +/** + * Operator for WalletsAndAddressesService to be used with Fiber coins. + * + * NOTE: The compatibility with coins not being managed by the local node is extremely limited + * at this time. + * + * You can find more information about the functions and properties this class implements by + * checking WalletsAndAddressesOperator and WalletsAndAddressesService. + */ +export class FiberWalletsAndAddressesOperator implements WalletsAndAddressesOperator { + /** + * Key used for saving the hw wallet list in persistent storage. NOTE: the value is changed if + * the wallets of the current coin are not managed by the local node. + */ + private hwWalletsDataStorageKey = 'hw-wallets'; + /** + * Key used for saving software wallet list in persistent storage. At this state it is only + * for testing. NOTE: the value is changed if the wallets of the current coin are not managed + * by the local node. + */ + private swWalletsDataStorageKey = 'sw-wallets'; + + // List with all the wallets of all coins and the subject used for informing when the list + // has been modified. + private walletsList: WalletBase[]; + private walletsSubject: ReplaySubject = new ReplaySubject(1); + // List with the wallets of the currently selected coin. + private currentWalletsList: WalletBase[]; + private currentWalletsSubject: ReplaySubject = new ReplaySubject(1); + + private walletsSubscription: Subscription; + private savingHwWalletDataSubscription: Subscription; + + // Coin the current instance will work with. + private currentCoin: Coin; + + // Services used by this operator. + private fiberApiService: FiberApiService; + private hwWalletService: HwWalletService; + private translate: TranslateService; + private storageService: StorageService; + + /** + * Processes the wallet data returned by the node API and converts it into a WalletBase instance. + * @param wallet Wallet data returned by the node. + * @param coinName Name of the coin that will be asigned to the wallet. + */ + static processWallet(wallet: any, coinName: string, addressFormatter: (address: string) => string): WalletBase { + // Fill the properties related to the wallet itself. + const processedWallet: WalletBase = { + label: wallet.meta.label, + id: wallet.meta.filename, + addresses: [], + encrypted: wallet.meta.encrypted, + isHardware: false, + hasHwSecurityWarnings: false, + stopShowingHwSecurityPopup: true, + walletType: wallet.meta.type, + coin: coinName, + }; + + // Fill the addres list. + if (wallet.entries) { + processedWallet.addresses = (wallet.entries as any[]).map((entry: any) => { + const isChangeAddress = processedWallet.walletType !== WalletTypes.Deterministic ? (entry.change === 1) : false; + + const address = AddressBase.create(addressFormatter, entry.address); + address.confirmed = true; + address.isChangeAddress = isChangeAddress; + + return address; + }); + } + + return processedWallet; + } + + constructor(injector: Injector, currentCoin: Coin) { + // Get the services. + this.fiberApiService = injector.get(FiberApiService); + this.hwWalletService = injector.get(HwWalletService); + this.translate = injector.get(TranslateService); + this.storageService = injector.get(StorageService); + + // Save the coin which will be used by this operator and change the persistent storage vars + // to correspond to the selected coin, if needed. + this.currentCoin = currentCoin; + if (!currentCoin.isLocal) { + this.hwWalletsDataStorageKey = this.hwWalletsDataStorageKey + '-' + currentCoin.coinName; + this.swWalletsDataStorageKey = this.swWalletsDataStorageKey + '-' + currentCoin.coinName; + } + } + + initialize(wallets: WalletBase[]) { + this.walletsList = wallets; + + // When the list with all the wallets is updated, the list with the wallets for the current + // coin is updated too. + this.walletsSubscription = this.walletsSubject.subscribe(() => { + this.currentWalletsList = this.walletsList.filter(wallet => wallet.coin === this.currentCoin.coinName); + this.currentWalletsSubject.next(this.currentWalletsList); + }); + + this.informDataUpdated(); + } + + dispose() { + if (this.savingHwWalletDataSubscription) { + this.savingHwWalletDataSubscription.unsubscribe(); + } + if (this.walletsSubscription) { + this.walletsSubscription.unsubscribe(); + } + + this.walletsSubject.complete(); + this.currentWalletsSubject.complete(); + } + + get allWallets(): Observable { + return this.walletsSubject.asObservable(); + } + + get currentWallets(): Observable { + return this.currentWalletsSubject.asObservable(); + } + + addAddressesToWallet(wallet: WalletBase, num: number, password?: string): Observable { + if (!wallet.isHardware) { + // Software wallets managed by the local node. + if (this.currentCoin.isLocal) { + const params = new Object(); + params['id'] = wallet.id; + params['num'] = num; + if (password) { + params['password'] = password; + } + + // Add the addresses on the backend. + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'wallet/newAddress', params).pipe(map((response: any) => { + // Find the affected wallet on the local list and add the addresses to it. + const affectedWallet = this.walletsList.find(w => w.id === wallet.id); + const newAddresses: AddressBase[] = []; + (response.addresses as any[]).forEach(value => { + const newAddress = AddressBase.create(this.formatAddress, value); + newAddress.confirmed = true; + newAddresses.push(newAddress); + affectedWallet.addresses.push(newAddress); + }); + + this.informDataUpdated(); + + return newAddresses; + })); + } else { + // Software wallets not managed by the local node. + + // Not implemented. + return of([]); + } + + } else { + // Generate the new addresses on the device. + return this.hwWalletService.getAddresses(num, wallet.addresses.length, this.currentCoin.skywalletCoinType).pipe(map(response => { + // Find the affected wallet on the local list and add the addresses to it. + const affectedWallet = this.walletsList.find(w => w.id === wallet.id); + const newAddresses: AddressBase[] = []; + (response.rawResponse as any[]).forEach(value => { + const newAddress = AddressBase.create(this.formatAddress, value); + newAddress.confirmed = false; + newAddresses.push(newAddress); + affectedWallet.addresses.push(newAddress); + }); + + this.saveHardwareWalletsAndInformUpdate(); + + return newAddresses; + })); + } + } + + scanAddresses(wallet: WalletBase, password?: string): Observable { + if (!wallet.isHardware) { + // Software wallets managed by the local node. + if (this.currentCoin.isLocal) { + const params = new Object(); + params['id'] = wallet.id; + if (password) { + params['password'] = password; + } + + // Request the backend to scan the addresses. + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'wallet/scan', params).pipe(map((response: any) => { + // Find the affected wallet on the local list and add the addresses to it. + const affectedWallet = this.walletsList.find(w => w.id === wallet.id); + const newAddresses: string[] = response.addresses; + if (newAddresses && newAddresses.length > 0) { + newAddresses.forEach(address => { + const newAddress = AddressBase.create(this.formatAddress, address); + newAddress.confirmed = true; + affectedWallet.addresses.push(newAddress); + }); + this.informDataUpdated(); + + return true; + } else { + return false; + } + })); + } else { + // Software wallets not managed by the local node. + + // Not implemented. + return of(false); + } + } else { + // Not implemented. + return of(false); + } + } + + getNextAddressAndUpdateWallet(wallet: WalletBase, password?: string): Observable { + if (!wallet.isHardware) { + // Software wallets managed by the local node. + if (this.currentCoin.isLocal) { + if (wallet.walletType === WalletTypes.Deterministic) { + throw new Error('Invalid wallet type.'); + } + + // Request the general info of the wallet, to get the updated address list. + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'wallet', { id: wallet.id }).pipe(mergeMap(walletData => { + // Get the index of the last external address. + const indexOfLast = this.getIndexOfLastExternalAddress(walletData.entries); + + // Check the transactions of the last external address. + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'transactions', {addrs: walletData.entries[indexOfLast].address}); + }), mergeMap(response => { + if ((response as any[]).length === 0) { + // If no new address is needed, complete the process for updating the wallet and + // returning the address. + return this.getLastAddressAndUpdateWallet(wallet, true); + } else { + if (!wallet.encrypted || password) { + // Add one address and repeat the process. + return this.addAddressesToWallet(wallet, 1, password).pipe(mergeMap(() => this.getNextAddressAndUpdateWallet(wallet, password))); + } else { + return of(null); + } + } + })); + } else { + // Software wallets not managed by the local node. + + // Not implemented. + return of(null); + } + } else { + // Not implemented. + return of(null); + } + } + + getLastAddressAndUpdateWallet(wallet: WalletBase, checkUnused: boolean): Observable { + if (!wallet.isHardware) { + // Software wallets managed by the local node. + if (this.currentCoin.isLocal) { + const finalResponse: LastAddress = { lastAddress: '' }; + + // Map with all the addreses which have already received coins. + let usedMap = new AddressMap(this.formatAddress); + + let firstStep: Observable>; + if (checkUnused) { + // Get which addresses have been used. + firstStep = getIfAddressesUsed(this.currentCoin, wallet, this.fiberApiService, this.storageService, this); + } else { + firstStep = of(undefined); + } + + return firstStep.pipe(mergeMap(response => { + if (checkUnused) { + usedMap = response; + } + + // Request the general info of the wallet, to get the updated address list. + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'wallet', { id: wallet.id }); + }), map(response => { + + // Get the index of the wallet on the wallet list. + let indexOnTheList = -1; + for (let i = 0; i < this.walletsList.length; i++) { + if (this.walletsList[i].id === wallet.id) { + indexOnTheList = i; + break; + } + } + + if (indexOnTheList === -1) { + throw new Error('Wallet not found.'); + } + + // Update the wallet and the balance. + this.walletsList[indexOnTheList] = FiberWalletsAndAddressesOperator.processWallet(response, this.currentCoin.coinName, this.formatAddress); + this.informDataUpdated(); + + // Get the index of the last external address. + const indexOfLastAddress = wallet.walletType !== WalletTypes.Deterministic ? + this.getIndexOfLastExternalAddress(response.entries) : (response.entries as any[]).length - 1; + + finalResponse.lastAddress = response.entries[indexOfLastAddress].address; + if (checkUnused) { + // Check how many previous addresses are unused. + let previousUnused = 0; + (response.entries as any[]).forEach((address, i) => { + if (i < indexOfLastAddress && (!address.change || address.change === 0) && (!usedMap.has(address.address) || !usedMap.get(address.address))) { + previousUnused += 1; + } + }); + + finalResponse.alreadyUsed = usedMap.has(finalResponse.lastAddress) && usedMap.get(finalResponse.lastAddress); + finalResponse.previousUnusedAddresses = previousUnused; + } + + return finalResponse; + })); + } else { + // Software wallets not managed by the local node. + + // Not implemented. + return of(null); + } + } else { + // Not implemented. + return of(null); + } + } + + updateWallet(wallet: WalletBase): Observable { + if (!wallet.isHardware) { + // Software wallets managed by the local node. + if (this.currentCoin.isLocal) { + return this.getLastAddressAndUpdateWallet(wallet, false).pipe(map(() => null)); + } else { + // Software wallets not managed by the local node. + + // Not implemented. + return of(null); + } + } else { + // Not implemented. + return of(null); + } + } + + /** + * Checks the address list of a wallet returned by the node API and returns the + * index of the last address for receiving coins (change addresses are ignored). + * It does not work with deterministic wallets. + * @param unprocessedAddressList Address list, as returned by the node API. + */ + private getIndexOfLastExternalAddress(unprocessedAddressList: any[]): number { + let indexOfLast = -1; + let childNumberOfLast = -1; + unprocessedAddressList.forEach((address, i) => { + if ((!address.change || address.change === 0) && address.child_number > childNumberOfLast) { + childNumberOfLast = address.child_number; + indexOfLast = i; + } + }); + + if (indexOfLast === -1) { + throw new Error('Unexpected error checking the wallet.'); + } + + return indexOfLast; + } + + informValuesUpdated(wallet: WalletBase) { + const affectedWalletIndex = this.walletsList.findIndex(w => w.id === wallet.id); + if (affectedWalletIndex === -1) { + return; + } + if (this.walletsList[affectedWalletIndex].coin !== this.currentCoin.coinName) { + return; + } + + // Create a duplicate of the provided wallet and save it on the wallet list. + const newWallet = duplicateWalletBase(wallet, true); + this.walletsList[affectedWalletIndex] = newWallet; + + // Save if needed and inform the changes. + if (wallet.isHardware) { + this.saveHardwareWalletsAndInformUpdate(); + } else { + this.informDataUpdated(); + } + } + + createWallet(args: CreateWalletArgs): Observable { + if (!args.isHardwareWallet) { + // Software wallets managed by the local node. + if (this.currentCoin.isLocal) { + return this.createNodeSoftwareWallet(args.softwareWalletArgs); + } else { + // Software wallets not managed by the local node. + + // Not implemented. + return of(null); + } + } else { + return this.createHardwareWallet(); + } + } + + /** + * Adds a new wallet to the node and adds it to the wallets list. + * @returns The newly creatd wallet. + */ + private createNodeSoftwareWallet(args: CreateSoftwareWalletArgs): Observable { + // Sanitize the seed. + args.seed = args.seed.replace(/(\n|\r\n)$/, ''); + + // Build the params object for the API request. + const params = { + label: args.label ? args.label : 'undefined', + scan: 100, + type: args.type, + }; + + if (args.type === WalletTypes.XPub) { + params['xpub'] = args.xPub; + } else { + params['seed'] = args.seed; + } + + if (args.password) { + params['password'] = args.password; + params['encrypt'] = true; + } + + if (args.type === WalletTypes.Bip44 && args.passphrase) { + params['seed-passphrase'] = args.passphrase; + } + + // Ask the node to create the wallet and return the data of the newly created wallet. + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'wallet/create', params).pipe(map(response => { + const wallet: WalletBase = FiberWalletsAndAddressesOperator.processWallet(response, this.currentCoin.coinName, this.formatAddress); + this.walletsList.push(wallet); + + this.informDataUpdated(); + + return wallet; + })); + } + + /** + * Adds a new hardware wallet to the wallets list, with the data of the currently connected device. + * @returns The newly creatd wallet. + */ + private createHardwareWallet(): Observable { + let addresses: string[]; + let lastAddressWithTx = 0; + let id: string; + const addressesMap = new AddressMap(this.formatAddress); + const addressesWithTxMap = new AddressMap(this.formatAddress); + + // Ask the device to return as many addresses as set on AppConfig.maxHardwareWalletAddresses. + return this.hwWalletService.getAddresses(AppConfig.maxHardwareWalletAddresses, 0, this.currentCoin.skywalletCoinType).pipe(mergeMap(response => { + // Save all addresses in a map. + addresses = response.rawResponse; + addresses.forEach(address => { + addressesMap.set(address, true); + }); + + id = this.getHwWalletID(addresses[0]); + + // Throw an error if any wallet has the same ID. + let walletAlreadyExists = false; + this.walletsList.forEach(wallet => { + if (wallet.id === id) { + walletAlreadyExists = true; + } + }); + if (walletAlreadyExists) { + return observableThrowError(processServiceError('The wallet already exists')); + } + + // Request the transaction history of all addresses. + const addressesString = addresses.join(','); + + return this.fiberApiService.post(this.currentCoin.nodeUrl, 'transactions', { addrs: addressesString }); + }), map(response => { + // Get the index of the last address of the list with transaction. + response.forEach(tx => { + tx.txn.outputs.forEach(output => { + if (addressesMap.has(output.dst)) { + addressesWithTxMap.set(output.dst, true); + } + }); + }); + addresses.forEach((address, i) => { + if (addressesWithTxMap.has(address)) { + lastAddressWithTx = i; + } + }); + + const newWallet = this.createHardwareWalletData( + this.translate.instant('hardware-wallet.general.default-wallet-name'), + addresses.slice(0, lastAddressWithTx + 1).map(add => { + const newAddress = AddressBase.create(this.formatAddress, add); + newAddress.confirmed = false; + + return newAddress; + }), true, false, + ); + + newWallet.id = id; + + // Add the wallet just after the last hw wallet of the wallet list. + let lastHardwareWalletIndex = this.walletsList.length - 1; + for (let i = 0; i < this.walletsList.length; i++) { + if (!this.walletsList[i].isHardware) { + lastHardwareWalletIndex = i - 1; + break; + } + } + this.walletsList.splice(lastHardwareWalletIndex + 1, 0, newWallet); + this.saveHardwareWalletsAndInformUpdate(); + + return newWallet; + })); + } + + deleteWallet(walletId: string) { + const index = this.walletsList.findIndex(w => w.id === walletId); + if (index === -1 || !this.walletsList[index].isHardware) { + return; + } + + this.walletsList.splice(index, 1); + this.saveHardwareWalletsAndInformUpdate(); + } + + /** + * Saves on persistent storage the data of the hw wallets on the wallet list for the current + * coin. It overwrites the previously saved data. It also calls informDataUpdated(). + */ + private saveHardwareWalletsAndInformUpdate() { + const hardwareWallets: WalletBase[] = []; + + this.walletsList.map(wallet => { + if (wallet.coin === this.currentCoin.coinName && wallet.isHardware) { + hardwareWallets.push(this.createHardwareWalletData( + wallet.label, + wallet.addresses.map(address => { + const newAddress = AddressBase.create(this.formatAddress, address.printableAddress); + newAddress.confirmed = address.confirmed; + + return newAddress; + }), + wallet.hasHwSecurityWarnings, + wallet.stopShowingHwSecurityPopup, + )); + } + }); + + // Cancel any previous saving operation. + if (this.savingHwWalletDataSubscription) { + this.savingHwWalletDataSubscription.unsubscribe(); + } + + // The data is saved as a JSON string. + this.savingHwWalletDataSubscription = + this.storageService.store(StorageType.CLIENT, this.hwWalletsDataStorageKey, JSON.stringify(hardwareWallets)) + .subscribe({ + next: null, + error: () => redirectToErrorPage(3), + }); + + this.informDataUpdated(); + } + + /** + * Helper function for creating a WalletBase object for a hw wallet. + */ + private createHardwareWalletData(label: string, addresses: AddressBase[], hasHwSecurityWarnings: boolean, stopShowingHwSecurityPopup: boolean): WalletBase { + return { + label: label, + id: '', + hasHwSecurityWarnings: hasHwSecurityWarnings, + stopShowingHwSecurityPopup: stopShowingHwSecurityPopup, + addresses: addresses, + encrypted: false, + isHardware: true, + walletType: WalletTypes.Deterministic, + coin: this.currentCoin.coinName, + }; + } + + loadWallets(): Observable { + let wallets: WalletBase[] = []; + + // Get the software wallets using the appropiate method. + let softwareWalletsStep: Observable; + if (this.currentCoin.isLocal) { + softwareWalletsStep = this.loadNodeWallets(); + } else { + softwareWalletsStep = this.loadSoftwareWallets(); + } + + // Get the software wallets. + return softwareWalletsStep.pipe(mergeMap((response: any[]) => { + wallets = response; + + // Get the hardware wallets. + if (this.hwWalletService.hwWalletCompatibilityActivated) { + return this.loadHardwareWallets(); + } + + return of([]); + }), map((hardwareWallets: WalletBase[]) => { + // Hw wallets are first on the list. + return hardwareWallets.concat(wallets); + })); + } + + /** + * Loads the software wallets managed by the local node. + */ + private loadNodeWallets(): Observable { + // Request the list from the node. + return this.fiberApiService.get(this.currentCoin.nodeUrl, 'wallets').pipe(map((response: any[]) => { + const wallets: WalletBase[] = []; + + // Process each wallet and include it if appropiate. + response.forEach(wallet => { + const processedWallet = FiberWalletsAndAddressesOperator.processWallet(wallet, this.currentCoin.coinName, this.formatAddress); + if (processedWallet.walletType === WalletTypes.Bip44 && AppConfig.bip44Enabled) { + wallets.push(processedWallet); + } + if (processedWallet.walletType === WalletTypes.XPub && AppConfig.xPubEnabled) { + wallets.push(processedWallet); + } + if (processedWallet.walletType === WalletTypes.Deterministic) { + wallets.push(processedWallet); + } + }); + + return wallets; + })); + } + + /** + * Loads all the hw wallets saved on persistent storage. + * @returns The list of hw wallets. + */ + private loadHardwareWallets(): Observable { + return this.storageService.get(StorageType.CLIENT, this.hwWalletsDataStorageKey).pipe( + map(storedWallets => { + if (storedWallets) { + const loadedWallets: WalletBase[] = JSON.parse(storedWallets); + + // Prepare to remove all unexpected properties, which could have been saved in a + // previous version of the app. + const knownPropertiesMap = new Map(); + const referenceObject = new WalletBase(); + Object.keys(referenceObject).forEach(property => { + knownPropertiesMap.set(property, true); + }); + + loadedWallets.forEach(wallet => { + // Remove all unexpected properties. + const propertiesToRemove: string[] = []; + Object.keys(wallet).forEach(property => { + if (!knownPropertiesMap.has(property)) { + propertiesToRemove.push(property); + } + }); + propertiesToRemove.forEach(property => { + delete wallet[property]; + }); + + // The wallet must be identified as a hw wallet and have at least one address. + // This is just a precaution. + wallet.isHardware = true; + if (!wallet.addresses) { + const newAddress = AddressBase.create(this.formatAddress, 'invalid'); + newAddress.confirmed = false; + wallet.addresses = [newAddress]; + } + + for (let i = 0; i < wallet.addresses.length; i++) { + const confirmed = wallet.addresses[i].confirmed; + const isChangeAddress = wallet.addresses[i].isChangeAddress; + + // Convert the saved address to the expected format. + if (wallet.addresses[i]['address']) { + // If the address was saved with the old format. + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['address']); + } else if (wallet.addresses[i]['printableAddressInternal']) { + // If the address was saved with the current format. + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['printableAddressInternal']); + } else { + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['invalid']); + } + + wallet.addresses[i].confirmed = confirmed; + wallet.addresses[i].isChangeAddress = isChangeAddress; + } + + // If the value was not retrieved, it means that the wallet was saved with a previous + // version of the app, which only used the Deterministic type for hw wallets. + if (!wallet.walletType) { + wallet.walletType = WalletTypes.Deterministic; + } + + wallet.coin = this.currentCoin.coinName; + + wallet.id = this.getHwWalletID(wallet.addresses[0].printableAddress); + }); + + return loadedWallets; + } + + return []; + }), + ); + } + + /** + * Loads all the software wallets saved on the persistent storage. At this state is only + * for testing. + */ + private loadSoftwareWallets(): Observable { + return this.storageService.get(StorageType.CLIENT, this.swWalletsDataStorageKey).pipe( + map(storedWallets => { + if (storedWallets) { + let loadedWallets: WalletBase[] = JSON.parse(storedWallets); + + loadedWallets = loadedWallets.filter(wallet => wallet.coin === this.currentCoin.coinName); + loadedWallets.forEach(wallet => { + // The wallet must be identified as a software wallet and have at least one address. + // This is just a precaution. + wallet.isHardware = false; + if (!wallet.addresses) { + const newAddress = AddressBase.create(this.formatAddress, 'invalid'); + newAddress.confirmed = true; + wallet.addresses = [newAddress]; + } + + // If an address was saved with the old format, convert it to the new one. + for (let i = 0; i < wallet.addresses.length; i++) { + if (wallet.addresses[i]['address']) { + const confirmed = wallet.addresses[i].confirmed; + const isChangeAddress = wallet.addresses[i].isChangeAddress; + + wallet.addresses[i] = AddressBase.create(this.formatAddress, wallet.addresses[i]['address']); + wallet.addresses[i].confirmed = confirmed; + wallet.addresses[i].isChangeAddress = isChangeAddress; + } + } + }); + + return loadedWallets; + } + + return []; + }), + ); + } + + /** + * Returns the ID a hw wallet must use. + * @param firstAddress First address of the wallet. + */ + private getHwWalletID(firstAddress: string): string { + return this.currentCoin.coinName + '-' + firstAddress; + } + + /** + * Makes walletsSubject emit, to inform that the wallet list has been updated. + */ + private informDataUpdated() { + this.walletsSubject.next(this.walletsList); + } + + formatAddress(address: string): string { + return address.trim(); + } +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-history-utils.ts b/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-history-utils.ts new file mode 100644 index 0000000..38a03c9 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-history-utils.ts @@ -0,0 +1,147 @@ +import { Observable } from 'rxjs'; +import { mergeMap, map } from 'rxjs/operators'; +import { BigNumber } from 'bignumber.js'; + +import { WalletBase, AddressBase, AddressMap } from '../../../wallet-operations/wallet-objects'; +import { OldTransaction, OldTransactionTypes } from '../../../wallet-operations/transaction-objects'; +import { StorageService, StorageType } from '../../../storage.service'; +import { calculateGeneralData } from '../../../../utils/history-utils'; +import { FiberApiService } from '../../../api/fiber-api.service'; +import { Coin } from '../../../../coins/coin'; +import { WalletsAndAddressesOperator } from '../../wallets-and-addresses-operator'; + +/** + * Checks the addresses of a wallet to know which ones have been used, defined as having + * received coins. + * @returns A map with all addresses, indicating which ones have been used and which ones + * have not. + */ +export function getIfAddressesUsed( + currentCoin: Coin, + wallet: WalletBase, + fiberApiService: FiberApiService, + storageService: StorageService, + walletsAndAddressesOperator: WalletsAndAddressesOperator, +): Observable> { + + const response = new AddressMap(walletsAndAddressesOperator.formatAddress); + wallet.addresses.forEach(address => response.set(address.printableAddress, false)); + + // Get the transaction history. + return getTransactionsHistory(currentCoin, [wallet], fiberApiService, storageService, walletsAndAddressesOperator).pipe(map(transactions => { + // Search all the outputs and set to true all the addresses found. + transactions.forEach(transaction => { + transaction.outputs.forEach(output => { + if (response.has(output.address)) { + response.set(output.address, true); + } + }); + }); + + return response; + })); +} + +/** + * Gets the transaction history of a wallet list. + * @param wallets Wallets to consult. + */ +export function getTransactionsHistory( + currentCoin: Coin, + wallets: WalletBase[], + fiberApiService: FiberApiService, + storageService: StorageService, + walletsAndAddressesOperator: WalletsAndAddressesOperator, +): Observable { + let transactions: OldTransaction[]; + /** + * Allows to easily know which addresses are part of the wallets and also to know + * which wallet the address belong to. + */ + const addressMap = new AddressMap(walletsAndAddressesOperator.formatAddress); + + // Get all the addresses of the wallets. + const addresses: AddressBase[] = []; + wallets.forEach(w => { + w.addresses.map(add => { + addresses.push(add); + // There could be more than one wallet with the address. This would happen if the wallet is repeated + // (like when using the same seed for a software and a hardware wallet). In that case, the wallet + // with most addresses is considered "the most complete one" and is used. + if (!addressMap.has(add.printableAddress) || addressMap.get(add.printableAddress).addresses.length < w.addresses.length) { + addressMap.set(add.printableAddress, w); + } + }); + }); + const addressList = addresses.map(a => a.printableAddress).join(','); + + // Get the transactions for all addresses. + return fiberApiService.post(currentCoin.nodeUrl, 'transactions', {addrs: addressList, verbose: true}).pipe(mergeMap((response: any[]) => { + // Process the response and convert it into a known object type. Some values are temporal. + transactions = response.map(transaction => ({ + relevantAddresses: [], + balance: new BigNumber(0), + hoursBalance: new BigNumber(0), + fee: new BigNumber(0), + confirmed: transaction.status.confirmed, + confirmations: transaction.status.confirmed ? 1 : 0, + timestamp: transaction.txn.timestamp, + id: transaction.txn.txid, + inputs: (transaction.txn.inputs as any[]).map(input => { + return { + hash: walletsAndAddressesOperator.formatAddress(input.uxid), + address: input.owner, + coins: new BigNumber(input.coins), + hours: new BigNumber(input.calculated_hours), + }; + }), + outputs: (transaction.txn.outputs as any[]).map(output => { + return { + hash: output.uxid, + address: walletsAndAddressesOperator.formatAddress(output.dst), + coins: new BigNumber(output.coins), + hours: new BigNumber(output.hours), + }; + }), + involvedLocalWallets: '', + numberOfInvolvedLocalWallets: 0, + type: OldTransactionTypes.MixedOrUnknown, + failed: false, + })); + + // Get the transaction notes. + return storageService.get(StorageType.NOTES, null); + }), map(notes => { + if (!notes) { + notes = {}; + } + + const notesMap: Map = new Map(); + Object.keys(notes).forEach(key => { + notesMap.set(key, notes[key]); + }); + + return transactions + // Sort the transactions by date. + .sort((a, b) => b.timestamp - a.timestamp) + .map(transaction => { + // Add to the transaction object the type, the balance and the involved wallets + // and addresses. + calculateGeneralData(transaction, addressMap, true, walletsAndAddressesOperator); + + // Calculate how many hours were burned. + let inputsHours = new BigNumber('0'); + transaction.inputs.map(input => inputsHours = inputsHours.plus(new BigNumber(input.hours))); + let outputsHours = new BigNumber('0'); + transaction.outputs.map(output => outputsHours = outputsHours.plus(new BigNumber(output.hours))); + transaction.fee = inputsHours.minus(outputsHours); + + const txNote = notesMap.get(transaction.id); + if (txNote) { + transaction.note = txNote; + } + + return transaction; + }); + })); +} diff --git a/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-tx-encoder.spec.ts b/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-tx-encoder.spec.ts new file mode 100644 index 0000000..925c2ad --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-tx-encoder.spec.ts @@ -0,0 +1,21 @@ +import { readJSON } from 'karma-read-json'; +import { FiberTxEncoder } from './fiber-tx-encoder'; +import BigNumber from 'bignumber.js'; + +describe('FiberTxEncoder', () => { + + describe('check encoding', () => { + const txs = readJSON('test-fixtures/encoded-txs.json').txs; + + for (let i = 0; i < txs.length; i++) { + it('encode tx ' + i, () => { + (txs[i].outputs as any[]).forEach(output => { + output.coins = new BigNumber(output.coins).dividedBy(1000000).toString(); + output.hours = new BigNumber(output.hours).toString(); + }); + + expect(FiberTxEncoder.encode(txs[i].inputs, txs[i].outputs, txs[i].signatures, txs[i].innerHash)).toBe(txs[i].raw); + }); + } + }); +}); diff --git a/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-tx-encoder.ts b/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-tx-encoder.ts new file mode 100644 index 0000000..2fa3adc --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/fiber/utils/fiber-tx-encoder.ts @@ -0,0 +1,222 @@ +import BigNumber from 'bignumber.js'; +import * as Base58 from 'base-x'; + +import { HwInput, HwOutput } from '../../../hw-wallet.service'; + +/** + * Allows to encode transactions, to be able to send them to the network. + */ +export class FiberTxEncoder { + /** + * Creates an encoded transaction using the Skycoin format. Check the encoded Skycoin + * transaction reference for more info. + * @param inputs List of all inputs. + * @param outputs List of all outputs. + * @param signatures List of all signatures. There must be one signature per input. + * @param innerHash Inner hash of the transaction. + * @param transactionType Number identifying the type of the transaction, as per the Skycoin + * transaction format. + */ + static encode(inputs: HwInput[], outputs: HwOutput[], signatures: string[], innerHash: string, transactionType = 0): string { + if (inputs.length !== signatures.length) { + throw new Error('Invalid number of signatures.'); + } + + // Calculate the size of the transaction and initialize the object used + // for writting the byte data. + const transactionSize = this.encodeSizeTransaction(inputs, outputs, signatures).toNumber(); + const buffer = new ArrayBuffer(transactionSize); + const dataView = new DataView(buffer); + let currentPos = 0; + + // Tx length + dataView.setUint32(currentPos, transactionSize, true); + currentPos += 4; + + // Tx type + dataView.setUint8(currentPos, transactionType); + currentPos += 1; + + // Tx innerHash + const innerHashBytes = this.convertToBytes(innerHash); + innerHashBytes.forEach(number => { + dataView.setUint8(currentPos, number); + currentPos += 1; + }); + + // Tx sigs maxlen check + if (signatures.length > 65535) { + throw new Error('Too many signatures.'); + } + + // Tx sigs length + dataView.setUint32(currentPos, signatures.length, true); + currentPos += 4; + + // Tx sigs + (signatures as string[]).forEach(sig => { + // Copy all bytes + const binarySig = this.convertToBytes(sig); + binarySig.forEach(number => { + dataView.setUint8(currentPos, number); + currentPos += 1; + }); + }); + + // Tx inputs maxlen check + if (inputs.length > 65535) { + throw new Error('Too many inputs.'); + } + + // Tx inputs length + dataView.setUint32(currentPos, inputs.length, true); + currentPos += 4; + + // Tx inputs + inputs.forEach(input => { + // Copy all bytes + const binaryInput = this.convertToBytes(input.hash); + binaryInput.forEach(number => { + dataView.setUint8(currentPos, number); + currentPos += 1; + }); + }); + + // Tx outputs maxlen check + if (outputs.length > 65535) { + throw new Error('Too many outputs.'); + } + + // Tx outputs length + dataView.setUint32(currentPos, outputs.length, true); + currentPos += 4; + + // Create an instance of the base58 decoder. + const decoder = Base58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'); + + // Tx outputs + outputs.forEach(output => { + // Decode the address + const decodedAddress = decoder.decode(output.address); + + // Address version + dataView.setUint8(currentPos, decodedAddress[20]); + currentPos += 1; + + // Address Key + for (let i = 0; i < 20; i++) { + dataView.setUint8(currentPos, decodedAddress[i]); + currentPos += 1; + } + + // Coins + currentPos = this.setUint64(dataView, currentPos, new BigNumber(output.coins).multipliedBy(1000000).decimalPlaces(0)); + // Hours + currentPos = this.setUint64(dataView, currentPos, new BigNumber(output.hours)); + }); + + // + + return this.convertToHex(buffer); + } + + /** + * Calculates the final size, in bytes, that an encoded transaction will have. + * @param inputs List of all inputs. + * @param outputs List of all outputs. + * @param signatures List of all signatures. + */ + private static encodeSizeTransaction(inputs: HwInput[], outputs: HwOutput[], signatures: string[]): BigNumber { + let size = new BigNumber(0); + + // Tx length + size = size.plus(4); + + // Tx type + size = size.plus(1); + + // Tx innerHash + size = size.plus(32); + + // Tx sigs + size = size.plus(4); + size = size.plus((new BigNumber(65).multipliedBy(signatures.length))); + + // Tx inputs + size = size.plus(4); + size = size.plus((new BigNumber(32).multipliedBy(inputs.length))); + + // Tx outputs + size = size.plus(4); + size = size.plus((new BigNumber(37).multipliedBy(outputs.length))); + + return size; + } + + /** + * Writes an Uint64 value on a DataView. + * @param dataView DataView in which the value will be written. + * @param currentPos Position inside the DataView in which the value will be written. + * @param value Value to be written. + * @returns The position in which the next value will have to be written on the DataView. + */ + private static setUint64(dataView: DataView, currentPos: number, value: BigNumber): number { + let hex = value.toString(16); + // Make sure the hex string has an even number of characters. + if (hex.length % 2 !== 0) { + hex = '0' + hex; + } + + const bytes = this.convertToBytes(hex); + for (let i = bytes.length - 1; i >= 0; i--) { + dataView.setUint8(currentPos, bytes[i]); + currentPos += 1; + } + + // Add zeros to fill the remaining space. + for (let i = 0; i < 8 - bytes.length; i++) { + dataView.setUint8(currentPos, 0); + currentPos += 1; + } + + return currentPos; + } + + /** + * Converts a hex string to a byte array. + * @param hexString String to convert. + */ + private static convertToBytes(hexString: string): number[] { + if (hexString.length % 2 !== 0) { + throw new Error('Invalid hex string.'); + } + + const result: number[] = []; + + for (let i = 0; i < hexString.length; i += 2) { + result.push(parseInt(hexString.substr(i, 2), 16)); + } + + return result; + } + + /** + * Converts an ArrayBuffer to a hex string. + * @param buffer ArrayBuffer to convert. + */ + private static convertToHex(buffer: ArrayBuffer) { + let result = ''; + + (new Uint8Array(buffer)).forEach((v) => { + let val = v.toString(16); + if (val.length === 0) { + val = '00'; + } else if (val.length === 1) { + val = '0' + val; + } + result += val; + }); + + return result; + } +} diff --git a/src/gui/static/src/app/services/coin-specific/history-operator.ts b/src/gui/static/src/app/services/coin-specific/history-operator.ts new file mode 100644 index 0000000..9c660a7 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/history-operator.ts @@ -0,0 +1,22 @@ +import { Observable } from 'rxjs'; + +import { WalletBase, AddressMap } from '../wallet-operations/wallet-objects'; +import { PendingTransactionsResponse, AddressesHistoryResponse, TransactionHistory, TransactionLimits } from '../wallet-operations/history.service'; + +/** + * Interface with the elements the operators for HistoryService must have. + * Much of it is similar to HistoryService, so you can find more info in that class. + */ +export interface HistoryOperator { + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(); + + // Functions for consulting the transactions. Documented on the service. + getIfAddressesUsed(wallet: WalletBase): Observable>; + getTransactionsHistory(wallet: WalletBase|null, transactionLimitperAddress: TransactionLimits): Observable; + getPendingTransactions(): Observable; + getAddressesHistory(wallet: WalletBase): Observable; +} diff --git a/src/gui/static/src/app/services/coin-specific/network-operator.ts b/src/gui/static/src/app/services/coin-specific/network-operator.ts new file mode 100644 index 0000000..f611be4 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/network-operator.ts @@ -0,0 +1,64 @@ +import { Observable } from 'rxjs'; + +export enum ConnectionSources { + /** + * Default node to which the node will always try to connect when started. + */ + Default = 'default', + /** + * Informed by a remote node. + */ + Exchange = 'exchange', +} + +/** + * Represents a connection a Fiber node has with another node. + */ +export interface Connection { + /** + * Address of the remote node. + */ + address: string; + /** + * Connection port. + */ + listenPort: number; + /** + * If the connection is outgoing or not. + */ + outgoing: boolean; + /** + * Highest block on the remote node. + */ + height: number; + /** + * Last time in which data was sent to the remote node, in Unix time. + */ + lastSent: number; + /** + * Last time in which data was received from the remote node, in Unix time. + */ + lastReceived: number; + /** + * Source from were the remote node was discovered. + */ + source: ConnectionSources; +} + +/** + * Interface with the elements the operators for NetworkService must have. + * Much of it is similar to NetworkService, so you can find more info in that class. + */ +export interface NetworkOperator { + // Properties. Documented on the service. + noConnections: boolean; + + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(); + + // Functions related to the state of the network. Documented on the service. + connections(): Observable; +} diff --git a/src/gui/static/src/app/services/coin-specific/node-operator.ts b/src/gui/static/src/app/services/coin-specific/node-operator.ts new file mode 100644 index 0000000..4a50998 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/node-operator.ts @@ -0,0 +1,20 @@ +import { BigNumber } from 'bignumber.js'; +import { Observable } from 'rxjs'; + +/** + * Interface with the elements the operators for NodeService must have. + * Much of it is similar to NodeService, so you can find more info in that class. + */ +export interface NodeOperator { + // Properties. Documented on the service. + remoteNodeDataUpdated: Observable; + nodeVersion: string; + currentMaxDecimals: number; + burnRate: BigNumber; + + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(); +} diff --git a/src/gui/static/src/app/services/coin-specific/operators-generator.ts b/src/gui/static/src/app/services/coin-specific/operators-generator.ts new file mode 100644 index 0000000..2751f56 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/operators-generator.ts @@ -0,0 +1,14 @@ +import { Injector } from '@angular/core'; + +import { OperatorSet } from '../operators.service'; +import { Coin } from '../../coins/coin'; + +/** + * Interface for the classes in charge of creating all the operators of a coin. + */ +export interface OperatorsGenerator { + /** + * Generates a complete set of operators for a coin. + */ + generate(coin: Coin, injector: Injector): OperatorSet; +} diff --git a/src/gui/static/src/app/services/coin-specific/software-wallet-operator.ts b/src/gui/static/src/app/services/coin-specific/software-wallet-operator.ts new file mode 100644 index 0000000..47946f3 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/software-wallet-operator.ts @@ -0,0 +1,22 @@ +import { Observable } from 'rxjs'; + +import { WalletBase } from '../wallet-operations/wallet-objects'; +import { SeedResponse } from '../wallet-operations/software-wallet.service'; + +/** + * Interface with the elements the operators for SoftwareWalletService must have. + * Much of it is similar to SoftwareWalletService, so you can find more info in that class. + */ +export interface SoftwareWalletOperator { + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(); + + // Functions for the software wallets. Documented on the service. + renameWallet(wallet: WalletBase, label: string): Observable; + toggleEncryption(wallet: WalletBase, password: string): Observable; + resetPassword(wallet: WalletBase, seed: string, password: string, passphrase: string): Observable; + getWalletSeed(wallet: WalletBase, password: string): Observable; +} diff --git a/src/gui/static/src/app/services/coin-specific/spending-operator.ts b/src/gui/static/src/app/services/coin-specific/spending-operator.ts new file mode 100644 index 0000000..357fa9a --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/spending-operator.ts @@ -0,0 +1,42 @@ +import { Observable } from 'rxjs'; +import BigNumber from 'bignumber.js'; + +import { WalletBase } from '../wallet-operations/wallet-objects'; +import { GeneratedTransaction, Output } from '../wallet-operations/transaction-objects'; +import { TransactionDestination, HoursDistributionOptions, RecommendedFees } from '../wallet-operations/spending.service'; + +/** + * Interface with the elements the operators for SpendingService must have. + * Much of it is similar to SpendingService, so you can find more info in that class. + */ +export interface SpendingOperator { + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(); + + // Functions for creating and sending transactions. Documented on the service. + createTransaction( + wallet: WalletBase|null, + addresses: string[]|null, + unspents: Output[]|null, + destinations: TransactionDestination[], + hoursDistributionOptions: HoursDistributionOptions, + changeAddress: string|null, + password: string|null, + unsigned: boolean, + fee: string): Observable; + + calculateFinalFee(howManyInputs: number, howManyOutputs: number, feePerUnit: BigNumber, maxUnits: BigNumber): BigNumber; + + signTransaction( + wallet: WalletBase, + password: string|null, + transaction: GeneratedTransaction, + rawTransactionString?): Observable; + + injectTransaction(encodedTx: string, note: string|null): Observable; + + getCurrentRecommendedFees(): Observable; +} diff --git a/src/gui/static/src/app/services/coin-specific/wallet-utils-operator.ts b/src/gui/static/src/app/services/coin-specific/wallet-utils-operator.ts new file mode 100644 index 0000000..8e5ae66 --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/wallet-utils-operator.ts @@ -0,0 +1,16 @@ +import { Observable } from 'rxjs'; + +/** + * Interface with the elements the operators for WalletUtilsService must have. + * Much of it is similar to WalletUtilsService, so you can find more info in that class. + */ +export interface WalletUtilsOperator { + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(): void; + + // Functions with utils related to the wallets. Documented on the service. + verifyAddress(address: string): Observable; +} diff --git a/src/gui/static/src/app/services/coin-specific/wallets-and-addresses-operator.ts b/src/gui/static/src/app/services/coin-specific/wallets-and-addresses-operator.ts new file mode 100644 index 0000000..2f957ac --- /dev/null +++ b/src/gui/static/src/app/services/coin-specific/wallets-and-addresses-operator.ts @@ -0,0 +1,106 @@ +import { Observable } from 'rxjs'; + +import { WalletBase, AddressBase, WalletTypes } from '../wallet-operations/wallet-objects'; + +/** + * Last external address (ignoring change addresses) of a wallet. + */ +export interface LastAddress { + /** + * Address string. + */ + lastAddress: string; + /** + * If the address has already been used (meaning that it has already received coins). + */ + alreadyUsed?: boolean; + /** + * How many unused external addresses the wallet has before this one. + */ + previousUnusedAddresses?: number; +} + +/** + * Data for the function for creating a wallet. + */ +export interface CreateWalletArgs { + /** + * If the wallet is from a hardware device. + */ + isHardwareWallet: boolean; + /** + * If creating a software wallet, the required data for creating it. + */ + softwareWalletArgs?: CreateSoftwareWalletArgs; +} + +/** + * Data needed for creating a software wallet. + */ +export interface CreateSoftwareWalletArgs { + /** + * Name given by the user to the wallet. + */ + label: string; + /** + * Type of the wallet to create. + */ + type: WalletTypes; + /** + * Wallet seed, if the selected type uses a seed. + */ + seed: string; + /** + * Wallet password, if it will be encrypted, null otherwise. + */ + password: string; + /** + * Passphrase for protecting the seed, if the selected type allows to use a passphrase. + */ + passphrase: string; + /** + * xPub key, if the xPub type was selected. + */ + xPub: string; +} + +/** + * Interface with the elements the operators for WalletsAndAddressesService must have. + * Much of it is similar to WalletsAndAddressesService, so you can find more info in that class. + */ +export interface WalletsAndAddressesOperator { + // Properties for getting access to the wallet lists. Documented on the service. + allWallets: Observable; + currentWallets: Observable; + + /** + * Initilizes the operator, so it can start to be used. + * @param wallets List with all the wallets of all coins registered in the app. Please make + * sure of not changing the reference of the array, so that any modification made inside the + * operation is reflected on the reference the service has. + */ + initialize(wallets: WalletBase[]): void; + /** + * Makes the operator close all observables and run cleaning procedures. Must be called when + * the operator is going to be replaced. + */ + dispose(): void; + + // Functions for creating and modifying the wallets. Documented on the service. + addAddressesToWallet(wallet: WalletBase, num: number, password?: string): Observable; + scanAddresses(wallet: WalletBase, password?: string): Observable; + getNextAddressAndUpdateWallet(wallet: WalletBase, password?: string): Observable; + getLastAddressAndUpdateWallet(wallet: WalletBase, checkUnused: boolean): Observable; + updateWallet(wallet: WalletBase): Observable; + informValuesUpdated(wallet: WalletBase); + createWallet(args: CreateWalletArgs): Observable; + deleteWallet(walletId: string): void; + formatAddress(address: string): string; + + /** + * Loads the wallets of the coin configured when the operator was created. The wallet list will + * be returned and won't be saved inside the operator, so you will still have to initialize + * the operator. The wallet list will contain the hw wallets first. + */ + loadWallets(): Observable; +} diff --git a/src/gui/static/src/app/services/coin.service.ts b/src/gui/static/src/app/services/coin.service.ts new file mode 100644 index 0000000..eff1dd7 --- /dev/null +++ b/src/gui/static/src/app/services/coin.service.ts @@ -0,0 +1,201 @@ +import { Injectable } from '@angular/core'; +import { ReplaySubject, Observable } from 'rxjs'; + +import { Coin } from '../coins/coin'; +import { environment } from '../../environments/environment'; +import { AppConfig } from '../app.config'; + +/** + * Allows to know which coins the wallet can work with and to change the currently selected coin. + */ +@Injectable() +export class CoinService { + + /** + * Allows to know the currently selected coin. + */ + get currentCoin(): Observable { + return this.currentCoinInternal.asObservable(); + } + private currentCoinInternal: ReplaySubject = new ReplaySubject(1); + + /** + * Allows to know the currently selected coin, as a synchronous value. + */ + get currentCoinInmediate(): Coin { + return this.currentCoinInmediateInternal; + } + private currentCoinInmediateInternal: Coin = null; + + /** + * List with the coins the wallet can work with. Values must not be overwritten. + */ + get coins(): Coin[] { + return this.coinsInternal; + } + private coinsInternal: Coin[] = []; + + private readonly currentCoinStorageKey = 'currentCoin'; + private readonly confirmationsStorageKeyPrefix = 'confirmations_'; + + /** + * Makes the service load the data it needs to work. + */ + initialize() { + this.loadAvailableCoins(); + this.loadAndUseSelectedCoin(); + + this.currentCoinInternal.subscribe(coin => { + // Keep synchronous value up to date. + this.currentCoinInmediateInternal = coin; + }); + } + + /** + * Changes the currently selected coin. + */ + changeCoin(coin: Coin) { + if (coin.coinName !== this.currentCoinInmediate.coinName) { + this.currentCoinInternal.next(coin); + this.saveCurrentCoin(); + } + } + + updateConfirmationsNeeded(newNumber: number) { + const convertedValue = Number(newNumber); + if (convertedValue === NaN || convertedValue < 1) { + throw new Error('Invalid number'); + } + + this.currentCoinInmediateInternal.confirmationsNeeded = newNumber; + localStorage.setItem(this.confirmationsStorageKeyPrefix + this.currentCoinInmediate.coinName, newNumber.toString()); + + this.currentCoinInternal.next(this.currentCoinInmediateInternal); + } + + /** + * Saves the name of the currently selected coin in persistent storage, to be abe to + * select it again by default. + */ + private saveCurrentCoin() { + // Save on session storage to be able to have different coins on different tabs. + sessionStorage.setItem(this.currentCoinStorageKey, this.currentCoinInmediate.coinName); + // Save on persistent storage. + localStorage.setItem(this.currentCoinStorageKey, this.currentCoinInmediate.coinName); + } + + /** + * Loads from the configuration file the list of the coins this wallet can work with. + */ + private loadAvailableCoins() { + // The names of the coins on the configuration file must be unique and only one coin can use + // the local node. + const Names = new Map(); + let localFound = false; + AppConfig.coins.forEach((value: Coin) => { + if (value.isLocal) { + if (localFound) { + throw new Error('Invalid configuration: the local node can be used by one coin only.'); + } else { + localFound = true; + // If using electron, get the local node URL from it. + if (window['electron']) { + value.nodeUrl = window['electron'].getLocalServerUrl() + '/api/'; + } + } + } + if (Names[value.coinName]) { + throw new Error('Invalid configuration: more than one coin with the same name.'); + } + if (value.normalConfirmationsNeeded < 1) { + throw new Error('Invalid configuration: coins must request at least one confirmation.'); + } + + // Get how many confirmations the coin needs. + const savedConfirmations = localStorage.getItem(this.confirmationsStorageKeyPrefix + value.coinName); + if (!savedConfirmations) { + value.confirmationsNeeded = value.normalConfirmationsNeeded; + } else { + value.confirmationsNeeded = value.normalConfirmationsNeeded; + value.confirmationsNeeded = Number(savedConfirmations); + } + + Names[value.coinName] = true; + }); + + // Get the coins, but ignore the dev only ones while running in production. + this.coinsInternal = AppConfig.coins.filter((coin: Coin) => { + if (environment.production) { + return !coin.devOnly; + } else { + return true; + } + }); + + // Sanitize the explorer URLs and the URL prefixes. + this.coinsInternal.forEach(coin => { + if (coin.explorerUrl && coin.explorerUrl.endsWith('/')) { + coin.explorerUrl = coin.explorerUrl.substr(0, coin.explorerUrl.length - 1); + } + + if (coin.uriSpecificatioPrefix && coin.uriSpecificatioPrefix.endsWith(':')) { + coin.uriSpecificatioPrefix = coin.uriSpecificatioPrefix.substr(0, coin.uriSpecificatioPrefix.length - 1); + } + }); + } + + /** + * Loads the coin saved as the last selected one and sets it as selected. + */ + private loadAndUseSelectedCoin() { + // First try to get the one saved on sessionStorage. If the wallet is open in more than + // one tab, this allows to have a different coin selected in each tab. + const sessionCoin = sessionStorage.getItem(this.currentCoinStorageKey); + if (sessionCoin) { + const retrievedCoin = this.tryToGetCoin(sessionCoin); + + if (retrievedCoin) { + this.currentCoinInternal.next(retrievedCoin); + + return; + } + } + + // Try using the persistent storage. + const coin = localStorage.getItem(this.currentCoinStorageKey); + if (coin) { + const retrievedCoin = this.tryToGetCoin(coin); + + if (retrievedCoin) { + this.currentCoinInternal.next(retrievedCoin); + + return; + } + } + + const defaultCoin = this.tryToGetCoin(''); + this.currentCoinInternal.next(defaultCoin); + } + + /** + * Checks the list of available coins and tries to get the one with the provided name. If it + * is not possible to find it, the function will try to get the default one or at least the + * first one on the list. + * @param name Name of the coin to find. + */ + private tryToGetCoin(name: string): Coin { + let coin: Coin; + + if (name) { + coin = this.coins.find((c: Coin) => c.coinName === name); + } + if (!coin) { + coin = this.coins.find((c: Coin) => c.coinName === AppConfig.defaultCoinName); + } + if (!coin) { + coin = this.coins[0]; + } + + return coin; + } +} diff --git a/src/gui/static/src/app/services/exchange.service.ts b/src/gui/static/src/app/services/exchange.service.ts new file mode 100644 index 0000000..06595cf --- /dev/null +++ b/src/gui/static/src/app/services/exchange.service.ts @@ -0,0 +1,297 @@ +import { throwError as observableThrowError, Observable, BehaviorSubject, SubscriptionLike, of } from 'rxjs'; +import { map, mergeMap, retryWhen, delay, catchError, tap } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import * as moment from 'moment'; + +import { StorageService, StorageType } from './storage.service'; +import { environment } from '../../environments/environment'; +import { processServiceError } from '../utils/errors'; +import { OperationError } from '../utils/operation-error'; + +/** + * Represents a trading pair acepted by Swaplab. + */ +export class TradingPair { + /** + * Coin to deposit. + */ + from: string; + /** + * Coin that will be received. + */ + to: string; + /** + * How many coins will be received per deposited coin. + */ + price: number; + /** + * Name of the trading pair. Works as the ID of the trading pair. + */ + pair: string; + /** + * Minimum number of coins that can be deposited per order. + */ + min: number; + /** + * Maximum number of coins that can be deposited per order. + */ + max: number; +} + +/** + * Response returned by the service when creating or checking an order. + */ +export class ExchangeOrder { + pair: string; + fromAmount: number|null; + toAmount: number; + toAddress: string; + toTag: string|null; + refundAddress: string|null; + refundTag: string|null; + id: string; + exchangeAddress: string; + exchangeTag: string|null; + toTx?: string|null; + status: string; + message?: string; +} + +/** + * Data of an order saved in the persistent storage. + */ +export class StoredExchangeOrder { + /** + * ID of the order. + */ + id: string; + /** + * Name of the coins pair. + */ + pair: string; + /** + * How many coins the user must sent. + */ + fromAmount: number; + /** + * Approximately how many coins the user will receive. The amount can change and will be + * final only after the order has been completed. + */ + toAmount: number; + /** + * Address where the user will receive the coins. + */ + address: string; + /** + * Unix date indicating when the order was saved. + */ + timestamp: number; + /** + * Approximately how many coins the user will receive per deposited coin, at the time + * the order was created. + */ + price: number; +} + +/** + * Allows to work with the Swaplab integration. + */ +@Injectable() +export class ExchangeService { + /** + * URL for connecting with the backend. + */ + private readonly API_ENDPOINT = environment.production ? 'https://swaplab.cc/api/v3' : '/swaplab/api/v3'; + /** + * Key used for saving the old orders in the persistent storage. + */ + private readonly STORAGE_KEY = 'exchange-orders'; + /** + * Key used for saving in the persistent storage the data of the last consulted order. + */ + private readonly LAST_VIEWED_STORAGE_KEY = 'last-viewed-order'; + /** + * Key for accessing the API. + */ + private readonly API_KEY = environment.swaplab.apiKey; + /** + * If the service must work in test mode. If true, the service will call the sandbox API + * endpoints and return false states for the orders. + */ + private readonly TEST_MODE = environment.swaplab.activateTestMode; + + /** + * Allows to know when the process of loading the last viewed order has been finished. + * If does not guarantee that an order was loaded, as maybe the user has never + * checked the state of an order. + */ + lastViewedOrderLoaded: BehaviorSubject = new BehaviorSubject(false); + + private saveLastViewedSubscription: SubscriptionLike; + + /** + * Last order the user has checked. Must be updated manually. It is used to show the status + * of that order again when opening the exchange section, so it must be erased if it is not + * longer appropriate to show the status again immediately after opening the exchange section. + */ + set lastViewedOrder(order: StoredExchangeOrder) { + this._lastViewedOrder = order; + + if (this.saveLastViewedSubscription) { + this.saveLastViewedSubscription.unsubscribe(); + } + this.saveLastViewedSubscription = this.storageService.store(StorageType.CLIENT, this.LAST_VIEWED_STORAGE_KEY, JSON.stringify(order)).subscribe(); + } + get lastViewedOrder(): StoredExchangeOrder { + return this._lastViewedOrder; + } + private _lastViewedOrder: StoredExchangeOrder; + + constructor( + private http: HttpClient, + private storageService: StorageService, + ) { + // Load the data of the last consulted order. + storageService.get(StorageType.CLIENT, this.LAST_VIEWED_STORAGE_KEY).subscribe(result => { + if (result) { + this.lastViewedOrder = JSON.parse(result); + } + this.lastViewedOrderLoaded.next(true); + }, () => { + this.lastViewedOrderLoaded.next(true); + }); + } + + /** + * Gets the complete list of trading pairs registered in the exchange service. + */ + tradingPairs(): Observable { + return this.post('trading_pairs').pipe(map(data => data.result)); + } + + /** + * Creates and saves a new exchange order. + * @param pair Name of the pair the order will use. + * @param fromAmount How many coins the user will send. + * @param toAddress Address where the user wants to receive the coins. + * @param price Price at the moment the order was created. + */ + exchange(pair: string, fromAmount: number, toAddress: string, price: number): Observable { + let response: ExchangeOrder; + + return this.post('orders', { pair, fromAmount, toAddress }).pipe( + mergeMap(data => { + response = data.result; + + return this.storeOrder(response, price); + }), map(() => response)); + } + + /** + * Checks on the backend the status of a previously created order. + * @param id ID of the order. + * @param devForceState If provided, the function will return the provided value as the state + * of the order. + * @returns Object with the current state of the order. If the service is in test mode, a + * simulated state is returned. + */ + status(id: string, devForceState?: string): Observable { + if (this.TEST_MODE && !devForceState) { + devForceState = 'user_waiting'; + } + + return this.post('orders/status', { id }, this.TEST_MODE ? { status: devForceState } : null).pipe( + // Retry after a delay, unless the service says that the order does not exist. + retryWhen((err) => { + return err.pipe(mergeMap((response: OperationError) => { + if (response.originalError && response.originalError.status && response.originalError.status === 404) { + return observableThrowError(response); + } + + return of(response); + }), delay(3000)); + }), map(data => data.result)); + } + + /** + * Returns the list of saved orders. If there are no orders, it returns null. + */ + history(): Observable { + return this.storageService.get(StorageType.CLIENT, this.STORAGE_KEY).pipe( + map((res) => JSON.parse(res))); + } + + /** + * Allows to know if the status of an order indicates that the order has + * been terminated. + */ + isOrderFinished(order: ExchangeOrder): boolean { + return ['complete', 'error', 'user_deposit_timeout'].indexOf(order.status) > -1; + } + + /** + * Sends a POST request to the service API. + * @param url URL to send the request to, without the "http://x:x/api/vx/" part. + * @param body Object with the key/value pairs to be sent to the backend. + * @param headers Additional headers to send. + */ + private post(url: string, body?: object, headers?: object): Observable { + return this.http.post(this.buildUrl(url), body, { + responseType: 'json', + headers: new HttpHeaders({ + 'api-key': this.API_KEY, + 'Accept': 'application/json', + ...headers, + }), + }).pipe(catchError((error: any) => observableThrowError(processServiceError(error)))); + } + + /** + * Sanitizes the URL and adds the sandbox part if the service is running in test mode. + */ + private buildUrl(url: string): string { + if (!this.TEST_MODE || url === 'trading_pairs') { + return `${this.API_ENDPOINT}/${url}`; + } + + return `${this.API_ENDPOINT}sandbox/${url}`; + } + + /** + * Adds an order to the list of saved orders. + * @param order Order to save. + * @param price Price at the time the order was created. + */ + private storeOrder(order: ExchangeOrder, price: number): Observable { + return this.history().pipe( + // If there are no previous orders, add the new order to an empty array, + catchError((err: OperationError) => { + try { + if (err.originalError && err.originalError.status && err.originalError.status === 404) { + return of([]); + } + } catch (e) {} + + return observableThrowError(err); + }), + mergeMap((oldOrders: StoredExchangeOrder[]) => { + const newOrder: StoredExchangeOrder = { + id: order.id, + pair: order.pair, + fromAmount: order.fromAmount, + toAmount: order.toAmount, + address: order.toAddress, + timestamp: moment().unix(), + price: price, + }; + + oldOrders.push(newOrder); + const data = JSON.stringify(oldOrders); + oldOrders.pop(); + + return this.storageService.store(StorageType.CLIENT, this.STORAGE_KEY, data).pipe( + tap(() => oldOrders.push(newOrder))); + })); + } +} diff --git a/src/gui/static/src/app/services/hw-wallet-daemon-tests.service.ts b/src/gui/static/src/app/services/hw-wallet-daemon-tests.service.ts new file mode 100644 index 0000000..e5c320b --- /dev/null +++ b/src/gui/static/src/app/services/hw-wallet-daemon-tests.service.ts @@ -0,0 +1,254 @@ +// This is a version of HwWalletDaemonService that uses a queue to ensure that +// only one operation is carried out at a time. It may be good for testing in +// some circunstances as it allow to see the exact request order without having +// to worry about racing conditions, but to use it in production it needs more +// testing, to be sure that to be sure that the queue is not going to get stuck +// because of some error. This testing has to be done after solving the problems +// that make the firmware respond extremely slow after some calls. + +/* +import { Injectable, NgZone } from '@angular/core'; +import { ApiService } from './api.service'; +import { Http, RequestOptions, Headers } from '@angular/http'; +import { Observable } from 'rxjs/Observable'; +import { HwWalletPinService } from './hw-wallet-pin.service'; +import { HwWalletSeedWordService } from './hw-wallet-seed-word.service'; +import { ISubscription } from 'rxjs/Subscription'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import 'rxjs/add/operator/timeout'; +import { Subject } from 'rxjs/Subject'; + +@Injectable() +export class HwWalletDaemonService { + + public static readonly errorCancelled = 'Cancelled'; + public static readonly errorConnectingWithTheDaemon = 'Error connecting with the hw wallet service'; + public static readonly errorTimeout = 'The operation was canceled due to inactivity'; + private readonly url = 'http://127.0.0.1:9510/api/v1'; + + private checkHwSubscription: ISubscription; + private hwConnected = false; + private connectionEventSubject = new BehaviorSubject(false); + private waiting = false; + private busy = false; + private queueDelay = 32; + private requestQueue: { + operation: Observable + subject: Subject; + }[] = []; + + get connectionEvent() { + return this.connectionEventSubject.asObservable(); + } + + constructor( + private http: Http, + private apiService: ApiService, + private hwWalletPinService: HwWalletPinService, + private hwWalletSeedWordService: HwWalletSeedWordService, + private ngZone: NgZone, + ) { } + + get(route: string) { + const trigger = new Subject(); + this.requestQueue.push({ + subject: trigger, + operation: trigger.flatMap(() => this.checkResponse(this.http.get( + this.url + route, + this.returnRequestOptions(), + ), route.includes('/available'))), + }); + + setTimeout(() => this.tryToRunNextRequest(), this.queueDelay); + + return this.requestQueue[this.requestQueue.length - 1].operation; + } + + post(route: string, params = {}) { + const trigger = new Subject(); + this.requestQueue.push({ + subject: trigger, + operation: trigger.flatMap(() => this.checkResponse(this.http.post( + this.url + route, + JSON.stringify(params), + this.returnRequestOptions(), + ))), + }); + + setTimeout(() => this.tryToRunNextRequest(), this.queueDelay); + + return this.requestQueue[this.requestQueue.length - 1].operation; + } + + put(route: string, params: any = null, sendMultipartFormData = false, smallTimeout = false) { + const trigger = new Subject(); + this.requestQueue.push({ + subject: trigger, + operation: trigger.flatMap(() => this.checkResponse(this.http.put( + this.url + route, + params, + this.returnRequestOptions(sendMultipartFormData), + ), false, smallTimeout)), + }); + + setTimeout(() => this.tryToRunNextRequest(), this.queueDelay); + + return this.requestQueue[this.requestQueue.length - 1].operation; + } + + delete(route: string) { + const trigger = new Subject(); + this.requestQueue.push({ + subject: trigger, + operation: trigger.flatMap(() => this.checkResponse(this.http.delete( + this.url + route, + this.returnRequestOptions(), + ))), + }); + + setTimeout(() => this.tryToRunNextRequest(), this.queueDelay); + + return this.requestQueue[this.requestQueue.length - 1].operation; + } + + private tryToRunNextRequest() { + if (!this.busy) { + if (this.requestQueue.length > 0) { + this.runNextRequest(); + } + } + } + + private runNextRequest() { + this.prepareToStart(); + this.requestQueue[0].subject.next(1); + this.requestQueue[0].subject.complete(); + } + + private prepareToStart() { + if (this.busy) { + throw new Error('The service is busy.'); + } + this.busy = true; + } + + private checkResponse(response: Observable, checkingConnected = false, smallTimeout = false) { + return response + .timeout(smallTimeout ? 30000 : 50000) + .flatMap((res: any) => { + if (!this.waiting) { + this.waiting = true; + setTimeout(() => { + this.waiting = false; + this.busy = false; + this.requestQueue.shift(); + this.tryToRunNextRequest(); + }, this.queueDelay); + } + + const finalResponse = res.json(); + + if (checkingConnected) { + this.ngZone.run(() => this.updateHwConnected(!!finalResponse.data)); + } else { + this.updateHwConnected(true); + } + + if (typeof finalResponse.data === 'string' && (finalResponse.data as string).indexOf('PinMatrixRequest') !== -1) { + return this.hwWalletPinService.requestPin().flatMap(pin => { + if (!pin) { + return this.put('/cancel').map(() => HwWalletDaemonService.errorCancelled); + } + + return this.post('/intermediate/pin_matrix', {pin: pin}); + }); + } + + if (typeof finalResponse.data === 'string' && (finalResponse.data as string).indexOf('WordRequest') !== -1) { + return this.hwWalletSeedWordService.requestWord().flatMap(word => { + if (!word) { + return this.put('/cancel').map(() => HwWalletDaemonService.errorCancelled); + } + + return this.post('/intermediate/word', {word: word}); + }); + } + + return Observable.of(finalResponse); + }) + .catch((error: any) => { + if (!this.waiting) { + this.waiting = true; + setTimeout(() => { + this.waiting = false; + this.busy = false; + this.requestQueue.shift(); + this.tryToRunNextRequest(); + }, this.queueDelay); + } + + if (error && error.name && error.name === 'TimeoutError') { + this.put('/cancel').subscribe(); + + return Observable.throw({_body: HwWalletDaemonService.errorTimeout }); + } + + if (error && error._body) { + let errorContent: string; + + if (error._body.error) { + errorContent = error._body.error; + } else { + try { + errorContent = JSON.parse(error._body).error; + } catch (e) {} + } + + if (errorContent) { + return this.apiService.processConnectionError(error, true); + } + } + + return Observable.throw({_body: HwWalletDaemonService.errorConnectingWithTheDaemon }); + }); + } + + private returnRequestOptions(sendMultipartFormData = false) { + const options = new RequestOptions(); + options.headers = new Headers(); + if (!sendMultipartFormData) { + options.headers.append('Content-Type', 'application/json'); + } + + return options; + } + + checkHw(wait: boolean) { + if (this.checkHwSubscription) { + this.checkHwSubscription.unsubscribe(); + } + + this.ngZone.runOutsideAngular(() => { + this.checkHwSubscription = Observable.of(1) + .delay(wait ? (this.hwConnected ? 2000 : 10000) : 0) + .flatMap(() => this.get('/available')) + .subscribe( + null, + () => this.ngZone.run(() => this.updateHwConnected(false)), + ); + }); + } + + private updateHwConnected(connected: boolean) { + if (connected && !this.hwConnected) { + this.hwConnected = true; + this.connectionEventSubject.next(this.hwConnected); + } else if (!connected && this.hwConnected) { + this.hwConnected = false; + this.connectionEventSubject.next(this.hwConnected); + } + this.checkHw(true); + } + +} +*/ diff --git a/src/gui/static/src/app/services/hw-wallet-daemon.service.ts b/src/gui/static/src/app/services/hw-wallet-daemon.service.ts new file mode 100644 index 0000000..aaaec31 --- /dev/null +++ b/src/gui/static/src/app/services/hw-wallet-daemon.service.ts @@ -0,0 +1,439 @@ +import { throwError as observableThrowError, of, Observable, SubscriptionLike, BehaviorSubject } from 'rxjs'; +import { delay, timeout, mergeMap, catchError } from 'rxjs/operators'; +import { Injectable, NgZone } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; + +import { HwWalletPinService } from './hw-wallet-pin.service'; +import { HwWalletSeedWordService } from './hw-wallet-seed-word.service'; +import { OperationError, HWOperationResults } from '../utils/operation-error'; +import { getErrorMsg } from '../utils/errors'; +import { environment } from '../../environments/environment'; +import { getTestAddressesMap } from '../utils/hw-test-addresses'; + +/** + * Allows to make request to the hw wallet daemon with ease. If an API request needs the user + * to provide more data, this service shows the appropiate UI for the user to provide it and + * then sends it to the daemon. + */ +@Injectable() +export class HwWalletDaemonService { + /** + * URL for accessing the API. + */ + private readonly url = 'http://127.0.0.1:9510/api/v1/'; + /** + * Max time the service will wait for responses from the daemon. + */ + private readonly timeoutMs = 55000; + + /** + * Allows to know when a devices has be connected/disconnected. + */ + private connectionEventSubject = new BehaviorSubject(false); + private checkHwSubscription: SubscriptionLike; + private hwConnected = false; + + /** + * How many times the service checked if the hw wallet is connected and it was not. + */ + private disconnectedChecks = 0; + /** + * How many times the service will quickly check if the device is connected, before starting + * to check less frequently. + */ + private readonly maxFastDisconnectedChecks = 32; + /** + * Time interval in which periodic data updates will be made. + */ + private readonly updatePeriod = 10 * 1000; + /** + * Time interval in which periodic data updates will be made. + */ + private readonly fastUpdatePeriod = 2 * 1000; + + /** + * Allows to know if a device is connected. + */ + get connectionEvent() { + return this.connectionEventSubject.asObservable(); + } + + constructor( + private http: HttpClient, + private hwWalletPinService: HwWalletPinService, + private hwWalletSeedWordService: HwWalletSeedWordService, + private ngZone: NgZone, + ) { } + + /** + * Sends a GET request to the hw wallet daemon. + * @param route URL to send the request to. You must omit the "http://x:x/api/vx/" part. + */ + get(route: string) { + return this.checkResponse(this.http.get( + this.getUrl(route), + this.returnRequestOptions(), + ), route.includes('/available')); + } + + /** + * Sends a POST request to the hw wallet daemon. + * @param route URL to send the request to. You must omit the "http://x:x/api/vx/" part. + * @param params Object with the key/value pairs to be sent to the daemon as params. + */ + post(route: string, params: any = null) { + if (!params) { + params = {}; + } + + return this.checkResponse(this.http.post( + this.getUrl(route), + JSON.stringify(params), + this.returnRequestOptions(), + )); + } + + /** + * Sends a PUT request to the hw wallet daemon. + * @param route URL to send the request to. You must omit the "http://x:x/api/vx/" part. + * @param params Object with the key/value pairs to be sent to the daemon as params. + * @param sendMultipartFormData If true, the data will be sent as multipart/form-data. + */ + put(route: string, params: any = null, sendMultipartFormData = false) { + return this.checkResponse(this.http.put( + this.getUrl(route), + params, + this.returnRequestOptions(sendMultipartFormData), + ), false); + } + + /** + * Sends a DELETE request to the hw wallet daemon. + * @param route URL to send the request to. You must omit the "http://x:x/api/vx/" part. + */ + delete(route: string) { + return this.checkResponse(this.http.delete( + this.getUrl(route), + this.returnRequestOptions(), + )); + } + + /** + * Checks and process the responses returned by the daemon. This allows to automatically + * update the connection status, getting the PIN code and more before returning the final + * response to the original caller. + * @param operationResponse Observable which will get the response from the daemon. + * @param checkingConnected true if the connection to the daemon was made specifically to + * check if a hw wallet is currently connected. + * @returns operationResponse, but with extra steps for making all appropiate operations with + * the daemon response before emiting it to the subscription. + */ + private checkResponse(operationResponse: Observable, checkingConnected = false): Observable { + return operationResponse.pipe( + // This allows to control the timeout errors, instead of having the browser + // killing the connection at will in an unpredictable way. + timeout(this.timeoutMs), + mergeMap((finalResponse: any) => { + // If in dev mode, check if the response has addresses that must be replaced by test + // addresses. Only predefined addresses are replaced. This is for being able to + // change the mainnet addresses returned by the device with tesnet addresses. + if (!environment.production) { + const testAddressesMap = getTestAddressesMap(); + + if (finalResponse.data && testAddressesMap.has(finalResponse.data[0])) { + for (let i = 0; i < (finalResponse.data as any[]).length; i++) { + if (testAddressesMap.has(finalResponse.data[i])) { + finalResponse.data[i] = testAddressesMap.get(finalResponse.data[i]); + } + } + } + } + + // The daemon may return single value responses as single value arrays. This extracts + // the response from the array. + if (finalResponse.data && finalResponse.data.length) { + if (finalResponse.data.length === 1) { + finalResponse.data = finalResponse.data[0]; + } + } + + if (checkingConnected) { + // Update the connection state with the obtained response. + this.ngZone.run(() => this.updateHwConnected(!!finalResponse.data)); + } else { + this.updateHwConnected(true); + } + + // If the daemon requested the PIN code, ask the user to enter it and send it to + // the daemon. If the user does not enter the PIN, cancel the operation. + if (typeof finalResponse.data === 'string' && (finalResponse.data as string).indexOf('PinMatrixRequest') !== -1) { + return this.hwWalletPinService.requestPin().pipe(mergeMap(pin => { + if (!pin) { + return this.put('/cancel').pipe(mergeMap(() => { + const response = new OperationError(); + response.originalError = null; + response.originalServerErrorMsg = ''; + response.type = HWOperationResults.FailedOrRefused; + response.translatableErrorMsg = this.getHardwareWalletErrorMsg(response.type); + + return observableThrowError(response); + })); + } + + return this.post('/intermediate/pin_matrix', {pin: pin}); + })); + } + + // If the daemon requested a seed word, ask the user to enter it and send it to + // the daemon. If the user does not enter the word, cancel the operation. + if (typeof finalResponse.data === 'string' && (finalResponse.data as string).indexOf('WordRequest') !== -1) { + return this.hwWalletSeedWordService.requestWord().pipe(mergeMap(word => { + if (!word) { + return this.put('/cancel').pipe(mergeMap(() => { + const response = new OperationError(); + response.originalError = null; + response.originalServerErrorMsg = ''; + response.type = HWOperationResults.FailedOrRefused; + response.translatableErrorMsg = this.getHardwareWalletErrorMsg(response.type); + + return observableThrowError(response); + })); + } + + return this.post('/intermediate/word', {word: word}); + })); + } + + // This allows the operation to continue. It is an intermediate step when the user has + // to press a button, which allow to reset the timeout counter, as a new http connection + // is made. + if (typeof finalResponse.data === 'string' && (finalResponse.data as string).indexOf('ButtonRequest') !== -1) { + return this.post('/intermediate/button'); + } + + return of(finalResponse); + }), catchError((error: any) => { + // If the error is already an OperationError intance, no more processing is needed. + // This is needed because in a long operation this part may be called several times + // and only the first one is needed for processing the error. + if ((error as OperationError).type) { + return observableThrowError(error); + } + + const response = new OperationError(); + response.originalError = error; + + // Process timeouts. + if (error && error.name && error.name === 'TimeoutError') { + this.put('/cancel').subscribe(); + + response.originalServerErrorMsg = error.name; + response.type = HWOperationResults.Timeout; + response.translatableErrorMsg = this.getHardwareWalletErrorMsg(response.type); + + return observableThrowError(response); + } + + // Process connection errors with the daemon. + const convertedError = error as HttpErrorResponse; + if (convertedError.status !== null && convertedError.status !== undefined) { + if (convertedError.status === 0 || convertedError.status === 504) { + response.originalServerErrorMsg = getErrorMsg(error); + response.type = HWOperationResults.DaemonConnectionError; + response.translatableErrorMsg = this.getHardwareWalletErrorMsg(response.type); + + return observableThrowError(response); + } + } + + // Process the error to get its details. + response.originalServerErrorMsg = getErrorMsg(error); + response.type = this.getHardwareWalletErrorType(response.originalServerErrorMsg); + response.translatableErrorMsg = this.getHardwareWalletErrorMsg(response.type); + + return observableThrowError(response); + })); + } + + /** + * Returns the options object requiered by HttpClient for sending a request. + * @param sendMultipartFormData If true, the data will be sent as multipart/form-data. + */ + private returnRequestOptions(sendMultipartFormData = false): any { + const options: any = {}; + options.headers = new HttpHeaders(); + if (!sendMultipartFormData) { + options.headers = options.headers.append('Content-Type', 'application/json'); + } + + return options; + } + + /** + * Checks if there is a hw wallet connected. + * @param wait false if the check must be made immediately. True if the normal delay must be + * used. + */ + private checkHw(wait: boolean) { + if (this.checkHwSubscription) { + this.checkHwSubscription.unsubscribe(); + } + + this.ngZone.runOutsideAngular(() => { + this.checkHwSubscription = of(1).pipe( + // The delay will be small for a limited number of times, just to catch the cases in + // which the user connects/disconnects the device quickly + delay(wait ? (this.hwConnected || this.disconnectedChecks < this.maxFastDisconnectedChecks ? this.fastUpdatePeriod : this.updatePeriod) : 0), + mergeMap(() => this.get('/available'))) + .subscribe({ + // After the response is obtained, the procedure in charge of processing all the + // responses obtained from the daemon automatically updates the connection status. + next: null, + error: () => this.ngZone.run(() => this.updateHwConnected(false)), + }); + }); + } + + /** + * Receives the the current connection status of the hw wallet and, if needed, dispatch events + * indicating if the device has been connected or disconnected. It also schedules the periodical + * automatic connection checking procedure to continue running after an appropiate delay. + * @param connected If the device is currently connected or not. + */ + private updateHwConnected(connected: boolean) { + if (connected) { + this.disconnectedChecks = 0; + } else { + // Keep track of how many checks have been made in which the device has been disconnected. + this.disconnectedChecks += 1; + } + + // Update the state if needed. + if (connected && !this.hwConnected) { + this.hwConnected = true; + this.connectionEventSubject.next(this.hwConnected); + } else if (!connected && this.hwConnected) { + this.hwConnected = false; + this.connectionEventSubject.next(this.hwConnected); + } + + // Make the automatic connection checking run periodically. + this.checkHw(true); + } + + /** + * Get the complete URL needed for making a request to the daemon API. + * @param url URL to send the request to, omitting the "http://x:x/api/vx/" part. + */ + private getUrl(url: string): string { + if (url.startsWith('/')) { + url = url.substr(1, url.length - 1); + } + + return this.url + url; + } + + /** + * Analyzes an error message to detect to which type it corresponds. + * @param responseContent Error message to analyze. + */ + getHardwareWalletErrorType(responseContent: string): HWOperationResults { + if (!responseContent || typeof responseContent !== 'string') { + responseContent = ''; + } + let result: HWOperationResults; + + // Changes in the responses returned by the daemon may affect this. + if (responseContent.toUpperCase().includes('failed or refused'.toUpperCase())) { + result = HWOperationResults.FailedOrRefused; + } else if (responseContent.toUpperCase().includes('PIN invalid'.toUpperCase())) { + result = HWOperationResults.WrongPin; + } else if (responseContent.toUpperCase().includes('canceled by user'.toUpperCase())) { + result = HWOperationResults.FailedOrRefused; + } else if (responseContent.toUpperCase().includes('cancelled by user'.toUpperCase())) { + result = HWOperationResults.FailedOrRefused; + } else if (responseContent.toUpperCase().includes('Expected WordAck after Button'.toUpperCase())) { + result = HWOperationResults.FailedOrRefused; + } else if (responseContent.toUpperCase().includes('Wrong word retyped'.toUpperCase())) { + result = HWOperationResults.WrongWord; + } else if (responseContent.toUpperCase().includes('PIN mismatch'.toUpperCase())) { + result = HWOperationResults.PinMismatch; + } else if (responseContent.toUpperCase().includes('Mnemonic not set'.toUpperCase())) { + result = HWOperationResults.WithoutSeed; + } else if (responseContent.toUpperCase().includes('Mnemonic required'.toUpperCase())) { + result = HWOperationResults.WithoutSeed; + } else if (responseContent.toUpperCase().includes('Invalid seed, are words in correct order?'.toUpperCase())) { + result = HWOperationResults.InvalidSeed; + } else if (responseContent.toUpperCase().includes('The seed is valid but does not match the one in the device'.toUpperCase())) { + result = HWOperationResults.WrongSeed; + } else if (responseContent.toUpperCase().includes('Invalid base58 character'.toUpperCase())) { + result = HWOperationResults.InvalidAddress; + } else if (responseContent.toUpperCase().includes('Invalid address length'.toUpperCase())) { + result = HWOperationResults.InvalidAddress; + } else if (responseContent.toUpperCase().includes('LIBUSB'.toUpperCase())) { + result = HWOperationResults.DaemonConnectionError; + } else if (responseContent.toUpperCase().includes('hidapi'.toUpperCase())) { + result = HWOperationResults.Disconnected; + setTimeout(() => this.checkHw(false)); + } else if (responseContent.toUpperCase().includes('device disconnected'.toUpperCase())) { + result = HWOperationResults.Disconnected; + setTimeout(() => this.checkHw(false)); + } else if (responseContent.toUpperCase().includes('no device connected'.toUpperCase())) { + result = HWOperationResults.Disconnected; + setTimeout(() => this.checkHw(false)); + } else if (responseContent.toUpperCase().includes('MessageType_Success'.toUpperCase())) { + result = HWOperationResults.Success; + } else { + result = HWOperationResults.UndefinedError; + } + + return result; + } + + /** + * Gets the translatable user-understandable message that corresponds to an error type. + * @param errorType Error type to check. + * @returns The error message. If the provided type does not have a corresponding error + * message, a generic error message is returned. + */ + getHardwareWalletErrorMsg(errorType: HWOperationResults): string { + let response: string; + if (errorType) { + if (errorType === HWOperationResults.FailedOrRefused) { + response = 'hardware-wallet.errors.refused'; + } else if (errorType === HWOperationResults.WrongPin) { + response = 'hardware-wallet.errors.incorrect-pin'; + } else if (errorType === HWOperationResults.IncorrectHardwareWallet) { + response = 'hardware-wallet.errors.incorrect-wallet'; + } else if (errorType === HWOperationResults.DaemonConnectionError) { + response = 'hardware-wallet.errors.daemon-connection'; + } else if (errorType === HWOperationResults.DaemonOutdated) { + response = 'hardware-wallet.errors.outdated-daemon'; + } else if (errorType === HWOperationResults.InvalidAddress) { + response = 'hardware-wallet.errors.invalid-address'; + } else if (errorType === HWOperationResults.Timeout) { + response = 'hardware-wallet.errors.timeout'; + } else if (errorType === HWOperationResults.Disconnected) { + response = 'hardware-wallet.errors.disconnected'; + } else if (errorType === HWOperationResults.NotInBootloaderMode) { + response = 'hardware-wallet.errors.not-in-bootloader-mode'; + } else if (errorType === HWOperationResults.PinMismatch) { + response = 'hardware-wallet.change-pin.pin-mismatch'; + } else if (errorType === HWOperationResults.WrongWord) { + response = 'hardware-wallet.restore-seed.error-wrong-word'; + } else if (errorType === HWOperationResults.InvalidSeed) { + response = 'hardware-wallet.restore-seed.error-invalid-seed'; + } else if (errorType === HWOperationResults.WrongSeed) { + response = 'hardware-wallet.restore-seed.error-wrong-seed'; + } else if (errorType === HWOperationResults.AddressGeneratorProblem) { + response = 'hardware-wallet.errors.invalid-address-generated'; + } else { + response = 'hardware-wallet.errors.generic-error'; + } + } else { + response = 'hardware-wallet.errors.generic-error'; + } + + return response; + } +} diff --git a/src/gui/static/src/app/services/hw-wallet-pin.service.ts b/src/gui/static/src/app/services/hw-wallet-pin.service.ts new file mode 100644 index 0000000..2ec7c38 --- /dev/null +++ b/src/gui/static/src/app/services/hw-wallet-pin.service.ts @@ -0,0 +1,78 @@ +import { Injectable } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { HwPinDialogParams } from '../components/layout/hardware-wallet/hw-pin-dialog/hw-pin-dialog.component'; + +/** + * Diferent modes in which the modal window used for requesting the hw wallet PIN can be while + * setting or changing the PIN. + */ +export enum ChangePinStates { + RequestingCurrentPin = 'RequestingCurrentPin', + RequestingNewPin = 'RequestingNewPin', + ConfirmingNewPin = 'ConfirmingNewPin', +} + +/** + * Allows to easily show the modal window used for requesting the hw wallet PIN. + */ +@Injectable() +export class HwWalletPinService { + + // Set on AppComponent to avoid a circular reference. + private requestPinComponentInternal; + /** + * Sets the class of the modal window used for entering the hw wallet PIN. + */ + set requestPinComponent(value) { + this.requestPinComponentInternal = value; + } + + // Values to be sent to HwPinDialogComponent to configure the modal window the next + // time it is openned. The values are public to make it posible to change them from + // different parts of the code, as there are multiple parts which need to configure + // the modal window but it is automatically opened by the daemon service. + /** + * If the modal window will be openned the next time for setting or changing the PIN + * (true) or just for checking the current PIN (false). + */ + changingPin: boolean; + /** + * If the modal window will be openned the next time for signing a transaction or not. + */ + signingTx: boolean; + /** + * State in which the modal window will be shown the next time if changingPin is true. + */ + changePinState: ChangePinStates; + + constructor( + private dialog: MatDialog, + ) {} + + /** + * Opens the modal window for the user to enter the PIN. + * @returns The PIN entered by the user, or null if the user cancelled the operation. + */ + requestPin(): Observable { + return this.requestPinComponentInternal.openDialog(this.dialog, { + changingPin: this.changingPin, + changePinState: this.changePinState, + signingTx: this.signingTx, + }).afterClosed().pipe(map(pin => { + if (this.changingPin) { + // If setting or changing the PIN, automatically change the state to the one corresponding + // to the next step. + if (this.changePinState === ChangePinStates.RequestingCurrentPin) { + this.changePinState = ChangePinStates.RequestingNewPin; + } else if (this.changePinState === ChangePinStates.RequestingNewPin) { + this.changePinState = ChangePinStates.ConfirmingNewPin; + } + } + + return pin; + })); + } +} diff --git a/src/gui/static/src/app/services/hw-wallet-seed-word.service.ts b/src/gui/static/src/app/services/hw-wallet-seed-word.service.ts new file mode 100644 index 0000000..1bd1f84 --- /dev/null +++ b/src/gui/static/src/app/services/hw-wallet-seed-word.service.ts @@ -0,0 +1,40 @@ +import { Injectable } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { SeedWordDialogParams } from '../components/layout/seed-word-dialog/seed-word-dialog.component'; + +/** + * Allows to easily show the modal window used for entering a seed word requested + * by the hw wallet. + */ +@Injectable() +export class HwWalletSeedWordService { + + // Set to SeedWordDialogComponent on AppComponent to avoid a circular reference. + private requestWordComponentInternal; + /** + * Sets the class of the modal window used for entering a seed word requested + * by the hw wallet. + */ + set requestWordComponent(value) { + this.requestWordComponentInternal = value; + } + + constructor( + private dialog: MatDialog, + ) {} + + /** + * Shows the modal window used for entering a seed word requested by the hw wallet. + * @returns The word entered by the user, or null if the user cancelled the operation. + */ + requestWord(): Observable { + return this.requestWordComponentInternal.openDialog(this.dialog, { + reason: 'HWWalletOperation', + }).afterClosed().pipe(map(word => { + return word; + })); + } +} diff --git a/src/gui/static/src/app/services/hw-wallet.service.ts b/src/gui/static/src/app/services/hw-wallet.service.ts new file mode 100644 index 0000000..94ce71c --- /dev/null +++ b/src/gui/static/src/app/services/hw-wallet.service.ts @@ -0,0 +1,701 @@ +import { throwError as observableThrowError, of, Observable, Subject, throwError } from 'rxjs'; +import { mergeMap, map, catchError } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { BigNumber } from 'bignumber.js'; +import { HttpClient } from '@angular/common/http'; + +import { AppConfig } from '../app.config'; +import { HwWalletDaemonService } from './hw-wallet-daemon.service'; +import { HwWalletPinService, ChangePinStates } from './hw-wallet-pin.service'; +import { OperationError, HWOperationResults } from '../utils/operation-error'; +import { getErrorMsg } from '../utils/errors'; +import { WalletUtilsService } from './wallet-operations/wallet-utils.service'; +import { WalletBase } from './wallet-operations/wallet-objects'; +import { isEqualOrSuperiorVersion } from '../utils/semver'; +import { SkywalletSupportedCoinTypes } from '../coins/settings/skywallet-supported-coin-types'; +import { CoinService } from './coin.service'; + +/** + * Data about a transaction recipient. + */ +export class HwWalletTxRecipientData { + address: string; + coins: BigNumber; + hours: BigNumber; +} + +/** + * Response when a hw wallet operation completes correctly. + */ +export class OperationResult { + // This property is currently not very usseful, as it is always set to done, but is not + // removed because there is chance of needing it in the future. + /** + * Operation result. + */ + result: HWOperationResults; + /** + * Raw response returned by the hw wallet daemon. + */ + rawResponse: any; +} + +/** + * Input of a hw wallet transaction. + */ +export interface HwInput { + hash: string; + index: number; +} + +/** + * Output of a hw wallet transaction. + */ +export interface HwOutput { + address: string; + coins: string; + hours: string; + /** + * Index of the address on the hw wallet. This indicates the device that the output is + * used for returning unused remaining coins and hours and that, because of that, it should + * not be shown while asking the user for confirmation. It only works if the destination + * address really is is on the device at the indicated index. + */ + address_index?: number; +} + +/** + * Input of a BTC hw wallet transaction. + */ +export interface HwBtcInput { + index: number; + prev_hash: string; +} + +/** + * Output of a BTC hw wallet transaction. + */ +export interface HwBtcOutput { + address: string; + coins: string; + /** + * Index of the address on the hw wallet. This indicates the device that the output is + * used for returning unused remaining coins and that, because of that, it should + * not be shown while asking the user for confirmation. It only works if the destination + * address really is is on the device at the indicated index. + */ + address_index?: number; +} + +@Injectable() +export class HwWalletService { + /** + * Max number of characters the hw wallet label can have. + */ + public static readonly maxLabelLength = 32; + + /** + * If true, the hw wallet options modal window will be shown the next time the wallets list + * is loaded on the UI. + */ + showOptionsWhenPossible = false; + + /** + * Emits every time a device connection/disconnection event is detected. + */ + private walletConnectedSubject: Subject = new Subject(); + /** + * Last modal window openned for asking the user confirmation for signing a transaction. + */ + private signTransactionDialog: MatDialogRef<{}, any>; + + // Set on AppComponent to avoid a circular reference. + private signTransactionConfirmationComponentInternal; + /** + * Sets the class of the modal window used for asking the user confirmation for signing a tx. + */ + set signTransactionConfirmationComponent(value) { + this.signTransactionConfirmationComponentInternal = value; + } + + constructor( + private dialog: MatDialog, + private hwWalletDaemonService: HwWalletDaemonService, + private hwWalletPinService: HwWalletPinService, + private walletUtilsService: WalletUtilsService, + private http: HttpClient, + private coinService: CoinService, + ) { + + if (this.hwWalletCompatibilityActivated) { + hwWalletDaemonService.connectionEvent.subscribe(connected => { + this.walletConnectedSubject.next(connected); + }); + } + } + + /** + * Indicates if the hw wallet compatibility should be activated in the app or not. + */ + get hwWalletCompatibilityActivated(): boolean { + return true; + } + + /** + * Emits every time a device connection/disconnection event is detected. + */ + get walletConnectedAsyncEvent(): Observable { + return this.walletConnectedSubject.asObservable(); + } + + /** + * Detects if there is currently a hw wallet connected. + */ + getDeviceConnected(): Observable { + return this.hwWalletDaemonService.get('/available').pipe(map((response: any) => { + return response.data; + })); + } + + /** + * Makes the device to cancel any currently active operation and return to the home screen. + */ + cancelLastAction(): Observable { + this.prepare(); + + return this.processDaemonResponse( + this.hwWalletDaemonService.put('/cancel'), + ); + } + + /** + * Gets the version of the daemon. + */ + private getDaemonVersion(): Observable { + this.prepare(); + + return this.processDaemonResponse( + this.hwWalletDaemonService.get('/version'), + ); + } + + /** + * Gets one or more of the addresses of the hw wallet. + * @param addressN How many addresses to recover. + * @param startIndex Starting index. + * @param coin Coin of the addresses. + */ + getAddresses(addressN: number, startIndex: number, coin: SkywalletSupportedCoinTypes): Observable { + // Cancel the current pending operation, if any. + return this.cancelLastAction().pipe(mergeMap(() => { + return this.getDaemonVersion(); + }), mergeMap(version => { + this.prepare(); + + const params = { + address_n: addressN, + start_index: startIndex, + confirm_address: false, + }; + + // Add the coin type param if needed. + if (isEqualOrSuperiorVersion(version.rawResponse.version, '0.2.0')) { + params['coin_type'] = coin; + } else if (coin !== SkywalletSupportedCoinTypes.SKY) { + // Previous versions of the daemon only work with Skycoin. + return throwError(this.createOutdatedDaemonError()); + } + + // Recover the addresses. + return this.processDaemonResponse( + this.hwWalletDaemonService.post( + '/generate_addresses', + params, + ), null, true, + ); + }), mergeMap(response => { + // Check if the device returned valid addresses and create an appropiate error if nedded. + return this.verifyAddresses(response.rawResponse, 0).pipe( + catchError(err => { + const resp = new OperationError(); + resp.originalError = err; + resp.type = HWOperationResults.AddressGeneratorProblem; + resp.translatableErrorMsg = this.hwWalletDaemonService.getHardwareWalletErrorMsg(resp.type); + resp.originalServerErrorMsg = ''; + + return observableThrowError(resp); + }), map(() => response)); + })); + } + + /** + * Checks if all the addresses on an array are valid. Uses concurrency. + * @param addresses List with the addresses to check. + * @param currentIndex Index of the address that will be checked on this pass, as this + * function uses concurrency. This value must normally be 0 when calling this function + * from outside. + * @returns No useful value is returned, but the observable will fail if there is an error + * in any of the addresses. + */ + private verifyAddresses(addresses: string[], currentIndex: number): Observable { + return this.walletUtilsService.verifyAddress(addresses[currentIndex]).pipe(mergeMap(valid => { + if (valid) { + if (currentIndex !== addresses.length - 1) { + return this.verifyAddresses(addresses, currentIndex + 1); + } else { + return of(0); + } + } else { + return throwError('Invalid address.'); + } + })); + } + + /** + * Makes the device ask the user to confirm an address. This allows to check if the software and + * hardware wallets are showing the same data. + * @param index Index of the address to confirm. + * @param coin Coin of the addresses that is going to be confirmed. + */ + confirmAddress(index: number, coin: SkywalletSupportedCoinTypes): Observable { + return this.cancelLastAction().pipe(mergeMap(() => { + return this.getDaemonVersion(); + }), mergeMap(version => { + this.prepare(); + + const params = { + address_n: 1, + start_index: index, + confirm_address: true, + }; + + // Add the coin type param if needed. + if (isEqualOrSuperiorVersion(version.rawResponse.version, '0.2.0')) { + params['coin_type'] = coin; + } else if (coin !== SkywalletSupportedCoinTypes.SKY) { + // Previous versions of the daemon only work with Skycoin. + return throwError(this.createOutdatedDaemonError()); + } + + return this.processDaemonResponse( + this.hwWalletDaemonService.post( + '/generate_addresses', + params, + ), null, true, + ); + })); + } + + /** + * Gets the features of the connected hw wallet. + * @param cancelPreviousOperation If true, the function will cancel any current pending + * operation. Trying to cancel the pending operations may cause problems if the device + * is in bootloader mode. + */ + getFeatures(cancelPreviousOperation = true): Observable { + + let cancel: Observable; + if (cancelPreviousOperation) { + cancel = this.cancelLastAction(); + } else { + cancel = of(0); + } + + return cancel.pipe(mergeMap(() => { + this.prepare(); + + return this.processDaemonResponse( + this.hwWalletDaemonService.get('/features'), + ); + })); + } + + /** + * Downloads the lastest firmware version and installs it on the connected hw wallet. + * For the operation to work the device must be in bootloader mode. + * @param downloadCompleteCallback Function called just after the firmware has been + * downloaded and is going to be sent to the device. + */ + updateFirmware(downloadCompleteCallback: () => any): Observable { + this.prepare(); + + // Check if the device is in bootloader mode. + return this.getFeatures(false).pipe(mergeMap(result => { + if (!result.rawResponse.bootloader_mode) { + const resp = new OperationError(); + resp.originalError = result; + resp.type = HWOperationResults.NotInBootloaderMode; + resp.translatableErrorMsg = this.hwWalletDaemonService.getHardwareWalletErrorMsg(resp.type); + resp.originalServerErrorMsg = ''; + + return observableThrowError(resp); + } + + // Get the version number of the lastest firmware. + return this.http.get(AppConfig.urlForHwWalletVersionChecking, { responseType: 'text' }).pipe( + catchError(() => { + return observableThrowError('hardware-wallet.update-firmware.connection-error'); + }), + mergeMap((res: any) => { + let lastestFirmwareVersion: string = res.trim(); + if (lastestFirmwareVersion.toLowerCase().startsWith('v')) { + lastestFirmwareVersion = lastestFirmwareVersion.substr(1, lastestFirmwareVersion.length - 1); + } + + // Download the lastest firmware. + return this.http.get(AppConfig.hwWalletDownloadUrlAndPrefix + lastestFirmwareVersion + '.bin', { responseType: 'arraybuffer' }).pipe( + catchError(() => { + return observableThrowError('hardware-wallet.update-firmware.connection-error'); + }), + mergeMap(firmware => { + downloadCompleteCallback(); + const data = new FormData(); + data.set('file', new Blob([firmware], { type: 'application/octet-stream'})); + + return this.hwWalletDaemonService.put('/firmware_update', data, true); + })); + })); + })); + } + + /** + * Sets or changes the PIN of the device. + * @param changingCurrentPin false if the function was called for setting a PIN in a device + * which does not have one, true otherwise. + */ + changePin(changingCurrentPin: boolean): Observable { + return this.cancelLastAction().pipe(mergeMap(() => { + this.prepare(); + + // Configure the modal window which will be used to ask for the PIN code. + this.hwWalletPinService.changingPin = true; + if (changingCurrentPin) { + this.hwWalletPinService.changePinState = ChangePinStates.RequestingCurrentPin; + } else { + this.hwWalletPinService.changePinState = ChangePinStates.RequestingNewPin; + } + + return this.processDaemonResponse( + this.hwWalletDaemonService.post('/configure_pin_code'), + ['PIN changed'], + ); + })); + } + + /** + * Removes the PIN code protection from the connected device. + */ + removePin(): Observable { + return this.cancelLastAction().pipe(mergeMap(() => { + this.prepare(); + + const params = {}; + params['remove_pin'] = true; + + return this.processDaemonResponse( + this.hwWalletDaemonService.post( + '/configure_pin_code', + params, + ), + ['PIN removed'], + ); + })); + } + + /** + * Makes a seedless device configure itself with a new random seed. + * @param wordCount How many words the new seed must have. Must be 12 or 24. + */ + generateMnemonic(wordCount: number): Observable { + return this.cancelLastAction().pipe(mergeMap(() => { + this.prepare(); + + const params = {}; + params['word_count'] = wordCount; + params['use_passphrase'] = false; + + return this.processDaemonResponse( + this.hwWalletDaemonService.post( + '/generate_mnemonic', + params, + ), + ['Mnemonic successfully configured'], + ); + })); + } + + /** + * Configures a seedless device with a seed entered by the user or checks if a seed entered + * by the user is equal to the one on the device. The procedure started by the function takes + * care of showing the UI needed for the user to enter the seed. + * @param wordCount How many words the seed has. + * @param dryRun If false, the function will be used to configure a seedless device with the + * seed provided by the user. If true, the function will just check if the seed provided + * by the user is equal to the one on the device. + */ + recoverMnemonic(wordCount: number, dryRun: boolean): Observable { + return this.cancelLastAction().pipe(mergeMap(() => { + this.prepare(); + + const params = {}; + params['word_count'] = wordCount; + params['use_passphrase'] = false; + params['dry_run'] = dryRun; + + return this.processDaemonResponse( + this.hwWalletDaemonService.post( + '/recovery', + params, + ), + ['Device recovered', 'The seed is valid and matches the one in the device'], + ); + })); + } + + /** + * Makes the device show the words of its seed, so the user can back it up. This function + * works only if the user has not completed a backup before. + */ + backup(): Observable { + return this.cancelLastAction().pipe(mergeMap(() => { + this.prepare(); + + return this.processDaemonResponse( + this.hwWalletDaemonService.post( + '/backup', + ), + ['Device backed up!'], + ); + })); + } + + /** + * Wipes the connected device, deleting the seed, label, PIN, etc. + */ + wipe(): Observable { + return this.cancelLastAction().pipe(mergeMap(() => { + this.prepare(); + + return this.processDaemonResponse( + this.hwWalletDaemonService.delete('/wipe'), + ['Device wiped', 'User data was wiped from the device'], + ); + })); + } + + /** + * Changes the label the device displays on the home screen. + * @param label New label to show. + */ + changeLabel(label: string): Observable { + return this.cancelLastAction().pipe(mergeMap(() => { + this.prepare(); + + return this.processDaemonResponse( + this.hwWalletDaemonService.post('/apply_settings', {label: label}), + ['Settings applied'], + ); + })); + } + + /** + * Makes the connected device create the signatures for a transaction. + * @param inputs Transaction inputs. + * @param outputs Transaction outputs. + */ + signTransaction(inputs: HwInput[] | HwBtcInput[], outputs: HwOutput[] | HwBtcOutput[]): Observable { + const signingFiberTransaction = !!(inputs[0] as HwInput).hash; + + // Show the confirmation dialog. + const previewData: HwWalletTxRecipientData[] = []; + outputs.forEach(output => { + if (output.address_index === undefined || output.address_index === null) { + const currentOutput = new HwWalletTxRecipientData(); + currentOutput.address = output.address; + currentOutput.coins = new BigNumber(output.coins); + if (signingFiberTransaction) { + currentOutput.hours = new BigNumber(output.hours); + } + + previewData.push(currentOutput); + } + }); + + this.signTransactionDialog = this.signTransactionConfirmationComponentInternal.openDialog(this.dialog, previewData); + + // Make the device ask for confirmation and create the signatures. + return this.cancelLastAction().pipe(mergeMap(() => { + this.prepare(); + + // Configure the modal window which will be used to ask for the PIN code. + this.hwWalletPinService.signingTx = true; + + const params = { + transaction_inputs: inputs, + transaction_outputs: outputs, + }; + + const apiEndpoint = signingFiberTransaction ? '/transaction_sign' : '/bitcoin_transaction_sign'; + + return this.processDaemonResponse( + this.hwWalletDaemonService.post( + apiEndpoint, + params, + ), null, true, + ).pipe(map(response => { + this.closeTransactionDialog(); + + return response; + }), catchError(error => { + this.closeTransactionDialog(); + + return observableThrowError(error); + })); + })); + } + + /** + * Checks if the first address of the connected hw wallet is equal to the provided address. + * This allows to check if the connected hw wallet is the one this app needs for an operation. + * @param firstAddress Address the device should have at index 0. + * @returns An observable which will fail if the connected device is not the expected one. + */ + checkIfCorrectHwConnected(wallet: WalletBase): Observable { + return this.getAddresses(1, 0, this.coinService.currentCoinInmediate.skywalletCoinType).pipe(mergeMap( + response => { + if (!wallet.isHardware || wallet.addresses[0].compareAddress(response.rawResponse[0])) { + const resp = new OperationError(); + resp.originalError = response; + resp.type = HWOperationResults.IncorrectHardwareWallet; + resp.translatableErrorMsg = this.hwWalletDaemonService.getHardwareWalletErrorMsg(resp.type); + resp.originalServerErrorMsg = ''; + + return observableThrowError(resp); + } + + return of(true); + }, + ), catchError(error => { + const convertedError = error as OperationError; + if (convertedError.type && convertedError.type === HWOperationResults.WithoutSeed) { + const resp = new OperationError(); + resp.originalError = error; + resp.type = HWOperationResults.IncorrectHardwareWallet; + resp.translatableErrorMsg = this.hwWalletDaemonService.getHardwareWalletErrorMsg(resp.type); + resp.originalServerErrorMsg = ''; + + return observableThrowError(resp); + } + + return observableThrowError(error); + })); + } + + /** + * Creates an error object to indicate that the daemon must be updated to be able to + * perform the operation. + */ + private createOutdatedDaemonError(): OperationError { + const err = new OperationError(); + err.type = HWOperationResults.DaemonOutdated; + err.originalError = {}; + err.translatableErrorMsg = 'hardware-wallet.errors.outdated-daemon'; + + return err; + } + + /** + * Closes the modal window used for asking the user to confirm a transaction. + */ + private closeTransactionDialog() { + if (this.signTransactionDialog) { + this.signTransactionDialog.close(); + this.signTransactionDialog = null; + } + } + + /** + * Gets the observable of an operation made with the hw wallet daemon service and + * adds to it the steps neded to process the response and errors, to get a properly + * formated response. + * @param daemonResponse Observable which will emit the response obtained from the daemon. + * @param successTexts Texts which are known to be part of the daemon response when the + * operation finishes correctly. If provided, the daemon response will have to contain + * any of the text on the array for the operation to be considered successful. + * @param responseShouldBeArray True if the daemon is expected to return the response + * as an array. + * @returns daemonResponse, but with extra steps for making all appropiate operations with + * the daemon response before emiting it to the subscription. + */ + private processDaemonResponse(daemonResponse: Observable, successTexts: string[] = null, responseShouldBeArray = false): Observable { + return daemonResponse.pipe(catchError((error: any) => { + // Process the error to get it in an appropiate format. + return observableThrowError(this.buildResponseObject(error, false)); + }), mergeMap(result => { + // If the response was expected to be an array but was a single value, add it to an array. + if (responseShouldBeArray && result.data && typeof result.data === 'string') { + result.data = [result.data]; + } + + // Process the response to get it in an appropiate format. + const response = this.buildResponseObject( + result.data ? result.data : null, + !successTexts ? true : typeof result.data === 'string' && successTexts.some(text => (result.data as string).includes(text)), + ); + + if (response.result === HWOperationResults.Success) { + return of(response); + } else { + return observableThrowError(response); + } + })); + } + + /** + * Makes all initial preparations needed before sending a request to the hw wallet daemon. + */ + private prepare() { + this.hwWalletPinService.changingPin = false; + this.hwWalletPinService.signingTx = false; + } + + /** + * Process a response obtained from the daemon and creates an appropriate object to return to + * the code which originally requested the operation. + * @param rawResponse Response obtained from the daemon. + * @param success If the operation was completed successfuly (true) or ended in an error (false). + */ + private buildResponseObject(rawResponse: any, success: boolean): any { + // If the daemon did not respond with an error. + if ((!rawResponse || !rawResponse.error) && success) { + const response: OperationResult = { + result: HWOperationResults.Success, + rawResponse: rawResponse, + }; + + return response; + + // If the daemon did respond with an error. + } else { + // If the response is already an OperationError instance, return it. + if ((rawResponse as OperationError).type) { + return rawResponse; + } + + // Create an appropiate OperationError instance. + const response = new OperationError(); + response.originalError = rawResponse; + response.originalServerErrorMsg = getErrorMsg(rawResponse); + + if (!response.originalServerErrorMsg) { + response.originalServerErrorMsg = rawResponse + ''; + } + + response.type = this.hwWalletDaemonService.getHardwareWalletErrorType(response.originalServerErrorMsg); + response.translatableErrorMsg = this.hwWalletDaemonService.getHardwareWalletErrorMsg(response.type); + + return response; + } + } +} diff --git a/src/gui/static/src/app/services/language.service.ts b/src/gui/static/src/app/services/language.service.ts new file mode 100644 index 0000000..05fed78 --- /dev/null +++ b/src/gui/static/src/app/services/language.service.ts @@ -0,0 +1,126 @@ +import { Injectable } from '@angular/core'; +import { TranslateService, LangChangeEvent } from '@ngx-translate/core'; +import { ReplaySubject, SubscriptionLike, Observable } from 'rxjs'; + +import { AppConfig } from '../app.config'; +import { StorageService, StorageType } from './storage.service'; + +/** + * Represents a language the app can use for the UI. + */ +export class LanguageData { + /** + * ID of the language. + */ + code: string; + /** + * Language name. + */ + name: string; + /** + * Name of the file containing the flag which is used for identifying the language. + */ + iconName: string; + + constructor(langObj) { + Object.assign(this, langObj); + } +} + +/** + * Allows to know which language is the UI using and to change it. + */ +@Injectable() +export class LanguageService { + /** + * Allows to know the currently selected language for the UI. + */ + get currentLanguage(): Observable { + return this.currentLanguageInternal.asObservable(); + } + private currentLanguageInternal = new ReplaySubject(1); + + /** + * Allows to know if the service was able to load from persistent storage what the lastest + * language selected by the user was. + */ + get savedSelectedLanguageLoaded(): Observable { + return this.savedSelectedLanguageLoadedInternal.asObservable(); + } + private savedSelectedLanguageLoadedInternal = new ReplaySubject(1); + + /** + * List with the languages availabe for the app to use. Values should not be overwritten. + */ + get languages(): LanguageData[] { + return this.languagesInternal; + } + private languagesInternal: LanguageData[] = []; + + private readonly storageKey = 'lang'; + private subscription: SubscriptionLike; + + constructor( + private translate: TranslateService, + private storageService: StorageService, + ) { } + + /** + * Makes the service initialize itself and ngx-translate. Should be called when + * starting the app. + */ + initialize() { + // Load the list of available languages from the configuration file. + const langs: string[] = []; + AppConfig.languages.forEach(lang => { + const LangObj = new LanguageData(lang); + this.languagesInternal.push(LangObj); + langs.push(LangObj.code); + }); + + // Initialize ngx-translate. + this.translate.addLangs(langs); + this.translate.setDefaultLang(AppConfig.defaultLanguage); + this.translate.onLangChange.subscribe((event: LangChangeEvent) => this.onLanguageChanged(event)); + + this.loadCurrentLanguage(); + } + + /** + * Changes the language used by the UI. + * @param langCode Code which identifies the desired language. + */ + changeLanguage(langCode: string) { + this.translate.use(langCode); + } + + /** + * Function called when the language used by ngx-translate is changed. Informs about the + * change and saves the code of the new selection. + */ + private onLanguageChanged(event: LangChangeEvent) { + this.currentLanguageInternal.next(this.languages.find(val => val.code === event.lang)); + + if (this.subscription) { + this.subscription.unsubscribe(); + } + this.subscription = this.storageService.store(StorageType.CLIENT, this.storageKey, event.lang).subscribe(); + } + + /** + * Loads from persistent storage what the last language selected by the user was and + * makes ngx-translate use it. + */ + private loadCurrentLanguage() { + this.storageService.get(StorageType.CLIENT, this.storageKey).subscribe(response => { + if (response && this.translate.getLangs().indexOf(response) !== -1) { + setTimeout(() => { this.changeLanguage(response); }, 16); + this.savedSelectedLanguageLoadedInternal.next(true); + } else { + this.savedSelectedLanguageLoadedInternal.next(false); + } + }, () => { + this.savedSelectedLanguageLoadedInternal.next(false); + }); + } +} diff --git a/src/gui/static/src/app/services/msg-bar.service.ts b/src/gui/static/src/app/services/msg-bar.service.ts new file mode 100644 index 0000000..457b6ac --- /dev/null +++ b/src/gui/static/src/app/services/msg-bar.service.ts @@ -0,0 +1,127 @@ +import { Injectable } from '@angular/core'; +import { SubscriptionLike, of } from 'rxjs'; +import { delay } from 'rxjs/operators'; + +import { MsgBarConfig, MsgBarComponent, MsgBarIcons, MsgBarColors } from '../components/layout/msg-bar/msg-bar.component'; +import { processServiceError } from '../utils/errors'; +import { AppConfig } from '../app.config'; +import { environment } from '../../environments/environment'; +import { OperationError, HWOperationResults } from '../utils/operation-error'; + +/** + * Allows to control the msg bar, which is a small horizontal bar used by the app + * for showing notifications. + */ +@Injectable() +export class MsgBarService { + + private timeSubscription: SubscriptionLike; + + /** + * Sets the component which will be used as the app msg bar. + */ + set msgBarComponent(value: MsgBarComponent) { + this.msgBarComponentInternal = value; + } + private msgBarComponentInternal: MsgBarComponent; + + /** + * Hides the msg bar. + */ + hide() { + if (this.msgBarComponentInternal) { + this.msgBarComponentInternal.hide(); + } + } + + /** + * Displays the msg bar for showing an error. + * @param body Text to show or OperationError instance from which the error will be obtained. + * @param duration How much time the msg bar will stay visible, in ms. The default + * value is 20000. + */ + showError(body: string | OperationError, duration = 20000) { + const config = new MsgBarConfig(); + // Process the body param to make sure the correct error msg is obtained. + config.text = processServiceError(body).translatableErrorMsg; + config.title = 'common.error-title'; + config.icon = MsgBarIcons.Error; + config.color = MsgBarColors.Red; + + // If showing a msg indicating an error connecting with the hw daemon or its version, the + // msg is modified to make sure it includes the download URL. + if ((body as OperationError).type && (body as OperationError).type === HWOperationResults.DaemonConnectionError) { + config.text = 'hardware-wallet.errors.daemon-connection'; + config.link = AppConfig.hwWalletDaemonDownloadUrl; + } else if ((body as OperationError).type && (body as OperationError).type === HWOperationResults.DaemonOutdated) { + config.text = 'hardware-wallet.errors.outdated-daemon'; + config.link = AppConfig.hwWalletDaemonDownloadUrl; + } + + this.show(config); + this.setTimer(duration); + } + + /** + * Displays the msg bar for showing a warning. + * @param body Text to show . + * @param duration How much time the msg bar will stay visible, in ms. The default + * value is 20000. + */ + showWarning(body: string, duration = 20000) { + const config = new MsgBarConfig(); + config.text = processServiceError(body).translatableErrorMsg; + config.title = 'common.warning-title'; + config.icon = MsgBarIcons.Warning; + config.color = MsgBarColors.Yellow; + + this.show(config); + this.setTimer(duration); + } + + /** + * Displays the msg bar for showing a confirmation. + * @param body Text to show . + * @param duration How much time the msg bar will stay visible, in ms. The default + * value is 10000. + */ + showDone(body: string, duration = 10000) { + const config = new MsgBarConfig(); + config.text = body; + config.title = 'common.done-title'; + config.icon = MsgBarIcons.Done; + config.color = MsgBarColors.Green; + + this.show(config); + this.setTimer(duration); + } + + /** + * Makes the msg bar to appear. + * @param config Data about how to display the bar. + */ + private show(config: MsgBarConfig) { + if (this.msgBarComponentInternal) { + this.msgBarComponentInternal.config = config; + this.msgBarComponentInternal.show(); + } + } + + /** + * Starts a timer which will close the msg bar after some time. If a timer was still + * running when calling this function, it is cancelled before starting the new one. + * @param duration Timer duration, in ms. + */ + private setTimer(duration = 10000) { + if (this.timeSubscription) { + this.timeSubscription.unsubscribe(); + } + + // This makes the e2e tests run faster. + if (environment.isInE2eMode) { + duration = 500; + } + + this.timeSubscription = of(1).pipe(delay(duration)).subscribe(() => this.hide()); + } +} diff --git a/src/gui/static/src/app/services/nav-bar-switch.service.ts b/src/gui/static/src/app/services/nav-bar-switch.service.ts new file mode 100644 index 0000000..dcf3121 --- /dev/null +++ b/src/gui/static/src/app/services/nav-bar-switch.service.ts @@ -0,0 +1,99 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; + +import { DoubleButtonActive } from '../components/layout/double-button/double-button.component'; + +/** + * Allows to make operations related to the switch shown at the right side of the navigation bar. + */ +@Injectable() +export class NavBarSwitchService { + + // Properties + /////////////////////////////////////////// + + /** + * Indicates if the navigation bar must show the 2 options switch on the right side. + */ + get switchVisible(): boolean { + return this.switchVisibleInternal; + } + private switchVisibleInternal = false; + + /** + * Indicates which option is selected. + */ + get activeComponent(): Observable { + return this.activeComponentInternal.asObservable(); + } + private activeComponentInternal = new BehaviorSubject(DoubleButtonActive.LeftButton); + + /** + * Text of the left option. + */ + get leftText(): string { + return this.leftTextInternal; + } + private leftTextInternal: string; + + /** + * Text of the right option. + */ + get rightText(): string { + return this.rightTextInternal; + } + private rightTextInternal: string; + + /** + * Indicates if the switch must be shown disabled. + */ + get switchDiabled(): boolean { + return this.switchDiabledInternal; + } + private switchDiabledInternal = false; + + // functions + /////////////////////////////////////////// + + /** + * Indicates which option must be shown selected. + */ + setActiveComponent(value: DoubleButtonActive) { + this.activeComponentInternal.next(value); + } + + /** + * Makes the switch visible. + * @param leftText Text for the option at the left. + * @param rightText Text for the option at the right. + * @param selectedButton Which option must be shown selected. + */ + showSwitch(leftText, rightText, selectedButton = DoubleButtonActive.LeftButton) { + this.setActiveComponent(selectedButton); + this.switchDiabledInternal = false; + this.switchVisibleInternal = true; + this.leftTextInternal = leftText; + this.rightTextInternal = rightText; + } + + /** + * Hides the switch. + */ + hideSwitch() { + this.switchVisibleInternal = false; + } + + /** + * Shows the switch enabled. + */ + enableSwitch() { + this.switchDiabledInternal = false; + } + + /** + * Shows the switch disabled. + */ + disableSwitch() { + this.switchDiabledInternal = true; + } +} diff --git a/src/gui/static/src/app/services/network.service.ts b/src/gui/static/src/app/services/network.service.ts new file mode 100644 index 0000000..3937715 --- /dev/null +++ b/src/gui/static/src/app/services/network.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +import { Connection, NetworkOperator } from './coin-specific/network-operator'; +import { OperatorService } from './operators.service'; + +/** + * Allows to know if the node is connected to any remote node and to get the list of those nodes. + * + * NOTE: the functionality for getting the list of remote nodes is currently designed for Fiber + * coins only. + */ +@Injectable() +export class NetworkService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: NetworkOperator; + + /** + * Indicates if the node is not currently connected to any remote node. + */ + get noConnections(): boolean { + return this.operator.noConnections; + } + + constructor(private operatorService: OperatorService) { } + + initialize() { + // Maintain the operator updated. + this.operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.networkOperator; + } else { + this.operator = null; + } + }); + } + + /** + * Gets the lists of remote nodes the node is currently connected to. + */ + connections(): Observable { + return this.operator.connections(); + } +} diff --git a/src/gui/static/src/app/services/node.service.ts b/src/gui/static/src/app/services/node.service.ts new file mode 100644 index 0000000..d13d470 --- /dev/null +++ b/src/gui/static/src/app/services/node.service.ts @@ -0,0 +1,79 @@ +import { delay, retryWhen } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +import { NodeOperator } from './coin-specific/node-operator'; +import { FiberApiService } from './api/fiber-api.service'; +import { OperatorService } from './operators.service'; +import { environment } from '../../environments/environment'; + +/** + * Allows to access general information about the local and remote nodes. + */ +@Injectable() +export class NodeService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: NodeOperator; + + /** + * Indicates if the csrf token protection is disabled on the local node. + */ + get localNodeCsrfDisabled() { + return this.localNodeCsrfDisabledInternal; + } + private localNodeCsrfDisabledInternal = false; + + /** + * If the data this service has about the remote node (or the local node, if the current coin + * is managed by the local node) has been updated. + */ + get remoteNodeDataUpdated(): Observable { + return this.operator.remoteNodeDataUpdated; + } + + /** + * Version number of the remote node. + */ + get nodeVersion() { + return this.operator.nodeVersion; + } + + /** + * Indicates the maximum number of decimals for the coin currently accepts. + */ + get currentMaxDecimals() { + return this.operator.currentMaxDecimals; + } + + /** + * Rate used for calculating the amount of hours that should be burned as transaction fee + * when sending coins. The minimum amount to burn is "totalHours / burnRate". + */ + get burnRate() { + return this.operator.burnRate; + } + + constructor( + private fiberApiService: FiberApiService, + operatorService: OperatorService, + ) { + // Maintain the operator updated. + operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.nodeOperator; + } else { + this.operator = null; + } + }); + } + + initialize() { + // Get the csrf config of the local node. + this.fiberApiService.get(environment.nodeUrl, 'health').pipe(retryWhen(errors => errors.pipe(delay(3000)))).subscribe(response => { + this.localNodeCsrfDisabledInternal = !response.csrf_enabled; + }); + } +} diff --git a/src/gui/static/src/app/services/operators.service.ts b/src/gui/static/src/app/services/operators.service.ts new file mode 100644 index 0000000..3fa506e --- /dev/null +++ b/src/gui/static/src/app/services/operators.service.ts @@ -0,0 +1,88 @@ +import { Observable, BehaviorSubject } from 'rxjs'; +import { Injectable, Injector } from '@angular/core'; + +import { BalanceAndOutputsOperator } from './coin-specific/balance-and-outputs-operator'; +import { BlockchainOperator } from './coin-specific/blockchain-operator'; +import { HistoryOperator } from './coin-specific/history-operator'; +import { NetworkOperator } from './coin-specific/network-operator'; +import { NodeOperator } from './coin-specific/node-operator'; +import { SoftwareWalletOperator } from './coin-specific/software-wallet-operator'; +import { SpendingOperator } from './coin-specific/spending-operator'; +import { WalletUtilsOperator } from './coin-specific/wallet-utils-operator'; +import { WalletsAndAddressesOperator } from './coin-specific/wallets-and-addresses-operator'; +import { CoinService } from './coin.service'; +import { OperatorsGenerator } from './coin-specific/operators-generator'; +import { CoinTypes } from '../coins/settings/coin-types'; + +/** + * Set will all the operators needed for a coin. + */ +export interface OperatorSet { + balanceAndOutputsOperator: BalanceAndOutputsOperator; + blockchainOperator: BlockchainOperator; + historyOperator: HistoryOperator; + networkOperator: NetworkOperator; + nodeOperator: NodeOperator; + softwareWalletOperator: SoftwareWalletOperator; + spendingOperator: SpendingOperator; + walletUtilsOperator: WalletUtilsOperator; + walletsAndAddressesOperator: WalletsAndAddressesOperator; +} + +/** + * Service in charge of updating the operators every time the coin changes. + */ +@Injectable() +export class OperatorService { + /** + * Currently active operators. + */ + private operators: OperatorSet; + private currentOperatorsSubject: BehaviorSubject = new BehaviorSubject(null); + + constructor( + private coinService: CoinService, + private injector: Injector, + ) { } + + /** + * Returns the currently active operators. It returns null while the operators + * are being created. + */ + get currentOperators(): Observable { + return this.currentOperatorsSubject.asObservable(); + } + + initialize(fiberOperatorsGenerator: OperatorsGenerator, btcOperatorsGenerator: OperatorsGenerator, ethOperatorsGenerator: OperatorsGenerator) { + this.coinService.currentCoin.subscribe(coin => { + // Wait 1 frame before removing the operators, to give time for the pages to + // be removed. + setTimeout(() => { + if (this.operators) { + this.operators.balanceAndOutputsOperator.dispose(); + this.operators.blockchainOperator.dispose(); + this.operators.historyOperator.dispose(); + this.operators.networkOperator.dispose(); + this.operators.nodeOperator.dispose(); + this.operators.softwareWalletOperator.dispose(); + this.operators.spendingOperator.dispose(); + this.operators.walletUtilsOperator.dispose(); + this.operators.walletsAndAddressesOperator.dispose(); + } + + this.currentOperatorsSubject.next(null); + + // Replace the current operators. + if (coin.coinType === CoinTypes.Fiber) { + this.operators = fiberOperatorsGenerator.generate(coin, this.injector); + } else if (coin.coinType === CoinTypes.BTC) { + this.operators = btcOperatorsGenerator.generate(coin, this.injector); + } else if (coin.coinType === CoinTypes.ETH) { + this.operators = ethOperatorsGenerator.generate(coin, this.injector); + } + + this.currentOperatorsSubject.next(this.operators); + }); + }); + } +} diff --git a/src/gui/static/src/app/services/price.service.ts b/src/gui/static/src/app/services/price.service.ts new file mode 100644 index 0000000..c1ab027 --- /dev/null +++ b/src/gui/static/src/app/services/price.service.ts @@ -0,0 +1,76 @@ +import { Injectable, NgZone } from '@angular/core'; +import { Subject, BehaviorSubject, of, Subscription, Observable } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { delay, mergeMap } from 'rxjs/operators'; + +import { environment } from '../../environments/environment'; +import { CoinService } from './coin.service'; + +/** + * Maintains updated and allows to known the current USD price of the coin. + */ +@Injectable() +export class PriceService { + /** + * Allows to know the current USD price of the coin. + */ + get price(): Observable { + return this.priceInternal.asObservable(); + } + private priceInternal: Subject = new BehaviorSubject(null); + + /** + * Time interval in which periodic data updates will be made. + */ + private readonly updatePeriod = 10 * 60 * 1000; + /** + * Time interval in which the periodic data updates will be restarted after an error. + */ + private readonly errorUpdatePeriod = 30 * 1000; + private priceSubscription: Subscription; + + constructor( + private http: HttpClient, + private ngZone: NgZone, + private coinService: CoinService, + ) { + // Update the price inmediatelly after the coin is changed. + coinService.currentCoin.subscribe(() => { + this.priceInternal.next(null); + this.startDataRefreshSubscription(0); + }); + } + + /** + * Makes the service start updating the data periodically. If this function was called + * before, the previous updating procedure is cancelled. + * @param delayMs Delay before starting to update the data. + */ + private startDataRefreshSubscription(delayMs: number) { + if (this.priceSubscription) { + this.priceSubscription.unsubscribe(); + } + + // If there is no API ID for getting the price, nothing is done. + if (!this.coinService.currentCoinInmediate.priceTickerId) { + return; + } + + if (!environment.isInE2eMode) { + this.ngZone.runOutsideAngular(() => { + this.priceSubscription = of(0).pipe(delay(delayMs), mergeMap(() => { + return this.http.get(`https://api.coinpaprika.com/v1/tickers/${this.coinService.currentCoinInmediate.priceTickerId}?quotes=USD`); + })).subscribe((response: any) => { + this.ngZone.run(() => this.priceInternal.next(response.quotes.USD.price)); + this.startDataRefreshSubscription(this.updatePeriod); + }, () => { + this.startDataRefreshSubscription(this.errorUpdatePeriod); + }); + }); + } else { + // Set the price to 1 and stop making updates during e2e tests, to avoid potential + // problems with the remote connection. + this.priceInternal.next(1); + } + } +} diff --git a/src/gui/static/src/app/services/purchase.service.ts b/src/gui/static/src/app/services/purchase.service.ts new file mode 100644 index 0000000..30e15d6 --- /dev/null +++ b/src/gui/static/src/app/services/purchase.service.ts @@ -0,0 +1,75 @@ +/* + IMPORTANT: Unused for a long time, it may need changes to work properly. +*/ + +import { Injectable } from '@angular/core'; +import { Subject, BehaviorSubject, Observable } from 'rxjs'; +import { PurchaseOrder, TellerConfig } from '../app.datatypes'; +import { HttpClient } from '@angular/common/http'; +import { environment } from '../../environments/environment'; +import { map, mergeMap } from 'rxjs/operators'; +import { WalletBase } from './wallet-operations/wallet-objects'; +import { WalletsAndAddressesService } from './wallet-operations/wallets-and-addresses.service'; + +@Injectable() +export class PurchaseService { + private configSubject: Subject = new BehaviorSubject(null); + private purchaseOrders: Subject = new BehaviorSubject([]); + private purchaseUrl = environment.tellerUrl; + + constructor( + private httpClient: HttpClient, + private walletsAndAddressesService: WalletsAndAddressesService, + ) { + this.getConfig(); + } + + all() { + return this.purchaseOrders.asObservable(); + } + + config(): Observable { + return this.configSubject.asObservable(); + } + + getConfig() { + return this.get('config').pipe( + map((response: any) => ({ + enabled: true, + sky_btc_exchange_rate: parseFloat(response.sky_btc_exchange_rate), + }))) + .subscribe(response => this.configSubject.next(response)); + } + + generate(wallet: WalletBase): Observable { + return this.walletsAndAddressesService.addAddressesToWallet(wallet, 1).pipe(mergeMap(address => { + return this.post('bind', { skyaddr: address[0].printableAddress, coin_type: 'BTC' }).pipe( + map(response => ({ + coin_type: response.coin_type, + deposit_address: response.deposit_address, + filename: wallet.id, + recipient_address: address[0].printableAddress, + status: 'waiting_deposit', + }))); + })); + } + + scan(address: string) { + return this.get('status?skyaddr=' + address).pipe( + map((response: any) => { + if (!response.statuses || response.statuses.length > 1) { + throw new Error('too many purchase orders found'); + } + + return response.statuses[0]; + })); + } + + private get(url): Observable { + return this.httpClient.get(this.purchaseUrl + url); + } + + private post(url, parameters = {}): Observable { + return this.httpClient.post(this.purchaseUrl + url, parameters); + } +} diff --git a/src/gui/static/src/app/services/storage.service.ts b/src/gui/static/src/app/services/storage.service.ts new file mode 100644 index 0000000..d7529f3 --- /dev/null +++ b/src/gui/static/src/app/services/storage.service.ts @@ -0,0 +1,84 @@ +import { Injectable } from '@angular/core'; +import { Observable, of, throwError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; + +import { FiberApiService } from './api/fiber-api.service'; +import { OperationError } from '../utils/operation-error'; +import { processServiceError } from '../utils/errors'; +import { environment } from '../../environments/environment'; + +/** + * Types of storage data. Types serve as a way of separating the saved data, so there could + * be 2 different values saved using the same key to identify them, but only if the 2 values + * are of different type. + */ +export enum StorageType { + /** + * Type used for general data. + */ + CLIENT = 'client', + /** + * Type used for transaction notes. + */ + NOTES = 'txid', +} + +/** + * Allows to save and read data to and from the node persistent key/value storage. + */ +@Injectable() +export class StorageService { + + constructor( + private fiberApiService: FiberApiService, + ) { } + + /** + * Retrieves data from the node persistent key/value storage. + * @param type Type of the value to be retrieved. + * @param key Key idenfying the value to be retrieved. If no key is provided, all the + * saved value of the provided type will be returned. + * @returns The retrieved data, or null if the data was not found. If a key is provided, + * the data will be directly in the response. If no key is provided, the response will + * be an object which will contain properties with the name of every key saved on the + * persistent key/value storage, set to the corresponding value. + */ + get(type: StorageType, key: string|null): Observable { + const params = { type }; + + if (key) { + params.key = key; + } + + return this.fiberApiService.get(environment.nodeUrl, 'data', params, { useV2: true }).pipe( + map(result => result.data), + catchError((err: OperationError) => { + // If the node returned a 404 error, it means the data was not found, not + // that there was an error during the operation, so we can continue. + err = processServiceError(err); + try { + if (err && err.originalError && err.originalError.status && err.originalError.status === 404) { + return of(null); + } + } catch (e) {} + + return throwError(err); + }), + ); + } + + /** + * Saves a value on the node persistent key/value storage. + * @param type Type of the value to be saved. + * @param key Key which will identify the value. If the key already exist, the saved data + * will be overwritten. + * @returns The returned observable returns nothing, but it can fail in case of error. + */ + store(type: StorageType, key: string, value: string): Observable { + return this.fiberApiService.post(environment.nodeUrl, 'data', { + type: type, + key: key, + val: value, + }, { useV2: true }); + } +} diff --git a/src/gui/static/src/app/services/wallet-operations/balance-and-outputs.service.ts b/src/gui/static/src/app/services/wallet-operations/balance-and-outputs.service.ts new file mode 100644 index 0000000..acd8712 --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/balance-and-outputs.service.ts @@ -0,0 +1,124 @@ +import { Observable } from 'rxjs'; +import { Injectable } from '@angular/core'; + +import { WalletWithBalance, WalletBase, WalletWithOutputs } from './wallet-objects'; +import { Output } from './transaction-objects'; +import { BalanceAndOutputsOperator } from '../coin-specific/balance-and-outputs-operator'; +import { OperatorService } from '../operators.service'; + +/** + * Allows to get the balance of the wallets and is in chage of maintaining those balances updated. + * It also allows to get the unspent outputs of the wallets and lists of addresses. + */ +@Injectable() +export class BalanceAndOutputsService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: BalanceAndOutputsOperator; + + constructor(operatorService: OperatorService) { + // Maintain the operator updated. + operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.balanceAndOutputsOperator; + } else { + this.operator = null; + } + }); + } + + /** + * Gets the last moment in which the balance was updated. Emits every time the system + * finishes checking the balance. + */ + get lastBalancesUpdateTime(): Observable { + return this.operator.lastBalancesUpdateTime; + } + + /** + * Gets the wallet list, with the balance of each wallet and address. It emits when the + * wallet list is updated and when the balance changes. Every time this observable emits, + * the wallet array is returned, but in fact, if there are not important changes in the + * structure of the wallets, if the only change was in the balance, the service will try + * to always update the values in the same array, this means that in most cases you will have + * the updated balance even if not listening to new events. Please note that the list will + * tell all the wallets have balance 0 util the service finishes connecting to the + * backend node for the first time. Also note that if any value of the returned wallets + * is modified, the changes must be notified to the wallets service or the behavior will + * be indeterminate. + */ + get walletsWithBalance(): Observable { + return this.operator.walletsWithBalance; + } + + /** + * Indicates if there are pending transactions affecting any of the wallets of the + * wallet list. + */ + get hasPendingTransactions(): Observable { + return this.operator.hasPendingTransactions; + } + + /** + * Indicates if the service already got the balances of the wallets from the node for + * the first time. The wallets returned by walletsWithBalance will always show blance 0 + * until this property returns true. + */ + get firstFullUpdateMade(): Observable { + return this.operator.firstFullUpdateMade; + } + + /** + * Indicates if the last time the system tried to refresh the balance there was an error. + */ + get hadErrorRefreshingBalance(): Observable { + return this.operator.hadErrorRefreshingBalance; + } + + /** + * Indicates if the balance is currently beeing refreshed. + */ + get refreshingBalance(): Observable { + return this.operator.refreshingBalance; + } + + /** + * Gets the wallet list, with the unspent outputs of each address. It emits when the + * wallet list is updated and when the balance changes. Please note that if any value + * of the returned wallets is modified, the changes must be notified to the wallets + * service or the behavior will be indeterminate. The response will include confirmed and + * unconfirmed outputs. + */ + get outputsWithWallets(): Observable { + return this.operator.outputsWithWallets; + } + + /** + * Gets the list of confirmed unspent outputs of a list of addresses. The data is not + * automatically updated. + * @param addresses List of addresses, comma separated. + * @returns Array with all the unspent outputs owned by any of the provide addresses. + */ + getOutputs(addresses: string): Observable { + return this.operator.getOutputs(addresses); + } + + /** + * Gets the list of confirmed unspent outputs owned by a wallet. The data is not + * automatically updated. + * @param wallet Wallet to check. + * @returns Array with all the unspent outputs owned by any of the addresses of the wallet. + */ + getWalletUnspentOutputs(wallet: WalletBase): Observable { + return this.operator.getWalletUnspentOutputs(wallet); + } + + /** + * Asks the service to update the balance inmediatelly. + */ + refreshBalance() { + return this.operator.refreshBalance(); + } +} diff --git a/src/gui/static/src/app/services/wallet-operations/hardware-wallet.service.ts b/src/gui/static/src/app/services/wallet-operations/hardware-wallet.service.ts new file mode 100644 index 0000000..b3150de --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/hardware-wallet.service.ts @@ -0,0 +1,215 @@ +import { Observable, of } from 'rxjs'; +import { map, catchError, mergeMap } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +import { WalletsAndAddressesService } from './wallets-and-addresses.service'; +import { WalletBase } from './wallet-objects'; +import { HwWalletService } from '../hw-wallet.service'; +import { AppConfig } from '../../app.config'; +import { CoinService } from '../coin.service'; + +/** + * List with the security problems that can be detected in a hw wallet. + */ +export enum HwSecurityWarnings { + /** + * The user has not made a backup of the seed of the device. + */ + NeedsBackup = 'NeedsBackup', + /** + * The device does not have PIN code protection activated. + */ + NeedsPin = 'NeedsPin', + /** + * It was not possible to connect to the remote server to know if the device is running + * an outdated firmware. + */ + FirmwareVersionNotVerified = 'FirmwareVersionNotVerified', + /** + * The device is running an outdated firmware. + */ + OutdatedFirmware = 'OutdatedFirmware', +} + +export interface HwFeaturesResponse { + /** + * Features returned by the device. + */ + features: any; + /** + * Security warnings found during the operation. + */ + securityWarnings: HwSecurityWarnings[]; + /** + * During the operation it was detected that the device is showing a label which is not + * equal to the one known by the app, so the name shown on the app was updated to match + * the one on the device. + */ + walletNameUpdated: boolean; +} + +/** + * Allows to perform operations which involve a hardware wallet and the local representation + * of it used by the app. + */ +@Injectable() +export class HardwareWalletService { + constructor( + private walletsAndAddressesService: WalletsAndAddressesService, + private hwWalletService: HwWalletService, + private http: HttpClient, + private coinService: CoinService, + ) { } + + /** + * Gets the features of the connected hw wallet and also updates the label and security warnings + * of a WalletBase instance with the data obtained from the currently connected device. + * @param wallet WalletBase instance to be updated. If null, the function will still work, it + * just will not update anything. + */ + getFeaturesAndUpdateData(wallet: WalletBase): Observable { + if (!wallet || wallet.isHardware) { + + let lastestFirmwareVersion: string; + + // Get the number of the most recent firmware version. + return this.http.get(AppConfig.urlForHwWalletVersionChecking, { responseType: 'text' }).pipe( + catchError(() => of(null)), + mergeMap((res: any) => { + // If it was not possible to get the number of the most recent firmware version, + // continue anyways. + if (res) { + lastestFirmwareVersion = res; + } else { + lastestFirmwareVersion = null; + } + + // Get the features. + return this.hwWalletService.getFeatures(); + }), + map(result => { + let lastestFirmwareVersionReaded = false; + let firmwareUpdated = false; + + // Compare the version number of the firmware of the connected device and the one obtained from the server. + if (lastestFirmwareVersion) { + lastestFirmwareVersion = lastestFirmwareVersion.trim(); + const versionParts = lastestFirmwareVersion.split('.'); + + if (versionParts.length === 3) { + lastestFirmwareVersionReaded = true; + + const numVersionParts = versionParts.map(value => Number.parseInt(value.replace(/\D/g, ''), 10)); + + const devMajorVersion = result.rawResponse.fw_major; + const devMinorVersion = result.rawResponse.fw_minor; + const devPatchVersion = result.rawResponse.fw_patch; + + if (devMajorVersion > numVersionParts[0]) { + firmwareUpdated = true; + } else { + if (devMajorVersion === numVersionParts[0]) { + if (devMinorVersion > numVersionParts[1]) { + firmwareUpdated = true; + } else { + if (devMinorVersion === numVersionParts[1] && devPatchVersion >= numVersionParts[2]) { + firmwareUpdated = true; + } + } + } + } + } + } + + // Create the security warnings list. + const warnings: HwSecurityWarnings[] = []; + let hasHwSecurityWarnings = false; + + if (result.rawResponse.needs_backup) { + warnings.push(HwSecurityWarnings.NeedsBackup); + hasHwSecurityWarnings = true; + } + if (!result.rawResponse.pin_protection) { + warnings.push(HwSecurityWarnings.NeedsPin); + hasHwSecurityWarnings = true; + } + + if (!lastestFirmwareVersionReaded) { + warnings.push(HwSecurityWarnings.FirmwareVersionNotVerified); + } else { + if (!firmwareUpdated) { + warnings.push(HwSecurityWarnings.OutdatedFirmware); + hasHwSecurityWarnings = true; + } + } + + // If a wallet was provided, update the label and security warnings, if needed. + let walletNameUpdated = false; + if (wallet) { + let changesMade = false; + + const deviceLabel = result.rawResponse.label ? result.rawResponse.label : (result.rawResponse.deviceId ? result.rawResponse.deviceId : result.rawResponse.device_id); + if (wallet.label !== deviceLabel) { + wallet.label = deviceLabel; + walletNameUpdated = true; + changesMade = true; + } + if (wallet.hasHwSecurityWarnings !== hasHwSecurityWarnings) { + wallet.hasHwSecurityWarnings = hasHwSecurityWarnings; + changesMade = true; + } + + if (changesMade) { + this.walletsAndAddressesService.informValuesUpdated(wallet); + } + } + + // Prepare the response. + const response = { + features: result.rawResponse, + securityWarnings: warnings, + walletNameUpdated: walletNameUpdated, + }; + + return response; + })); + } else { + return null; + } + } + + /** + * Asks the user to confirm an addresses on the connected device. This allows the user + * to confirm that the address displayed by this app is equal to the one on the device. + * @param wallet Wallet to check. + * @param addressIndex Index of the addresses on the provided wallet. + */ + confirmAddress(wallet: WalletBase, addressIndex: number): Observable { + return this.hwWalletService.checkIfCorrectHwConnected(wallet).pipe( + mergeMap(() => this.hwWalletService.confirmAddress(addressIndex, this.coinService.currentCoinInmediate.skywalletCoinType)), + map(() => { + // If the user confirms the operation, update the local data. + wallet.addresses[addressIndex].confirmed = true; + this.walletsAndAddressesService.informValuesUpdated(wallet); + }), + ); + } + + /** + * Asks the device to change the label shown on its physical scren. It also changes the + * label/name saved on the local wallet object. + * @param wallet Wallet to modify. + * @param newLabel New label or name. + */ + changeLabel(wallet: WalletBase, newLabel: string): Observable { + return this.hwWalletService.checkIfCorrectHwConnected(wallet).pipe( + mergeMap(() => this.hwWalletService.changeLabel(newLabel)), + map(() => { + // If the user confirms the operation, update the local data. + wallet.label = newLabel; + this.walletsAndAddressesService.informValuesUpdated(wallet); + }), + ); + } +} diff --git a/src/gui/static/src/app/services/wallet-operations/history.service.ts b/src/gui/static/src/app/services/wallet-operations/history.service.ts new file mode 100644 index 0000000..92f2ddb --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/history.service.ts @@ -0,0 +1,156 @@ +import { Observable } from 'rxjs'; +import { Injectable } from '@angular/core'; + +import { WalletBase, AddressWithBalance, AddressMap } from './wallet-objects'; +import { OldTransaction } from './transaction-objects'; +import { HistoryOperator } from '../coin-specific/history-operator'; +import { OperatorService } from '../operators.service'; + +export interface PendingTransactionsResponse { + /** + * Pending transactions affecting one or more of the user addresses. + */ + user: PendingTransactionData[]; + /** + * All pending transactions known by the node, including the ones affecting one + * or more of the user addresses. + */ + all: PendingTransactionData[]; +} + +export interface PendingTransactionData { + /** + * Transaction ID. + */ + id: string; + /** + * How many coins are on the outputs. + */ + coins: string; + /** + * How many hours are on the outputs. + */ + hours?: string; + /** + * Transaction timestamp, in Unix format. + */ + timestamp: number; + /** + * How many confirmations the transaction currently has. + */ + confirmations: number; +} + +export interface AddressesHistoryResponse { + /** + * External address list. + */ + externalAddresses: AddressesState[]; + /** + * Change address list. + */ + changeAddresses: AddressesState[]; + /** + * If true, the response does not include one or more addresses of the wallet. + */ + omitedAddresses: boolean; +} + +export interface AddressesState { + /** + * Address Object. + */ + address: AddressWithBalance; + /** + * Index of the address in its chain (list of external or change addresses). + */ + indexInWallet: number; + /** + * If the address has already received any coins. + */ + alreadyUsed: boolean; +} + +/** + * Response returned by HistoryService.getTransactionsHistory. + */ +export interface TransactionHistory { + /** + * Transaction list. + */ + transactions: OldTransaction[]; + /** + * List with the addresses for which transactions were ignored due to the value sent in the + * transactionLimitperAddress param. + */ + addressesWitAdditionalTransactions: AddressMap; +} + +/** + * Values indicating the limits in how many transactions per address will be retrieved when + * getting the transaction history. + */ +export enum TransactionLimits { + NormalLimit = 'NormalLimit', + ExtraLimit = 'ExtraLimit', + MaxAllowed = 'MaxAllowed', +} + +/** + * Allows to get the transaction history and pending transactions. + */ +@Injectable() +export class HistoryService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: HistoryOperator; + + constructor(operatorService: OperatorService) { + // Maintain the operator updated. + operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.historyOperator; + } else { + this.operator = null; + } + }); + } + + /** + * Gets the transaction history of all the wallets or a specific wallet. + * @param wallet Specific wallet for which the transaction history will be returned. If null, + * the transactions of all wallets will be returned. + * @param transactionLimitperAddress How many transactions per address will be retrieved. Some + * coins will ignore this walue and return all the transactions. + */ + getTransactionsHistory(wallet: WalletBase|null, transactionLimitperAddress: TransactionLimits): Observable { + return this.operator.getTransactionsHistory(wallet, transactionLimitperAddress); + } + + /** + * Checks the addresses of a wallet to know which ones have been used, defined as having + * received coins. + * @returns A map with all addresses, indicating which ones have been used and which ones + * have not. + */ + getIfAddressesUsed(wallet: WalletBase): Observable> { + return this.operator.getIfAddressesUsed(wallet); + } + + /** + * Gets the list of pending transactions currently on the node. The data is not + * automatically updated. + */ + getPendingTransactions(): Observable { + return this.operator.getPendingTransactions(); + } + + /** + * Gets the address list of a wallet. Not for deterministic wallets. + */ + getAddressesHistory(wallet: WalletBase): Observable { + return this.operator.getAddressesHistory(wallet); + } +} diff --git a/src/gui/static/src/app/services/wallet-operations/software-wallet.service.ts b/src/gui/static/src/app/services/wallet-operations/software-wallet.service.ts new file mode 100644 index 0000000..e69f86f --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/software-wallet.service.ts @@ -0,0 +1,77 @@ +import { Observable } from 'rxjs'; +import { Injectable } from '@angular/core'; + +import { WalletBase, WalletTypes } from './wallet-objects'; +import { SoftwareWalletOperator } from '../coin-specific/software-wallet-operator'; +import { OperatorService } from '../operators.service'; + +export interface SeedResponse { + seed: String; + passphrase: String; + walletType: WalletTypes; +} + +/** + * Allows to perform operations related to a software wallet. + */ +@Injectable() +export class SoftwareWalletService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: SoftwareWalletOperator; + + constructor(operatorService: OperatorService) { + // Maintain the operator updated. + operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.softwareWalletOperator; + } else { + this.operator = null; + } + }); + } + + /** + * Allows to change the name or label which identifies a wallet. + * @param wallet Wallet to modify. + * @param label New name or label. + * @returns The returned observable returns nothing, but it can fail in case of error. + */ + renameWallet(wallet: WalletBase, label: string): Observable { + return this.operator.renameWallet(wallet, label); + } + + /** + * Makes an encrypted wallet to be unencrypted, or an unencrypted wallet to be encrypted. + * @param wallet Wallet to modify. + * @param password If the wallet is encrypted, the password of the wallet, to be able to + * disable the encryptation. If the wallet is unencrypted, the password that will be used + * for encrypting it. + * @returns The returned observable returns nothing, but it can fail in case of error. + */ + toggleEncryption(wallet: WalletBase, password: string): Observable { + return this.operator.toggleEncryption(wallet, password); + } + + /** + * Removes or changes the password of an encrypted wallet. + * @param wallet Wallet to modify. + * @param seed Seed of the wallet. + * @param password New password for the wallet. If empty or null, the wallet will be + * unencrypted after finishing the operation. + */ + resetPassword(wallet: WalletBase, seed: string, password: string, passphrase: string): Observable { + return this.operator.resetPassword(wallet, seed, password, passphrase); + } + + /** + * Gets the seed of an encrypted wallet. + * @param wallet Wallet to get the seed from. + * @param password Wallet password. + */ + getWalletSeed(wallet: WalletBase, password: string): Observable { + return this.operator.getWalletSeed(wallet, password); + } +} diff --git a/src/gui/static/src/app/services/wallet-operations/spending.service.ts b/src/gui/static/src/app/services/wallet-operations/spending.service.ts new file mode 100644 index 0000000..503be13 --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/spending.service.ts @@ -0,0 +1,236 @@ +import { Observable } from 'rxjs'; +import { Injectable } from '@angular/core'; +import BigNumber from 'bignumber.js'; + +import { WalletBase } from './wallet-objects'; +import { GeneratedTransaction, Output } from './transaction-objects'; +import { SpendingOperator } from '../coin-specific/spending-operator'; +import { OperatorService } from '../operators.service'; + +/** + * Defines a destination to were coins will be sent. + */ +export interface TransactionDestination { + /** + * Address to where the coins will be sent. + */ + address: string; + /** + * How many coins to send. + */ + coins: string; + /** + * How many hours to send. Only needed if the node is not supposed to calculate the + * hours automatically. + */ + hours?: string; +} + +/** + * Modes the node can use to distribute the hours when creating a transacton. + */ +export enum HoursDistributionTypes { + /** + * Every destination will have an specific amout of hours. + */ + Manual = 'manual', + /** + * The node will automatically calculate how many hours to send to each output. + */ + Auto = 'auto', +} + +/** + * Specifies how the node must distribute the hours when creating a transaction. + */ +export interface HoursDistributionOptions { + /** + * How the node will make the calculation. + */ + type: HoursDistributionTypes; + /** + * Specific mode used if the node will automatically calculate the hours. + */ + mode?: 'share'; + /** + * Value used by the node to know how many hours to send and retain (is posible), if the node + * will automatically calculate the hours. + */ + share_factor?: string; +} + +/** + * Recommended fees for getting a transaction approved. The object will normally contain only the + * fees for the currently selected coin. + */ +export interface RecommendedFees { + recommendedBtcFees: RecommendedBtcFees; + recommendedEthFees: RecommendedEthFees; + /** + * If true, it means that the backend did not return at least one of the recommended fee values. + * If this happens, some values may not be adecuate and the user must be informed. + */ + thereWereProblems: boolean; +} + +/** + * Recommended fees for getting a BTC transaction approved after a relatively predictable + * amount of time. + */ +export interface RecommendedBtcFees { + /** + * Sats per byte for getting a transaction approved in the next block. + */ + veryHigh: BigNumber; + /** + * Sats per byte for getting a transaction approved in 1 or 2 blocks. + */ + high: BigNumber; + /** + * Sats per byte for getting a transaction approved in 5+ blocks. + */ + normal: BigNumber; + /** + * Sats per byte for getting a transaction approved in 10+ blocks. + */ + low: BigNumber; + /** + * Sats per byte for getting a transaction approved in 20+ blocks. + */ + veryLow: BigNumber; +} + +/** + * Recommended fees for getting a ETH transaction approved. + */ +export interface RecommendedEthFees { + /** + * Rocommended gas price, in gwei. + */ + gasPrice: BigNumber; + /** + * Recommended gas limit. If there was a problem getting it, it will be null and the + * "thereWereProblems" property of the parent object must be true. + */ + gasLimit: BigNumber; +} + +/** + * Allows to create, prepare and send transactions. + */ +@Injectable() +export class SpendingService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: SpendingOperator; + + constructor(operatorService: OperatorService) { + // Maintain the operator updated. + operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.spendingOperator; + } else { + this.operator = null; + } + }); + } + + /** + * Creates a transaction, but does not send it to the network. + * @param wallet Wallet from which the coins will be send. If null is provided, you will have to + * provide a list of addresses or unspent outputs from were the coins will be sent and the function + * will return an unsigned transaction. + * @param addresses Optional list of addresses from were the coins will be sent. All addresses should + * be from the provided wallet (if any). If an unspent outputs list is provided, this param is ignored. + * @param unspents Optional list of unspent outputs from were the coins will be sent. All outputs + * should be from the provided wallet (if any). + * @param hoursDistributionOptions Object indicating how the hours will be distributed, if the + * currently selected coin uses hours. + * @param destinations Array with indications about hows many coins will be sent and where. + * @param changeAddress Optional custom address where the remaining coins and hours will be sent. If not + * provided, one will be selected automatically. + * @param password Wallet password, if the wallet is encrypted. + * @param unsigned If the transaction must be signed or not. When using a hw wallet the transaction will + * have to be signed by the device, so it will have to be connected. If no wallet param was provided, this + * param is ignored and the transaction will be unsigned. + * @param fee Fee. For btc-like coins, the number of the minimun divisions of the coin per byte (like sats + * per byte for Bitcoin). For eth-like coins, gas price (in Gwei) and gas limit, separated by '/'. + * Not needed for all coins. + * @returns The generated transaction, without the note. + */ + createTransaction( + wallet: WalletBase|null, + addresses: string[]|null, + unspents: Output[]|null, + destinations: TransactionDestination[], + hoursDistributionOptions: HoursDistributionOptions|null, + changeAddress: string|null, + password: string|null, + unsigned: boolean, + fee: string): Observable { + + return this.operator.createTransaction( + wallet, + addresses, + unspents, + destinations, + hoursDistributionOptions, + changeAddress, + password, + unsigned, + fee); + } + + /** + * Calculates the final fee in coins that will have to be paid for sending a transaction. + * @param howManyInputs How many inputs the transaction will have, if applicable for + * the currently selected coin. + * @param howManyOutputs How many outputs the transaction will have, if applicable for + * the currently selected coin. + * @param feePerUnit The fee that will have to be paid per unit. The unit would be sats for + * Bitcoin and Gas for Ethereum. + * @param maxUnits Max number of units that can be spent in the transaction, if applicable for + * the currently selected coin. + */ + calculateFinalFee(howManyInputs: number, howManyOutputs: number, feePerUnit: BigNumber, maxUnits: BigNumber): BigNumber { + return this.operator.calculateFinalFee(howManyInputs, howManyOutputs, feePerUnit, maxUnits); + } + + /** + * Signs an unsigned transaction. + * @param wallet Wallet which will be used to sign the transaction. + * @param password Wallet password, if the provided walled is an encrypted software wallet. + * @param transaction Transaction to sign. + * @param rawTransactionString Encoded transaction to sign. If provided, the value of the + * transaction param is ignored. Only valid if using a software wallet. + * @returns The encoded signed transaction. + */ + signTransaction( + wallet: WalletBase, + password: string|null, + transaction: GeneratedTransaction, + rawTransactionString = ''): Observable { + + return this.operator.signTransaction(wallet, password, transaction, rawTransactionString); + } + + /** + * Sends a signed transaction to the network, to efectivelly send the coins. + * @param encodedTx Transaction to send. + * @param note Optional local note for the transaction. + * @returns If the note was saved or not. + */ + injectTransaction(encodedTx: string, note: string|null): Observable { + return this.operator.injectTransaction(encodedTx, note); + } + + /** + * Gets a collection of recommended fees for getting a transaction approved after a relatively + * predictable amount of time. + */ + getCurrentRecommendedFees(): Observable { + return this.operator.getCurrentRecommendedFees(); + } +} diff --git a/src/gui/static/src/app/services/wallet-operations/transaction-objects.ts b/src/gui/static/src/app/services/wallet-operations/transaction-objects.ts new file mode 100644 index 0000000..ee5e934 --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/transaction-objects.ts @@ -0,0 +1,188 @@ +/** + * This file contains the objects used to represent the transactions and its parts in the app. + */ +import BigNumber from 'bignumber.js'; + +import { WalletBase } from './wallet-objects'; + +/** + * Object with the properties of an input. + */ +export interface Input { + hash: string; + address: string; + coins: BigNumber; + hours?: BigNumber; + /** + * ID of the transaction where the original output was created. Only for Btc-like coins. + */ + transactionId?: string; + /** + * Index of the original output in the transaction where it was created. Only for Btc-like coins. + */ + indexInTransaction?: number; +} + +/** + * Object with the properties of an output; + */ +export interface Output { + hash: string; + address: string; + coins: BigNumber; + hours?: BigNumber; + confirmations?: number; + /** + * Locking script for Btc-like coins. NOTE: a value is assigned to this var only when creating + * a transaction while sending coins and is for internal use of the spending operator. + */ + lockingScript?: string; + /** + * ID of the transaction where the output was created. Only for Btc-like coins. + */ + transactionId?: string; + /** + * Index of the output in the transaction where it was created. Only for Btc-like coins. + */ + indexInTransaction?: number; + /** + * If true, the output was created for returning unused coins. NOTE: only for internal + * processing in the operators when the transaction was created by the app. + */ + returningCoins?: boolean; +} + +/** + * Base transaction object, from which other transaction objects inherit. + */ +export interface TransactionBase { + /** + * Input list. + */ + inputs: Input[]; + /** + * Output list. + */ + outputs: Output[]; + /** + * Transaction fee, in coins or hours. + */ + fee: BigNumber; + /** + * Local note set by the user to identify the transaction. + */ + note?: string; +} + +/** + * Transaction generated by the app to be sent to the node. + */ +export interface GeneratedTransaction extends TransactionBase { + /** + * Indicates the wallet or addresses sending the transaction. + */ + from: string; + /** + * List of addresses to were the transaction is sent. + */ + to: string; + /** + * Encoded transaction. + */ + encoded: string; + /** + * Inner hash of the transaction. + */ + innerHash: string; + /** + * Wallet used to create the transaction, if an specific wallet was used. + */ + wallet?: WalletBase; + /** + * How many coins the transaction is going to send. + */ + coinsToSend: BigNumber; + /** + * How many hours the transaction is going to send. + */ + hoursToSend?: BigNumber; +} + +/** + * List with the types for OldTransaction. + */ +export enum OldTransactionTypes { + /** + * Coins were received. + */ + Incoming = 'Incoming', + /** + * Coins were sent. + */ + Outgoing = 'Outgoing', + /** + * Coins were moved between addresses of the same wallet. + */ + MovedBetweenAddresses = 'MovedBetweenAddresses', + /** + * Coins were moved between wallets the user has. + */ + MovedBetweenWallets = 'MovedBetweenWallets', + /** + * The transaction involved a mix of addresses that did not allow to determine exactly + * how the user's wallets were affected. Transaction objects with this type do not include + * a balance. + */ + MixedOrUnknown = 'MixedOrUnknown', +} + +/** + * Old transaction from the transactions history. + */ +export interface OldTransaction extends TransactionBase { + /** + * How many coins were received or sent (if the number is negative). + */ + balance: BigNumber; + /** + * How many hours were received or sent (if the number is negative). + */ + hoursBalance?: BigNumber; + /** + * The addresses which sent the coins o the ones which received them, depending on + * whether the transaction was for sending or receiving coins. + */ + relevantAddresses: string[]; + /** + * Id of the transaction. + */ + id: string; + /** + * Transaction timestamp, in Unix time. + */ + timestamp: number; + /** + * If the transaction has been already confirmed by the network. + */ + confirmed: boolean; + /** + * How many confirmations the transaction has in the network. + */ + confirmations: number; + /** + * Transaction type. + */ + type: OldTransactionTypes; + /** + * Names of the local wallets which were involved in the transaction. + */ + involvedLocalWallets: string; + /** + * How many local wallets were involved in the transaction. + */ + numberOfInvolvedLocalWallets: number; + /** + * Indicates if the transaction failed. For eth-like coins only. + */ + failed: boolean; +} diff --git a/src/gui/static/src/app/services/wallet-operations/wallet-objects.ts b/src/gui/static/src/app/services/wallet-operations/wallet-objects.ts new file mode 100644 index 0000000..dbdcc04 --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/wallet-objects.ts @@ -0,0 +1,357 @@ +import BigNumber from 'bignumber.js'; + +import { Output } from './transaction-objects'; + +/** + * This file contains the objects used to represent the wallets and addresses in the app. + */ + + /** + * List with the different wallet types. + */ +export enum WalletTypes { + Deterministic = 'deterministic', + Bip44 = 'bip44', + XPub = 'xpub', +} + +// Base wallets +//////////////////////////////////////////////// + +/** + * Basic wallet object with the most important properties. + */ +export class WalletBase { + // NOTE: All properties must have an initial value or there could be problems creating duplicates. + + /** + * Name used to identify the wallet. + */ + label = ''; + /** + * Unique ID of the wallet. In software wallets it is the name of the file and in hw + * wallets it is the first address in printable format. + */ + id = ''; + /** + * Address list. + */ + addresses: AddressBase[] = []; + /** + * If the wallet is encrypted with a password. Only valid for software wallets. + */ + encrypted = false; + /** + * If it is a software wallet (false) or a hw wallet (true). + */ + isHardware = false; + /** + * If the last time the wallet was checked there were security warning found. Only valid for + * hw wallets. + */ + hasHwSecurityWarnings = false; + /** + * If the user asked the app to stop blocking access to some functions by showing a security + * popup when hasHwSecurityWarnings is true. Only valid for hw wallets. + */ + stopShowingHwSecurityPopup = false; + /** + * Type of the wallet. + */ + walletType: WalletTypes = WalletTypes.Deterministic; + /** + * Name of the coin this wallet belongs to. + */ + coin = ''; +} + +/** + * Special map type, specially created for using an address string as the key. As somme + * addresses may be represented in different ways, with rules like "a" being equial to "A", + * normal maps are not adequate when an address string is going to be used a the key, as + * addresses from different sources may be represented in different ways, making a normal + * map unable to retrieve the desired value. The special class takes care of that, ensuring + * the desired data is retrieved even when using different representations of the same address. + * + * All available functions are equivalents for the same functions found in the Map class. + */ +export class AddressMap { + private baseMap = new Map(); + private addressFormatter: (address: string) => string; + + /** + * Creates an instance of AddressMap. + * @param addressFormatter Function to apply to the addresses the format used by the currently + * selected coin. Found in WalletsAndAddressesService or the appropiate operator. + */ + constructor(addressFormatter: (address: string) => string) { + this.addressFormatter = addressFormatter; + } + + has(key: string): boolean { + return this.baseMap.has(this.addressFormatter(key)); + } + + get(key: string): T { + return this.baseMap.get(this.addressFormatter(key)); + } + + set(key: string, value: T) { + this.baseMap.set(this.addressFormatter(key), value); + } + + forEach(callbackfn: (value: T, key: string, map: Map) => void): void { + this.baseMap.forEach(callbackfn); + } + + delete(key: string): void { + this.baseMap.delete(key); + } + + get size(): number { + return this.baseMap.size; + } +} + +/** + * Properties for AddressBase. It is a separated class to make it easier to perform + * some operations. + */ +class AddressBaseProperties { + // NOTE: All properties must have an initial value or there could be problems creating duplicates. + protected addressFormatterInternal: (address: string) => string = null; + protected printableAddressInternal = ''; + + /** + * If the address has been confirmed by the user on the hw wallet and can be shown on the UI. + * Only valid if the address is in a hw wallet. + */ + confirmed = false; + /** + * If the address is a change address. Only relevant for bip44 wallets. + */ + isChangeAddress ? = false; +} + +/** + * Basic address object with the most important properties. + */ +export class AddressBase extends AddressBaseProperties { + /** + * Creates a new instance of AddressBase. + * @param addressFormatter Function to apply to the addresses the format used by the currently + * selected coin. Found in WalletsAndAddressesService or the appropiate operator. + * @param addressString String with the address. + */ + static create(addressFormatter: (address: string) => string, addressString = ''): AddressBase { + const newInstance = new AddressBase(); + newInstance.addressFormatterInternal = addressFormatter; + newInstance.printableAddressInternal = addressFormatter(addressString); + + return newInstance; + } + + protected constructor() { super(); } + + /** + * Address formater used for creating this instance. + */ + get addressFormatter(): (address: string) => string { return this.addressFormatterInternal; } + + /** + * Address string with optimal format for showing it in the UI. Some addresses can + * only be represented in one way, but others, like ETH addresses and Bech32 addreeses, can be + * represented in different ways. This property returns the address with a consistent format, + * which may be different from the string used for creating the current instance, so it is + * possible to use the value of this property to compare addresses, but as it would be needed + * to make the comparation with another formatted address, which may make the code much more + * difficult to read and maintain, it is recommended to use instead the compareAddress() + * function available in this class or to use the AddressMap class, is a map is needed. + */ + get printableAddress(): string { return this.printableAddressInternal; } + + /** + * Compares an address with the one contained by this instance. + * @param unformattedAddress Address to compare. If the address is of a type which may be + * represented in different ways, this function takes care of processing it, so it is not + * needed to format it before sending it to this function. + */ + compareAddress(unformattedAddress: string): boolean { + return this.addressFormatter(unformattedAddress as string) === this.printableAddress; + } +} + +/** + * Creates a duplicate of a WalletBase object. If the provided wallet has properties which are not + * part of WalletBase, those properties are removed. + * @param wallet Object to duplicate. + * @param duplicateAddresses If the addresses must be duplicated as instancies of AddressBase + * (true) or if the address arrays must be returned empty (false). + */ +export function duplicateWalletBase(wallet: WalletBase, duplicateAddresses: boolean): WalletBase { + const response = new WalletBase(); + Object.assign(response, wallet); + removeAdditionalProperties(true, response); + + response.addresses = []; + if (duplicateAddresses) { + wallet.addresses.forEach(address => { + response.addresses.push(duplicateAddressBase(address)); + }); + } + + return response; +} + +/** + * Creates a duplicate of a AddressBase object. If the provided address has properties which + * are not part of AddressBase, those properties are removed. + * @param address Object to duplicate. + */ +function duplicateAddressBase(address: AddressBase): AddressBase { + const response = AddressBase.create(address.addressFormatter); + Object.assign(response, address); + removeAdditionalProperties(false, response); + + return response; +} + +/** + * Removes from an object all the properties which are not part of WalletBase or AddressBase. + * @param useWalletBaseAsReference If true, only the properties of WalletBase will be keep; if + * false, only the properties of AddressBase will be keep. + * @param objectToClean Object to be cleaned. + */ +function removeAdditionalProperties(useWalletBaseAsReference: boolean, objectToClean: any) { + const knownPropertiesMap = new Map(); + const reference: Object = useWalletBaseAsReference ? new WalletBase() : new AddressBaseProperties(); + Object.keys(reference).forEach(property => { + knownPropertiesMap.set(property, true); + }); + + const propertiesToRemove: string[] = []; + Object.keys(objectToClean).forEach(property => { + if (!knownPropertiesMap.has(property)) { + propertiesToRemove.push(property); + } + }); + + propertiesToRemove.forEach(property => { + delete objectToClean[property]; + }); +} + +// Wallets with balance +//////////////////////////////////////////////// + +/** + * Object with the basic data of a wallet and data about its balance. + */ +export class WalletWithBalance extends WalletBase { + /** + * Balance taking into account all transactions. + */ + coins = new BigNumber(0); + hours = new BigNumber(0); + /** + * Balance taking into account only the confirmed transactions. + */ + confirmedCoins = new BigNumber(0); + confirmedHours = new BigNumber(0); + /** + * Balance taking into account the confirmed transactions, minus all coins sent in + * pending transacions. + */ + availableCoins = new BigNumber(0); + availableHours = new BigNumber(0); + hasPendingCoins = false; + hasPendingHours = false; + addresses: AddressWithBalance[] = []; +} + +/** + * Object with the basic data of an address and data about its balance. + */ +export class AddressWithBalance extends AddressBase { + public constructor() { super(); } + + coins = new BigNumber(0); + hours = new BigNumber(0); + confirmedCoins = new BigNumber(0); + confirmedHours = new BigNumber(0); + availableCoins = new BigNumber(0); + availableHours = new BigNumber(0); + hasPendingCoins = false; + hasPendingHours = false; +} + +/** + * Creates a new WalletWithBalance instance with copies of the values of + * a WalletBase object. + */ +export function walletWithBalanceFromBase(wallet: WalletBase): WalletWithBalance { + const response = new WalletWithBalance(); + Object.assign(response, duplicateWalletBase(wallet, false)); + + wallet.addresses.forEach(address => { + response.addresses.push(addressWithBalanceFromBase(address)); + }); + + return response; +} + +/** + * Creates a new AddressWithBalance instance with copies of the values of + * an AddressBase object. + */ +function addressWithBalanceFromBase(address: AddressBase): AddressWithBalance { + const response = new AddressWithBalance(); + Object.assign(response, duplicateAddressBase(address)); + + return response; +} + +// Wallets with outputs +//////////////////////////////////////////////// + +/** + * Object with the basic data of a wallet and data about its unspent outputs. + */ +export class WalletWithOutputs extends WalletBase { + addresses: AddressWithOutputs[] = []; +} + +/** + * Object with the basic data of an address and data about its unspent outputs. + */ +export class AddressWithOutputs extends AddressBase { + public constructor() { super(); } + + outputs: Output[] = []; +} + +/** + * Creates a new WalletWithOutputs instance with copies of the values of + * a WalletBase object. + */ +export function walletWithOutputsFromBase(wallet: WalletBase): WalletWithOutputs { + const response = new WalletWithOutputs(); + Object.assign(response, duplicateWalletBase(wallet, false)); + + wallet.addresses.forEach(address => { + response.addresses.push(addressWithOutputsFromBase(address)); + }); + + return response; +} + +/** + * Creates a new AddressWithOutputs instance with copies of the values of + * an AddressBase object. + */ +function addressWithOutputsFromBase(address: AddressBase): AddressWithOutputs { + const response = new AddressWithOutputs(); + Object.assign(response, duplicateAddressBase(address)); + + return response; +} diff --git a/src/gui/static/src/app/services/wallet-operations/wallet-utils.service.ts b/src/gui/static/src/app/services/wallet-operations/wallet-utils.service.ts new file mode 100644 index 0000000..314d3fd --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/wallet-utils.service.ts @@ -0,0 +1,72 @@ +import { Observable, of } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; + +import { FiberApiService } from '../api/fiber-api.service'; +import { WalletUtilsOperator } from '../coin-specific/wallet-utils-operator'; +import { OperatorService } from '../operators.service'; +import { environment } from '../../../environments/environment'; + +/** + * Includes help functions for working with the wallets. + */ +@Injectable() +export class WalletUtilsService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: WalletUtilsOperator; + + constructor( + private fiberApiService: FiberApiService, + operatorService: OperatorService, + ) { + // Maintain the operator updated. + operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.walletUtilsOperator; + } else { + this.operator = null; + } + }); + } + + /** + * Gets the path of the folder were the local node saves the data of the software wallets it manages. + */ + folder(): Observable { + return this.fiberApiService.get(environment.nodeUrl, 'wallets/folderName').pipe(map(response => response.address)); + } + + /** + * Checks if a string is a valid address. + * @param address String to check. + * @returns True if the address is valid or false otherwise. + */ + verifyAddress(address: string): Observable { + return this.operator.verifyAddress(address); + } + + /** + * Checks if a string is a valid seed. + * @param address String to check. + * @returns True if the seed is valid or false otherwise. + */ + verifySeed(seed: string): Observable { + return this.fiberApiService.post(environment.nodeUrl, 'wallet/seed/verify', {seed: seed}, {useV2: true}) + .pipe(map(() => true), catchError(() => of(false))); + } + + /** + * Creates a new random seed. + * @param entropy Use 128 for a 12 word seed or 256 for a 24 word seed. + */ + generateSeed(entropy: number): Observable { + if (entropy !== 128 && entropy !== 256) { + throw new Error('Invalid entropy value.'); + } + + return this.fiberApiService.get(environment.nodeUrl, 'wallet/newSeed', { entropy }).pipe(map(response => response.seed)); + } +} diff --git a/src/gui/static/src/app/services/wallet-operations/wallets-and-addresses.service.ts b/src/gui/static/src/app/services/wallet-operations/wallets-and-addresses.service.ts new file mode 100644 index 0000000..7f13ba1 --- /dev/null +++ b/src/gui/static/src/app/services/wallet-operations/wallets-and-addresses.service.ts @@ -0,0 +1,265 @@ +import { Observable, BehaviorSubject, of, Subscription } from 'rxjs'; +import { mergeMap } from 'rxjs/operators'; +import { Injectable, Injector } from '@angular/core'; + +import { WalletBase, AddressBase } from './wallet-objects'; +import { CoinService } from '../coin.service'; +import { FiberWalletsAndAddressesOperator } from '../coin-specific/fiber/fiber-wallets-and-addresses-operator'; +import { WalletsAndAddressesOperator, LastAddress, CreateWalletArgs } from '../coin-specific/wallets-and-addresses-operator'; +import { redirectToErrorPage } from '../../utils/errors'; +import { OperatorService } from '../operators.service'; +import { CoinTypes } from '../../coins/settings/coin-types'; +import { BtcWalletsAndAddressesOperator } from '../coin-specific/btc/btc-wallets-and-addresses-operator'; +import { EthWalletsAndAddressesOperator } from '../coin-specific/eth/eth-wallets-and-addresses-operator'; + +/** + * Manages the list with the wallets and its addresses. It works like a CRUD for the wallet list, + * so it does not contain functions for specific things, like changing the label of a wallet. + */ +@Injectable() +export class WalletsAndAddressesService { + /** + * Instance with the actual code for making most of the operations of this service. It is + * specific for the currently selected coin. + */ + private operator: WalletsAndAddressesOperator; + /** + * Temporal operators used only for loading all the wallets. + */ + private tempOperators: WalletsAndAddressesOperator[]; + + // List with all the wallets of all coins registered in the app. It is used for initializing + // The operators. + private walletsList: WalletBase[]; + // Indicates if the wallets have been loaded. + private walletsAlreadyLoadedSubject: BehaviorSubject = new BehaviorSubject(false); + // If the wallets have already been loaded. + private walletsLoaded = false; + + private loadWalletsSubscription: Subscription; + + constructor( + private coinService: CoinService, + private injector: Injector, + operatorService: OperatorService, + ) { + // Maintain the operator updated. + operatorService.currentOperators.subscribe(operators => { + if (operators) { + this.operator = operators.walletsAndAddressesOperator; + + if (!this.walletsLoaded) { + // Load the wallet list, which is needed for initializing the operator. + this.loadWallets(); + } else { + // Initialize the operator. + this.operator.initialize(this.walletsList); + } + } else { + this.operator = null; + } + }); + } + + /** + * Allows to know if the wallets have been loaded. + */ + get walletsAlreadyLoaded(): Observable { + return this.walletsAlreadyLoadedSubject.asObservable(); + } + + /** + * Gets the complete wallet list. It emits every time the wallet list is updated. Please note + * that if any value of the returned wallets is modified, the changes must be notified by + * calling the informValuesUpdated function or the behavior will be indeterminate. + */ + get allWallets(): Observable { + return this.operator.allWallets; + } + + /** + * Gets the list of the wallets for the currently selected coin. It emits every time the + * wallet list is updated. Please note that if any value of the returned wallets is modified, + * the changes must be notified by calling the informValuesUpdated function or the behavior + * will be indeterminate. + */ + get currentWallets(): Observable { + return this.operator.currentWallets; + } + + /** + * Adds one or more addresses to a wallet. + * @param wallet Wallet to which the addresses will be added. + * @param num Number of addresses to create. + * @param password Wallet password, if the wallet is encrypted. + * @returns An array with the newly created addresses. + */ + addAddressesToWallet(wallet: WalletBase, num: number, password?: string): Observable { + return this.operator.addAddressesToWallet(wallet, num, password); + } + + /** + * Scans the addreses of a wallet, to find if there is an addreeses with transactions which is + * not on the addresses list. If that happens, the last address with at least one transaction + * and all the addresses that precede it in the deterministic generation order are added to + * the wallet. + * @param wallet Wallet to scan. + * @param password Wallet password, if the wallet is encrypted. + * @returns true if new addresses were added to the wallet, false otherwise. + */ + scanAddresses(wallet: WalletBase, password?: string): Observable { + return this.operator.scanAddresses(wallet, password); + } + + /** + * Gets the next external address (change addresses are ignored) of a wallet. + * If the last address of the wallet has already been used, a new address is automatically + * created. It also updates the wallet on the wallet list with all the unknown new addresses it + * may have on the node (if apply) and requests a balance update. It does not work with + * deterministic wallets. + * @param wallet Wallet to check. + * @param password Passowrd of the wallet. + * @returns The next address of the wallet. If the wallet is encrypted, a new address must be + * created and the password was not provided, null is returned. + */ + getNextAddressAndUpdateWallet(wallet: WalletBase, password?: string): Observable { + return this.operator.getNextAddressAndUpdateWallet(wallet, password); + } + + /** + * Gets the last external address (change addresses are ignored) of a wallet. + * It also updates the wallet on the wallet list with all the unknown new addresses it may have + * on the node (if apply) and requests a balance update. + * @param wallet Wallet to check. + * @param checkUnused if false, the response will only include the address string, the usage + * info will not be included. + */ + getLastAddressAndUpdateWallet(wallet: WalletBase, checkUnused: boolean): Observable { + return this.operator.getLastAddressAndUpdateWallet(wallet, checkUnused); + } + + /** + * Updates a wallet on the wallet list with all the unknown new addresses it may have + * on the node (if apply) and requests a balance update. A wallet may have additional + * addresses on the node for multiple reasons, like the node adding them automatically as + * expected with bip44 wallets and if the wallet was changed externally. + * @param wallet Wallet to update. + */ + updateWallet(wallet: WalletBase): Observable { + return this.operator.updateWallet(wallet); + } + + /** + * This function must be called when any value of a wallet is changed, to ensure the wallet + * list is updated and to inform all the subscribers of the wallet list that there was a change. + * @param wallet Object with all the properties of the wallet. Its ID must coincide with the + * ID of one of the wallets of the wallet list or nothing will happen. Note that this object + * is not directly saved on the wallet list, so you must always call this function after + * making changes to a wallet. + */ + informValuesUpdated(wallet: WalletBase) { + this.operator.informValuesUpdated(wallet); + } + + /** + * Creates a new wallet. If creating a software wallet, the requiered params must be provided. + * If creating a hardware wallet, it will be created with the data of the currently + * connected device. + * @param args Data for creating the wallet. + * @returns The newly creatd wallet. + */ + createWallet(args: CreateWalletArgs): Observable { + return this.operator.createWallet(args); + } + + /** + * Removes a wallet from the wallet list, if possible. + * @param walletId Id of the wallet to be removed. If the ID is not on the wallet list or + * is not for a hw wallet, nothing happens. + */ + deleteWallet(walletId: string) { + return this.operator.deleteWallet(walletId); + } + + /** + * Gets the saved wallets data and populates de wallet list with it. + */ + private loadWallets(): void { + // Cancel any previous operation. It is a precaution only for potential errors in case + // the coin is changed before the list is obtained. + if (this.loadWalletsSubscription) { + this.loadWalletsSubscription.unsubscribe(); + + this.tempOperators.forEach(val => { + val.dispose(); + }); + } + + // Create one temporal operator for each coin. + this.tempOperators = []; + this.coinService.coins.forEach(coin => { + if (coin.coinType === CoinTypes.Fiber) { + this.tempOperators.push(new FiberWalletsAndAddressesOperator(this.injector, coin)); + } else if (coin.coinType === CoinTypes.BTC) { + this.tempOperators.push(new BtcWalletsAndAddressesOperator(this.injector, coin)); + } else if (coin.coinType === CoinTypes.ETH) { + this.tempOperators.push(new EthWalletsAndAddressesOperator(this.injector, coin)); + } + }); + + // Load the wallets of every coin. + this.loadWalletsSubscription = this.loadWalletsRecursively([], this.tempOperators).subscribe((wallets: WalletBase[]) => { + this.walletsList = wallets; + + this.tempOperators.forEach(val => { + val.dispose(); + }); + + // Initialize the current operator. + this.operator.initialize(this.walletsList); + + this.walletsLoaded = true; + + this.walletsAlreadyLoadedSubject.next(true); + }, () => { + // The error page will show error number 2. + redirectToErrorPage(2); + }); + } + + /** + * Recursively loads the wallets of different coins. + * @param currentWallets Array with the wallets that have already been loaded. Should be empty + * when calling this function externally. + * @param operators Array with operators for every coin. The operators will be used for loading + * the wallets. After finishing using one, it will be cleaned and removed from the array. + * @returns An array with all the loaded wallets. + */ + private loadWalletsRecursively(currentWallets: WalletBase[], operators: WalletsAndAddressesOperator[]): Observable { + return operators[operators.length - 1].loadWallets().pipe(mergeMap((wallets: WalletBase[]) => { + currentWallets = wallets.concat(currentWallets); + + // Clean and remove the operator. + operators.pop().dispose(); + + if (operators.length > 0) { + return this.loadWalletsRecursively(currentWallets, operators); + } else { + return of(currentWallets); + } + })); + } + + /** + * Takes an address string and applies to it the correct format for the currently + * selected coin. Some addresses can only be represented in one way, but others, + * like ETH addresses and Bech32 addreeses, can be represented in different + * ways, so this function makes all those addresses have a consistent format, so it + * is posible to show then in an optimal way or compare them in a safe way. However, + * if possible, try not to use this function for comparing addresses, but instead use the + * comparison function of AddressBase or the AddressMap object. + */ + get formatAddress(): (address: string) => string { + return this.operator.formatAddress; + } +} diff --git a/src/gui/static/src/app/services/wizard-guard.service.ts b/src/gui/static/src/app/services/wizard-guard.service.ts new file mode 100644 index 0000000..96d3b02 --- /dev/null +++ b/src/gui/static/src/app/services/wizard-guard.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; +import { first, filter } from 'rxjs/operators'; + +import { WalletsAndAddressesService } from './wallet-operations/wallets-and-addresses.service'; + +/** + * Forces the app to always redirect the user to the wizard if there are no + * registered wallets. + */ +@Injectable() +export class WizardGuardService implements CanActivate { + constructor( + private walletsAndAddressesService: WalletsAndAddressesService, + private router: Router, + ) { } + + /** + * Function called by the system to know if it is possible to navigate to a page. + */ + canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise { + return new Promise(resolve => { + // Check if the wallets have been loaded. + this.walletsAndAddressesService.walletsAlreadyLoaded.pipe(filter(val => val), first()).subscribe(() => { + // Go to the wizard if there are no wallets. + this.walletsAndAddressesService.allWallets.pipe(first()).subscribe(wallets => { + if (wallets.length === 0) { + this.router.navigate(['/wizard']); + + return resolve(false); + } + + return resolve(true); + }); + }); + }); + } +} diff --git a/src/gui/static/src/app/utils/errors.spec.ts b/src/gui/static/src/app/utils/errors.spec.ts new file mode 100644 index 0000000..758ab01 --- /dev/null +++ b/src/gui/static/src/app/utils/errors.spec.ts @@ -0,0 +1,16 @@ +import { processErrorMsg } from './errors'; + +describe('errors', () => { + const message1 = '400 Bad Request - error description.'; + const message2 = '403 Forbidden - error description.'; + const message3 = '500 Internal Server Error - error description.'; + + it('parses message from 400 and 403 responses', () => { + expect(processErrorMsg(message1)).toEqual('Error description.'); + expect(processErrorMsg(message2)).toEqual('Error description.'); + }); + + it('does not parse message from other responses', () => { + expect(processErrorMsg(message3)).toEqual(message3); + }); +}); diff --git a/src/gui/static/src/app/utils/errors.ts b/src/gui/static/src/app/utils/errors.ts new file mode 100644 index 0000000..519ef78 --- /dev/null +++ b/src/gui/static/src/app/utils/errors.ts @@ -0,0 +1,200 @@ +/** + * This file contains functions for processing the errors and make it easier to work with them. + */ +import { HttpErrorResponse } from '@angular/common/http'; + +import { OperationError, OperationErrorTypes } from './operation-error'; + +/** + * Prepares an error msg to be displayed on the UI. + */ +export function processErrorMsg(msg: string): string { + if (!msg || msg.length === 0) { + return msg; + } + + // Check if the string is from a known error. If it is, use the correct error string. + const knownErrorMsg = checkIfKnownErrorStrings(msg); + if (knownErrorMsg) { + return knownErrorMsg; + } + + // Some times an error message could be in fact a JSON string. In those cases, the real + // error msg is inside the "error.message" property. + if (msg.indexOf('"error":') !== -1) { + try { + msg = JSON.parse(msg).error.message; + } catch (e) { } + } + + // Remove unnecessary error codes. + if (msg.startsWith('400') || msg.startsWith('403')) { + const parts = msg.split(' - ', 2); + + msg = parts.length === 2 ? parts[1] : msg; + } + + // The msg will start with an uppercase letter and end with a period. + msg = msg.trim(); + const firstLetter = msg.substr(0, 1); + if (firstLetter.toUpperCase() !== firstLetter) { + msg = firstLetter.toUpperCase() + msg.substr(1, msg.length - 1); + } + if (!msg.endsWith('.') && !msg.endsWith(',') && !msg.endsWith(':') && !msg.endsWith(';') && !msg.endsWith('?') && !msg.endsWith('!')) { + msg = msg + '.'; + } + + return msg; +} + +/** + * Process an error and creates an OperationError instance from it. It can successfully + * process various types of errors (connection errors, operation errors and more), strings + * and even OperationError intances, so it is relatively safe to use this function to + * process almost all errors before using them, even the ones returned by services which + * normally return OperationError instances in case of error, just to be sure to have a standard + * OperationError object to work with. + * @param error Error to process. + */ +export function processServiceError(error: any): OperationError { + // Check if the provided error is already an OperationError instance. + if (error.type) { + return error; + } + + const response = new OperationError(); + response.originalError = error; + + // Check if the provided error is empty or a string. + if (!error || typeof error === 'string') { + response.originalServerErrorMsg = error ? error : ''; + response.translatableErrorMsg = error ? error : 'service.api.unknown-error'; + response.type = OperationErrorTypes.Unknown; + + return response; + } + + // Extract the error msg from the provided error param. + response.originalServerErrorMsg = getErrorMsg(error); + + // Check if the provided error is a known API error. + const convertedError = error as HttpErrorResponse; + if (convertedError.status !== null && convertedError.status !== undefined) { + if (convertedError.status === 0 || convertedError.status === 504) { + response.type = OperationErrorTypes.NoInternet; + response.translatableErrorMsg = 'service.api.no-internet-error'; + } else if (convertedError.status === 0 || convertedError.status === 403) { + response.type = OperationErrorTypes.ApiDisabled; + response.translatableErrorMsg = 'service.api.api-disabled-error'; + } else if (convertedError.status === 400 && response.originalServerErrorMsg.toUpperCase().indexOf('Invalid password'.toUpperCase()) !== -1) { + response.type = OperationErrorTypes.Unauthorized; + response.translatableErrorMsg = 'service.api.incorrect-password-error'; + } + } + + // Use defaults and process the error msg if needed. + if (!response.type) { + response.type = OperationErrorTypes.Unknown; + if (response.originalServerErrorMsg) { + response.translatableErrorMsg = processErrorMsg(response.originalServerErrorMsg); + } else { + response.translatableErrorMsg = 'service.api.unknown-error'; + } + } + + return response; +} + +/** + * Tries to get the error msg of an error object. + * @param error Error to process. + * @returns The error msg, or null, if it was not possible to retrieve the error msg. + */ +export function getErrorMsg(error: any): string { + if (error) { + // Check different posibilities, testing a normal error object and different + // known ubications in which the error msg could be located. + if (typeof error['_body'] === 'string') { + return error['_body']; + } else if (error.originalServerErrorMsg && typeof error.originalServerErrorMsg === 'string') { + return error.originalServerErrorMsg; + } else if (error.error && typeof error.error === 'string') { + return error.error; + } else if (error.error && error.error.error && error.error.error.message) { + return error.error.error.message; + } else if (error.error && error.error.error && typeof error.error.error === 'string') { + return error.error.error; + } else if (error.message) { + return error.message; + } else if (error._body && error._body.error) { + return error._body.error; + } else { + try { + const errorContent = JSON.parse(error._body).error; + + return errorContent; + } catch (e) {} + } + } + + return null; +} + +/** + * Makes the browser navigate to the error page. + * @param errorCode Error code the error page must show. Consult the code of the error page to + * for more info about the codes. + */ +export function redirectToErrorPage(errorCode: number) { + window.location.assign('assets/error-alert/index.html?' + errorCode); +} + +/** + * Checks if a string contains a known error msg. + * @param errorString String to check. + * @returns If the string is known, the translatable var for showing the error in the UI. If + * not, null is returned. + */ +function checkIfKnownErrorStrings(errorString: string): string { + errorString = errorString.toUpperCase(); + + let translatableVar: string = null; + + if (errorString.includes('CHANGEADDRESS MUST NOT BE THE NULL ADDRESS')) { + translatableVar = 'null-change-address-error'; + } else if (errorString.includes('TO IS REQUIRED')) { + translatableVar = 'to-required-error'; + } else if (errorString.includes('TO.COINS MUST NOT BE ZERO')) { + translatableVar = 'zero-coins-error'; + } else if (errorString.includes('TO.ADDRESS MUST NOT BE THE NULL ADDRESS')) { + translatableVar = 'null-destination-error'; + } else if (errorString.includes('TO CONTAINS DUPLICATE VALUES')) { + translatableVar = 'duplicate-destination-error'; + } else if (errorString.includes('TO.HOURS MUST BE ZERO FOR AUTO TYPE HOURS SELECTION')) { + translatableVar = 'hours-in-automatic-mode-error'; + } else if (errorString.includes('HOURSSELECTION.MODE IS REQUIRED FOR AUTO TYPE HOURS SELECTION')) { + translatableVar = 'hours-allocation-mode-needed-error'; + } else if (errorString.includes('INVALID HOURSSELECTION.MODE')) { + translatableVar = 'invalid-hours-allocation-mode-error'; + } else if (errorString.includes('HOURSSELECTION.MODE CANNOT BE USED FOR MANUAL TYPE HOURS SELECTION')) { + translatableVar = 'hours-allocation-mode-not-needed-error'; + } else if (errorString.includes('INVALID HOURSSELECTION.TYPE')) { + translatableVar = 'invalid-hours-mode-error'; + } else if (errorString.includes('HOURSSELECTION.SHAREFACTOR MUST BE SET FOR SHARE MODE')) { + translatableVar = 'share-factor-needed-error'; + } else if (errorString.includes('HOURSSELECTION.SHAREFACTOR CAN ONLY BE USED FOR SHARE MODE')) { + translatableVar = 'share-factor-not-needed-error'; + } else if (errorString.includes('HOURSSELECTION.SHAREFACTOR MUST BE >= 0 AND <= 1')) { + translatableVar = 'invalid-share-factor-error'; + } else if (errorString.includes('TRANSACTION VIOLATES HARD CONSTRAINT: DUPLICATE OUTPUT IN TRANSACTION')) { + translatableVar = 'change-equal-to-destination-error'; + } else if (errorString.includes('FINGERPRINT CONFLICT FOR')) { + translatableVar = 'repeated-wallet'; + } + + if (translatableVar) { + return 'send.known-node-errors.' + translatableVar; + } + + return null; +} diff --git a/src/gui/static/src/app/utils/general-utils.spec.ts b/src/gui/static/src/app/utils/general-utils.spec.ts new file mode 100644 index 0000000..eb340c0 --- /dev/null +++ b/src/gui/static/src/app/utils/general-utils.spec.ts @@ -0,0 +1,17 @@ +import { shouldUpgradeVersion } from './general-utils'; + +describe('semver', () => { + it('correctly compares versions', () => { + expect(shouldUpgradeVersion('0.23.0', '0.22.0')).toBeFalsy(); + expect(shouldUpgradeVersion('0.23.0', '0.23.0')).toBeFalsy(); + expect(shouldUpgradeVersion('0.23.0', '0.23.1')).toBeTruthy(); + expect(shouldUpgradeVersion('0.23.1', '0.24.0')).toBeTruthy(); + expect(shouldUpgradeVersion('0.24.0', '1.0.0')).toBeTruthy(); + }); + + it('correctly handles rc versions', () => { + expect(shouldUpgradeVersion('0.23.1-rc.1', '0.23.0')).toBeFalsy(); + expect(shouldUpgradeVersion('0.23.1-rc.1', '0.23.1')).toBeTruthy(); + expect(shouldUpgradeVersion('0.23.1-rc.1', '0.23.2')).toBeTruthy(); + }); +}); diff --git a/src/gui/static/src/app/utils/general-utils.ts b/src/gui/static/src/app/utils/general-utils.ts new file mode 100644 index 0000000..d6ef3ae --- /dev/null +++ b/src/gui/static/src/app/utils/general-utils.ts @@ -0,0 +1,56 @@ +/** + * This file contains general helper functions. + */ + +/** + * Indicates if an update is needed by comparing two version numbers. + * @param from Current version number. Must be a 3 parts number using the SemVer format. + * Each part must contain numbers only, but the last part may end with '-rc', in which + * case this version will be considered older than the one on the 'to' param if both + * versions differ only by the '-rc' part. + * @param to Number of the lastest version. Must be a 3 parts number using the SemVer format. + * Each part must contain numbers only. + * @returns true if 'from' is smaller than 'to'. + */ +export function shouldUpgradeVersion(from: string, to: string): boolean { + const toParts = to.split('.'); + const fromSplit = from.split('-'); + const fromParts = fromSplit[0].split('.'); + + for (let i = 0; i < 3; i++) { + const toNumber = Number(toParts[i]); + const fromNumber = Number(fromParts[i]); + + if (toNumber > fromNumber) { + return true; + } + + if (toNumber < fromNumber) { + return false; + } + } + + return fromSplit.length === 2 && fromSplit[1].indexOf('rc') !== -1; +} + +/** + * Copies a text to the clipboard. + * @param text Text to be copied. + */ +export function copyTextToClipboard(text: string) { + const selBox = document.createElement('textarea'); + + selBox.style.position = 'fixed'; + selBox.style.left = '0'; + selBox.style.top = '0'; + selBox.style.opacity = '0'; + selBox.value = text; + + document.body.appendChild(selBox); + selBox.focus(); + selBox.select(); + + document.execCommand('copy'); + document.body.removeChild(selBox); +} + diff --git a/src/gui/static/src/app/utils/history-utils.ts b/src/gui/static/src/app/utils/history-utils.ts new file mode 100644 index 0000000..f8ebc12 --- /dev/null +++ b/src/gui/static/src/app/utils/history-utils.ts @@ -0,0 +1,181 @@ +import { WalletBase, AddressMap } from '../services/wallet-operations/wallet-objects'; +import { OldTransaction, OldTransactionTypes } from '../services/wallet-operations/transaction-objects'; +import { WalletsAndAddressesOperator } from '../services/coin-specific/wallets-and-addresses-operator'; + +/** + * Takes an OldTransaction object and calculates the transaction type, the balance and the + * involved local wallets and addresses. The values are added to the provided + * OldTransaction instance. + * @param transaction Transaction to work with. + * @param addressMap Map with all the local addresses, pointing to their wallets. + * @param calculateHours If the hours balance must be calculated. + */ +export function calculateGeneralData(transaction: OldTransaction, addressMap: AddressMap, calculateHours: boolean, walletsAndAddressesOperator: WalletsAndAddressesOperator): void { + const involvedWallets = new Map(); + + // Check the inputs related to local wallets and if there are multiple local wallets involved + // with the inputs. + let ownsInputs = false; + let ownsAllInputs = true; + let firstLocalInputWallet: string; + let thereAreOtherLocalInputWallets = false; + transaction.inputs.map(input => { + if (addressMap.has(input.address)) { + ownsInputs = true; + involvedWallets.set(addressMap.get(input.address).label, true); + if (!firstLocalInputWallet) { + firstLocalInputWallet = addressMap.get(input.address).id; + } else if (addressMap.get(input.address).id !== firstLocalInputWallet) { + thereAreOtherLocalInputWallets = true; + } + } else { + ownsAllInputs = false; + } + }); + + // Check the outputs related to local wallets and if there are multiple local wallets involved + // with the outputs. + let ownsOutputs = false; + let ownsAllOutputs = true; + let firstLocalOutputWallet: string; + let thereAreOtherLocalOutputWallets = false; + transaction.outputs.map(output => { + if (addressMap.has(output.address)) { + ownsOutputs = true; + involvedWallets.set(addressMap.get(output.address).label, true); + if (!firstLocalOutputWallet) { + firstLocalOutputWallet = addressMap.get(output.address).id; + } else if (addressMap.get(output.address).id !== firstLocalOutputWallet) { + thereAreOtherLocalOutputWallets = true; + } + } else { + ownsAllOutputs = false; + } + }); + + // Set the transaction type. + transaction.type = OldTransactionTypes.MixedOrUnknown; + if (ownsInputs && !ownsOutputs) { + transaction.type = OldTransactionTypes.Outgoing; + } else if (!ownsInputs && ownsOutputs) { + transaction.type = OldTransactionTypes.Incoming; + } else if (ownsAllInputs && ownsAllOutputs) { + if (!thereAreOtherLocalInputWallets && !thereAreOtherLocalOutputWallets && firstLocalInputWallet === firstLocalOutputWallet) { + transaction.type = OldTransactionTypes.MovedBetweenAddresses; + } else if (!thereAreOtherLocalInputWallets) { + transaction.type = OldTransactionTypes.MovedBetweenWallets; + } + } else if (ownsInputs && ownsOutputs && !ownsAllOutputs) { + if (!thereAreOtherLocalInputWallets && !thereAreOtherLocalOutputWallets && firstLocalInputWallet === firstLocalOutputWallet) { + transaction.type = OldTransactionTypes.Outgoing; + } + } + + // Get the names of the involved local wallets. + transaction.involvedLocalWallets = ''; + involvedWallets.forEach((value, key) => { + transaction.involvedLocalWallets = transaction.involvedLocalWallets + key + ', '; + }); + + transaction.involvedLocalWallets = transaction.involvedLocalWallets.substr(0, transaction.involvedLocalWallets.length - 2); + transaction.numberOfInvolvedLocalWallets = involvedWallets.size; + + // Saves the list of relevant local addresses involved in the transaction. + const involvedLocalAddresses = new Map(); + + // Calculate the balance and involved addresses depending on the transaction type. + if (transaction.type === OldTransactionTypes.Incoming) { + transaction.outputs.map(output => { + // If the transactions is an incoming one, all coins and hours on outputs + // pointing to local addresses are considered received. + if (addressMap.has(output.address)) { + involvedLocalAddresses.set(output.address, true); + transaction.balance = transaction.balance.plus(output.coins); + if (calculateHours) { + transaction.hoursBalance = transaction.hoursBalance.plus(output.hours); + } + } + }); + } else if (transaction.type === OldTransactionTypes.Outgoing) { + // If the transaction is an outgoing one, all addresses of all wallets used for inputs + // are considered potential return addresses, so all coins sent to those addresses + // will be excluded when counting how many coins and hours were sent. + const possibleReturnAddressesMap = new AddressMap(walletsAndAddressesOperator.formatAddress); + transaction.inputs.map(input => { + if (addressMap.has(input.address)) { + involvedLocalAddresses.set(input.address, true); + addressMap.get(input.address).addresses + .map(add => possibleReturnAddressesMap.set(add.printableAddress, true)); + } + }); + + // Sum all coins and hours that were sent. + transaction.outputs.map(output => { + if (!possibleReturnAddressesMap.has(output.address)) { + transaction.balance = transaction.balance.minus(output.coins); + if (calculateHours) { + transaction.hoursBalance = transaction.hoursBalance.plus(output.hours); + } + } + }); + } else if ( + transaction.type === OldTransactionTypes.MovedBetweenAddresses || + transaction.type === OldTransactionTypes.MovedBetweenWallets + ) { + const inputAddressesMap = new AddressMap(walletsAndAddressesOperator.formatAddress); + + transaction.inputs.map(input => { + inputAddressesMap.set(input.address, true); + involvedLocalAddresses.set(input.address, true); + }); + + // Sum how many coins and hours were moved to addresses different to the ones which + // own the inputs. + transaction.outputs.map(output => { + if (!inputAddressesMap.has(output.address)) { + involvedLocalAddresses.set(output.address, true); + transaction.balance = transaction.balance.plus(output.coins); + if (calculateHours) { + transaction.hoursBalance = transaction.hoursBalance.plus(output.hours); + } + } + }); + } else { + // If the transaction type is unknown, all local addresses are considered relevant + // and no balance data is calculated. + transaction.inputs.map(input => { + if (addressMap.has(input.address)) { + involvedLocalAddresses.set(input.address, true); + } + }); + transaction.outputs.map(output => { + if (addressMap.has(output.address)) { + involvedLocalAddresses.set(output.address, true); + } + }); + } + + // Create the list of relevant local addresses involved on the transaction. + involvedLocalAddresses.forEach((value, key) => { + transaction.relevantAddresses.push(walletsAndAddressesOperator.formatAddress(key)); + }); +} + +/** + * Gets the name of the bitmap that should be used as the icon for a transaction. The returned + * string contains only the base name, without the color part or the file extension. + * @param transaction Transaction to check. + */ +export function getTransactionIconName(transaction: OldTransaction): string { + if (transaction.type === OldTransactionTypes.Incoming) { + return 'received'; + } else if (transaction.type === OldTransactionTypes.Outgoing) { + return 'sent'; + } else if (transaction.type === OldTransactionTypes.MovedBetweenAddresses) { + return 'internal'; + } else if (transaction.type === OldTransactionTypes.MovedBetweenWallets) { + return 'internal'; + } + + return 'unknown'; +} diff --git a/src/gui/static/src/app/utils/hw-test-addresses.ts b/src/gui/static/src/app/utils/hw-test-addresses.ts new file mode 100644 index 0000000..fb3d591 --- /dev/null +++ b/src/gui/static/src/app/utils/hw-test-addresses.ts @@ -0,0 +1,13 @@ +/** + * Returns a map with known mainnet addresses (as keys) and the corresponding testnet + * equivalents (as values). This is for being able to work with testnet and regtest + * nodes when it is only possible to get mainnet addresses. + */ +export function getTestAddressesMap(): Map { + const response = new Map(); + + // Populate the map here. You must calculate the tesnet equivalents before doing this. + // Please do not include the changes in the repo. + + return response; +} diff --git a/src/gui/static/src/app/utils/operation-error.ts b/src/gui/static/src/app/utils/operation-error.ts new file mode 100644 index 0000000..8f8a02c --- /dev/null +++ b/src/gui/static/src/app/utils/operation-error.ts @@ -0,0 +1,123 @@ +/** + * This file contains the basic class and values for easily working with errors on the app. + */ + +/** + * Possible values of OperationError.type for identifying errors during general operations. + */ +export enum OperationErrorTypes { + /** + * There is no internet connection. + */ + NoInternet = 'NoInternet', + /** + * The user is not authorized. Normally means that the password is incorrect. + */ + Unauthorized = 'Unauthorized', + /** + * The needed API endpoint is disabled. + */ + ApiDisabled = 'ApiDisabled', + /** + * The error is not in the list of known errors that require special treatment. This does not + * mean the error is rare or specially bad. Just showing the error msg should be enough. + */ + Unknown = 'Unknown', +} + +/** + * Possible results of a hw wallet operation. + */ +export enum HWOperationResults { + /** + * The operation was completed successfuly. + */ + Success = 'Success', + /** + * The user canceled the operation. Due to how the hw wallet daemon works, it may also mean + * that there was an unexpected error, but only on rare cases. + */ + FailedOrRefused = 'FailedOrRefused', + /** + * The user entered a different PIN when asked to repeat the new PIN to confirm it. + */ + PinMismatch = 'PinMismatch', + /** + * The device does not have a seed. + */ + WithoutSeed = 'WithoutSeed', + /** + * The user entered a wrong PIN. + */ + WrongPin = 'WrongPin', + /** + * The currently connected device is not the one needed for completing the operation. + */ + IncorrectHardwareWallet = 'IncorrectHardwareWallet', + /** + * The user entered a word which does not match the one requested by the device. + */ + WrongWord = 'WrongWord', + /** + * The seed entered by the user is not a valid BIP39 seed. + */ + InvalidSeed = 'InvalidSeed', + /** + * The seed entered by the user is different from the one on the device. + */ + WrongSeed = 'WrongSeed', + /** + * Unknown or unexpected error. + */ + UndefinedError = 'UndefinedError', + /** + * There is no device connected. + */ + Disconnected = 'Disconnected', + /** + * It was not possible to connect with the hw daemon. + */ + DaemonConnectionError = 'DaemonConnectionError', + /** + * The current version of the daemon is not capable of performing the operation. + */ + DaemonOutdated = 'DaemonOutdated', + /** + * An invalid address was sent to the device. + */ + InvalidAddress = 'InvalidAddress', + /** + * The operation was automatically cancelled due to inactivity. + */ + Timeout = 'Timeout', + /** + * The device must be in bootloader mode for completing the operation and it is not. + */ + NotInBootloaderMode = 'NotInBootloaderMode', + /** + * The device generated an invalid address. + */ + AddressGeneratorProblem = 'AddressGeneratorProblem', +} + +/** + * Base object for working with errors throughout the application. + */ +export class OperationError { + /** + * Specific error type. Allows to know the cause of the error. + */ + type: OperationErrorTypes | HWOperationResults; + /** + * Original error object from which this OperationError instance was created. + */ + originalError: any; + /** + * Original, unprocessed, error msg. + */ + originalServerErrorMsg: string; + /** + * Processed error msg, which can be passed to the 'translate' pipe to display it on the UI. + */ + translatableErrorMsg: string; +} diff --git a/src/gui/static/src/app/utils/semver.ts b/src/gui/static/src/app/utils/semver.ts new file mode 100644 index 0000000..77bbc40 --- /dev/null +++ b/src/gui/static/src/app/utils/semver.ts @@ -0,0 +1,26 @@ +/** + * Return true if current is equal or superior to target. Versions must be composed of 3 + * parts, separated by points. + */ +export function isEqualOrSuperiorVersion(current: string, target: string): boolean { + const currentParts = current.split('.'); + if (currentParts.length !== 3) { return false; } + + const targetParts = target.split('.'); + if (targetParts.length !== 3) { return false; } + + for (let i = 0; i < 3; i++) { + const currentNumber = Number(currentParts[i]); + const targetNumber = Number(targetParts[i]); + + if (currentNumber > targetNumber) { + return true; + } + + if (currentNumber < targetNumber) { + return false; + } + } + + return true; +} diff --git a/src/gui/static/src/assets/.gitkeep b/src/gui/static/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/static/src/assets/bip39-word-list.json b/src/gui/static/src/assets/bip39-word-list.json new file mode 100644 index 0000000..c495654 --- /dev/null +++ b/src/gui/static/src/assets/bip39-word-list.json @@ -0,0 +1,2049 @@ +{ "list": ["abandon", +"ability", +"able", +"about", +"above", +"absent", +"absorb", +"abstract", +"absurd", +"abuse", +"access", +"accident", +"account", +"accuse", +"achieve", +"acid", +"acoustic", +"acquire", +"across", +"act", +"action", +"actor", +"actress", +"actual", +"adapt", +"add", +"addict", +"address", +"adjust", +"admit", +"adult", +"advance", +"advice", +"aerobic", +"affair", +"afford", +"afraid", +"again", +"age", +"agent", +"agree", +"ahead", +"aim", +"air", +"airport", +"aisle", +"alarm", +"album", +"alcohol", +"alert", +"alien", +"all", +"alley", +"allow", +"almost", +"alone", +"alpha", +"already", +"also", +"alter", +"always", +"amateur", +"amazing", +"among", +"amount", +"amused", +"analyst", +"anchor", +"ancient", +"anger", +"angle", +"angry", +"animal", +"ankle", +"announce", +"annual", +"another", +"answer", +"antenna", +"antique", +"anxiety", +"any", +"apart", +"apology", +"appear", +"apple", +"approve", +"april", +"arch", +"arctic", +"area", +"arena", +"argue", +"arm", +"armed", +"armor", +"army", +"around", +"arrange", +"arrest", +"arrive", +"arrow", +"art", +"artefact", +"artist", +"artwork", +"ask", +"aspect", +"assault", +"asset", +"assist", +"assume", +"asthma", +"athlete", +"atom", +"attack", +"attend", +"attitude", +"attract", +"auction", +"audit", +"august", +"aunt", +"author", +"auto", +"autumn", +"average", +"avocado", +"avoid", +"awake", +"aware", +"away", +"awesome", +"awful", +"awkward", +"axis", +"baby", +"bachelor", +"bacon", +"badge", +"bag", +"balance", +"balcony", +"ball", +"bamboo", +"banana", +"banner", +"bar", +"barely", +"bargain", +"barrel", +"base", +"basic", +"basket", +"battle", +"beach", +"bean", +"beauty", +"because", +"become", +"beef", +"before", +"begin", +"behave", +"behind", +"believe", +"below", +"belt", +"bench", +"benefit", +"best", +"betray", +"better", +"between", +"beyond", +"bicycle", +"bid", +"bike", +"bind", +"biology", +"bird", +"birth", +"bitter", +"black", +"blade", +"blame", +"blanket", +"blast", +"bleak", +"bless", +"blind", +"blood", +"blossom", +"blouse", +"blue", +"blur", +"blush", +"board", +"boat", +"body", +"boil", +"bomb", +"bone", +"bonus", +"book", +"boost", +"border", +"boring", +"borrow", +"boss", +"bottom", +"bounce", +"box", +"boy", +"bracket", +"brain", +"brand", +"brass", +"brave", +"bread", +"breeze", +"brick", +"bridge", +"brief", +"bright", +"bring", +"brisk", +"broccoli", +"broken", +"bronze", +"broom", +"brother", +"brown", +"brush", +"bubble", +"buddy", +"budget", +"buffalo", +"build", +"bulb", +"bulk", +"bullet", +"bundle", +"bunker", +"burden", +"burger", +"burst", +"bus", +"business", +"busy", +"butter", +"buyer", +"buzz", +"cabbage", +"cabin", +"cable", +"cactus", +"cage", +"cake", +"call", +"calm", +"camera", +"camp", +"can", +"canal", +"cancel", +"candy", +"cannon", +"canoe", +"canvas", +"canyon", +"capable", +"capital", +"captain", +"car", +"carbon", +"card", +"cargo", +"carpet", +"carry", +"cart", +"case", +"cash", +"casino", +"castle", +"casual", +"cat", +"catalog", +"catch", +"category", +"cattle", +"caught", +"cause", +"caution", +"cave", +"ceiling", +"celery", +"cement", +"census", +"century", +"cereal", +"certain", +"chair", +"chalk", +"champion", +"change", +"chaos", +"chapter", +"charge", +"chase", +"chat", +"cheap", +"check", +"cheese", +"chef", +"cherry", +"chest", +"chicken", +"chief", +"child", +"chimney", +"choice", +"choose", +"chronic", +"chuckle", +"chunk", +"churn", +"cigar", +"cinnamon", +"circle", +"citizen", +"city", +"civil", +"claim", +"clap", +"clarify", +"claw", +"clay", +"clean", +"clerk", +"clever", +"click", +"client", +"cliff", +"climb", +"clinic", +"clip", +"clock", +"clog", +"close", +"cloth", +"cloud", +"clown", +"club", +"clump", +"cluster", +"clutch", +"coach", +"coast", +"coconut", +"code", +"coffee", +"coil", +"coin", +"collect", +"color", +"column", +"combine", +"come", +"comfort", +"comic", +"common", +"company", +"concert", +"conduct", +"confirm", +"congress", +"connect", +"consider", +"control", +"convince", +"cook", +"cool", +"copper", +"copy", +"coral", +"core", +"corn", +"correct", +"cost", +"cotton", +"couch", +"country", +"couple", +"course", +"cousin", +"cover", +"coyote", +"crack", +"cradle", +"craft", +"cram", +"crane", +"crash", +"crater", +"crawl", +"crazy", +"cream", +"credit", +"creek", +"crew", +"cricket", +"crime", +"crisp", +"critic", +"crop", +"cross", +"crouch", +"crowd", +"crucial", +"cruel", +"cruise", +"crumble", +"crunch", +"crush", +"cry", +"crystal", +"cube", +"culture", +"cup", +"cupboard", +"curious", +"current", +"curtain", +"curve", +"cushion", +"custom", +"cute", +"cycle", +"dad", +"damage", +"damp", +"dance", +"danger", +"daring", +"dash", +"daughter", +"dawn", +"day", +"deal", +"debate", +"debris", +"decade", +"december", +"decide", +"decline", +"decorate", +"decrease", +"deer", +"defense", +"define", +"defy", +"degree", +"delay", +"deliver", +"demand", +"demise", +"denial", +"dentist", +"deny", +"depart", +"depend", +"deposit", +"depth", +"deputy", +"derive", +"describe", +"desert", +"design", +"desk", +"despair", +"destroy", +"detail", +"detect", +"develop", +"device", +"devote", +"diagram", +"dial", +"diamond", +"diary", +"dice", +"diesel", +"diet", +"differ", +"digital", +"dignity", +"dilemma", +"dinner", +"dinosaur", +"direct", +"dirt", +"disagree", +"discover", +"disease", +"dish", +"dismiss", +"disorder", +"display", +"distance", +"divert", +"divide", +"divorce", +"dizzy", +"doctor", +"document", +"dog", +"doll", +"dolphin", +"domain", +"donate", +"donkey", +"donor", +"door", +"dose", +"double", +"dove", +"draft", +"dragon", +"drama", +"drastic", +"draw", +"dream", +"dress", +"drift", +"drill", +"drink", +"drip", +"drive", +"drop", +"drum", +"dry", +"duck", +"dumb", +"dune", +"during", +"dust", +"dutch", +"duty", +"dwarf", +"dynamic", +"eager", +"eagle", +"early", +"earn", +"earth", +"easily", +"east", +"easy", +"echo", +"ecology", +"economy", +"edge", +"edit", +"educate", +"effort", +"egg", +"eight", +"either", +"elbow", +"elder", +"electric", +"elegant", +"element", +"elephant", +"elevator", +"elite", +"else", +"embark", +"embody", +"embrace", +"emerge", +"emotion", +"employ", +"empower", +"empty", +"enable", +"enact", +"end", +"endless", +"endorse", +"enemy", +"energy", +"enforce", +"engage", +"engine", +"enhance", +"enjoy", +"enlist", +"enough", +"enrich", +"enroll", +"ensure", +"enter", +"entire", +"entry", +"envelope", +"episode", +"equal", +"equip", +"era", +"erase", +"erode", +"erosion", +"error", +"erupt", +"escape", +"essay", +"essence", +"estate", +"eternal", +"ethics", +"evidence", +"evil", +"evoke", +"evolve", +"exact", +"example", +"excess", +"exchange", +"excite", +"exclude", +"excuse", +"execute", +"exercise", +"exhaust", +"exhibit", +"exile", +"exist", +"exit", +"exotic", +"expand", +"expect", +"expire", +"explain", +"expose", +"express", +"extend", +"extra", +"eye", +"eyebrow", +"fabric", +"face", +"faculty", +"fade", +"faint", +"faith", +"fall", +"false", +"fame", +"family", +"famous", +"fan", +"fancy", +"fantasy", +"farm", +"fashion", +"fat", +"fatal", +"father", +"fatigue", +"fault", +"favorite", +"feature", +"february", +"federal", +"fee", +"feed", +"feel", +"female", +"fence", +"festival", +"fetch", +"fever", +"few", +"fiber", +"fiction", +"field", +"figure", +"file", +"film", +"filter", +"final", +"find", +"fine", +"finger", +"finish", +"fire", +"firm", +"first", +"fiscal", +"fish", +"fit", +"fitness", +"fix", +"flag", +"flame", +"flash", +"flat", +"flavor", +"flee", +"flight", +"flip", +"float", +"flock", +"floor", +"flower", +"fluid", +"flush", +"fly", +"foam", +"focus", +"fog", +"foil", +"fold", +"follow", +"food", +"foot", +"force", +"forest", +"forget", +"fork", +"fortune", +"forum", +"forward", +"fossil", +"foster", +"found", +"fox", +"fragile", +"frame", +"frequent", +"fresh", +"friend", +"fringe", +"frog", +"front", +"frost", +"frown", +"frozen", +"fruit", +"fuel", +"fun", +"funny", +"furnace", +"fury", +"future", +"gadget", +"gain", +"galaxy", +"gallery", +"game", +"gap", +"garage", +"garbage", +"garden", +"garlic", +"garment", +"gas", +"gasp", +"gate", +"gather", +"gauge", +"gaze", +"general", +"genius", +"genre", +"gentle", +"genuine", +"gesture", +"ghost", +"giant", +"gift", +"giggle", +"ginger", +"giraffe", +"girl", +"give", +"glad", +"glance", +"glare", +"glass", +"glide", +"glimpse", +"globe", +"gloom", +"glory", +"glove", +"glow", +"glue", +"goat", +"goddess", +"gold", +"good", +"goose", +"gorilla", +"gospel", +"gossip", +"govern", +"gown", +"grab", +"grace", +"grain", +"grant", +"grape", +"grass", +"gravity", +"great", +"green", +"grid", +"grief", +"grit", +"grocery", +"group", +"grow", +"grunt", +"guard", +"guess", +"guide", +"guilt", +"guitar", +"gun", +"gym", +"habit", +"hair", +"half", +"hammer", +"hamster", +"hand", +"happy", +"harbor", +"hard", +"harsh", +"harvest", +"hat", +"have", +"hawk", +"hazard", +"head", +"health", +"heart", +"heavy", +"hedgehog", +"height", +"hello", +"helmet", +"help", +"hen", +"hero", +"hidden", +"high", +"hill", +"hint", +"hip", +"hire", +"history", +"hobby", +"hockey", +"hold", +"hole", +"holiday", +"hollow", +"home", +"honey", +"hood", +"hope", +"horn", +"horror", +"horse", +"hospital", +"host", +"hotel", +"hour", +"hover", +"hub", +"huge", +"human", +"humble", +"humor", +"hundred", +"hungry", +"hunt", +"hurdle", +"hurry", +"hurt", +"husband", +"hybrid", +"ice", +"icon", +"idea", +"identify", +"idle", +"ignore", +"ill", +"illegal", +"illness", +"image", +"imitate", +"immense", +"immune", +"impact", +"impose", +"improve", +"impulse", +"inch", +"include", +"income", +"increase", +"index", +"indicate", +"indoor", +"industry", +"infant", +"inflict", +"inform", +"inhale", +"inherit", +"initial", +"inject", +"injury", +"inmate", +"inner", +"innocent", +"input", +"inquiry", +"insane", +"insect", +"inside", +"inspire", +"install", +"intact", +"interest", +"into", +"invest", +"invite", +"involve", +"iron", +"island", +"isolate", +"issue", +"item", +"ivory", +"jacket", +"jaguar", +"jar", +"jazz", +"jealous", +"jeans", +"jelly", +"jewel", +"job", +"join", +"joke", +"journey", +"joy", +"judge", +"juice", +"jump", +"jungle", +"junior", +"junk", +"just", +"kangaroo", +"keen", +"keep", +"ketchup", +"key", +"kick", +"kid", +"kidney", +"kind", +"kingdom", +"kiss", +"kit", +"kitchen", +"kite", +"kitten", +"kiwi", +"knee", +"knife", +"knock", +"know", +"lab", +"label", +"labor", +"ladder", +"lady", +"lake", +"lamp", +"language", +"laptop", +"large", +"later", +"latin", +"laugh", +"laundry", +"lava", +"law", +"lawn", +"lawsuit", +"layer", +"lazy", +"leader", +"leaf", +"learn", +"leave", +"lecture", +"left", +"leg", +"legal", +"legend", +"leisure", +"lemon", +"lend", +"length", +"lens", +"leopard", +"lesson", +"letter", +"level", +"liar", +"liberty", +"library", +"license", +"life", +"lift", +"light", +"like", +"limb", +"limit", +"link", +"lion", +"liquid", +"list", +"little", +"live", +"lizard", +"load", +"loan", +"lobster", +"local", +"lock", +"logic", +"lonely", +"long", +"loop", +"lottery", +"loud", +"lounge", +"love", +"loyal", +"lucky", +"luggage", +"lumber", +"lunar", +"lunch", +"luxury", +"lyrics", +"machine", +"mad", +"magic", +"magnet", +"maid", +"mail", +"main", +"major", +"make", +"mammal", +"man", +"manage", +"mandate", +"mango", +"mansion", +"manual", +"maple", +"marble", +"march", +"margin", +"marine", +"market", +"marriage", +"mask", +"mass", +"master", +"match", +"material", +"math", +"matrix", +"matter", +"maximum", +"maze", +"meadow", +"mean", +"measure", +"meat", +"mechanic", +"medal", +"media", +"melody", +"melt", +"member", +"memory", +"mention", +"menu", +"mercy", +"merge", +"merit", +"merry", +"mesh", +"message", +"metal", +"method", +"middle", +"midnight", +"milk", +"million", +"mimic", +"mind", +"minimum", +"minor", +"minute", +"miracle", +"mirror", +"misery", +"miss", +"mistake", +"mix", +"mixed", +"mixture", +"mobile", +"model", +"modify", +"mom", +"moment", +"monitor", +"monkey", +"monster", +"month", +"moon", +"moral", +"more", +"morning", +"mosquito", +"mother", +"motion", +"motor", +"mountain", +"mouse", +"move", +"movie", +"much", +"muffin", +"mule", +"multiply", +"muscle", +"museum", +"mushroom", +"music", +"must", +"mutual", +"myself", +"mystery", +"myth", +"naive", +"name", +"napkin", +"narrow", +"nasty", +"nation", +"nature", +"near", +"neck", +"need", +"negative", +"neglect", +"neither", +"nephew", +"nerve", +"nest", +"net", +"network", +"neutral", +"never", +"news", +"next", +"nice", +"night", +"noble", +"noise", +"nominee", +"noodle", +"normal", +"north", +"nose", +"notable", +"note", +"nothing", +"notice", +"novel", +"now", +"nuclear", +"number", +"nurse", +"nut", +"oak", +"obey", +"object", +"oblige", +"obscure", +"observe", +"obtain", +"obvious", +"occur", +"ocean", +"october", +"odor", +"off", +"offer", +"office", +"often", +"oil", +"okay", +"old", +"olive", +"olympic", +"omit", +"once", +"one", +"onion", +"online", +"only", +"open", +"opera", +"opinion", +"oppose", +"option", +"orange", +"orbit", +"orchard", +"order", +"ordinary", +"organ", +"orient", +"original", +"orphan", +"ostrich", +"other", +"outdoor", +"outer", +"output", +"outside", +"oval", +"oven", +"over", +"own", +"owner", +"oxygen", +"oyster", +"ozone", +"pact", +"paddle", +"page", +"pair", +"palace", +"palm", +"panda", +"panel", +"panic", +"panther", +"paper", +"parade", +"parent", +"park", +"parrot", +"party", +"pass", +"patch", +"path", +"patient", +"patrol", +"pattern", +"pause", +"pave", +"payment", +"peace", +"peanut", +"pear", +"peasant", +"pelican", +"pen", +"penalty", +"pencil", +"people", +"pepper", +"perfect", +"permit", +"person", +"pet", +"phone", +"photo", +"phrase", +"physical", +"piano", +"picnic", +"picture", +"piece", +"pig", +"pigeon", +"pill", +"pilot", +"pink", +"pioneer", +"pipe", +"pistol", +"pitch", +"pizza", +"place", +"planet", +"plastic", +"plate", +"play", +"please", +"pledge", +"pluck", +"plug", +"plunge", +"poem", +"poet", +"point", +"polar", +"pole", +"police", +"pond", +"pony", +"pool", +"popular", +"portion", +"position", +"possible", +"post", +"potato", +"pottery", +"poverty", +"powder", +"power", +"practice", +"praise", +"predict", +"prefer", +"prepare", +"present", +"pretty", +"prevent", +"price", +"pride", +"primary", +"print", +"priority", +"prison", +"private", +"prize", +"problem", +"process", +"produce", +"profit", +"program", +"project", +"promote", +"proof", +"property", +"prosper", +"protect", +"proud", +"provide", +"public", +"pudding", +"pull", +"pulp", +"pulse", +"pumpkin", +"punch", +"pupil", +"puppy", +"purchase", +"purity", +"purpose", +"purse", +"push", +"put", +"puzzle", +"pyramid", +"quality", +"quantum", +"quarter", +"question", +"quick", +"quit", +"quiz", +"quote", +"rabbit", +"raccoon", +"race", +"rack", +"radar", +"radio", +"rail", +"rain", +"raise", +"rally", +"ramp", +"ranch", +"random", +"range", +"rapid", +"rare", +"rate", +"rather", +"raven", +"raw", +"razor", +"ready", +"real", +"reason", +"rebel", +"rebuild", +"recall", +"receive", +"recipe", +"record", +"recycle", +"reduce", +"reflect", +"reform", +"refuse", +"region", +"regret", +"regular", +"reject", +"relax", +"release", +"relief", +"rely", +"remain", +"remember", +"remind", +"remove", +"render", +"renew", +"rent", +"reopen", +"repair", +"repeat", +"replace", +"report", +"require", +"rescue", +"resemble", +"resist", +"resource", +"response", +"result", +"retire", +"retreat", +"return", +"reunion", +"reveal", +"review", +"reward", +"rhythm", +"rib", +"ribbon", +"rice", +"rich", +"ride", +"ridge", +"rifle", +"right", +"rigid", +"ring", +"riot", +"ripple", +"risk", +"ritual", +"rival", +"river", +"road", +"roast", +"robot", +"robust", +"rocket", +"romance", +"roof", +"rookie", +"room", +"rose", +"rotate", +"rough", +"round", +"route", +"royal", +"rubber", +"rude", +"rug", +"rule", +"run", +"runway", +"rural", +"sad", +"saddle", +"sadness", +"safe", +"sail", +"salad", +"salmon", +"salon", +"salt", +"salute", +"same", +"sample", +"sand", +"satisfy", +"satoshi", +"sauce", +"sausage", +"save", +"say", +"scale", +"scan", +"scare", +"scatter", +"scene", +"scheme", +"school", +"science", +"scissors", +"scorpion", +"scout", +"scrap", +"screen", +"script", +"scrub", +"sea", +"search", +"season", +"seat", +"second", +"secret", +"section", +"security", +"seed", +"seek", +"segment", +"select", +"sell", +"seminar", +"senior", +"sense", +"sentence", +"series", +"service", +"session", +"settle", +"setup", +"seven", +"shadow", +"shaft", +"shallow", +"share", +"shed", +"shell", +"sheriff", +"shield", +"shift", +"shine", +"ship", +"shiver", +"shock", +"shoe", +"shoot", +"shop", +"short", +"shoulder", +"shove", +"shrimp", +"shrug", +"shuffle", +"shy", +"sibling", +"sick", +"side", +"siege", +"sight", +"sign", +"silent", +"silk", +"silly", +"silver", +"similar", +"simple", +"since", +"sing", +"siren", +"sister", +"situate", +"six", +"size", +"skate", +"sketch", +"ski", +"skill", +"skin", +"skirt", +"skull", +"slab", +"slam", +"sleep", +"slender", +"slice", +"slide", +"slight", +"slim", +"slogan", +"slot", +"slow", +"slush", +"small", +"smart", +"smile", +"smoke", +"smooth", +"snack", +"snake", +"snap", +"sniff", +"snow", +"soap", +"soccer", +"social", +"sock", +"soda", +"soft", +"solar", +"soldier", +"solid", +"solution", +"solve", +"someone", +"song", +"soon", +"sorry", +"sort", +"soul", +"sound", +"soup", +"source", +"south", +"space", +"spare", +"spatial", +"spawn", +"speak", +"special", +"speed", +"spell", +"spend", +"sphere", +"spice", +"spider", +"spike", +"spin", +"spirit", +"split", +"spoil", +"sponsor", +"spoon", +"sport", +"spot", +"spray", +"spread", +"spring", +"spy", +"square", +"squeeze", +"squirrel", +"stable", +"stadium", +"staff", +"stage", +"stairs", +"stamp", +"stand", +"start", +"state", +"stay", +"steak", +"steel", +"stem", +"step", +"stereo", +"stick", +"still", +"sting", +"stock", +"stomach", +"stone", +"stool", +"story", +"stove", +"strategy", +"street", +"strike", +"strong", +"struggle", +"student", +"stuff", +"stumble", +"style", +"subject", +"submit", +"subway", +"success", +"such", +"sudden", +"suffer", +"sugar", +"suggest", +"suit", +"summer", +"sun", +"sunny", +"sunset", +"super", +"supply", +"supreme", +"sure", +"surface", +"surge", +"surprise", +"surround", +"survey", +"suspect", +"sustain", +"swallow", +"swamp", +"swap", +"swarm", +"swear", +"sweet", +"swift", +"swim", +"swing", +"switch", +"sword", +"symbol", +"symptom", +"syrup", +"system", +"table", +"tackle", +"tag", +"tail", +"talent", +"talk", +"tank", +"tape", +"target", +"task", +"taste", +"tattoo", +"taxi", +"teach", +"team", +"tell", +"ten", +"tenant", +"tennis", +"tent", +"term", +"test", +"text", +"thank", +"that", +"theme", +"then", +"theory", +"there", +"they", +"thing", +"this", +"thought", +"three", +"thrive", +"throw", +"thumb", +"thunder", +"ticket", +"tide", +"tiger", +"tilt", +"timber", +"time", +"tiny", +"tip", +"tired", +"tissue", +"title", +"toast", +"tobacco", +"today", +"toddler", +"toe", +"together", +"toilet", +"token", +"tomato", +"tomorrow", +"tone", +"tongue", +"tonight", +"tool", +"tooth", +"top", +"topic", +"topple", +"torch", +"tornado", +"tortoise", +"toss", +"total", +"tourist", +"toward", +"tower", +"town", +"toy", +"track", +"trade", +"traffic", +"tragic", +"train", +"transfer", +"trap", +"trash", +"travel", +"tray", +"treat", +"tree", +"trend", +"trial", +"tribe", +"trick", +"trigger", +"trim", +"trip", +"trophy", +"trouble", +"truck", +"true", +"truly", +"trumpet", +"trust", +"truth", +"try", +"tube", +"tuition", +"tumble", +"tuna", +"tunnel", +"turkey", +"turn", +"turtle", +"twelve", +"twenty", +"twice", +"twin", +"twist", +"two", +"type", +"typical", +"ugly", +"umbrella", +"unable", +"unaware", +"uncle", +"uncover", +"under", +"undo", +"unfair", +"unfold", +"unhappy", +"uniform", +"unique", +"unit", +"universe", +"unknown", +"unlock", +"until", +"unusual", +"unveil", +"update", +"upgrade", +"uphold", +"upon", +"upper", +"upset", +"urban", +"urge", +"usage", +"use", +"used", +"useful", +"useless", +"usual", +"utility", +"vacant", +"vacuum", +"vague", +"valid", +"valley", +"valve", +"van", +"vanish", +"vapor", +"various", +"vast", +"vault", +"vehicle", +"velvet", +"vendor", +"venture", +"venue", +"verb", +"verify", +"version", +"very", +"vessel", +"veteran", +"viable", +"vibrant", +"vicious", +"victory", +"video", +"view", +"village", +"vintage", +"violin", +"virtual", +"virus", +"visa", +"visit", +"visual", +"vital", +"vivid", +"vocal", +"voice", +"void", +"volcano", +"volume", +"vote", +"voyage", +"wage", +"wagon", +"wait", +"walk", +"wall", +"walnut", +"want", +"warfare", +"warm", +"warrior", +"wash", +"wasp", +"waste", +"water", +"wave", +"way", +"wealth", +"weapon", +"wear", +"weasel", +"weather", +"web", +"wedding", +"weekend", +"weird", +"welcome", +"west", +"wet", +"whale", +"what", +"wheat", +"wheel", +"when", +"where", +"whip", +"whisper", +"wide", +"width", +"wife", +"wild", +"will", +"win", +"window", +"wine", +"wing", +"wink", +"winner", +"winter", +"wire", +"wisdom", +"wise", +"wish", +"witness", +"wolf", +"woman", +"wonder", +"wood", +"wool", +"word", +"work", +"world", +"worry", +"worth", +"wrap", +"wreck", +"wrestle", +"wrist", +"write", +"wrong", +"yard", +"year", +"yellow", +"you", +"young", +"youth", +"zebra", +"zero", +"zone", +"zoo"] +} \ No newline at end of file diff --git a/src/gui/static/src/assets/coins/bitcoin/big-icon.png b/src/gui/static/src/assets/coins/bitcoin/big-icon.png new file mode 100644 index 0000000..8cc7c31 Binary files /dev/null and b/src/gui/static/src/assets/coins/bitcoin/big-icon.png differ diff --git a/src/gui/static/src/assets/coins/bitcoin/gradient.png b/src/gui/static/src/assets/coins/bitcoin/gradient.png new file mode 100644 index 0000000..1759907 Binary files /dev/null and b/src/gui/static/src/assets/coins/bitcoin/gradient.png differ diff --git a/src/gui/static/src/assets/coins/bitcoin/header.jpg b/src/gui/static/src/assets/coins/bitcoin/header.jpg new file mode 100644 index 0000000..30d5663 Binary files /dev/null and b/src/gui/static/src/assets/coins/bitcoin/header.jpg differ diff --git a/src/gui/static/src/assets/coins/bitcoin/icon.png b/src/gui/static/src/assets/coins/bitcoin/icon.png new file mode 100644 index 0000000..5fed5a7 Binary files /dev/null and b/src/gui/static/src/assets/coins/bitcoin/icon.png differ diff --git a/src/gui/static/src/assets/coins/ethereum/big-icon.png b/src/gui/static/src/assets/coins/ethereum/big-icon.png new file mode 100644 index 0000000..0e39d84 Binary files /dev/null and b/src/gui/static/src/assets/coins/ethereum/big-icon.png differ diff --git a/src/gui/static/src/assets/coins/ethereum/gradient.png b/src/gui/static/src/assets/coins/ethereum/gradient.png new file mode 100644 index 0000000..45d611b Binary files /dev/null and b/src/gui/static/src/assets/coins/ethereum/gradient.png differ diff --git a/src/gui/static/src/assets/coins/ethereum/header.jpg b/src/gui/static/src/assets/coins/ethereum/header.jpg new file mode 100644 index 0000000..bc52a20 Binary files /dev/null and b/src/gui/static/src/assets/coins/ethereum/header.jpg differ diff --git a/src/gui/static/src/assets/coins/ethereum/icon.png b/src/gui/static/src/assets/coins/ethereum/icon.png new file mode 100644 index 0000000..af6939d Binary files /dev/null and b/src/gui/static/src/assets/coins/ethereum/icon.png differ diff --git a/src/gui/static/src/assets/coins/generic.jpg b/src/gui/static/src/assets/coins/generic.jpg new file mode 100644 index 0000000..a1617c9 Binary files /dev/null and b/src/gui/static/src/assets/coins/generic.jpg differ diff --git a/src/gui/static/src/assets/coins/skycoin/big-icon.png b/src/gui/static/src/assets/coins/skycoin/big-icon.png new file mode 100644 index 0000000..4415dff Binary files /dev/null and b/src/gui/static/src/assets/coins/skycoin/big-icon.png differ diff --git a/src/gui/static/src/assets/coins/skycoin/gradient.png b/src/gui/static/src/assets/coins/skycoin/gradient.png new file mode 100644 index 0000000..cca8760 Binary files /dev/null and b/src/gui/static/src/assets/coins/skycoin/gradient.png differ diff --git a/src/gui/static/src/assets/coins/skycoin/header.jpg b/src/gui/static/src/assets/coins/skycoin/header.jpg new file mode 100644 index 0000000..4590215 Binary files /dev/null and b/src/gui/static/src/assets/coins/skycoin/header.jpg differ diff --git a/src/gui/static/src/assets/coins/skycoin/icon.png b/src/gui/static/src/assets/coins/skycoin/icon.png new file mode 100644 index 0000000..f0af828 Binary files /dev/null and b/src/gui/static/src/assets/coins/skycoin/icon.png differ diff --git a/src/gui/static/src/assets/coins/testcoin/big-icon.png b/src/gui/static/src/assets/coins/testcoin/big-icon.png new file mode 100644 index 0000000..842b972 Binary files /dev/null and b/src/gui/static/src/assets/coins/testcoin/big-icon.png differ diff --git a/src/gui/static/src/assets/coins/testcoin/gradient.png b/src/gui/static/src/assets/coins/testcoin/gradient.png new file mode 100644 index 0000000..59f2b27 Binary files /dev/null and b/src/gui/static/src/assets/coins/testcoin/gradient.png differ diff --git a/src/gui/static/src/assets/coins/testcoin/header.jpg b/src/gui/static/src/assets/coins/testcoin/header.jpg new file mode 100644 index 0000000..f7792d6 Binary files /dev/null and b/src/gui/static/src/assets/coins/testcoin/header.jpg differ diff --git a/src/gui/static/src/assets/coins/testcoin/icon.png b/src/gui/static/src/assets/coins/testcoin/icon.png new file mode 100644 index 0000000..5fed5a7 Binary files /dev/null and b/src/gui/static/src/assets/coins/testcoin/icon.png differ diff --git a/src/gui/static/src/assets/error-alert/big-error-icon.png b/src/gui/static/src/assets/error-alert/big-error-icon.png new file mode 100644 index 0000000..bcbda0c Binary files /dev/null and b/src/gui/static/src/assets/error-alert/big-error-icon.png differ diff --git a/src/gui/static/src/assets/error-alert/code.js b/src/gui/static/src/assets/error-alert/code.js new file mode 100644 index 0000000..12ff545 --- /dev/null +++ b/src/gui/static/src/assets/error-alert/code.js @@ -0,0 +1,23 @@ +var lang = navigator.language || navigator.userLanguage; +var telegramLink1 = ''; +var telegramLink2 = ''; + +// Send ?2 at the end of the URL to show error number 2. +if (window.location.toString().indexOf('?2') !== -1) { + // It is possible to add more languages in the future. + if (lang.substr(0, 2).toLowerCase == 'en' || true) { + document.getElementById('title').innerHTML = 'Error #2'; + document.getElementById('text').innerHTML = 'It was not possible to complete initial setup procedure. Please restart the app and/or seek help on our ' + telegramLink1 + 'Telegram.' + telegramLink2; + } +} else if (window.location.toString().indexOf('?3') !== -1) { + // It is possible to add more languages in the future. + if (lang.substr(0, 2).toLowerCase == 'en' || true) { + document.getElementById('title').innerHTML = 'Error #3'; + document.getElementById('text').innerHTML = 'There was a problem saving the changes made to the wallet and the application has been terminated for security reasons. Please close the app and try again.'; + } +} else { + if (lang.substr(0, 2).toLowerCase == 'en' || true) { + document.getElementById('title').innerHTML = 'Error #1'; + document.getElementById('text').innerHTML = 'It is not possible to connect to the backend. Please restart the app and/or seek help on our ' + telegramLink1 + 'Telegram.' + telegramLink2; + } +} diff --git a/src/gui/static/src/assets/error-alert/index.html b/src/gui/static/src/assets/error-alert/index.html new file mode 100644 index 0000000..68afaad --- /dev/null +++ b/src/gui/static/src/assets/error-alert/index.html @@ -0,0 +1,71 @@ + + + + + + + + +
+
+ +
+
+
+
+ + + + diff --git a/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.eot b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.eot new file mode 100644 index 0000000..70508eb Binary files /dev/null and b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.eot differ diff --git a/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.ijmap b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.ijmap new file mode 100644 index 0000000..d9f1d25 --- /dev/null +++ b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.ijmap @@ -0,0 +1 @@ +{"icons":{"e84d":{"name":"3d Rotation"},"eb3b":{"name":"Ac Unit"},"e190":{"name":"Access Alarm"},"e191":{"name":"Access Alarms"},"e192":{"name":"Access Time"},"e84e":{"name":"Accessibility"},"e914":{"name":"Accessible"},"e84f":{"name":"Account Balance"},"e850":{"name":"Account Balance Wallet"},"e851":{"name":"Account Box"},"e853":{"name":"Account Circle"},"e60e":{"name":"Adb"},"e145":{"name":"Add"},"e439":{"name":"Add A Photo"},"e193":{"name":"Add Alarm"},"e003":{"name":"Add Alert"},"e146":{"name":"Add Box"},"e147":{"name":"Add Circle"},"e148":{"name":"Add Circle Outline"},"e567":{"name":"Add Location"},"e854":{"name":"Add Shopping Cart"},"e39d":{"name":"Add To Photos"},"e05c":{"name":"Add To Queue"},"e39e":{"name":"Adjust"},"e630":{"name":"Airline Seat Flat"},"e631":{"name":"Airline Seat Flat Angled"},"e632":{"name":"Airline Seat Individual Suite"},"e633":{"name":"Airline Seat Legroom Extra"},"e634":{"name":"Airline Seat Legroom Normal"},"e635":{"name":"Airline Seat Legroom Reduced"},"e636":{"name":"Airline Seat Recline Extra"},"e637":{"name":"Airline Seat Recline Normal"},"e195":{"name":"Airplanemode Active"},"e194":{"name":"Airplanemode Inactive"},"e055":{"name":"Airplay"},"eb3c":{"name":"Airport Shuttle"},"e855":{"name":"Alarm"},"e856":{"name":"Alarm Add"},"e857":{"name":"Alarm Off"},"e858":{"name":"Alarm On"},"e019":{"name":"Album"},"eb3d":{"name":"All Inclusive"},"e90b":{"name":"All Out"},"e859":{"name":"Android"},"e85a":{"name":"Announcement"},"e5c3":{"name":"Apps"},"e149":{"name":"Archive"},"e5c4":{"name":"Arrow Back"},"e5db":{"name":"Arrow Downward"},"e5c5":{"name":"Arrow Drop Down"},"e5c6":{"name":"Arrow Drop Down Circle"},"e5c7":{"name":"Arrow Drop Up"},"e5c8":{"name":"Arrow Forward"},"e5d8":{"name":"Arrow Upward"},"e060":{"name":"Art Track"},"e85b":{"name":"Aspect Ratio"},"e85c":{"name":"Assessment"},"e85d":{"name":"Assignment"},"e85e":{"name":"Assignment Ind"},"e85f":{"name":"Assignment Late"},"e860":{"name":"Assignment Return"},"e861":{"name":"Assignment Returned"},"e862":{"name":"Assignment Turned In"},"e39f":{"name":"Assistant"},"e3a0":{"name":"Assistant Photo"},"e226":{"name":"Attach File"},"e227":{"name":"Attach Money"},"e2bc":{"name":"Attachment"},"e3a1":{"name":"Audiotrack"},"e863":{"name":"Autorenew"},"e01b":{"name":"Av Timer"},"e14a":{"name":"Backspace"},"e864":{"name":"Backup"},"e19c":{"name":"Battery Alert"},"e1a3":{"name":"Battery Charging Full"},"e1a4":{"name":"Battery Full"},"e1a5":{"name":"Battery Std"},"e1a6":{"name":"Battery Unknown"},"eb3e":{"name":"Beach Access"},"e52d":{"name":"Beenhere"},"e14b":{"name":"Block"},"e1a7":{"name":"Bluetooth"},"e60f":{"name":"Bluetooth Audio"},"e1a8":{"name":"Bluetooth Connected"},"e1a9":{"name":"Bluetooth Disabled"},"e1aa":{"name":"Bluetooth Searching"},"e3a2":{"name":"Blur Circular"},"e3a3":{"name":"Blur Linear"},"e3a4":{"name":"Blur Off"},"e3a5":{"name":"Blur On"},"e865":{"name":"Book"},"e866":{"name":"Bookmark"},"e867":{"name":"Bookmark Border"},"e228":{"name":"Border All"},"e229":{"name":"Border Bottom"},"e22a":{"name":"Border Clear"},"e22b":{"name":"Border Color"},"e22c":{"name":"Border Horizontal"},"e22d":{"name":"Border Inner"},"e22e":{"name":"Border Left"},"e22f":{"name":"Border Outer"},"e230":{"name":"Border Right"},"e231":{"name":"Border Style"},"e232":{"name":"Border Top"},"e233":{"name":"Border Vertical"},"e06b":{"name":"Branding Watermark"},"e3a6":{"name":"Brightness 1"},"e3a7":{"name":"Brightness 2"},"e3a8":{"name":"Brightness 3"},"e3a9":{"name":"Brightness 4"},"e3aa":{"name":"Brightness 5"},"e3ab":{"name":"Brightness 6"},"e3ac":{"name":"Brightness 7"},"e1ab":{"name":"Brightness Auto"},"e1ac":{"name":"Brightness High"},"e1ad":{"name":"Brightness Low"},"e1ae":{"name":"Brightness Medium"},"e3ad":{"name":"Broken Image"},"e3ae":{"name":"Brush"},"e6dd":{"name":"Bubble Chart"},"e868":{"name":"Bug Report"},"e869":{"name":"Build"},"e43c":{"name":"Burst Mode"},"e0af":{"name":"Business"},"eb3f":{"name":"Business Center"},"e86a":{"name":"Cached"},"e7e9":{"name":"Cake"},"e0b0":{"name":"Call"},"e0b1":{"name":"Call End"},"e0b2":{"name":"Call Made"},"e0b3":{"name":"Call Merge"},"e0b4":{"name":"Call Missed"},"e0e4":{"name":"Call Missed Outgoing"},"e0b5":{"name":"Call Received"},"e0b6":{"name":"Call Split"},"e06c":{"name":"Call To Action"},"e3af":{"name":"Camera"},"e3b0":{"name":"Camera Alt"},"e8fc":{"name":"Camera Enhance"},"e3b1":{"name":"Camera Front"},"e3b2":{"name":"Camera Rear"},"e3b3":{"name":"Camera Roll"},"e5c9":{"name":"Cancel"},"e8f6":{"name":"Card Giftcard"},"e8f7":{"name":"Card Membership"},"e8f8":{"name":"Card Travel"},"eb40":{"name":"Casino"},"e307":{"name":"Cast"},"e308":{"name":"Cast Connected"},"e3b4":{"name":"Center Focus Strong"},"e3b5":{"name":"Center Focus Weak"},"e86b":{"name":"Change History"},"e0b7":{"name":"Chat"},"e0ca":{"name":"Chat Bubble"},"e0cb":{"name":"Chat Bubble Outline"},"e5ca":{"name":"Check"},"e834":{"name":"Check Box"},"e835":{"name":"Check Box Outline Blank"},"e86c":{"name":"Check Circle"},"e5cb":{"name":"Chevron Left"},"e5cc":{"name":"Chevron Right"},"eb41":{"name":"Child Care"},"eb42":{"name":"Child Friendly"},"e86d":{"name":"Chrome Reader Mode"},"e86e":{"name":"Class"},"e14c":{"name":"Clear"},"e0b8":{"name":"Clear All"},"e5cd":{"name":"Close"},"e01c":{"name":"Closed Caption"},"e2bd":{"name":"Cloud"},"e2be":{"name":"Cloud Circle"},"e2bf":{"name":"Cloud Done"},"e2c0":{"name":"Cloud Download"},"e2c1":{"name":"Cloud Off"},"e2c2":{"name":"Cloud Queue"},"e2c3":{"name":"Cloud Upload"},"e86f":{"name":"Code"},"e3b6":{"name":"Collections"},"e431":{"name":"Collections Bookmark"},"e3b7":{"name":"Color Lens"},"e3b8":{"name":"Colorize"},"e0b9":{"name":"Comment"},"e3b9":{"name":"Compare"},"e915":{"name":"Compare Arrows"},"e30a":{"name":"Computer"},"e638":{"name":"Confirmation Number"},"e0d0":{"name":"Contact Mail"},"e0cf":{"name":"Contact Phone"},"e0ba":{"name":"Contacts"},"e14d":{"name":"Content Copy"},"e14e":{"name":"Content Cut"},"e14f":{"name":"Content Paste"},"e3ba":{"name":"Control Point"},"e3bb":{"name":"Control Point Duplicate"},"e90c":{"name":"Copyright"},"e150":{"name":"Create"},"e2cc":{"name":"Create New Folder"},"e870":{"name":"Credit Card"},"e3be":{"name":"Crop"},"e3bc":{"name":"Crop 16 9"},"e3bd":{"name":"Crop 3 2"},"e3bf":{"name":"Crop 5 4"},"e3c0":{"name":"Crop 7 5"},"e3c1":{"name":"Crop Din"},"e3c2":{"name":"Crop Free"},"e3c3":{"name":"Crop Landscape"},"e3c4":{"name":"Crop Original"},"e3c5":{"name":"Crop Portrait"},"e437":{"name":"Crop Rotate"},"e3c6":{"name":"Crop Square"},"e871":{"name":"Dashboard"},"e1af":{"name":"Data Usage"},"e916":{"name":"Date Range"},"e3c7":{"name":"Dehaze"},"e872":{"name":"Delete"},"e92b":{"name":"Delete Forever"},"e16c":{"name":"Delete Sweep"},"e873":{"name":"Description"},"e30b":{"name":"Desktop Mac"},"e30c":{"name":"Desktop Windows"},"e3c8":{"name":"Details"},"e30d":{"name":"Developer Board"},"e1b0":{"name":"Developer Mode"},"e335":{"name":"Device Hub"},"e1b1":{"name":"Devices"},"e337":{"name":"Devices Other"},"e0bb":{"name":"Dialer Sip"},"e0bc":{"name":"Dialpad"},"e52e":{"name":"Directions"},"e52f":{"name":"Directions Bike"},"e532":{"name":"Directions Boat"},"e530":{"name":"Directions Bus"},"e531":{"name":"Directions Car"},"e534":{"name":"Directions Railway"},"e566":{"name":"Directions Run"},"e533":{"name":"Directions Subway"},"e535":{"name":"Directions Transit"},"e536":{"name":"Directions Walk"},"e610":{"name":"Disc Full"},"e875":{"name":"Dns"},"e612":{"name":"Do Not Disturb"},"e611":{"name":"Do Not Disturb Alt"},"e643":{"name":"Do Not Disturb Off"},"e644":{"name":"Do Not Disturb On"},"e30e":{"name":"Dock"},"e7ee":{"name":"Domain"},"e876":{"name":"Done"},"e877":{"name":"Done All"},"e917":{"name":"Donut Large"},"e918":{"name":"Donut Small"},"e151":{"name":"Drafts"},"e25d":{"name":"Drag Handle"},"e613":{"name":"Drive Eta"},"e1b2":{"name":"Dvr"},"e3c9":{"name":"Edit"},"e568":{"name":"Edit Location"},"e8fb":{"name":"Eject"},"e0be":{"name":"Email"},"e63f":{"name":"Enhanced Encryption"},"e01d":{"name":"Equalizer"},"e000":{"name":"Error"},"e001":{"name":"Error Outline"},"e926":{"name":"Euro Symbol"},"e56d":{"name":"Ev Station"},"e878":{"name":"Event"},"e614":{"name":"Event Available"},"e615":{"name":"Event Busy"},"e616":{"name":"Event Note"},"e903":{"name":"Event Seat"},"e879":{"name":"Exit To App"},"e5ce":{"name":"Expand Less"},"e5cf":{"name":"Expand More"},"e01e":{"name":"Explicit"},"e87a":{"name":"Explore"},"e3ca":{"name":"Exposure"},"e3cb":{"name":"Exposure Neg 1"},"e3cc":{"name":"Exposure Neg 2"},"e3cd":{"name":"Exposure Plus 1"},"e3ce":{"name":"Exposure Plus 2"},"e3cf":{"name":"Exposure Zero"},"e87b":{"name":"Extension"},"e87c":{"name":"Face"},"e01f":{"name":"Fast Forward"},"e020":{"name":"Fast Rewind"},"e87d":{"name":"Favorite"},"e87e":{"name":"Favorite Border"},"e06d":{"name":"Featured Play List"},"e06e":{"name":"Featured Video"},"e87f":{"name":"Feedback"},"e05d":{"name":"Fiber Dvr"},"e061":{"name":"Fiber Manual Record"},"e05e":{"name":"Fiber New"},"e06a":{"name":"Fiber Pin"},"e062":{"name":"Fiber Smart Record"},"e2c4":{"name":"File Download"},"e2c6":{"name":"File Upload"},"e3d3":{"name":"Filter"},"e3d0":{"name":"Filter 1"},"e3d1":{"name":"Filter 2"},"e3d2":{"name":"Filter 3"},"e3d4":{"name":"Filter 4"},"e3d5":{"name":"Filter 5"},"e3d6":{"name":"Filter 6"},"e3d7":{"name":"Filter 7"},"e3d8":{"name":"Filter 8"},"e3d9":{"name":"Filter 9"},"e3da":{"name":"Filter 9 Plus"},"e3db":{"name":"Filter B And W"},"e3dc":{"name":"Filter Center Focus"},"e3dd":{"name":"Filter Drama"},"e3de":{"name":"Filter Frames"},"e3df":{"name":"Filter Hdr"},"e152":{"name":"Filter List"},"e3e0":{"name":"Filter None"},"e3e2":{"name":"Filter Tilt Shift"},"e3e3":{"name":"Filter Vintage"},"e880":{"name":"Find In Page"},"e881":{"name":"Find Replace"},"e90d":{"name":"Fingerprint"},"e5dc":{"name":"First Page"},"eb43":{"name":"Fitness Center"},"e153":{"name":"Flag"},"e3e4":{"name":"Flare"},"e3e5":{"name":"Flash Auto"},"e3e6":{"name":"Flash Off"},"e3e7":{"name":"Flash On"},"e539":{"name":"Flight"},"e904":{"name":"Flight Land"},"e905":{"name":"Flight Takeoff"},"e3e8":{"name":"Flip"},"e882":{"name":"Flip To Back"},"e883":{"name":"Flip To Front"},"e2c7":{"name":"Folder"},"e2c8":{"name":"Folder Open"},"e2c9":{"name":"Folder Shared"},"e617":{"name":"Folder Special"},"e167":{"name":"Font Download"},"e234":{"name":"Format Align Center"},"e235":{"name":"Format Align Justify"},"e236":{"name":"Format Align Left"},"e237":{"name":"Format Align Right"},"e238":{"name":"Format Bold"},"e239":{"name":"Format Clear"},"e23a":{"name":"Format Color Fill"},"e23b":{"name":"Format Color Reset"},"e23c":{"name":"Format Color Text"},"e23d":{"name":"Format Indent Decrease"},"e23e":{"name":"Format Indent Increase"},"e23f":{"name":"Format Italic"},"e240":{"name":"Format Line Spacing"},"e241":{"name":"Format List Bulleted"},"e242":{"name":"Format List Numbered"},"e243":{"name":"Format Paint"},"e244":{"name":"Format Quote"},"e25e":{"name":"Format Shapes"},"e245":{"name":"Format Size"},"e246":{"name":"Format Strikethrough"},"e247":{"name":"Format Textdirection L To R"},"e248":{"name":"Format Textdirection R To L"},"e249":{"name":"Format Underlined"},"e0bf":{"name":"Forum"},"e154":{"name":"Forward"},"e056":{"name":"Forward 10"},"e057":{"name":"Forward 30"},"e058":{"name":"Forward 5"},"eb44":{"name":"Free Breakfast"},"e5d0":{"name":"Fullscreen"},"e5d1":{"name":"Fullscreen Exit"},"e24a":{"name":"Functions"},"e927":{"name":"G Translate"},"e30f":{"name":"Gamepad"},"e021":{"name":"Games"},"e90e":{"name":"Gavel"},"e155":{"name":"Gesture"},"e884":{"name":"Get App"},"e908":{"name":"Gif"},"eb45":{"name":"Golf Course"},"e1b3":{"name":"Gps Fixed"},"e1b4":{"name":"Gps Not Fixed"},"e1b5":{"name":"Gps Off"},"e885":{"name":"Grade"},"e3e9":{"name":"Gradient"},"e3ea":{"name":"Grain"},"e1b8":{"name":"Graphic Eq"},"e3eb":{"name":"Grid Off"},"e3ec":{"name":"Grid On"},"e7ef":{"name":"Group"},"e7f0":{"name":"Group Add"},"e886":{"name":"Group Work"},"e052":{"name":"Hd"},"e3ed":{"name":"Hdr Off"},"e3ee":{"name":"Hdr On"},"e3f1":{"name":"Hdr Strong"},"e3f2":{"name":"Hdr Weak"},"e310":{"name":"Headset"},"e311":{"name":"Headset Mic"},"e3f3":{"name":"Healing"},"e023":{"name":"Hearing"},"e887":{"name":"Help"},"e8fd":{"name":"Help Outline"},"e024":{"name":"High Quality"},"e25f":{"name":"Highlight"},"e888":{"name":"Highlight Off"},"e889":{"name":"History"},"e88a":{"name":"Home"},"eb46":{"name":"Hot Tub"},"e53a":{"name":"Hotel"},"e88b":{"name":"Hourglass Empty"},"e88c":{"name":"Hourglass Full"},"e902":{"name":"Http"},"e88d":{"name":"Https"},"e3f4":{"name":"Image"},"e3f5":{"name":"Image Aspect Ratio"},"e0e0":{"name":"Import Contacts"},"e0c3":{"name":"Import Export"},"e912":{"name":"Important Devices"},"e156":{"name":"Inbox"},"e909":{"name":"Indeterminate Check Box"},"e88e":{"name":"Info"},"e88f":{"name":"Info Outline"},"e890":{"name":"Input"},"e24b":{"name":"Insert Chart"},"e24c":{"name":"Insert Comment"},"e24d":{"name":"Insert Drive File"},"e24e":{"name":"Insert Emoticon"},"e24f":{"name":"Insert Invitation"},"e250":{"name":"Insert Link"},"e251":{"name":"Insert Photo"},"e891":{"name":"Invert Colors"},"e0c4":{"name":"Invert Colors Off"},"e3f6":{"name":"Iso"},"e312":{"name":"Keyboard"},"e313":{"name":"Keyboard Arrow Down"},"e314":{"name":"Keyboard Arrow Left"},"e315":{"name":"Keyboard Arrow Right"},"e316":{"name":"Keyboard Arrow Up"},"e317":{"name":"Keyboard Backspace"},"e318":{"name":"Keyboard Capslock"},"e31a":{"name":"Keyboard Hide"},"e31b":{"name":"Keyboard Return"},"e31c":{"name":"Keyboard Tab"},"e31d":{"name":"Keyboard Voice"},"eb47":{"name":"Kitchen"},"e892":{"name":"Label"},"e893":{"name":"Label Outline"},"e3f7":{"name":"Landscape"},"e894":{"name":"Language"},"e31e":{"name":"Laptop"},"e31f":{"name":"Laptop Chromebook"},"e320":{"name":"Laptop Mac"},"e321":{"name":"Laptop Windows"},"e5dd":{"name":"Last Page"},"e895":{"name":"Launch"},"e53b":{"name":"Layers"},"e53c":{"name":"Layers Clear"},"e3f8":{"name":"Leak Add"},"e3f9":{"name":"Leak Remove"},"e3fa":{"name":"Lens"},"e02e":{"name":"Library Add"},"e02f":{"name":"Library Books"},"e030":{"name":"Library Music"},"e90f":{"name":"Lightbulb Outline"},"e919":{"name":"Line Style"},"e91a":{"name":"Line Weight"},"e260":{"name":"Linear Scale"},"e157":{"name":"Link"},"e438":{"name":"Linked Camera"},"e896":{"name":"List"},"e0c6":{"name":"Live Help"},"e639":{"name":"Live Tv"},"e53f":{"name":"Local Activity"},"e53d":{"name":"Local Airport"},"e53e":{"name":"Local Atm"},"e540":{"name":"Local Bar"},"e541":{"name":"Local Cafe"},"e542":{"name":"Local Car Wash"},"e543":{"name":"Local Convenience Store"},"e556":{"name":"Local Dining"},"e544":{"name":"Local Drink"},"e545":{"name":"Local Florist"},"e546":{"name":"Local Gas Station"},"e547":{"name":"Local Grocery Store"},"e548":{"name":"Local Hospital"},"e549":{"name":"Local Hotel"},"e54a":{"name":"Local Laundry Service"},"e54b":{"name":"Local Library"},"e54c":{"name":"Local Mall"},"e54d":{"name":"Local Movies"},"e54e":{"name":"Local Offer"},"e54f":{"name":"Local Parking"},"e550":{"name":"Local Pharmacy"},"e551":{"name":"Local Phone"},"e552":{"name":"Local Pizza"},"e553":{"name":"Local Play"},"e554":{"name":"Local Post Office"},"e555":{"name":"Local Printshop"},"e557":{"name":"Local See"},"e558":{"name":"Local Shipping"},"e559":{"name":"Local Taxi"},"e7f1":{"name":"Location City"},"e1b6":{"name":"Location Disabled"},"e0c7":{"name":"Location Off"},"e0c8":{"name":"Location On"},"e1b7":{"name":"Location Searching"},"e897":{"name":"Lock"},"e898":{"name":"Lock Open"},"e899":{"name":"Lock Outline"},"e3fc":{"name":"Looks"},"e3fb":{"name":"Looks 3"},"e3fd":{"name":"Looks 4"},"e3fe":{"name":"Looks 5"},"e3ff":{"name":"Looks 6"},"e400":{"name":"Looks One"},"e401":{"name":"Looks Two"},"e028":{"name":"Loop"},"e402":{"name":"Loupe"},"e16d":{"name":"Low Priority"},"e89a":{"name":"Loyalty"},"e158":{"name":"Mail"},"e0e1":{"name":"Mail Outline"},"e55b":{"name":"Map"},"e159":{"name":"Markunread"},"e89b":{"name":"Markunread Mailbox"},"e322":{"name":"Memory"},"e5d2":{"name":"Menu"},"e252":{"name":"Merge Type"},"e0c9":{"name":"Message"},"e029":{"name":"Mic"},"e02a":{"name":"Mic None"},"e02b":{"name":"Mic Off"},"e618":{"name":"Mms"},"e253":{"name":"Mode Comment"},"e254":{"name":"Mode Edit"},"e263":{"name":"Monetization On"},"e25c":{"name":"Money Off"},"e403":{"name":"Monochrome Photos"},"e7f2":{"name":"Mood"},"e7f3":{"name":"Mood Bad"},"e619":{"name":"More"},"e5d3":{"name":"More Horiz"},"e5d4":{"name":"More Vert"},"e91b":{"name":"Motorcycle"},"e323":{"name":"Mouse"},"e168":{"name":"Move To Inbox"},"e02c":{"name":"Movie"},"e404":{"name":"Movie Creation"},"e43a":{"name":"Movie Filter"},"e6df":{"name":"Multiline Chart"},"e405":{"name":"Music Note"},"e063":{"name":"Music Video"},"e55c":{"name":"My Location"},"e406":{"name":"Nature"},"e407":{"name":"Nature People"},"e408":{"name":"Navigate Before"},"e409":{"name":"Navigate Next"},"e55d":{"name":"Navigation"},"e569":{"name":"Near Me"},"e1b9":{"name":"Network Cell"},"e640":{"name":"Network Check"},"e61a":{"name":"Network Locked"},"e1ba":{"name":"Network Wifi"},"e031":{"name":"New Releases"},"e16a":{"name":"Next Week"},"e1bb":{"name":"Nfc"},"e641":{"name":"No Encryption"},"e0cc":{"name":"No Sim"},"e033":{"name":"Not Interested"},"e06f":{"name":"Note"},"e89c":{"name":"Note Add"},"e7f4":{"name":"Notifications"},"e7f7":{"name":"Notifications Active"},"e7f5":{"name":"Notifications None"},"e7f6":{"name":"Notifications Off"},"e7f8":{"name":"Notifications Paused"},"e90a":{"name":"Offline Pin"},"e63a":{"name":"Ondemand Video"},"e91c":{"name":"Opacity"},"e89d":{"name":"Open In Browser"},"e89e":{"name":"Open In New"},"e89f":{"name":"Open With"},"e7f9":{"name":"Pages"},"e8a0":{"name":"Pageview"},"e40a":{"name":"Palette"},"e925":{"name":"Pan Tool"},"e40b":{"name":"Panorama"},"e40c":{"name":"Panorama Fish Eye"},"e40d":{"name":"Panorama Horizontal"},"e40e":{"name":"Panorama Vertical"},"e40f":{"name":"Panorama Wide Angle"},"e7fa":{"name":"Party Mode"},"e034":{"name":"Pause"},"e035":{"name":"Pause Circle Filled"},"e036":{"name":"Pause Circle Outline"},"e8a1":{"name":"Payment"},"e7fb":{"name":"People"},"e7fc":{"name":"People Outline"},"e8a2":{"name":"Perm Camera Mic"},"e8a3":{"name":"Perm Contact Calendar"},"e8a4":{"name":"Perm Data Setting"},"e8a5":{"name":"Perm Device Information"},"e8a6":{"name":"Perm Identity"},"e8a7":{"name":"Perm Media"},"e8a8":{"name":"Perm Phone Msg"},"e8a9":{"name":"Perm Scan Wifi"},"e7fd":{"name":"Person"},"e7fe":{"name":"Person Add"},"e7ff":{"name":"Person Outline"},"e55a":{"name":"Person Pin"},"e56a":{"name":"Person Pin Circle"},"e63b":{"name":"Personal Video"},"e91d":{"name":"Pets"},"e0cd":{"name":"Phone"},"e324":{"name":"Phone Android"},"e61b":{"name":"Phone Bluetooth Speaker"},"e61c":{"name":"Phone Forwarded"},"e61d":{"name":"Phone In Talk"},"e325":{"name":"Phone Iphone"},"e61e":{"name":"Phone Locked"},"e61f":{"name":"Phone Missed"},"e620":{"name":"Phone Paused"},"e326":{"name":"Phonelink"},"e0db":{"name":"Phonelink Erase"},"e0dc":{"name":"Phonelink Lock"},"e327":{"name":"Phonelink Off"},"e0dd":{"name":"Phonelink Ring"},"e0de":{"name":"Phonelink Setup"},"e410":{"name":"Photo"},"e411":{"name":"Photo Album"},"e412":{"name":"Photo Camera"},"e43b":{"name":"Photo Filter"},"e413":{"name":"Photo Library"},"e432":{"name":"Photo Size Select Actual"},"e433":{"name":"Photo Size Select Large"},"e434":{"name":"Photo Size Select Small"},"e415":{"name":"Picture As Pdf"},"e8aa":{"name":"Picture In Picture"},"e911":{"name":"Picture In Picture Alt"},"e6c4":{"name":"Pie Chart"},"e6c5":{"name":"Pie Chart Outlined"},"e55e":{"name":"Pin Drop"},"e55f":{"name":"Place"},"e037":{"name":"Play Arrow"},"e038":{"name":"Play Circle Filled"},"e039":{"name":"Play Circle Outline"},"e906":{"name":"Play For Work"},"e03b":{"name":"Playlist Add"},"e065":{"name":"Playlist Add Check"},"e05f":{"name":"Playlist Play"},"e800":{"name":"Plus One"},"e801":{"name":"Poll"},"e8ab":{"name":"Polymer"},"eb48":{"name":"Pool"},"e0ce":{"name":"Portable Wifi Off"},"e416":{"name":"Portrait"},"e63c":{"name":"Power"},"e336":{"name":"Power Input"},"e8ac":{"name":"Power Settings New"},"e91e":{"name":"Pregnant Woman"},"e0df":{"name":"Present To All"},"e8ad":{"name":"Print"},"e645":{"name":"Priority High"},"e80b":{"name":"Public"},"e255":{"name":"Publish"},"e8ae":{"name":"Query Builder"},"e8af":{"name":"Question Answer"},"e03c":{"name":"Queue"},"e03d":{"name":"Queue Music"},"e066":{"name":"Queue Play Next"},"e03e":{"name":"Radio"},"e837":{"name":"Radio Button Checked"},"e836":{"name":"Radio Button Unchecked"},"e560":{"name":"Rate Review"},"e8b0":{"name":"Receipt"},"e03f":{"name":"Recent Actors"},"e91f":{"name":"Record Voice Over"},"e8b1":{"name":"Redeem"},"e15a":{"name":"Redo"},"e5d5":{"name":"Refresh"},"e15b":{"name":"Remove"},"e15c":{"name":"Remove Circle"},"e15d":{"name":"Remove Circle Outline"},"e067":{"name":"Remove From Queue"},"e417":{"name":"Remove Red Eye"},"e928":{"name":"Remove Shopping Cart"},"e8fe":{"name":"Reorder"},"e040":{"name":"Repeat"},"e041":{"name":"Repeat One"},"e042":{"name":"Replay"},"e059":{"name":"Replay 10"},"e05a":{"name":"Replay 30"},"e05b":{"name":"Replay 5"},"e15e":{"name":"Reply"},"e15f":{"name":"Reply All"},"e160":{"name":"Report"},"e8b2":{"name":"Report Problem"},"e56c":{"name":"Restaurant"},"e561":{"name":"Restaurant Menu"},"e8b3":{"name":"Restore"},"e929":{"name":"Restore Page"},"e0d1":{"name":"Ring Volume"},"e8b4":{"name":"Room"},"eb49":{"name":"Room Service"},"e418":{"name":"Rotate 90 Degrees Ccw"},"e419":{"name":"Rotate Left"},"e41a":{"name":"Rotate Right"},"e920":{"name":"Rounded Corner"},"e328":{"name":"Router"},"e921":{"name":"Rowing"},"e0e5":{"name":"Rss Feed"},"e642":{"name":"Rv Hookup"},"e562":{"name":"Satellite"},"e161":{"name":"Save"},"e329":{"name":"Scanner"},"e8b5":{"name":"Schedule"},"e80c":{"name":"School"},"e1be":{"name":"Screen Lock Landscape"},"e1bf":{"name":"Screen Lock Portrait"},"e1c0":{"name":"Screen Lock Rotation"},"e1c1":{"name":"Screen Rotation"},"e0e2":{"name":"Screen Share"},"e623":{"name":"Sd Card"},"e1c2":{"name":"Sd Storage"},"e8b6":{"name":"Search"},"e32a":{"name":"Security"},"e162":{"name":"Select All"},"e163":{"name":"Send"},"e811":{"name":"Sentiment Dissatisfied"},"e812":{"name":"Sentiment Neutral"},"e813":{"name":"Sentiment Satisfied"},"e814":{"name":"Sentiment Very Dissatisfied"},"e815":{"name":"Sentiment Very Satisfied"},"e8b8":{"name":"Settings"},"e8b9":{"name":"Settings Applications"},"e8ba":{"name":"Settings Backup Restore"},"e8bb":{"name":"Settings Bluetooth"},"e8bd":{"name":"Settings Brightness"},"e8bc":{"name":"Settings Cell"},"e8be":{"name":"Settings Ethernet"},"e8bf":{"name":"Settings Input Antenna"},"e8c0":{"name":"Settings Input Component"},"e8c1":{"name":"Settings Input Composite"},"e8c2":{"name":"Settings Input Hdmi"},"e8c3":{"name":"Settings Input Svideo"},"e8c4":{"name":"Settings Overscan"},"e8c5":{"name":"Settings Phone"},"e8c6":{"name":"Settings Power"},"e8c7":{"name":"Settings Remote"},"e1c3":{"name":"Settings System Daydream"},"e8c8":{"name":"Settings Voice"},"e80d":{"name":"Share"},"e8c9":{"name":"Shop"},"e8ca":{"name":"Shop Two"},"e8cb":{"name":"Shopping Basket"},"e8cc":{"name":"Shopping Cart"},"e261":{"name":"Short Text"},"e6e1":{"name":"Show Chart"},"e043":{"name":"Shuffle"},"e1c8":{"name":"Signal Cellular 4 Bar"},"e1cd":{"name":"Signal Cellular Connected No Internet 4 Bar"},"e1ce":{"name":"Signal Cellular No Sim"},"e1cf":{"name":"Signal Cellular Null"},"e1d0":{"name":"Signal Cellular Off"},"e1d8":{"name":"Signal Wifi 4 Bar"},"e1d9":{"name":"Signal Wifi 4 Bar Lock"},"e1da":{"name":"Signal Wifi Off"},"e32b":{"name":"Sim Card"},"e624":{"name":"Sim Card Alert"},"e044":{"name":"Skip Next"},"e045":{"name":"Skip Previous"},"e41b":{"name":"Slideshow"},"e068":{"name":"Slow Motion Video"},"e32c":{"name":"Smartphone"},"eb4a":{"name":"Smoke Free"},"eb4b":{"name":"Smoking Rooms"},"e625":{"name":"Sms"},"e626":{"name":"Sms Failed"},"e046":{"name":"Snooze"},"e164":{"name":"Sort"},"e053":{"name":"Sort By Alpha"},"eb4c":{"name":"Spa"},"e256":{"name":"Space Bar"},"e32d":{"name":"Speaker"},"e32e":{"name":"Speaker Group"},"e8cd":{"name":"Speaker Notes"},"e92a":{"name":"Speaker Notes Off"},"e0d2":{"name":"Speaker Phone"},"e8ce":{"name":"Spellcheck"},"e838":{"name":"Star"},"e83a":{"name":"Star Border"},"e839":{"name":"Star Half"},"e8d0":{"name":"Stars"},"e0d3":{"name":"Stay Current Landscape"},"e0d4":{"name":"Stay Current Portrait"},"e0d5":{"name":"Stay Primary Landscape"},"e0d6":{"name":"Stay Primary Portrait"},"e047":{"name":"Stop"},"e0e3":{"name":"Stop Screen Share"},"e1db":{"name":"Storage"},"e8d1":{"name":"Store"},"e563":{"name":"Store Mall Directory"},"e41c":{"name":"Straighten"},"e56e":{"name":"Streetview"},"e257":{"name":"Strikethrough S"},"e41d":{"name":"Style"},"e5d9":{"name":"Subdirectory Arrow Left"},"e5da":{"name":"Subdirectory Arrow Right"},"e8d2":{"name":"Subject"},"e064":{"name":"Subscriptions"},"e048":{"name":"Subtitles"},"e56f":{"name":"Subway"},"e8d3":{"name":"Supervisor Account"},"e049":{"name":"Surround Sound"},"e0d7":{"name":"Swap Calls"},"e8d4":{"name":"Swap Horiz"},"e8d5":{"name":"Swap Vert"},"e8d6":{"name":"Swap Vertical Circle"},"e41e":{"name":"Switch Camera"},"e41f":{"name":"Switch Video"},"e627":{"name":"Sync"},"e628":{"name":"Sync Disabled"},"e629":{"name":"Sync Problem"},"e62a":{"name":"System Update"},"e8d7":{"name":"System Update Alt"},"e8d8":{"name":"Tab"},"e8d9":{"name":"Tab Unselected"},"e32f":{"name":"Tablet"},"e330":{"name":"Tablet Android"},"e331":{"name":"Tablet Mac"},"e420":{"name":"Tag Faces"},"e62b":{"name":"Tap And Play"},"e564":{"name":"Terrain"},"e262":{"name":"Text Fields"},"e165":{"name":"Text Format"},"e0d8":{"name":"Textsms"},"e421":{"name":"Texture"},"e8da":{"name":"Theaters"},"e8db":{"name":"Thumb Down"},"e8dc":{"name":"Thumb Up"},"e8dd":{"name":"Thumbs Up Down"},"e62c":{"name":"Time To Leave"},"e422":{"name":"Timelapse"},"e922":{"name":"Timeline"},"e425":{"name":"Timer"},"e423":{"name":"Timer 10"},"e424":{"name":"Timer 3"},"e426":{"name":"Timer Off"},"e264":{"name":"Title"},"e8de":{"name":"Toc"},"e8df":{"name":"Today"},"e8e0":{"name":"Toll"},"e427":{"name":"Tonality"},"e913":{"name":"Touch App"},"e332":{"name":"Toys"},"e8e1":{"name":"Track Changes"},"e565":{"name":"Traffic"},"e570":{"name":"Train"},"e571":{"name":"Tram"},"e572":{"name":"Transfer Within A Station"},"e428":{"name":"Transform"},"e8e2":{"name":"Translate"},"e8e3":{"name":"Trending Down"},"e8e4":{"name":"Trending Flat"},"e8e5":{"name":"Trending Up"},"e429":{"name":"Tune"},"e8e6":{"name":"Turned In"},"e8e7":{"name":"Turned In Not"},"e333":{"name":"Tv"},"e169":{"name":"Unarchive"},"e166":{"name":"Undo"},"e5d6":{"name":"Unfold Less"},"e5d7":{"name":"Unfold More"},"e923":{"name":"Update"},"e1e0":{"name":"Usb"},"e8e8":{"name":"Verified User"},"e258":{"name":"Vertical Align Bottom"},"e259":{"name":"Vertical Align Center"},"e25a":{"name":"Vertical Align Top"},"e62d":{"name":"Vibration"},"e070":{"name":"Video Call"},"e071":{"name":"Video Label"},"e04a":{"name":"Video Library"},"e04b":{"name":"Videocam"},"e04c":{"name":"Videocam Off"},"e338":{"name":"Videogame Asset"},"e8e9":{"name":"View Agenda"},"e8ea":{"name":"View Array"},"e8eb":{"name":"View Carousel"},"e8ec":{"name":"View Column"},"e42a":{"name":"View Comfy"},"e42b":{"name":"View Compact"},"e8ed":{"name":"View Day"},"e8ee":{"name":"View Headline"},"e8ef":{"name":"View List"},"e8f0":{"name":"View Module"},"e8f1":{"name":"View Quilt"},"e8f2":{"name":"View Stream"},"e8f3":{"name":"View Week"},"e435":{"name":"Vignette"},"e8f4":{"name":"Visibility"},"e8f5":{"name":"Visibility Off"},"e62e":{"name":"Voice Chat"},"e0d9":{"name":"Voicemail"},"e04d":{"name":"Volume Down"},"e04e":{"name":"Volume Mute"},"e04f":{"name":"Volume Off"},"e050":{"name":"Volume Up"},"e0da":{"name":"Vpn Key"},"e62f":{"name":"Vpn Lock"},"e1bc":{"name":"Wallpaper"},"e002":{"name":"Warning"},"e334":{"name":"Watch"},"e924":{"name":"Watch Later"},"e42c":{"name":"Wb Auto"},"e42d":{"name":"Wb Cloudy"},"e42e":{"name":"Wb Incandescent"},"e436":{"name":"Wb Iridescent"},"e430":{"name":"Wb Sunny"},"e63d":{"name":"Wc"},"e051":{"name":"Web"},"e069":{"name":"Web Asset"},"e16b":{"name":"Weekend"},"e80e":{"name":"Whatshot"},"e1bd":{"name":"Widgets"},"e63e":{"name":"Wifi"},"e1e1":{"name":"Wifi Lock"},"e1e2":{"name":"Wifi Tethering"},"e8f9":{"name":"Work"},"e25b":{"name":"Wrap Text"},"e8fa":{"name":"Youtube Searched For"},"e8ff":{"name":"Zoom In"},"e900":{"name":"Zoom Out"},"e56b":{"name":"Zoom Out Map"}}} \ No newline at end of file diff --git a/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.svg b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.svg new file mode 100644 index 0000000..a449327 --- /dev/null +++ b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.svg @@ -0,0 +1,2373 @@ + + + + + +Created by FontForge 20151118 at Mon Feb 8 11:58:02 2016 + By shyndman +Copyright 2015 Google, Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.ttf b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.ttf new file mode 100644 index 0000000..7015564 Binary files /dev/null and b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.ttf differ diff --git a/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.woff b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.woff new file mode 100644 index 0000000..b648a3e Binary files /dev/null and b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.woff differ diff --git a/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.woff2 b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.woff2 new file mode 100644 index 0000000..9fa2112 Binary files /dev/null and b/src/gui/static/src/assets/fonts/material-icons/MaterialIcons-Regular.woff2 differ diff --git a/src/gui/static/src/assets/fonts/material-icons/material-icons.css b/src/gui/static/src/assets/fonts/material-icons/material-icons.css new file mode 100644 index 0000000..2270c09 --- /dev/null +++ b/src/gui/static/src/assets/fonts/material-icons/material-icons.css @@ -0,0 +1,36 @@ +@font-face { + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: url(MaterialIcons-Regular.eot); /* For IE6-8 */ + src: local('Material Icons'), + local('MaterialIcons-Regular'), + url(MaterialIcons-Regular.woff2) format('woff2'), + url(MaterialIcons-Regular.woff) format('woff'), + url(MaterialIcons-Regular.ttf) format('truetype'); +} + +.material-icons { + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 24px; /* Preferred icon size */ + display: inline-block; + line-height: 1; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + white-space: nowrap; + direction: ltr; + + /* Support for all WebKit browsers. */ + -webkit-font-smoothing: antialiased; + /* Support for Safari and Chrome. */ + text-rendering: optimizeLegibility; + + /* Support for Firefox. */ + -moz-osx-font-smoothing: grayscale; + + /* Support for IE. */ + font-feature-settings: 'liga'; +} diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-Bold.woff b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Bold.woff new file mode 100644 index 0000000..780de6d Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Bold.woff differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-Bold.woff2 b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Bold.woff2 new file mode 100644 index 0000000..72a32ab Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Bold.woff2 differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-BoldItalic.woff b/src/gui/static/src/assets/fonts/skycoin/Skycoin-BoldItalic.woff new file mode 100644 index 0000000..20ec4ab Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-BoldItalic.woff differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-BoldItalic.woff2 b/src/gui/static/src/assets/fonts/skycoin/Skycoin-BoldItalic.woff2 new file mode 100644 index 0000000..642a2d4 Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-BoldItalic.woff2 differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-Light.woff b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Light.woff new file mode 100644 index 0000000..a994609 Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Light.woff differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-Light.woff2 b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Light.woff2 new file mode 100644 index 0000000..b3238fa Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Light.woff2 differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-LightItalic.woff b/src/gui/static/src/assets/fonts/skycoin/Skycoin-LightItalic.woff new file mode 100644 index 0000000..7cc63b7 Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-LightItalic.woff differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-LightItalic.woff2 b/src/gui/static/src/assets/fonts/skycoin/Skycoin-LightItalic.woff2 new file mode 100644 index 0000000..3f438f8 Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-LightItalic.woff2 differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-Regular.woff b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Regular.woff new file mode 100644 index 0000000..40c056e Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Regular.woff differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-Regular.woff2 b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Regular.woff2 new file mode 100644 index 0000000..46f89cf Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-Regular.woff2 differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-RegularItalic.woff b/src/gui/static/src/assets/fonts/skycoin/Skycoin-RegularItalic.woff new file mode 100644 index 0000000..ddc9c01 Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-RegularItalic.woff differ diff --git a/src/gui/static/src/assets/fonts/skycoin/Skycoin-RegularItalic.woff2 b/src/gui/static/src/assets/fonts/skycoin/Skycoin-RegularItalic.woff2 new file mode 100644 index 0000000..08d7a51 Binary files /dev/null and b/src/gui/static/src/assets/fonts/skycoin/Skycoin-RegularItalic.woff2 differ diff --git a/src/gui/static/src/assets/header.png b/src/gui/static/src/assets/header.png new file mode 100644 index 0000000..be1002a Binary files /dev/null and b/src/gui/static/src/assets/header.png differ diff --git a/src/gui/static/src/assets/i18n/README.md b/src/gui/static/src/assets/i18n/README.md new file mode 100644 index 0000000..89d32fd --- /dev/null +++ b/src/gui/static/src/assets/i18n/README.md @@ -0,0 +1,369 @@ +This folder contains the GUI translation files. To maintain order and be able +to easily make any necessary updates to the translation files after updating +the main text file, please follow its instructions if you are working with +its contents. + +# Table of Contents + +- [Contents of this folder](#contents-of-this-folder) +- [About the meaning of "xx" in this file](#about-the-meaning-of-"xx"-in-this-file) +- [Add a new translation](#add-a-new-translation) +- [Verify the translation files](#verify-the-translation-files) + - [Checking for problems](#checking-for-problems) + - [Checking if a language file needs to be updated](#checking-if-a-language-file-needs-to-be-updated) +- [Update a translation](#update-a-translation) +- [How to edit the translation files](#how-to-edit-the-translation-files) + - [Which application should be used for editing the files](#which-application-should-be-used-for-editing-the-files) + - [Special codes](#special-codes) +- [Writing style](#writing-style) +- [Make a translation available in the application](#make-a-translation-available-in-the-application) + +# Contents of this folder + +The contents of this folder are: + +- `README.md`: this file. + +- `check.js`: file with the script for detecting if a translation file has errors +or should be updated. + +- `en.json`: main file with all the texts of the application, in English. It should +only be modified when changing the texts of the application (add, modify and +delete). This means that the file must not be modified while creating a new +ranslation or modifying an existing one. + +- Various `xx.json` files: files with the translated versions of the texts of +`en.json`. + +- Various `xx_base.json` files: files with copies of `en.json` made the last time the +corresponding `xx.json` file was modified. + +Normally there is no need to modify the first two files. + +For more information about the `xx.json` and `xx_base.json`, please check the +[Add a new translation](#add-a-new-translation) and +[Update a translation](#update-a-translation) sections. + +# About the meaning of "xx" in this file + +Several parts of this file uses "xx" as part of file names or scripts, like +`xx.json` and `xx_base.json`. In fact, no file in this folder should be called +`xx.json` or `xx_base.json`, the "xx" part must be replaces with the two +characters code of the language. For example, if you are working with the Chinese +translation, the files will be `zh.json` and `zh_base.json`, instead of `xx.json` +and `xx_base.json`. The same if true for the scripts, if you are working with the +Chinese translation, instead of running `node check.js xx` you must run +`node check.js zh`. + +# Add a new translation + +First you must create in this folder two copies of the `en.json` file. The first +copy must be called `xx.json`, where the `xx` part must be the two characters code +of the new language. For example, for Chinese the name of the file should be +`zh.json`; for Spanish, `es.json`; for French, `fr.json`, etc. + +The second copy of `en.json` must be renamed to `xx_base.json`, where the `xx` part +must be the two characters code of the new language. This means that if the first +copy is named `zh.json`, the second one should be named `zh_base.json`. + +It is not necessary to follow a specific standard for the two characters code, but +it must be limited to two letters and be a recognizable code for the language. + +After creating the two files, simply translate the texts in `xx.json`. Please make +sure you do not modify the structure of `xx.json`, just modify the texts. + +The `xx_base.json` file must not be modified in any way, as it is used only as a way +to know what the state of `en.json` was the last time the `xx.json` file was +modified. This copy will be compared in the future with `en.json`, to verify if +there were modifications to `en.json` since the last time the translation file was +modified and if an update is needed. + +If the `xx.json` and `xx_base.json` files do not have the same elements, the +automatic tests could fail when uploading the changes to the repository, preventing +the changes from being accepted, so, again, it is important not to modify the +structure of `xx.json`, but only its contents. + +After doing all this, the translation will be ready, but will not be available in +the GUI until adding it to the code. + +# Verify the translation files + +This folder includes a script that is capable of automatically checking the +translation files, to detect problems and know what should be updated. + +For using it, your computer must have `Node.js` installed. + +## Checking for problems + +For detecting basic problems on the translation files, open a command line window +in this folder and run `node check.js`. This will check the following: + +- The `en.json` must exist, as it is the main language file for the app. + +- For every `xx.json` file (except `en.json`) an `xx_base.json` file must exist +and viceversa. + +- A `xx.json` file and its corresponding `xx_base.json` file must have the exact +same elements (only the content of that elements could be different), as the +`xx.json` is suposed to be the translation of the contents of `xx_base.json`. + +As you can see, this only checks for errors that could be made while creating or +modifying the `xx.json` and `xx_base.json` files, and does not check if any +translation needs to be updated. + +At the end of the script excecution, the console will display the list of all +errors found, if any. This check could be done automatically when making changes +to the repository, to reject updates with problems, so it is good idea to run it +manually before uploading changes. + +Note: at this time the script does not check if the elements of the files are +in the same order, but this could be added in the future, so it is recomended +not to change the order of the elements. + +## Checking if a language file needs to be updated + +To detect if an specific language needs updating, run `node check.js xx`, +where xx is the two characters code of the language you want to check. If you +want to check all languages, run `node check.js all`. + +By doing this, the script will perform all the checks described in the +[Checking for problems](#checking-for-problems) section, plus this: + +- The `en.json` and `xx_base.json` should have the same elements. If `en.json` +has elements that `xx_base.json` does not contain, it means that, since the +last time the translation file was updated, new texts have been added to the +application. If `xx_base.json` has elements that `en.json` does not contain, +it means that, since the last time the translation file was updated, some texts +have been removed from the application. Both cases mean that the translation +file should be updated. + +- The elements of `en.json` and `xx_base.json` should have the same content. +If any element have different content, it means that since the last time the +translation file was updated, some texts of the applications have been changed. +This means that the translation file should be updated. + +At the end of the script excecution, the console will display the list of all +errors found, if any. + +# Update a translation + +Before updating a translation file, you should follow the steps of the +[Checking if a language file needs to be updated](#Checking-if-a-language-file-needs-to-be-updated) +section. By doing so you will quikly know exactly what texts must be added, +deleted or edited. + +After doing that, make all the required modifications in the `xx.json` file, +this means adding, deleting and modifying all the elements indicated by the +script. Please be sure to modify only what is required and to add any new +element in the same position that it is in the `en.json` file. This process +is manual, so be sure check all the changes before finishing. + +After doing the modifications in `xx.json`, delete the `xx_base.json` file, +create a copy of `en.json` and rename it `xx_base.json`. The objetive is to +simply update the `xx_base.json` file to the current state of `en.json`. +this will make possible to check in the future if more updates are nedded, +due to new changes in `en.json`. + +Once all the changes are made, check again the language file as indicated +in the +[Checking if a language file needs to be updated](#Checking-if-a-language-file-needs-to-be-updated) +section. The script should not return errors. If the script returns errors, +please solve them before continuing. + +# How to edit the translation files + +The translation files are in json format (.json files). It is possible to +open these files in a text editor and edit them like normal text files. +However, the json files are used for coding and have a very strict format. +Because of this, **editing the files manually is not recommended** unless +you know exactly what you are doing. + +If you do not know the json format, this section includes useful +information to be able to edit the files easily. + +## Which application should be used for editing the files + +There are several application that allow editing json files, including +some text editors. However, it is recommended to use the Json Editor app +for Google Chrome. Among the advantages of this application are that it +is multiplatform, it allows editing the contents without having to +directly modify the json code and has a relatively simple interface. You +can add it to your Chrome browser from here: +https://chrome.google.com/webstore/detail/json-editor/lhkmoheomjbkfloacpgllgjcamhihfaj + +The app looks like this: + +![app](app1.png) + +As you can see, you can load/save files on the upper-right corner of +the app. The left part shows the source code and the right part shows +a tree view of the elements of the file and its contents. You can +ignore the source code and work with the tree view only. + +![app](app2.png) + +As you will not be editing the soutce code, you can hide it by presing +and draging the 3-dot button (1). While editing the file, you can use +the arrows (2) to expand/contract the different sections in which the +elements are organized. Once you find an item that you want to edit, +click on the content and modify the text (3). Please, do not make any +changes to the name of the element (4). + +You can use the 6-dot buttons (5) to move the elements to a different +location, but please avoid doing it, as that could alter the order of +the file in a way that would make it stop working. Also, as you will +not be working with the source code, avoid using the arrow +buttons (6). + +## Special codes + +Some texts in the language files have special codes that are not +shown in the user interface of the wallet, but serve special purposes. +The codes are: + +- **\\"**: due to how json files work, it is not possible to write +double quotes directly in the texts, the ccorrect way to add double +quotes to a json file is **\\"** (note that the 2 characters must not +be separated by a white space). If you use the Json Editor app for +Google Chrome, you can write double quotes normally and the app will +automatically add the **\\** character behind them, but that is just +a convenience for when you are writing, you could still find the +**\\"** code in files you are editing and have to work with it. + +- **{{ }}**: any text block similar to **{{ something }}** is a +special identifier that the code will replace with a different value +when the app is running. For example, if you find a text like "Your +balance is {{ value }} coins", the application will show something +like "Your balance is 21 coins". In that example the "21" is a value +that the app has to calculate, so it is not possible to add it directly +into the language file. If you find a **{{ }}** text block, please do +not translate it, just move the whole **{{ }}** text block to where the +value should be displayed. If you want to leave a while space before the +value, simply add a white space before the **{{ }}** text block, and do +the same after it if you want a white space after the value. + +- **\
**: this code means "new line". It is just a way to tell +the code that the text after it should be added in a new line. + +# Writing style + +The file contains many different types of texts: buttons, labels, +indications, titles and more. the name of each text can give important +information about what the text is used for and which writing format +should be used. Specifically, many texts have predefined prefixes or +suffixes that indicate what the text is used for and some special +characteristics that the text must follow. The prefixes and suffixes are: + +- **title**: the text if the title of a page or a modal window. Those +text use title format, so each word must start with an uppercase letter +and don't end with period. + +- **button**: the text is used in a small button (like the blue +confirmation buttons shown in most modal windows). Those text indicate +actions and should be kept as short as possible, as the button are small. +Those text use title format, so each word must start with an uppercase +letter and don't end with period. + +- **title-and-button**: the text is a title, but it is also used inside +a button, so it must be treated as a title, but must also be kept as +short as possible. + +- **label**: the text is used to identify a form field (it is shown at +the top of an area in wich the user can enter text or select an option). +Those text don't dont use title format, so normally only the first word +must start with an uppercase letter. Those text don't end with period or +any other spcial character. + +- **check**: the text is used in a check box (a small box which the user +can select to accept something). Those text don't dont use title format, +so normally only the first word must start with an uppercase letter. +Those text don't end with period. + +- **error**, **warning**, **help**, **desc** and **info**: those text are +used to give general information to the user; don't dont use title format, +so normally only the first word must start with an uppercase letter; and +end with period. + +- **confirmation**: the text is used for asking the user to confirm an +action. Those texts normally end with a question which should be answered +with yes/no, continue/cancel or similar options which are added by the +code, so it is important to maintain the nature of the question. + +- **part#**: those text are divided in various parts. The reason for +dividing a text is that the whoole text will be shown in a single line, +but each part will have different properties in the UI. For example, a +part could be a link, or could be in a different color, or the code could +add additional content in the middle of 2 parts. + +- **small-label**: the text is used as a part of a text line. Those texts +are normally the left part of a line shown on a list, just like this +prefixes and suffixes list, so they end with a colon, but that is not always +the case. Those text must be kept as short as possible, as the UI has little +space for them. + +- **table-label**: the text is used on the header of a table, to identify +a column. In the case of small-table-label, the text must be kept as short +as possible. Those text don't dont use title format, so normally only the +first word must start with an uppercase letter. + +Not all the text have a prefix o rsuffix from the previous list and +sometimes it is not too easy to identify what each text is for and how +it is used in the code. Because of that, and to avoid having to check the +previous list constantly, it is advisable to follow the following +recommendations: + +- **Respect the capitalization style**: different elements on the +application use a particular capitalization style, so changing +capitalization on the translation file may make the UI look +inconsistent. + +- **Respect the finishing characters**: some texts end with a period and +others with a blank space. Those elements may be important for the +UI, as a way for separating the texts from another text which is added +at the right by the code, so removing the periods and blank spaces at +the end may cause problems to the UI. + +- **Use the contex**t: most of the texts are inside groups with other +related texts, which may give some context. + +# Make a translation available in the application + +Although creating the translation files is the most important step, it is +necessary to make some additional changes before a translation is +available in the application. + +The first thing to do is to add a bitmap in +[src/gui/static/src/assets/img/lang](src/gui/static/src/assets/img/lang), +with the flag that will be used to identify the language. The bitmap +should be a .png file with transparent background and a size of 64x64 +pixels. However, the flag does not have to occupy all the space of the +bitmap, but it should be 64 pixels wide and only 42 pixels high, +centered. Please use as a reference the flags that are already in +the folder. + +After adding the flag, you must modify the +[src/gui/static/src/app/app.config.ts](src/gui/static/src/app/app.config.ts) +file. In particular, you must add a new entry to the `languages` array, +with the data about the language. The object you must add is similar +to this: + +``` +{ + code: 'en', + name: 'English', + iconName: 'en.png' +} +``` + +The properties are: + +- `code`: 2 letter code that was assigned to the language. It must match +the name given to the translation file. + +- `name`: Name of the language. + +- `iconName`: Name of the file with the flag, which was added in the +previous step. + +Please use as a reference the data of the languages that have already +been added to the `languages` array. diff --git a/src/gui/static/src/assets/i18n/app1.png b/src/gui/static/src/assets/i18n/app1.png new file mode 100644 index 0000000..67c7501 Binary files /dev/null and b/src/gui/static/src/assets/i18n/app1.png differ diff --git a/src/gui/static/src/assets/i18n/app2.png b/src/gui/static/src/assets/i18n/app2.png new file mode 100644 index 0000000..6cabfe6 Binary files /dev/null and b/src/gui/static/src/assets/i18n/app2.png differ diff --git a/src/gui/static/src/assets/i18n/check.js b/src/gui/static/src/assets/i18n/check.js new file mode 100644 index 0000000..b70f022 --- /dev/null +++ b/src/gui/static/src/assets/i18n/check.js @@ -0,0 +1,230 @@ +'use strict' + +const fs = require('fs'); + +///////////////////////////////////////////// +// Initial configuration +///////////////////////////////////////////// + +console.log('Starting to check the language files.', '\n'); + +// Load the current English file. +if (!fs.existsSync('en.json')) { + exitWithError('Unable to find the English language file.'); +} +let currentData = JSON.parse(fs.readFileSync('en.json', 'utf8')); + +// 2 charaters code of the languages that will be checked. +const langs = []; +// If false, the code will only verify the differences in the elements (ignoring its contents) of the +// base files and the files with the translations. If not, the code will also verify the differences +// in the elements and contents of the base files and the current English file. +let checkFull = false; + +// If a param was send, it must be "all" or the 2 charaters code of the language that must be checked. +// If a param is provided, checkFull is set to true. +if (process.argv.length > 2) { + if (process.argv.length > 3) { + exitWithError('Invalid number of parameters.'); + } + + if (process.argv[2] != 'all') { + if (process.argv[2].length !== 2) { + exitWithError('You can only send as parameter to this script the 2-letter code of one of the language files in this folder, or "all".'); + } + langs.push(process.argv[2]); + } + + checkFull = true; +} + +// If no language code was send as param, the code will check all languages. +if (langs.length === 0) { + let localFiles = fs.readdirSync('./'); + + const langFiles = []; + const langFilesMap = new Map(); + const baseLangFilesMap = new Map(); + localFiles.forEach(file => { + if (file.length === 12 && file.endsWith('_base.json')) { + langs.push(file.substring(0, 2)); + baseLangFilesMap.set(file.substring(0, 2), true); + } + if (file !== 'en.json' && file.length === 7 && file.endsWith('.json')) { + langFiles.push(file.substring(0, 2)); + langFilesMap.set(file.substring(0, 2), true); + } + }); + + langs.forEach(lang => { + if (!langFilesMap.has(lang)) { + exitWithError('The \"' + lang + '_base.json\" base file does not have its corresponding language file.'); + } + }); + + langFiles.forEach(lang => { + if (!baseLangFilesMap.has(lang)) { + exitWithError('The \"' + lang + '.json\" file does not have its corresponding base file.'); + } + }); + + if (langs.length === 0) { + exitWithError('No language files to check.'); + } +} + +console.log('Checking the following languages:'); +langs.forEach(lang => { + console.log(lang); +}); +console.log(''); + +///////////////////////////////////////////// +// Verifications +///////////////////////////////////////////// + +// The following arrays will contain the list of elements with problems. Each element of the +// arrays contains a "lang" property with the language identifier and a "elements" array with +// the path of the problematic elements. + +// Elements that are present in a base file but not in its corresponding translation file. +const baseFileOnly = []; +// Elements that are present in a translation file but not in its corresponding base file. +const translatedFileOnly = []; +// Elements that are present in the English file but not in the currently checked base translation file. +const enOnly = []; +// Elements that are present in the currently checked base translation file but not in the English file. +const translatedOnly = []; +// Elements that have different values in the currently checked base translation file and the English file. +const different = []; + +function addNewLangToArray(array, lang) { + array.push({ + lang: lang, + elements: [] + }); +} + +langs.forEach(lang => { + addNewLangToArray(baseFileOnly, lang); + addNewLangToArray(translatedFileOnly, lang); + addNewLangToArray(enOnly, lang); + addNewLangToArray(translatedOnly, lang); + addNewLangToArray(different, lang); + + // Try to load the translation file and its corresponding base file. + if (!fs.existsSync(lang + '.json')) { + exitWithError('Unable to find the ' + lang + '.json file.'); + } + let translationData = JSON.parse(fs.readFileSync(lang + '.json', 'utf8')); + + if (!fs.existsSync(lang + '_base.json')) { + exitWithError('Unable to find the ' + lang + '_base.json language file.'); + } + let baseTranslationData = JSON.parse(fs.readFileSync(lang + '_base.json', 'utf8')); + + // Check the differences in the elements of the translation file and its base file. + checkElement('', '', baseTranslationData, translationData, baseFileOnly, true); + checkElement('', '', translationData, baseTranslationData, translatedFileOnly, true); + + // Check the differences in the elements and content of the base translation file the English file. + if (checkFull) { + checkElement('', '', currentData, baseTranslationData, enOnly, false); + checkElement('', '', baseTranslationData, currentData, translatedOnly, true); + } +}); + + +// Check recursively if the elements and content of two language objects are the same. +// +// path: path of the currently checked element. As this function works with nested elements, +// the path is the name of all the parents, separated by a dot. +// key: name of the current element. +// fist: first element for the comparation. +// second: second element for the comparation. +// arrayForMissingElements: array in which the list of "fist" elements that are not in "second" +// will be added. +// ignoreDifferences: if false, each time the content of an element in "fist" is different to the +// same element in "second" that element will be added to the "different" array. +function checkElement(path, key, fist, second, arrayForMissingElements, ignoreDifferences) { + let pathPrefix = ''; + if (path.length > 0) { + pathPrefix = '.'; + } + + // This means that, at some point, the code found an element in the "first" branch that is + // not in the "second" branch. + if (second === undefined || second === null) { + arrayForMissingElements[arrayForMissingElements.length - 1].elements.push(path + pathPrefix + key); + return; + } + + if (typeof fist !== 'object') { + // If the current element is a string, compare the contents, but ony if ignoreDifferences + // is true. + if (!ignoreDifferences && fist != second) { + different[different.length - 1].elements.push(path + pathPrefix + key); + } + } else { + // If the current element is an object, check the childs. + Object.keys(fist).forEach(currentKey => { + checkElement(path + pathPrefix + key, currentKey, fist[currentKey], second[currentKey], arrayForMissingElements, ignoreDifferences); + }); + } +} + +///////////////////////////////////////////// +// Results processing +///////////////////////////////////////////// + +// Becomes true if any of the verifications failed. +let failedValidation = false; + +// If "failedValidation" is false, writes to the console the header of the error list +// and updates the value of "failedValidation" to true. +function updateErrorSumary() { + if (!failedValidation) { + failedValidation = true; + console.log('The following problems were found:', '\n'); + } +} + +// Checks all arrays for errors. This loop is for the languages. +for (let i = 0; i < baseFileOnly.length; i++) { + + // This loop if for checking all the arrays. + [baseFileOnly, translatedFileOnly, enOnly, translatedOnly, different].forEach((array, idx) => { + // If the array has elements, it means that errors were found. + if (array[i].elements.length > 0) { + updateErrorSumary(); + + // Show the appropriate error text according to the current array. + if (idx === 0) { + console.log('The \"' + baseFileOnly[i].lang + '_base.json\" base file has elements that are not present in \"' + baseFileOnly[i].lang + '.json\":'); + } else if (idx === 1) { + console.log("\"" + translatedFileOnly[i].lang + '.json\" has elements that are not present in the \"' + baseFileOnly[i].lang + '_base.json\" base file:'); + } else if (idx === 2) { + console.log('The \"en.json\" file has elements that are not present in the \"' + enOnly[i].lang + '_base.json\" base file:'); + } else if (idx === 3) { + console.log('The \"' + translatedOnly[i].lang + '_base.json\" base file has elements that are not present in \"en.json\":'); + } else if (idx === 4) { + console.log('The \"' + different[i].lang + '_base.json\" base file has values that do not match the ones in \"en.json\":'); + } + // Show all the elements with errors. + array[i].elements.forEach(element => console.log(element)); + console.log(''); + } + }); +} + +// If no error was detected, show a success message on the console. If not, exit with an error code. +if (!failedValidation) { + console.log('The verification passed without problems.'); +} else { + process.exit(1); +} + +function exitWithError(errorMessage) { + console.log('Error: ' + errorMessage) + process.exit(1); +} diff --git a/src/gui/static/src/assets/i18n/en.json b/src/gui/static/src/assets/i18n/en.json new file mode 100644 index 0000000..bb74c8b --- /dev/null +++ b/src/gui/static/src/assets/i18n/en.json @@ -0,0 +1,881 @@ +{ + "common": { + "usd": "USD", + "loading": "Loading...", + "done-title": "Done", + "warning-title": "Warning", + "error-title": "Error", + "changes-made": "The changes have been made.", + "back-button": "Back", + "create-button": "Create", + "load-button": "Load", + "cancel-button": "Cancel", + "continue-button": "Continue", + "close-button": "Close", + "generic-confirmation-check": "I understand the risks and want to continue", + "copied": "The text has been copied to the clipboard.", + "confirmations": "Confirmations", + "unconfirmed-balance-info": "This balance will be final after your last transactions receive more confirmations from the network. The currently confirmed balance is {{ balance }}. For more information check your pending transactions." + }, + + "errors": { + "window-size": "The window is too narrow for the content." + }, + + "language": { + "title": "Select Language" + }, + + "header": { + "syncing-blocks": "Syncing blocks", + "explorer-link": "{{ coinName }} Explorer", + + "top-bar": { + "updated-label": "Balance updated:", + "updated-time": "{{ time }} min ago", + "less-than": "less than a min ago", + "connection-error-info": "Connection error, press to retry." + }, + + "warnings": { + "update-part1": "Wallet update", + "update-part2": "Not used. The code adds the versión number of the lastest update here.", + "update-part3": "available.", + "synchronizing": "The wallet is synchronizing. Data you see may not be updated.", + "pending-txs-part1": "You have", + "pending-txs-part2": "pending transactions.", + "pending-txs-part3": "The balances and some other data may not be updated.", + "pending-link-error": "You are already in the transaction history page.", + "no-connections": "No connections active, your client is not connected to any other nodes!", + "no-backend-part1": "Cannot reach backend. Please restart the app and/or seek help on our", + "no-backend-part2": "Telegram.", + "no-backend-part3": "", + "csrf": "Security vulnerability: CSRF is not working, please exit immediately." + } + }, + + "password": { + "title": "Enter Password", + "password-label": "Password", + "password-error-info": "You must enter a password.", + "confirm-password-label": "Confirm password", + "confirm-error-info": "The two passwords must match.", + "proceed-button": "Proceed", + "reset-link": "I forgot my password", + "incorrect-password-error": "Incorrect password.", + "decrypting-error": "Error decrypting the wallet." + }, + + "buy": { + "title-and-button": "Buy", + "deposit-address": "Choose an address to generate a BTC deposit link for:", + "select-address": "Select address", + "generate": "Generate", + "deposit-location": "Deposit Location", + "deposit-location-desc": "Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.", + "make-choice": "Make a choice", + "wallets-desc": "Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.", + "send": "Send Bitcoin", + "send-desc": "Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.", + "fraction-warning": "Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!", + "receive": "Receive Sky", + "receive-desc": "After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.", + "status-button": "Status:", + "check-status-button": "Check Status", + "new-order-button": "New Order" + }, + + "wizard": { + "create-title": "Create Wallet", + "create-desc": "If you don't have a wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to \"Load\" and enter your seed.", + "encrypt-title": "Encrypt Wallet", + "encrypt-desc": "Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.", + "hardware-wallet-link": "Using a Skywallet?", + "hardware-wallet-alt-link": "Use a Skywallet", + "new-button": "New", + "load-button": "Load", + "finish-button": "Finish", + + "confirm": { + "title": "Safeguard Your Seed!", + "desc": "We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your wallet!", + "checkbox": "It’s safe, I swear." + } + }, + + "change-coin": { + "title": "Change active coin", + "search": "Search", + "with-wallet": "Coins you have created wallets for:", + "without-wallet": "Coins you have not created wallets for:", + "no-results": "No coins match the search term" + }, + + "wallet": { + "title-and-button": "Wallets", + "no-wallets": "Currently there are no wallets", + "show-empty-button": "Show Empty", + "hide-empty-button": "Hide Empty", + "add-button": "New Wallet", + "load-button": "Load Wallet", + "hardware-wallet-button": "Skywallet", + "encryption-enabled": "Encryption enabled.", + "encryption-disabled": "Encryption disabled.", + "warning-hw-security": "Possible security risk. Access the Skywallet options (by pressing the \"Skywallet\" button below the wallets list) while the device is connected for more information.", + "wallet-table-label": "Wallet", + "hardware-wallet-table-label": "Skywallet", + "legacy-small-label": "Legacy", + "legacy-info": "The wallet was not created with the most up-to-date procedure, but you can continue using it normally. This message is purely informative.", + "xpub-small-label": "xPub", + "xpub-info": "This is a read-only wallet, you can't use it for sending coins.", + "delete-confirmation": "WARNING: The wallet \"{{ name }}\" will be removed from the list. To add it again, you will have to reconnect the device and open the Skywallet options (by pressing the \"Skywallet\" button below the wallets list). Do you want to continue?", + "delete-confirmation-check": "Yeah, I want to delete the wallet", + "max-hardware-wallets-error": "You have already reached the max number of addresses that can be added to the Skywallet.", + "add-many-confirmation": "WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?", + "busy-error": "Please wait for the previous operation to be completed.", + + "new": { + "create-title": "Create Wallet", + "load-title": "Load Wallet", + "not-available-warning": "Sorry, it is not possible to create wallets for this coin at this time.", + "skywallet-only-warning": "You can only create wallets for this coin using a Skywallet.", + "advanced-options-link": "Advanced wallet options", + "advanced-options-close-warning": "The changes you have made will be lost. Are you sure you want to continue?", + "name-label": "Name", + "name-error-info": "You must enter a name.", + "coin-label": "Coin", + "type-label": "Type", + "type-deterministic": "Deterministic (Legacy)", + "type-bip44": "Bip44 (New)", + "type-xpub": "xPub (Read-Only)", + "type-info": "\"Bip44\" is the new recomended method for creating wallets, while \"Deterministic\" is the method used by old versions of the software. \"Bip44\" and \"Deterministic\" wallets are always different, even if you use the same seed.", + "passphrase-label": "Seed passphrase (optional)", + "passphrase-info": "Additional text for the seed. If provided, anyone trying to restore the wallet will need the seed AND the provided passphrase.", + "passphrase-warning-title": "Warning", + "passphrase-warning": "Be extremely cautious with the passphrase. If you need to recover the wallet you will have to enter not only the seed, but also EXACTLY the same passphrase you are entering here, character by character. If you have the seed but not the passphrase, you won't be able to recover access to the funds.", + "words-number-label": "How many words the seed has", + "xpub-label": "xPub key", + "xpub-error-info": "You must enter a valid value.", + "seed-label": "Seed", + "seed-error-info": "You must enter a seed.", + "confirm-seed-label": "Confirm seed", + "confirm-seed-error-info": "The two seeds must match.", + "seed-warning": "Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!", + "12-words": "12 words", + "24-words": "24 words", + "generate-12-help": "Generate a 12 word seed.", + "generate-24-help": "Generate a 24 word seed.", + "encrypt-check": "Encrypt wallet", + "encrypt-warning-non-xpub": "We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.", + "encrypt-warning-xpub": "We suggest that you encrypt each one of your wallets with a password.", + "seed-checking-error": "It was not possible to verify the validity of the seed.", + "unconventional-seed-title": "Possible Error", + "unconventional-seed-text": "You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.", + "unconventional-seed-check": "Continue with the unconventional seed", + "synchronizing-warning-text": "The wallet is still synchronizing and the operation could not restore all the addresses. If some addresses are not restored, you will have to wait for the wallet to be fully synchronized and use the \"Force Rescan\" function or add them again manually.", + "wallet-created": "The wallet has been added to the list.", + + "seed": { + "enter-seed": "Press here to enter the seed", + "change-seed": "Press to change", + "confirm-seed": "Press here to confirm the seed", + "confirmed-seed": "Seed confirmed", + "use-custom": "Enter the seed manually", + "use-normal": "Enter the seed using the recommended method", + "custom-seed-warning-text": "This option is only recommended for advanced users. Making mistakes with the seed could cause you to lose access to the funds in case of a problem.", + "custom-seed-warning-text-recovering": "To avoid possible problems, this option should only be used if you want to recover an unconventional seed.", + "incorrect-word-error": "The word you have entered does not match the requested one.", + "invalid-seed-error": "The seed you have entered is not valid. Please try again.", + "enter-word": "Enter the word #{{number}}", + "word-error-info": "You must enter a word.", + "new-seed-info": "You must enter the words of the seed that was generated by the system, to confirm it.", + "recover-seed-info": "Please be sure to enter the correct words in the correct order." + } + }, + + "rename": { + "title": "Rename Wallet", + "name-label": "Name", + "label-error-info": "You must enter a name.", + "rename-button": "Rename" + }, + + "wallet-options": { + "title": "Options", + "add": "Add Addresses", + "encrypt": "Encrypt Wallet", + "decrypt": "Decrypt Wallet", + "decrypt-warning": "Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.", + "scan": "Force Rescan", + "scan-help": "Use this option to make the system automatically rescan the wallet if the balance is not correct or to retrieve missing addresses.", + "delete": "Delete Wallet", + "cancelled-error": "Operation cancelled." + }, + + "scan-addresses": { + "synchronizing-warning-text": "The wallet is still synchronizing and the process may not be completely effective. Do you want to continue?", + "done-with-new-addresses": "The process has been completed and new addresses have been added to the wallet.", + "done-without-new-addresses": "The process has been completed and no new data was found for the wallet." + }, + + "add-addresses": { + "title": "Select Quantity", + "quantity-label": "How many addresses to create", + "quantity-error-info": "You must enter a value between 1 and 100", + "error": "There was an unexpected error. Please try again." + }, + + "address": { + "show": "Press to show", + "copy": "Copy", + "copy-address": "Copy address", + "copied": "Copied!", + "confirm": "Confirm address", + "outputs": "Unspent outputs", + "history": "History" + } + }, + + "qr": { + "title": "QR Code", + "receive-title": "Receive Coins", + "data-label": "QR data", + "address-label": "Address", + "address-info": "Coins sent to this address will be credited to the wallet.", + "password-info": "To maintain your privacy, the password will be used to create a new address for receiving coins, since the last one has already been used.", + "used-address-warning": "This address has already received coins. To maintain privacy, it is recommended to use the addresses only once. Please enter the password when opening this window if you want a new address to be created.", + "address-history-link": "Wallet addresses", + "unused-addresses-warning": "You have unused addresses before this one. Use this link to check them.", + "request-link": "Request specific amount", + "amount-label": "Requested amount", + "hours-label": "Requested hours", + "message-label": "Message", + "invalid": "(invalid value)" + }, + + "send": { + "title-and-button": "Send", + "unsigned-button": "Unsigned", + "signed-button": "Signed", + "unsigned-confirmation": "The unsigned transactions form does not allow to send transactions normally, but simply creates the text of a transaction, which must be signed before it can be sent to the network. This is useful for creating transactions that will be signed on an always offline device, for security reasons. Are you sure you wish to continue?", + "synchronizing-warning": "The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?", + "available-balance-indication": "Excluding pending balance", + "wallets-updated-warning": "The wallet list has been updated.", + "from-label": "Send from", + "to-label": "Send to", + "amount-label": "Amount", + "personal-note-label": "Personal note", + "gas-price-label": "Gas price", + "gas-limit-label": "Gas limit", + "fee-options": "Fee options", + "fee-label": "Aproximate fee", + "fee-measure": "{{ measure }} per byte", + "fee-problem-warning": "There was a problem trying to get the recommended fee, so it will have to be entered manually before sending the transaction.", + "fee-low-warning": "The fee you entered is lower than recommended, the transaction could take a very long time to be confirmed.", + "fee-high-warning": "The fee you entered is higher than recommended, the cost for sending the transaction could be higher than desired.", + "fee-unknown-warning": "The system is still obtaining the information about the recommended fees, so it is not possible to determine if the fee you entered is convenient.", + "fee-problem-warning2": "There was a problem trying to get the recommended fee, so it is not possible to determine if the fee you entered is convenient.", + "fee-error-info": "The value is too low or invalid.", + "personal-note-help": "Use this field to add a text for allowing you to identify the transaction in the future. This text is saved locally, so it will only be visible from this computer.", + "wallet-label": "Wallet", + "wallet-error-info": "You must select a wallet.", + "invalid-amount": "Please enter a valid amount", + "convert-confirmation": "Do you also want the already introduced amount to be converted from {{from}} to {{to}}?", + "convert-confirmation-plural": "Do you also want the already introduced amounts to be converted from {{from}} to {{to}}?", + "send-all-available-coins-link": "send all", + "precision-error-warning": "A precision error was detected during conversion. Please check the amount that will be sent.", + "invaid-amount-warning": "An invalid value was detected during conversion. Please check the amount that will be sent.", + "precision-errors-warning": "Precision errors were detected during conversion. Please check the amount that will be sent.", + "invaid-amounts-warning": "Invalid values were detected during conversion. Please check the amount that will be sent.", + "multiple-problems-warning": "Some values were not converted because they were invalid or could have been converted with precision errors. Please check the amount that will be sent.", + "addresses-label": "Addresses", + "addresses-error-info": "You must enter at least one valid address.", + "no-available-balance-error": "No available balance has been computed.", + "no-wallet-selected-error": "There are no coins to send.", + "no-coins-left-error": "There are no coins left to send.", + "addresses-help": "Limit the addresses from where the coins and hours could be sent.", + "addresses-manual-help": "List of the addresses from which the coins will be sent, comma separated. All addresses must belong to the same wallet or you will not be able to sign the transaction with the desktop wallet.", + "all-addresses": "All the addresses of the selected wallet", + "outputs-label": "Unspent outputs", + "outputs-help": "Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown.", + "outputs-error": "There was an error trying to get the outputs. Please make sure you have entered valid addresses.", + "all-outputs": "All the outputs of the selected addresses", + "enter-addresses-for-outputs": "Valid addresses must be entered first", + "enter-wallet-for-outputs-and-addresses": "A valid wallet must be selected first", + "invalid-addresses-for-outputs": "No outputs available", + "loading-available": "Loading available balance...", + "waiting-for-available": "Waiting for a valid fee to calculate the available balance...", + "available-funds-without-hours-msg-part1": "You can send up to", + "available-funds-without-hours-msg-part2": "(at least", + "available-funds-without-hours-msg-part3": "must be used as transaction fee for sending all the coins).", + "available-funds-msg-part1": "With your current selection you can send up to", + "available-funds-msg-part2": "and", + "available-funds-msg-part3": "(at least", + "available-funds-msg-part4": "must be used as transaction fee for sending all the coins or hours).", + "change-address-label": "Custom change address", + "change-address-error-info": "The change address is not valid.", + "change-address-select-from-list-link": "Select", + "change-address-help": "Address to receive change. If it's not provided, it will be chosen automatically. Click on the \"Select\" link to choose an address from one of your wallets.", + "destinations-label": "Destinations", + "destinations-help1": "Destination addresses and their coins.", + "destinations-help2": "Destination addresses, their coins and hours.", + "destination-label": "Destination", + "destination-help": "Destination address and the coins that will be sent to it.", + "hours-allocation-check": "Use automatic {{ coinHoursName }} allocation", + "options-link": "Options", + "coin-hours-options-link": "Hours options", + "hours-share-factor-label": "{{ coinHoursName }} share factor", + "hours-share-factor-help": "This control allows to select the factor (percentage) of {{ coinHoursName }} that will be send. The higher the value, the more {{ coinHoursName }} will be sent and less will be retained.", + "close-hours-share-factor-alert": "The option will be resetted to the default value. Are you sure you want to continue?", + "preview-button": "Preview", + "send-button": "Send", + "show-button": "Show", + "simple-form-button": "Simple", + "advanced-form-button": "Advanced", + "select-wallet": "Select wallet", + "saving-note-error": "The transaction was successfully sent, but it was not possible to save the note.", + "sent": "Transaction successfully sent.", + "total-to-send": "Total:", + "sending-all-hours-with-coins-waning": "By sending all the available coins, all the hours in the selected wallet will be sent or burn. If you want to retain hours, you must not send all the coins. Are you sure you want to continue?", + "advanced-sending-all-hours-with-coins-waning": "By sending all the available coins, all the hours in the selected source(s) will be sent or burn. If you want to retain hours, you must not send all the coins. Are you sure you want to continue?", + "sending-all-hours-waning": "You selected to send all the hours. Are you sure you want to continue?", + "high-hours-share-waning": "Your selection may result in sending all the hours in the selected wallet. Are you sure you want to continue?", + "advanced-high-hours-share-waning": "Your selection may result in sending all the hours in the selected source(s). Are you sure you want to continue?", + "invalid-address": "Invalid destination address found: ", + "invalid-addresses": "Invalid destination addresses found: ", + "invalid-address-error": "The destination address is not valid.", + "one-invalid-address-error": "One of the destination addresses is not valid.", + "various-invalid-addresses-error": "Some destination addresses are not valid.", + "all-addresses-invalid-error": "The destination addresses are not valid.", + "invalid-addresses-error": "Please make sure the address is valid.", + "address-error-info": "Please enter a valid address.", + "invalid-value-error-info": "Invalid value.", + "insufficient-funds-error-info": "The entered value is greater than the available balance.", + + "known-node-errors": { + "null-change-address-error": "The null address can't be used as the custom change address. Please enter a valid address.", + "to-required-error": "You must provide a destination address for sending coins. Please enter a valid address.", + "zero-coins-error": "It's not possible to send zero coins. Please enter a valid amount.", + "null-destination-error": "The null address can't be used as destination. Please enter a valid address.", + "duplicate-destination-error": "There are duplicate destinations. Please do not repeat the same address and amount in more than one destination.", + "hours-in-automatic-mode-error": "Specific hour amounts can't be specified while using automatic hour distribution. Please try with different values and contact support if the problem is not solved.", + "hours-allocation-mode-needed-error": "The hour allocation mode is required. Please try with different values and contact support if the problem is not solved.", + "invalid-hours-allocation-mode-error": "Invalid hour allocation mode. Please try with different values and contact support if the problem is not solved.", + "hours-allocation-mode-not-needed-error": "The hour allocation mode can't be specified while using manual hour distribution. Please try with different values and contact support if the problem is not solved.", + "invalid-hours-mode-error": "Invalid hour distribution method. Please try with different values and contact support if the problem is not solved.", + "share-factor-needed-error": "The hours share factor is needed. Please try with different values and contact support if the problem is not solved.", + "share-factor-not-needed-error": "The hours share factor can't be specified while using manual hour distribution. Please try with different values and contact support if the problem is not solved.", + "invalid-share-factor-error": "Invalid share factor. Please try with different values and contact support if the problem is not solved.", + "change-equal-to-destination-error": "The transaction can't be created because a repeated amount of coins would be returned to the same destination address. Please try again with different values.", + "repeated-wallet": "A wallet for the specified seed already exists." + }, + + "fees": { + "very-high": "Very high", + "high": "High", + "Normal": "Normal", + "Low": "Low", + "very-Low": "Very Low", + "custom": "Custom" + }, + + "eth-fees": { + "Normal": "Recommended", + "custom": "Custom" + }, + + "bulk-send": { + "title": "Bulk Send", + "indications": "To send to multiple destinations in a quick way, type each address, coin amount and hour amount (optional) on a line, separated by a comma. Example: if you want to send 10 coins and 5 hours to the \"xyz\" address, type \"xyz,10,5\"; if you want the hours to be calculated automatically, type \"xyz,10\". Decimal values must be separated with a dot.", + "indications-without-hours": "To send to multiple destinations in a quick way, type each address and coin amount on a line, separated by a comma. Example: if you want to send 10 coins to the \"xyz\" address, type \"xyz,10\". Decimal values must be separated with a dot.", + "data-error-info": "You must enter a value.", + "process-button": "Process", + "no-data-error": "There is no text to process.", + "inconsistent-data-error": "If you set how many hours you want to send to a destination, you must do so for all destinations.", + "invalid-data-error": "The entered text has an invalid format." + } + }, + + "select-address": { + "title": "Select Address", + "wallet-addresses": "View Wallet Addresses", + "no-addresses": "There are no confirmed addresses on this wallet." + }, + + "get-address": { + "title": "Get Address", + "password-info": "To maintain your privacy, the password will be used to create a new address for receiving coins, since the last one has already been used.", + "used-address-warning": "An address that has already received coins was generated, as the wallet password was not provided. To maintain privacy, it is recommended to use the addresses only once." + }, + + "offline-transactions": { + "loading-problem": "Error trying to get the necessary data", + "wallet-error-info": "You must select a wallet.", + "tx-error-info": "You must enter a valid transaction text.", + "copy-tx": { + "signed-title": "Signed Transaction", + "unsigned-title": "Unsigned Transaction", + "text-unsigned": "This is the unsigned transaction that has been created with the data that you have entered. Please copy the text to be able to sign it with the \"Sign Transaction\" option.", + "text-signed": "This is the signed transaction. You can send it to the network using the \"Broadcast Transaction\" option.", + "input-label": "Transaction text", + "copy-button": "Copy", + "reset-confirmation": "Do you want the the form to be cleaned, so you can create another transaction?", + "reset-done": "The form has been cleaned." + }, + + "sign-tx": { + "title": "Sign Transaction", + "text": "Use this form to sign a transaction. For the operation to work correctly, you must select the wallet which includes all the inputs/addresses used to send coins in the transaction.", + "wallet-label": "Wallet", + "select-wallet": "Select wallet", + "input-label": "Transaction text", + "sign-button": "Sign", + "signed": "The transaction has been signed." + }, + + "broadcast-tx": { + "title": "Broadcast Transaction", + "text": "Use this form to send a signed transaction to the network.", + "input-label": "Transaction text", + "send-button": "Send", + "sent": "The transaction has been sent." + } + }, + + "reset": { + "title": "Reset Password", + "invalid-wallet": "Invalid wallet", + "wallet-label": "Wallet", + "seed-label": "Wallet seed", + "seed-error-info": "You must enter a seed.", + "enter-seed": "Press here to enter the seed", + "words-number-label": "How many words the seed has", + "12-words": "12 words", + "24-words": "24 words", + "passphrase-label": "Wallet passphrase (if any)", + "password-label": "New password (leave empty if you want the wallet not to be encrypted)", + "confirm-label": "Confirm new password", + "confirm-error-info": "The two passwords must match.", + "reset-button": "Reset", + "done": "Password successfully changed." + }, + + "tx": { + "confirm-transaction-title": "Confirm Transaction", + "from-small-label": "From:", + "to-small-label": "To:", + "wallet-small-label": "Wallet:", + "wallets-small-label": "Wallets:", + "date-small-label": "Date:", + "status-small-label": "Status:", + "amount-small-label": "Amount:", + "coins-small-label": "Coins:", + "hours-small-label": "Hours:", + "fee-small-label": "Fee:", + "balance-to-send-info": "Includes the transaction fee.", + "approximate-fee-warning": " / Approximate", + "approximate-fee-info": "The fee could be less after processing the transaction. Any unused amount will be returned to the source address.", + "id-small-label": "Tx ID:", + "note-small-label": "Note:", + "without-note": "Without note", + "show-more-link": "Show more", + "hours-moved": "moved", + "hours-sent": "sent", + "hours-received": "received", + "hours-burned": "burned", + "inputs-title": "Inputs", + "outputs-title": "Outputs", + "internal": "You own this address", + "confirmed-transaction": "Confirmed", + "pending-transaction": "Pending ({{currentConfirmations}} / {{confirmationsNeeded}})", + "current-rate-help": "Calculated at the current rate.", + "hours-burned-help": "{{ hoursName }} burned as fee for sending the transaction.", + "coinbase": "COINBASE (new coins and fees)" + }, + + "edit-note": { + "title": "Edit Note", + "change-button": "Change" + }, + + "backup": { + "title": "Backup Wallet", + "wallet-directory": "Wallet Directory:", + "seed-warning": "BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.", + "desc": "Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.", + "wallet-table-label": "Wallet name", + "filename-table-label": "Filename", + "save-addresses-button": "Save Addresses", + "show-seed-button": "Show Seed", + "no-wallets": "There are no wallets", + "unencrypted-info": "For security reasons, it is not possible to show the seeds of unencrypted wallets. To get the seed, please encrypt the wallet with a password or follow the instruction shown at the top of this page.", + "hw-wallet-info": "For getting the seed of a Skywallet, please use the \"Skywallet\" option at the bottom of the wallets page.", + "xpub-info": "It is not possible to show the seeds of xPub wallets.", + "not-compatible-error": "Your web browser is not compatible with this function.", + + "seed-modal-window": { + "title": "Wallet Seed", + "seed-label": "Seed", + "passphrase-label": "Passphrase", + "type-label": "Wallet type", + "type-deterministic": "Deterministic", + "type-bip44": "Bip44", + "type-xpub": "xPub" + } + }, + + "blockchain": { + "title": "Blockchain", + "blocks-label": "Number of blocks", + "time-label": "Timestamp of last block", + "hash-label": "Hash of last block", + "confirmations-label": "Confirmations needed", + "current-supply-label": "Current {{ coinName }} supply", + "total-supply-label": "Total {{ coinName }} supply", + "current-coinhour-supply-label": "Current {{ coinHoursName }} supply", + "total-coinhour-supply-label": "Total {{ coinHoursName }} supply", + "edit-confirmations-info": "Change how many confirmations a transaction must have for it to be considered final.", + "edit-confirmations-warning": "The number of confirmations needed helps to keep your funds safe. This option must only be used by experienced users who understand the risks involved. Are you sure you want to continue?", + "confirmations-warning": "The recommended number of confirmations for this coin is {{ number }}.", + + "select-confirmation": { + "title": "Edit Confirmations Needed", + "confirmations-label": "Confirmations", + "confirmations-error-info": "You must enter a valid integer value between 0 and {{ max }}.", + "apply-button": "Apply" + } + }, + + "network": { + "title": "Networking", + "error-no-connections": "No connections", + "peer-small-table-label": "Peer", + "source-small-table-label": "Source", + "block-height-small-table-label": "Block height", + "block-height-short-small-table-label": "Block", + "last-seen-small-table-label": "Last seen", + "last-received-help": "Last received.", + "last-sent-help": "Last sent.", + "in-help": "Incoming.", + "out-help": "Outgoing.", + + "sources": { + "default": "Default peer", + "exchange": "Peer exchange" + } + }, + + "pending-txs": { + "title": "Pending Transactions", + "timestamp-table-label": "Timestamp", + "txid-table-label": "Transaction ID", + "none": "No pending transactions", + "my-transactions-button": "Mine", + "all-transactions-button": "All", + "unknown-date": "Unknown" + }, + + "outputs": { + "title": "Outputs", + "error-no-outputs": "No unspent outputs" + }, + + "history": { + "title-and-button": "History", + "tx-detail-title": "Transaction Detail", + "failed": "Failed", + "failed-info": "The transaction fee was paid but the funds were not sent.", + "complex-transaction": "Complex transaction", + "moving": "Moving {{ coinName }} between addresses", + "moved": "{{ coinName }} moved between addresses", + "moving-wallet": "Moving {{ coinName }} between wallets", + "moved-wallet": "{{ coinName }} moved between wallets", + "sending": "Sending {{ coinName }}", + "sent": "{{ coinName }} sent", + "receiving": "Receiving {{ coinName }}", + "received": "{{ coinName }} received", + "pending-indication": "Pending ({{currentConfirmations}} / {{confirmationsNeeded}})", + "confirmations-help": "The transaction only has {{currentConfirmations}} of {{confirmationsNeeded}} confirmations needed for being considered completed.", + "transaction-note-small-label": "Note:", + "involved-wallets-small-label": "Involved local wallets:", + "involved-wallet-small-label": "Involved local wallet:", + "no-txs": "You have no transaction history", + "no-txs-filter": "There are no transactions matching the current filter criteria", + "no-filter": "No filter active (press to select wallets/addresses)", + "filter": "Active filter: ", + "filters": "Active filters: ", + "all-addresses": "All addresses", + "other-wallets-title": "Other Wallets", + "wallets-title": "Wallets", + "addresses": "Addresses", + "load-more": "Load more", + "view-all": "View all {{ number }} transactions", + "use-explorer": "Use the blockchain explorer for accessing the full transaction history", + "show-addresses": "Show the addresses", + "hide-addresses": "Hide the addresses", + "balance-help": "Does not include {{ amount }} you paid as fee." + }, + + "address-history": { + "title": "Wallet Addresses", + "omited-addresses-warning": "There was a problem and some addresses were ignored.", + "invalid-wallet": "Invalid wallet", + "add-button": "Add Addresses", + "normal-address-table-label": "Normal address", + "normal-address-info": "Addresses you normally use to receive coins.", + "change-address-table-label": "Change address", + "change-address-info": "Automatically created addresses where any remaining coins are sent when you submit a transaction.", + "unused-table-label": "Unused", + "used-yes": "Yes", + "used-yes-info": "This address has not yet received any coins.", + "used-no": "No", + "used-no-info": "This address has already received coins. To maintain privacy, it is recommended to use the addresses only once.", + "history": "History", + "view-all": "Showing the last {{ current }} addresses. Press to show all {{ total }} addresses" + }, + + "teller": { + "done": "Completed", + "waiting-confirm": "Waiting for confirmation", + "waiting-deposit": "Waiting for Bitcoin deposit", + "waiting-send": "Waiting to send Skycoin", + "unknown": "Unknown" + }, + + "confirmation" : { + "default-title": "Confirmation", + "yes-button": "Yes", + "no-button": "No" + }, + + "service": { + "api" : { + "no-internet-error": "You do not have a internet connection or the node has stopped working.", + "incorrect-password-error": "Incorrect password.", + "unknown-error": "It was not possible to perform the operation.", + "api-disabled-error": "API disabled." + } + }, + + "hardware-wallet": { + "general" : { + "default-wallet-name": "New Skywallet", + "confirm": "Please confirm the operation on the Skywallet.", + "confirm-and-more": "Please confirm the operation on the Skywallet and follow the instructions displayed.", + "follow": "Please follow the instructions displayed on the Skywallet.", + "completed": "Operation completed successfully.", + "name-updated": "The name used to identify this Skywallet in the wallet list has been updated to match the one shown on the device." + }, + "errors": { + "generic-error": "Unable to perform the operation. Make sure you have connected a valid Skywallet and that it is not waiting for input.", + "disconnected": "Unable to perform the operation. The Skywallet is not connected.", + "incorrect-wallet": "Unable to perform the operation. The connected Skywallet is different from the expected one.", + "incorrect-pin": "Unable to perform the operation. The PIN you have entered is incorrect.", + "refused": "The operation was canceled.", + "too-many-inputs-outputs": "The transaction has too many inputs or outputs for the Skywallet. Please try again creating several smaller transactions, each one with a smaller number of recipients (if the current transaction has many) or coins.", + "outdated-daemon": "It was not possible to complete the operation because the Skywallet daemon is outdated. You can download the latest version from ", + "daemon-connection": "Problem connecting to the Skywallet Daemon, please make sure it is running and try again. You can download it from ", + "timeout": "The operation was canceled due to inactivity. Please try again.", + "invalid-address-generated": "There was a problem with the address generator and the operation had to be canceled.", + "invalid-address": "Invalid address.", + "not-in-bootloader-mode": "To use this option the Skywallet must be in bootloader mode." + }, + "security-warning" : { + "title": "Security Warning", + "text": "The last time this Skywallet was connected, one or more security warnings were found. We recommend that you open the Skywallet options (by pressing the link below) while the device is connected and solve the security problems before continuing.", + "link": "Open the Skywallet options window." + }, + "options" : { + "connecting": "Connecting...", + "disconnected": "No Skywallet detected. Please connect a Skywallet to use this option.", + "unconfigured-detected-title": "Unconfigured Skywallet", + "unconfigured-detected": "A seedless Skywallet has been detected. Select \"Configure Automatically\" if you want to configure it as a brand new wallet and start using it. Select \"Restore Backup\" if you want to configure the Skywallet with a previously created seed backup.", + "configured-detected": "Skywallet detected. The device is identified in the wallets list as:", + "security-warnings-title": "Security Warnings", + "security-warning-title": "Security Warning", + "unchecked-version-warning": "It was not possible to verify if the firmware of your Skywallet is up to date. This could be due to problems with your internet connection or because the service is under maintenance.", + "outdated-version-warning": "The firmware of your Skywallet is outdated. We recommend you to update it as soon as possible to ensure safety. To do this, select the \"Update Firmware\" option.", + "backup-warning": "You should backup the Skywallet seed or you could lose access to the funds in case of problems. To do this, select the \"Create a Backup\" option.", + "pin-warning": "The connected Skywallet does not have a PIN. The PIN code protects the Skywallet from unauthorized parties accessing the device. To create a PIN code, select the \"Create PIN Code\" option.", + "options": "Options:", + "update-firmware": "Update Firmware", + "configure-automatically": "Configure Automatically", + "restore-backup": "Restore Backup", + "create-backup": "Create a Backup", + "wipe": "Wipe the Device", + "confirm-seed": "Confirm Seed", + "create-pin": "Create PIN Code", + "change-pin": "Change PIN Code", + "delete-pin": "Delete PIN Code", + "forgotten-pin-part1": "If you cannot access the wallet because you have forgotten the PIN, you can wipe the Skywallet and then restore it with the seed by clicking", + "forgotten-pin-part2": "here.", + "firmware-version": "Device firmware version:" + }, + "update-firmware-warning" : { + "title": "Outdated Firmware", + "text": "WARNING: the firmware in your Skywallet is outdated. To stay safe, it is recommended to update it.", + "update": "Update" + }, + "update-firmware" : { + "title-connecting": "Connecting...", + "title-update": "Update Firmware", + "title-install": "Install Firmware", + "text-downloading": "Checking device and downloading files...", + "text-bootloader": "WARNING: if you have already configured this device, before continuing you must have a backup of your seed or you could permanently lose access to the funds.", + "text-not-bootloader": "To update the firmware of your Skywallet you must connect it in bootloader mode (connect it to the computer while pressing the two physical buttons of the device). WARNING: if you have already configured this device, before continuing you must have a backup of your seed or you could permanently lose access to the funds.", + "text-no-firmware": "Welcome. The currently connected Skywallet does not have a firmware installed. A firmware will now be installed so you can start using the device. NOTE: if you have already configured this device and want to recover the funds, you will need your seed.", + "follow": "The firmware update has been sent to the Skywallet. Please continue the process on the device.", + "connection-error": "It was not possible to download the firmware. This could be due to problems with your internet connection or because the service is under maintenance.", + "timeout": "The operation was canceled due to inactivity. Please disconnect the device, reconnect it and try again.", + "finished": "Your device has been configured correctly. Please unplug it before continuing." + }, + "generate-seed" : { + "text": "Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.", + "configuring": "Configuring..." + }, + "restore-seed" : { + "text": "Before proceeding, please select the number of words that the seed you want to recover has.", + "check-text": "You can use this option to enter a seed and check if it is equal to the one in the Skywallet. Before start, select the number of words the seed you want to check has.", + "warning" : "WARNING: to avoid potential problems, use only seeds created with a Skywallet.", + "error-wrong-word": "Error: the retyped word does not match the one requested by the Skywallet.", + "error-invalid-seed": "Error: the seed is not valid. Please be sure to enter the correct words in the correct order.", + "error-wrong-seed": "Error: the seed is valid but does not match the one in the device.", + "correct-seed": "The seed is valid and matches the one in the device." + }, + "added" : { + "title": "New Skywallet", + "configuring": "New Skywallet detected. Configuring...", + "done": "Done", + "added1": "The connected Skywallet has been added to the wallets list with the following name:", + "added2": "Now you can check the balance and the addresses of the Skywallet even when it is not connected.", + "added-error-info": "You must enter a name.", + "characters-warning": "If you use non-standard English characters, the name may not be displayed correctly on the device." + }, + "wipe" : { + "warning": "WARNING: All the data on the Skywallet will be deleted. If you do not have a backup, you will not be able to access your funds again.", + "confirm-delete-check": "Also remove from the wallets list" + }, + "create-backup" : { + "warning": "WARNING: You can only create a backup of your Skywallet seed once. If you decide to continue, you will have to write down a group of words (on paper, never on a computer) that will appear on the screen of the Skywallet and store the list in a safe place. Anyone with access to the word list (the \"seed\") will be able access the wallet funds, so extreme caution is advised.", + "instructions": "Write down the word list that appear on the screen of the Skywallet. Make sure you respect the order and write each word correctly." + }, + "seed-word" : { + "title": "Enter Word", + "enter-word": "Enter the word shown on the device", + "info": "You will be asked to enter the words of your backup seed in random order. Also, additional random words could be requested.", + "word-label": "Requested word", + "error-invalid-word": "The entered word is not valid.", + "error-loading-words": "Loading the word list. Please wait." + }, + "change-pin" : { + "pin-mismatch": "Unable to perform the operation. The PINs you have entered do not match." + }, + "remove-pin" : { + "warning": "WARNING: It is not recommended to remove the PIN code from your Skywallet, as it will be vulnerable to being used by unauthorized parties." + }, + "enter-pin" : { + "title": "Enter PIN", + "title-change-current": "Enter the Current PIN", + "title-change-new": "Enter the New PIN", + "title-change-confirm": "Confirm the New PIN", + "instructions-generic": "The PIN layout is displayed on the Skywallet screen.", + "instructions-tx": "Enter the PIN to confirm and sign the transaction. The PIN layout is displayed on the Skywallet screen.", + "instructions-change": "Please enter a secure PIN consisting of 4 to 8 numbers. The PIN layout is displayed on the Skywallet screen.", + "help": "Need help?" + }, + "pin-help" : { + "title": "Help", + "part1": "When it is necessary to enter the PIN to continue, the Skywallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol •.", + "part2": "To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the Skywallet and press the corresponding buttons in the software wallet. For example, if the PIN is \"23\" and the number 2 is in the upper left, number 3 in the middle of the Skywallet numbers matrix, press the upper left and middle button in that order in the software wallet.", + "part3": "If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is \"23\", you can not simply type \"23\" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the Skywallet. Taking into account the previous example, you would have to press the \"7\" and \"5\" keys, because those are the keys that you are in the same position as the numbers shown by the Skywallet." + }, + "create-tx" : { + "title": "Create Transaction", + "upper-text": "Please confirm the operation in the Skywallet after verifying if the following data matches EXACTLY with the transaction you wish to send and with those shown by the Skywallet:", + "lower-text": "If any data does not correspond to what the Skywallet shows or the transaction you wish to send, cancel the operation on your Skywallet.", + "separator-for-coins-and-hours": "and", + "separator-to-destination": "to" + }, + "confirm-address" : { + "title": "Confirm Address", + "instructions": "Please confirm on the Skywallet if the address is:", + "short-confirmation": "Address confirmed.", + "confirmation": "Address confirmed. For security, you can re-show the address in the Skywallet using the \"Confirm address\" option, in the menu that you can display by pressing the button at the right of the address balance." + } + }, + + "time-from-now": { + "few-seconds": "a few seconds ago", + "minute": "one minute ago", + "minutes": "{{time}} minutes ago", + "hour": "one hour ago", + "hours": "{{time}} hours ago", + "day": "one day ago", + "days": "{{time}} days ago" + }, + + "exchange": { + "title-and-button": "Buy {{ coinName }}", + "label-you-send": "You send", + "label-you-get": "You get (approx.)", + "label-to-address": "To {{coin}} address", + "label-price": "Exchange rate", + "label-stimate-transaction-time": "Exchange time", + "exchange-button": "Exchange", + "min-amount": "Minimum amount:", + "max-amount": "Maximum amount:", + "agree-part1": "I agree with the", + "agree-part2": "Terms of Use", + "agree-part3": "and the", + "agree-part4": "Privacy Policy", + "powered-by": "Powered by", + "need-help": "Need help?", + "support-portal": "Support portal", + "history": "Order history", + "order-not-found": "Order not found", + "label-status": "Status", + "exchanging": "Exchanging {{from}} for {{to}}", + "destination-select-from-list-link": "Select", + "unavailable": "The exchange service is not available in portable version", + "offline": "Exchange is temporarily offline", + "problem-connecting": "Unable to connect with the service. Please check your Internet connection and try again later", + "invalid-address-error": "Invalid address.", + "from-coin-error-info": "You must select a coin.", + "invalid-value-error-info": "Invalid value.", + "address-error-info": "Please enter a valid address.", + "statuses": { + "user-waiting": "Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below", + "user-waiting-info": "The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.", + "market-waiting-confirmations": "Waiting for transaction confirmations", + "market-waiting-confirmations-info": "The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.", + "market-confirmed": "Transaction accepted", + "market-confirmed-info": "The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.", + "market-exchanged": "Traded {{from}} for {{to}}", + "market-exchanged-info": "The exchange has been made. The funds will be transferred to your address in a moment.", + "market-withdraw-waiting": "Sending {{to}} to your address", + "market-withdraw-waiting-info": "The process for sending the coins to your address has been initiated.", + "complete": "Exchange completed!", + "complete-info": "The funds have been successfully sent to your address.", + "error": "Error occurred", + "error-info": "There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page.", + "user-deposit-timeout": "Order canceled due to inactivity", + "user-deposit-timeout-info": "The system has canceled the order because no deposit was detected, please open a new order. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page." + }, + "history-window": { + "title": "Order History", + "address": "Address:", + "date": "Date:" + }, + "details": { + "exchange-addr-label": "Exchange address (valid for this exchange operation only)", + "exchange-addr-tag-label": "Payment ID or Destination Tag which must be used for the transaction", + "tx-id-label": "Transaction ID", + "order-id-label": "Order ID", + "initial-price-label": "Initial exchange rate", + "error-msg-label": "Error message", + "details-link": "Details", + "start-date-label": "Start date", + "back-alert": "The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the \"Order history\" button" + } + } +} diff --git a/src/gui/static/src/assets/i18n/es.json b/src/gui/static/src/assets/i18n/es.json new file mode 100644 index 0000000..e31ad5b --- /dev/null +++ b/src/gui/static/src/assets/i18n/es.json @@ -0,0 +1,876 @@ +{ + "common": { + "usd": "USD", + "loading": "Cargando...", + "done-title": "Listo", + "warning-title": "Advertencia", + "error-title": "Error", + "changes-made": "Los cambios se han hecho.", + "back-button": "Volver", + "create-button": "Crear", + "load-button": "Cargar", + "cancel-button": "Cancelar", + "continue-button": "Continuar", + "close-button": "Cerrar", + "generic-confirmation-check": "Entiendo los riesgos y deseo continuar", + "copied": "El texto ha sido copiado al portapapeles.", + "confirmations": "Confirmaciones", + "unconfirmed-balance-info": "Este saldo será final después de que sus últimas transacciones reciban más confirmaciones de la red. El saldo confirmado actualmente es {{ balance }}. Para más información verifique sus transacciones pendientes." + }, + + "errors": { + "window-size": "La ventana es demasiado estrecha para el contenido." + }, + + "language": { + "title": "Seleccionar Lenguaje" + }, + + "header": { + "syncing-blocks": "Sincronizando bloques", + "explorer-link": "Explorador de {{ coinName }}", + + "top-bar": { + "updated-label": "Balance actualizado:", + "updated-time": "hace {{ time }} min", + "less-than": "hace menos de 1 min", + "connection-error-info": "Error de conexión, pulse para reintentar." + }, + + "warnings": { + "update-part1": "La actualización", + "update-part2": "Not used. The code adds the versión number of the lastest update here.", + "update-part3": "está disponible.", + "synchronizing": "La billetera está sincronizando. Los datos mostrados pueden estar desactualizados.", + "pending-txs-part1": "Usted tiene", + "pending-txs-part2": "transacciones pendientes.", + "pending-txs-part3": "Los saldos y algunos otros datos pueden no estar actualizados.", + "pending-link-error": "Usted ya está en el historial de transacciones.", + "no-connections": "Sin conexiones activas, ¡el cliente no está conectado a otros nodos!", + "no-backend-part1": "Sin acceso al servidor. Por favor, reinicie la aplicación y/o contáctenos vía", + "no-backend-part2": "Telegram.", + "no-backend-part3": "", + "csrf": "Vulnerabilidad de seguridad: CSRF no funciona. Por favor, salga de inmediato." + } + }, + + "password": { + "title": "Introduzca Su Contraseña", + "password-label": "Contraseña", + "password-error-info": "Debe ingresar una contraseña.", + "confirm-password-label": "Confirmar contraseña", + "confirm-error-info": "Las dos contraseñas deben coincidir.", + "proceed-button": "Proceder", + "reset-link": "He olvidado mi contraseña", + "incorrect-password-error": "Contraseña incorrecta.", + "decrypting-error": "Error al desencriptar la billetera" + }, + + "buy": { + "title-and-button": "Comprar", + "deposit-address": "Seleccione una dirección para la cual generar un enlace de depósito BTC:", + "select-address": "Seleccione una dirección", + "generate": "Generar", + "deposit-location": "Localización de Depósito", + "deposit-location-desc": "Seleccione la billetera en la que desea que le depositemos sus Skycoins después de recibir los Bitcoins.", + "make-choice": "Realice una selección", + "wallets-desc": "Una nueva dirección BTC es generada cada vez que se selecciona una nueva billetera y dirección. Una única dirección de Skycoin puede tener asignadas hasta 5 direcciones BTC.", + "send": "Enviar Bitcoins", + "send-desc": "Envíe Bitcoins a la dirección abajo indicada. Al recibirlos, le depositaremos los Skycoins en una nueva dirección en la billetera seleccionada más arriba, a la tasa de cambio actual de {{ rate }} SKY/BTC.", + "fraction-warning": "¡Envíe sólo múltiplos de la tasa SKY/BTC! Los Skycoins son enviados en números enteros, ¡no se envían fracciones de SKY!", + "receive": "Recibir SKY", + "receive-desc": "Después de recibir los Bitcoins, le enviaremos sus Skycoins. El tiempo de espera para recibir sus SKY puede ser de entre 20 minutos y una hora.", + "status-button": "Estatus:", + "check-status-button": "Revisar Estatus", + "new-order-button": "Nueva Orden" + }, + + "wizard": { + "create-title": "Crear Billetera", + "create-desc": "Si no tiene una billetera, use la semilla generada automáticamente para crear una nueva. Si ya tiene una billetera, seleccione \"Cargar\" e introduzca su semilla.", + "encrypt-title": "Encriptar Billetera", + "encrypt-desc": "Incremente la seguridad de su billetera encriptándola. Al introducir una contraseña más abajo, su billetera será encriptada. Sólo quien tenga la contraseña podrá acceder a la billetera y retirar fondos.", + "hardware-wallet-link": "¿Utilizando una Skywallet?", + "hardware-wallet-alt-link": "Utilizar una Skywallet", + "new-button": "Nueva", + "load-button": "Cargar", + "finish-button": "Finalizar", + + "confirm": { + "title": "¡Resguarde Su Semilla!", + "desc": "Queremos asegurarnos de que ha anotado su semilla y la ha almacenado en un lugar seguro. ¡Si olvida su semilla, NO podrá recuperar su billetera!", + "checkbox": "Está segura, lo garantizo." + } + }, + + "change-coin": { + "title": "Cambiar moneda activa", + "search": "Buscar", + "with-wallet": "Monedas para las que ha creado billeteras:", + "without-wallet": "Monedas para las que no ha creado billeteras:", + "no-results": "Ninguna moneda coincide con el término de búsqueda" + }, + + "wallet": { + "title-and-button": "Billeteras", + "no-wallets": "Actualmente no hay billeteras", + "show-empty-button": "Mostrar Vacías", + "hide-empty-button": "Ocultar Vacías", + "add-button": "Nueva Billetera", + "load-button": "Cargar Billetera", + "hardware-wallet-button": "Skywallet", + "encryption-enabled": "Encriptado habilitado.", + "encryption-disabled": "Encriptado deshabilitado.", + "warning-hw-security": "Posible riesgo de seguridad. Acceda a las opciones de la Skywallet (presionando el botón \"Skywallet\" debajo de la lista de billeteras) mientras el dispositivo está conectado, para más información.", + "wallet-table-label": "Billetera", + "hardware-wallet-table-label": "Skywallet", + "legacy-small-label": "Antigua", + "legacy-info": "La billetera no se creó con el procedimiento más actualizado, pero usted puede continuar usándola normalmente. Este mensaje es puramente informativo.", + "xpub-small-label": "xPub", + "xpub-info": "Esta es una billetera de solo lectura, no puede usarse para enviar monedas.", + "delete-confirmation": "ADVERTENCIA: la billetera \"{{ name }}\" será removida de la lista. Para agregarla nuevamente, deberá volver a conectar el dispositivo y abrir las opciones de la Skywallet (presionando el botón \"Skywallet\" debajo de la lista de las billeteras). ¿Desea continuar?", + "delete-confirmation-check": "Sí, quiero borrar la billetera", + "max-hardware-wallets-error": "Ya ha alcanzado el número máximo de direcciones que se puede agregar a la Skywallet.", + "add-many-confirmation": "ADVERTENCIA: si agrega demasiadas direcciones sin usar las anteriores o si usa las últimas y no las primeras, es posible que algunas direcciones no se recuperen automáticamente si intenta restaurar la billetera con la semilla (tendrá que agregarlas manualmente). ¿Desea continuar?", + "busy-error": "Por favor espere a que se complete la operación anterior.", + + "new": { + "create-title": "Crear Billetera", + "load-title": "Cargar Billetera", + "not-available-warning": "Lo sentimos, no es posible crear billeteras para esta moneda en este momento.", + "skywallet-only-warning": "Solo puede crear billeteras para esta moneda usando una Skywallet.", + "advanced-options-link": "Opciones avanzadas de billetera", + "advanced-options-close-warning": "Los cambios que ha realizado se perderán. ¿Seguro que desea continuar?", + "name-label": "Nombre", + "name-error-info": "Debe ingresar un nombre.", + "coin-label": "Moneda", + "type-label": "Tipo", + "type-deterministic": "Determinista (Antigua)", + "type-bip44": "Bip44 (Nueva)", + "type-xpub": "xPub (Solo Lectura)", + "type-info": "\"Bip44\" es el nuevo método recomendado para crear billeteras, mientras que \"Determinista\" es el método utilizado por las versiones anteriores del software. Las billeteras \"Bip44\" y \"Determinista\" son siempre diferentes, incluso si usa la misma semilla.", + "passphrase-label": "Passphrase de la semilla (opcional)", + "passphrase-info": "Texto adicional para la semilla. Si se proporciona, cualquier persona que intente restaurar la billetera necesitará la semilla Y TAMBIÉN la passphrase provista.", + "passphrase-warning-title": "Advertencia", + "passphrase-warning": "Sea extremadamente cauteloso con la passphrase. Si necesita recuperar la billetera, deberá ingresar no solo la semilla, sino también EXACTAMENTE la misma passphrase que ingrese aquí, caracter por caracter. Si tiene la semilla pero no la passphrase, no podrá recuperar el acceso a los fondos.", + "words-number-label": "Cuantas palabras tiene la semilla", + "xpub-label": "Llave xPub", + "xpub-error-info": "Debe ingresar un valor válido.", + "seed-label": "Semilla", + "seed-error-info": "Debe ingresar una semilla.", + "confirm-seed-label": "Confirmar semilla", + "confirm-seed-error-info": "Las dos semillas deben coincidir.", + "seed-warning": "¡Recuerde esta semilla! Manténgala en un lugar seguro. ¡Si olvida su semilla, no podrá recuperar la billetera!", + "12-words": "12 palabras", + "24-words": "24 palabras", + "generate-12-help": "Generar una semilla de 12 palabras.", + "generate-24-help": "Generar una semilla de 24 palabras.", + "encrypt-check": "Encriptar billetera", + "encrypt-warning-non-xpub": "Le sugerimos que encripte con una contraseña cada una de sus billeteras. Si olvida su contraseña, puede restaurarla con la semilla. Asegúrese de guardar su semilla en un lugar seguro antes de encriptar la billetera.", + "encrypt-warning-xpub": "Le sugerimos que encripte con una contraseña cada una de sus billeteras.", + "seed-checking-error": "No fue posible verificar la validez de la semilla.", + "unconventional-seed-title": "Posible Error", + "unconventional-seed-text": "Usted introdujo una semilla no convencional. Si lo hizo por alguna razón en especial, puede continuar (sólo recomendable para usuarios avanzados). Sin embargo, si su intención es utilizar una semilla normal del sistema, usted debe borrar los textos y/o caracteres especiales adicionales.", + "unconventional-seed-check": "Continuar con la semilla no convencional", + "synchronizing-warning-text": "La billetera todavía está sincronizando los datos y la operación podría no restaurar todas las direcciones. Si algunas direcciones no son restauradas, usted deberá esperar a que la billetera esté totalmente sincronizada y usar la opción \"Forzar Reescaneo\" o agregarlas nuevamente de forma manual.", + "wallet-created": "La billetera ha sido agregada a la lista.", + + "seed": { + "enter-seed": "Presione aquí para ingresar la semilla", + "change-seed": "Presione para cambiar", + "confirm-seed": "Presione aquí para confirmar la semilla", + "confirmed-seed": "Semilla confirmada", + "use-custom-seed-help": "Presione aquí si desea ingresar la semilla manualmente.", + "use-normal-seed-help": "Presione aquí si desea ingresar la semilla utilizando el método recomendado.", + "custom-seed-warning-text": "Esta opción solo es recomendada para usuarios avanzados. Cometer errores con la semilla puede hacer que pierda el acceso a los fondos en caso de que surja algún problema.", + "custom-seed-warning-text-recovering": "Para evitar posibles problemas, esta opción solo debe usarse si desea recuperar una semilla no convencional.", + "incorrect-word-error": "La palabra que ha ingresado no coincide con la que se ha solicitado.", + "invalid-seed-error": "La semilla que ha ingresado no es válida. Por favor, vuelva a intentarlo.", + "enter-word": "Ingrese la palabra número {{number}}", + "word-error-info": "Debe ingresar una palabra.", + "new-seed-info": "Usted debe ingresar las palabras de la semilla que fue generada por el sistema, para confirmarla.", + "recover-seed-info": "Por favor, asegúrese de ingresar las palabras correctas en el orden correcto." + } + }, + + "rename": { + "title": "Renombrar Billetera", + "name-label": "Nombre", + "label-error-info": "Debe ingresar un nombre.", + "rename-button": "Renombrar" + }, + + "wallet-options": { + "title": "Opciones", + "add": "Agregar Direcciones", + "encrypt": "Encriptar Billetera", + "decrypt": "Desencriptar Billetera", + "decrypt-warning": "Advertencia: por razones de seguridad, no se recomienda mantener las billeteras sin encriptar. Se recomienda precaución.", + "scan": "Forzar Reescaneo", + "scan-help": "Use esta opción para hacer que el sistema vuelva a escanear automáticamente la billetera, en caso de que el saldo no sea correcto o para recuperar las direcciones que pudieran faltar.", + "delete": "Eliminar Billetera", + "cancelled-error": "Operación cancelada." + }, + + "scan-addresses": { + "synchronizing-warning-text": "La billetera todavía se está sincronizando y el proceso podría no ser completamente efectivo. ¿Desea continuar?", + "done-with-new-addresses": "El proceso se ha completado y se han agregado nuevas direcciones a la billetera.", + "done-without-new-addresses": "El proceso se ha completado y no se encontraron datos nuevos para la billetera." + }, + + "add-addresses": { + "title": "Seleccionar Cantidad", + "quantity-label": "Cantidad de direcciones a crear", + "quantity-error-info": "Debe ingresar un valor entre 1 y 100.", + "error": "Hubo un error inesperado. Por favor, inténtelo de nuevo." + }, + + "address": { + "show": "Presione para mostrar", + "copy": "Copiar", + "copy-address": "Copiar dirección", + "copied": "¡Copiado!", + "confirm": "Confirmar dirección", + "outputs": "Salidas no gastadas", + "history": "Historial" + } + }, + + "qr": { + "title": "Código QR", + "receive-title": "Recibir Monedas", + "data-label": "Datos del código QR", + "address-label": "Dirección", + "address-info": "Las monedas enviadas a esta dirección se acreditarán a la billetera.", + "password-info": "Para mantener su privacidad, la contraseña se utilizará para crear una nueva dirección para recibir monedas, ya que la última ya ha sido utilizada.", + "used-address-warning": "Esta dirección ya ha recibido monedas. Para mantener la privacidad, se recomienda usar las direcciones solo una vez. Por favor, ingrese la contraseña al abrir esta ventana si desea que se cree una nueva dirección.", + "address-history-link": "Direcciones de la billetera", + "unused-addresses-warning": "Tiene direcciones no utilizadas antes de esta. Use este enlace para verificarlas.", + "request-link": "Solicitar monto específico", + "amount-label": "Monto solicitado", + "hours-label": "Horas solicitadas", + "message-label": "Mensaje", + "invalid": "(valor inválido)" + }, + + "send": { + "title-and-button": "Enviar", + "unsigned-button": "Sin firmar", + "signed-button": "Firmada", + "unsigned-confirmation": "El formulario de transacciones sin firmar no permite enviar transacciones normalmente, sino que simplemente crea el texto de la transacción, el cual debe ser firmado antes de que pueda ser enviado a la red. Esto es útil para crear transacciones que serán firmadas en un equipo que siempre está fuera de línea, por razones de seguridad. ¿Desea continuar?", + "synchronizing-warning": "La billetera todavía está sincronizando los datos, por lo que el saldo que se muestra puede ser incorrecto. ¿Seguro de que desea continuar?", + "available-balance-indication": "Excluyendo el saldo pendiente", + "wallets-updated-warning": "La lista de billeteras ha sido actualizada.", + "from-label": "Enviar desde", + "to-label": "Enviar a", + "amount-label": "Cantidad", + "personal-note-label": "Nota personal", + "gas-price-label": "Precio por gas", + "gas-limit-label": "Límite de gas", + "fee-options": "Opciones de comisión", + "fee-label": "Comisión aproximada", + "fee-measure": "{{ measure }} por byte", + "fee-problem-warning": "Hubo un problema al intentar obtener la comisión recomendada, por lo que deberá ser ingresada manualmente antes de enviar la transacción.", + "fee-low-warning": "La comisión que ingresó es inferior a la recomendada, la transacción podría demorar mucho tiempo en confirmarse.", + "fee-high-warning": "La comisión que ingresó es más alta que la recomendada, el costo por enviar la transacción podría ser más alto de lo deseado.", + "fee-unknown-warning": "El sistema aún está obteniendo la información de las comisiones recomendadas, por lo que no es posible determinar si la comisión que ingresó es conveniente.", + "fee-problem-warning2": "Hubo un problema al intentar obtener la comisión recomendada, por lo que no es posible determinar si la comisión que ingresó es conveniente.", + "fee-error-info": "El valor es demasiado bajo o inválido.", + "personal-note-help": "Use este campo para agregar un texto que le permita identificar la transacción en el futuro. Este texto se guarda localmente, por lo que solo será visible desde esta computadora.", + "wallet-label": "Billetera", + "wallet-error-info": "Debe seleccionar una billetera.", + "invalid-amount": "Por favor introduzca una cantidad válida", + "convert-confirmation": "¿También desea que la cantidad introducida se convierta de {{from}} a {{to}}?", + "convert-confirmation-plural": "¿También desea que las cantidades introducidas se conviertan de {{from}} a {{to}}?", + "send-all-available-coins-link": "enviar todo", + "precision-error-warning": "Se detectó un error de precisión durante la conversión. Por favor verifique la cantidad que se enviará.", + "invaid-amount-warning": "Se detectó un valor inválido durante la conversión. Por favor verifique la cantidad que se enviará.", + "precision-errors-warning": "Se detectaron errores de precisión durante la conversión. Por favor verifique la cantidad que se enviará.", + "invaid-amounts-warning": "Se detectaron valores inválidos durante la conversión. Por favor verifique la cantidad que se enviará.", + "multiple-problems-warning": "Algunos valores no se convirtieron por ser inválidos o podrían haberse convertido con errores de precisión. Por favor verifique la cantidad que se enviará.", + "addresses-label": "Direcciones", + "addresses-error-info": "Debe ingresar al menos una dirección válida.", + "no-available-balance-error": "No se ha calculado el saldo disponible.", + "no-wallet-selected-error": "No hay monedas para enviar.", + "no-coins-left-error": "No hay monedas restantes para enviar.", + "addresses-help": "Limite las direcciones desde donde se podrían enviar las monedas y las horas.", + "addresses-manual-help": "Lista de las direcciones desde las cuales se enviarán las monedas, separadas por comas. Todas las direcciones deben pertenecer a la misma billetera o no podrá firmar la transacción con la billetera de escritorio.", + "all-addresses": "Todas las direcciones de la billetera seleccionada", + "outputs-label": "Salidas no gastadas", + "outputs-help": "Limite las salidas no gastadas desde donde se podrían enviar las monedas y las horas. Solo se muestran las salidas de las direcciones seleccionadas.", + "outputs-error": "Hubo un error al intentar obtener las salidas. Por favor asegúrese de haber ingresado direcciones válidas.", + "all-outputs": "Todas las salidas no gastadas de las direcciones seleccionadas", + "enter-addresses-for-outputs": "Debe ingresar direcciones válidas primero", + "enter-wallet-for-outputs-and-addresses": "Debe seleccionar una billetera válida primero", + "invalid-addresses-for-outputs": "No hay salidas disponibles", + "loading-available": "Cargando saldo disponible...", + "waiting-for-available": "Esperando una comisión válida para calcular el saldo disponible...", + "available-funds-without-hours-msg-part1": "Puede enviar hasta", + "available-funds-without-hours-msg-part2": "(al menos", + "available-funds-without-hours-msg-part3": "deben usarse como comisión de transacción para enviar todas las monedas).", + "available-funds-msg-part1": "Con su selección actual puede enviar hasta", + "available-funds-msg-part2": "y", + "available-funds-msg-part3": "(al menos", + "available-funds-msg-part4": "deben ser utilizadas como comisión de transacción para enviar todas las monedas u horas).", + "change-address-label": "Dirección de retorno personalizada", + "change-address-error-info": "La dirección de retorno no es válida.", + "change-address-select-from-list-link": "Seleccionar", + "change-address-help": "Dirección para recibir el cambio. Si no se proporciona, será elegida automáticamente. Haga clic en el enlace \"Seleccionar\" para elegir una dirección de una de sus billeteras.", + "destinations-label": "Destinos", + "destinations-help1": "Direcciones de destino y sus monedas.", + "destinations-help2": "Direcciones de destino, sus monedas y horas.", + "destination-label": "Destino", + "destination-help": "Dirección de destino y las monedas que se le enviarán.", + "hours-allocation-check": "Usar una distribución automática de {{ coinHoursName }}", + "options-link": "Opciones", + "coin-hours-options-link": "Opciones de horas", + "hours-share-factor-label": "Factor de distribución de {{ coinHoursName }}", + "hours-share-factor-help": "Este control permite seleccionar el porcentaje de {{ coinHoursName }} que serán enviadas. de Mientras mayor sea el valor, más {{ coinHoursName }} se enviarán y menos serán retenidas.", + "close-hours-share-factor-alert": "La opción se restablecerá al valor predeterminado. Seguro que desea continuar?", + "preview-button": "Preview", + "send-button": "Enviar", + "show-button": "Mostrar", + "simple-form-button": "Simple", + "advanced-form-button": "Advanzado", + "select-wallet": "Seleccionar billetera", + "saving-note-error": "La transacción se envió correctamente, pero no fue posible guardar la nota.", + "sent": "La transacción se envió correctamente.", + "total-to-send": "Total:", + "sending-all-hours-with-coins-waning": "Al enviar todas las monedas, todas las horas de la billetera seleccionada serán enviadas o quemadas. Si desea retener horas, no debe enviar todas las monedas. ¿Seguro que desea continuar?", + "advanced-sending-all-hours-with-coins-waning": "Al enviar todas las monedas, todas las horas de la(s) fuente(s) seleccionada(s) serán enviadas o quemadas. Si desea retener horas, no debe enviar todas las monedas. ¿Seguro que desea continuar?", + "sending-all-hours-waning": "Usted seleccionó enviar todas las horas. ¿Seguro que desea continuar?", + "high-hours-share-waning": "Su selección puede resultar en el envío de todas las horas de la billetera seleccionada. ¿Seguro que desea continuar?", + "advanced-high-hours-share-waning": "Su selección puede resultar en el envío de todas las horas de la(s) fuente(s) seleccionada(s). ¿Seguro que desea continuar?", + "invalid-address": "Dirección de destino inválida encontrada: ", + "invalid-addresses": "Direcciones de destino inválidas encontradas: ", + "invalid-address-error": "La dirección de destino no es válida.", + "one-invalid-address-error": "Una de las direcciones de destino no es válida.", + "various-invalid-addresses-error": "Algunas direcciones de destino no son válidas.", + "all-addresses-invalid-error": "Las direcciones de destino no son válidas.", + "invalid-addresses-error": "Por favor asegúrese de que la dirección sea válida.", + "address-error-info": "Por favor introduzca una dirección válida.", + "invalid-value-error-info": "Valor inválido.", + "insufficient-funds-error-info": "El valor ingresado es mayor que el saldo disponible.", + + "known-node-errors": { + "null-change-address-error": "La dirección nula no se puede utilizar como dirección de retorno personalizada. Por favor introduzca una dirección válida.", + "to-required-error": "Debe proporcionar una dirección de destino para enviar monedas. Por favor introduzca una dirección válida.", + "zero-coins-error": "No es posible enviar cero monedas. Por favor introduzca una cantidad válida.", + "null-destination-error": "La dirección nula no se puede utilizar como dirección de destino. Por favor introduzca una dirección válida.", + "duplicate-destination-error": "Hay destinos duplicados. Por favor no repita la misma dirección y cantidad en más de un destino.", + "hours-in-automatic-mode-error": "No se pueden especificar cantidades de horas mientras se usa la distribución automática de horas. Por favor pruebe con valores diferentes y póngase en contacto con el servicio de soporte si el problema no se resuelve.", + "hours-allocation-mode-needed-error": "Se requiere el modo de asignación de horas. Por favor pruebe con valores diferentes y póngase en contacto con el servicio de soporte si el problema no se resuelve.", + "invalid-hours-allocation-mode-error": "Modo de asignación de horas no válido. Por favor pruebe con valores diferentes y póngase en contacto con el servicio de soporte si el problema no se resuelve.", + "hours-allocation-mode-not-needed-error": "El modo de asignación de horas no se puede especificar mientras se usa la distribución de horas manual. Por favor pruebe con valores diferentes y póngase en contacto con el servicio de soporte si el problema no se resuelve.", + "invalid-hours-mode-error": "Método de distribución de horas no válido. Por favor pruebe con valores diferentes y póngase en contacto con el servicio de soporte si el problema no se resuelve.", + "share-factor-needed-error": "Se necesita el factor de distribución de horas. Por favor pruebe con valores diferentes y póngase en contacto con el servicio de soporte si el problema no se resuelve.", + "share-factor-not-needed-error": "El factor de distribución de horas no puede ser especificado mientras se usa la distribución de horas manual. Por favor pruebe con valores diferentes y póngase en contacto con el servicio de soporte si el problema no se resuelve.", + "invalid-share-factor-error": "Factor de distribución de horas inv+alido. Por favor pruebe con valores diferentes y póngase en contacto con el servicio de soporte si el problema no se resuelve.", + "change-equal-to-destination-error": "No es posible crear la transacción debido a que se regresaría una cantidad repetida de monedas a la misma dirección de destino. Por favor inténtelo nuevamente con valores diferentes.", + "repeated-wallet": "Una billetera para la semilla indicada ya existe." + }, + + "fees": { + "very-high": "Muy alta", + "high": "Alta", + "Normal": "Normal", + "Low": "Baja", + "very-Low": "Muy baja", + "custom": "Personalizada" + }, + + "eth-fees": { + "Normal": "Recomendada", + "custom": "Personalizada" + }, + + "bulk-send": { + "title": "Envío Masivo", + "indications": "Para enviar a múltiples destinos de forma rápida, escriba cada dirección, cantidad de monedas y cantidad de horas (opcional) en una línea, separadas por una coma. Ejemplo: si desea enviar 10 monedas y 5 horas a la dirección \"xyz\", escriba \"xyz,10,5\"; si desea que las horas se calculen automáticamente, escriba \"xyz,10\". Los valores decimales se deben separar con un punto.", + "indications-without-hours": "Para enviar a múltiples destinos de forma rápida, escriba cada dirección y cantidad de monedas en una línea, separadas por una coma. Ejemplo: si desea enviar 10 monedas a la dirección \"xyz\", escriba \"xyz,10\". Los valores decimales se deben separar con un punto.", + "data-error-info": "Debe ingresar un valor.", + "process-button": "Procesar", + "no-data-error": "No hay texto para procesar.", + "inconsistent-data-error": "Si establece cuántas horas desea enviar a un destino, debe hacerlo para todos los destinos.", + "invalid-data-error": "El texto ingresado tiene un formato inválido." + } + }, + + "select-address": { + "title": "Seleccionar Dirección", + "wallet-addresses": "Ver las Direcciones de la Billetera", + "no-addresses": "No hay direcciones confirmadas en esta billetera." + }, + + "get-address": { + "title": "Obtener Dirección", + "password-info": "Para mantener su privacidad, la contraseña se utilizará para crear una nueva dirección para recibir monedas, ya que la última ya ha sido utilizada.", + "used-address-warning": "Se generó una dirección que ya recibió monedas, ya que no se proporcionó la contraseña de la billetera. Para mantener la privacidad, se recomienda usar las direcciones solo una vez." + }, + + "offline-transactions": { + "loading-problem": "Error al intentar obtener los datos necesarios", + "wallet-error-info": "Debe seleccionar una billetera.", + "tx-error-info": "Debe ingresar un texto de transacción válido.", + "copy-tx": { + "signed-title": "Transacción Firmada", + "unsigned-title": "Transacción Sin Firmar", + "text-unsigned": "Esta es la transacción sin firmar que se ha creado con los datos que ha ingresado. Por favor copie el texto para poder firmarlo con la opción \"Firmar transacción\".", + "text-signed": "Esta es la transacción firmada. Puede enviarla a la red utilizando la opción \"Transmitir Transacción\".", + "input-label": "Texto de la transacción", + "copy-button": "Copiar", + "reset-confirmation": "¿Desea que se limpie el formulario, de forma que pueda crear otra transacción?", + "reset-done": "El formulario ha sido limpiado." + }, + + "sign-tx": { + "title": "Firmar Transacción", + "text": "Use este formulario para firmar una transacción. Para que la operación funcione correctamente debe seleccionar la billetera que incluye todas las entradas/direcciones utilizadas para enviar monedas en la transacción.", + "wallet-label": "Billetera", + "select-wallet": "Seleccione una billetera", + "input-label": "Texto de la transacción", + "sign-button": "Firmar", + "signed": "La transacción ha sido firmada." + }, + + "broadcast-tx": { + "title": "Transmitir Transacción", + "text": "Use este formulario para enviar una transacción firmada a la red.", + "input-label": "Texto de la transacción", + "send-button": "Enviar", + "sent": "La transacción ha sido enviada." + } + }, + + "reset": { + "title": "Restablecer Contraseña", + "invalid-wallet": "Billetera inválida", + "wallet-label": "Billetera", + "seed-label": "Semilla de la billetera", + "seed-error-info": "Debe ingresar una semilla.", + "enter-seed": "Presione aquí para ingresar la semilla", + "words-number-label": "Cuantas palabras tiene la semilla", + "12-words": "12 palabras", + "24-words": "24 palabras", + "passphrase-label": "Passphrase de la billetera (si tiene)", + "password-label": "Nueva contraseña (deje en blanco si desea que la billetera no esté encriptada)", + "confirm-label": "Confirme la contraseña", + "confirm-error-info": "Las dos contraseñas deben coincidir.", + "reset-button": "Restablecer", + "done": "Contraseña cambiada correctamente." + }, + + "tx": { + "confirm-transaction-title": "Confirmar Transacción", + "from-small-label": "Desde:", + "to-small-label": "A:", + "wallet-small-label": "Billetera:", + "wallets-small-label": "Billeteras:", + "date-small-label": "Fecha:", + "status-small-label": "Estatus:", + "amount-small-label": "Cantidad:", + "coins-small-label": "Monedas:", + "hours-small-label": "Horas:", + "fee-small-label": "Comisión:", + "balance-to-send-info": "Incluye la comisión de transacción.", + "approximate-fee-warning": " / Aproximado", + "approximate-fee-info": "La comisión podría ser menor después de procesar la transacción. Cualquier cantidad no utilizada se devolverá a la dirección de origen.", + "id-small-label": "Tx ID:", + "note-small-label": "Nota:", + "without-note": "Sin nota", + "show-more-link": "Mostrar más", + "hours-moved": "movida(s)", + "hours-sent": "enviada(s)", + "hours-received": "recibida(s)", + "hours-burned": "quemada(s)", + "inputs-title": "Entradas", + "outputs-title": "Salidas", + "internal": "Esta dirección le pertenece", + "confirmed-transaction": "Confirmada", + "pending-transaction": "Pendiente ({{currentConfirmations}} / {{confirmationsNeeded}})", + "current-rate-help": "Calculado a la tasa actual.", + "coinbase": "COINBASE (nuevas monedas y comisiones)" + }, + + "edit-note": { + "title": "Editar Nota", + "change-button": "Cambiar" + }, + + "backup": { + "title": "Respaldar Billetera", + "wallet-directory": "Directorio de la Billetera:", + "seed-warning": "RESPALDE SU SEMILLA. EN PAPEL. EN UN LUGAR SEGURO. Mientras tenga su semilla, podrá recuperar las monedas.", + "desc": "Use la tabla de más abajo para obtener las semillas de sus billeteras encriptadas.
Para obtener las semillas de las billeteras no encriptadas, abra el directorio de más arriba, abra los archivos .wlt en un editor de texto y recupere las semillas.", + "wallet-table-label": "Nombre de la billetera", + "filename-table-label": "Archivo", + "save-addresses-button": "Guardar Direcciones", + "show-seed-button": "Mostrar semilla", + "no-wallets": "No hay billeteras", + "unencrypted-info": "Por razones de seguridad, no es posible mostrar las semillas de las billeteras sin encriptar. Para obtener la semilla, por favor encripte la billetera con una contraseña o siga las instrucciones en la parte superior de esta página.", + "hw-wallet-info": "Para obtener la semilla de una Skywallet, por favor use la opción \"Skywallet\" de la parte inferior de la página de billeteras.", + "xpub-info": "No es posible mostrar las semillas de las billeteras xPub.", + "not-compatible-error": "Su navegador web no es compatible con esta función.", + + "seed-modal-window": { + "title": "Semilla de la Billetera", + "seed-label": "Semilla", + "passphrase-label": "Passphrase", + "type-label": "Tipo de billetera", + "type-deterministic": "Determinista", + "type-bip44": "Bip44", + "type-xpub": "xPub" + } + }, + + "blockchain": { + "title": "Blockchain", + "blocks-label": "Cantidad de bloques", + "time-label": "Fecha del último bloque", + "hash-label": "Hash del último bloque", + "current-supply-label": "Suministro de {{ coinName }} actual", + "total-supply-label": "Suministro de {{ coinName }} total", + "current-coinhour-supply-label": "Suministro de {{ coinHoursName }} actual", + "total-coinhour-supply-label": "Suministro de {{ coinHoursName }} total", + + "select-confirmation": { + "title": "Editar confirmaciones necesarias", + "confirmations-label": "Confirmaciones", + "confirmations-error-info": "Debe ingresar un valor entero válido entre 0 y {{ max }}.", + "apply-button": "Aplicar" + } + }, + + "network": { + "title": "Red", + "error-no-connections": "Sin conexiones", + "peer-small-table-label": "Par", + "source-small-table-label": "Fuente", + "block-height-small-table-label": "Altura del bloque", + "block-height-short-small-table-label": "Bloque", + "last-seen-small-table-label": "Última vez visto", + "last-received-help": "Última recepción.", + "last-sent-help": "Último envío.", + "in-help": "Entrante.", + "out-help": "Saliente.", + + "sources": { + "default": "Par por defecto", + "exchange": "Intercambio de pares" + } + }, + + "pending-txs": { + "title": "Transacciones Pendientes", + "timestamp-table-label": "Fecha", + "txid-table-label": "ID de la transacción", + "none": "Actualmente no hay transacciones pendientes", + "my-transactions-button": "Mías", + "all-transactions-button": "Todas", + "unknown-date": "Desconocida" + }, + + "outputs": { + "title": "Salidas", + "error-no-outputs": "No hay salidas no gastadas" + }, + + "history": { + "title-and-button": "Historial", + "tx-detail-title": "Detalles de la Transacción", + "failed": "Fallida", + "failed-info": "Se pagó la comisión de transacción pero no se enviaron los fondos.", + "complex-transaction": "Transacción compleja", + "moving": "Moviendo {{ coinName }} entre direcciones", + "moved": "{{ coinName }} movido entre direcciones", + "moving-wallet": "Moviendo {{ coinName }} entre billeteras", + "moved-wallet": "{{ coinName }} movido entre billeteras", + "sending": "Enviando {{ coinName }}", + "sent": "{{ coinName }} enviado", + "receiving": "Recibiendo {{ coinName }}", + "received": "{{ coinName }} recibido", + "pending-indication": "Pendiente ({{currentConfirmations}} / {{confirmationsNeeded}})", + "confirmations-help": "La transacción solo tiene {{currentConfirmations}} de {{confirmationsNeeded}} confirmaciones necesarias para considerarse completada.", + "transaction-note-small-label": "Nota:", + "involved-wallets-small-label": "Billeteras locales involucradas:", + "involved-wallet-small-label": "Billetera local involucrada:", + "no-txs": "Usted no tiene historial de transacciones", + "no-txs-filter": "No hay transacciones que coincidan con los criterios de filtro actuales", + "no-filter": "Sin filtros activos (presione para seleccionar billeteras/direcciones)", + "filter": "Filtro activo: ", + "filters": "Filtros activos: ", + "all-addresses": "Todas las direcciones", + "other-wallets-title": "Otras Billeteras", + "wallets-title": "Billeteras", + "addresses": "Direcciones", + "load-more": "Cargar más", + "view-all": "Ver todas las {{ number }} transacciones", + "use-explorer": "Use el explorador de blockchain para acceder al historial de transacciones completo", + "show-addresses": "Mostrar las direcciones", + "hide-addresses": "Ocultar las direcciones", + "balance-help": "No incluye {{ amount }} pagados por usted como comisión." + }, + + "address-history": { + "title": "Direcciones de la Billetera", + "omited-addresses-warning": "Hubo un problema y se ignoraron algunas direcciones.", + "invalid-wallet": "Billetera inválida", + "add-button": "Añadir direcciones", + "normal-address-table-label": "Dirección normal", + "normal-address-info": "Direcciones que normalmente usa para recibir monedas.", + "change-address-table-label": "Dirección de cambio", + "change-address-info": "Direcciones creadas automáticamente a las que se envían las monedas restantes cuando envía una transacción.", + "unused-table-label": "Sin usar", + "used-yes": "Sí", + "used-yes-info": "Esta dirección aún no ha recibido ninguna moneda.", + "used-no": "No", + "used-no-info": "Esta dirección ya ha recibido monedas. Para mantener la privacidad, se recomienda usar las direcciones solo una vez.", + "history": "Historial", + "view-all": "Mostrando las últimas {{ current }} direcciones. Presione para mostrar todas las {{ total }} direcciones" + }, + + "teller": { + "done": "Completado", + "waiting-confirm": "Esperando confirmación", + "waiting-deposit": "Esperando depósito de Bitcoins", + "waiting-send": "Esperando para envíar Skycoins", + "unknown": "Desconocido" + }, + + "confirmation" : { + "default-title": "Confirmación", + "yes-button": "Sí", + "no-button": "No" + }, + + "service": { + "api" : { + "no-internet-error": "Usted no está conectado a Internet o el nodo ha dejado de funcionar.", + "incorrect-password-error": "Contraseña incorrecta.", + "unknown-error": "No fue posible realizar la operación.", + "api-disabled-error": "API deshabilitada." + } + }, + + "hardware-wallet": { + "general" : { + "default-wallet-name": "Nueva Skywallet", + "confirm": "Por favor, confirme la operación en la Skywallet.", + "confirm-and-more": "Por favor confirme la operación en la Skywallet y siga las instrucciones.", + "follow": "Por favor siga las instrucciones mostradas en la Skywallet.", + "completed": "La operación se realizó con éxito.", + "name-updated": "El nombre utilizado para identificar esta Skywallet en la lista de billeteras se ha actualizado para que coincida con el que se muestra en el dispositivo." + }, + "errors": { + "generic-error": "No se puede realizar la operación. Asegúrese de haber conectado una Skywallet válida y de que no esté esperando por alguna confirmación o respuesta.", + "disconnected": "No se puede realizar la operación. La Skywallet no está conectada.", + "incorrect-wallet": "No se puede realizar la operación. La Skywallet conectada es diferente a la esperada.", + "incorrect-pin": "No se puede realizar la operación. El PIN que ha introducido no es correcto.", + "refused": "La operación fue cancelada.", + "too-many-inputs-outputs": "La transacción tiene demasiadas entradas o salidas para la Skywallet. Por favor vuelva a intentarlo creando varias transacciones más pequeñas, cada una con un número menor de destinatarios (si la transacción actual tiene muchos) o monedas.", + "outdated-daemon": "No fue posible completar la operación porque el Skywallet Daemon está desactualizado. Puede descargar la última versión desde ", + "daemon-connection": "Problema para conectarse al Skywallet Daemon, por favor asegúrese de que se esté ejecutando e inténtelo nuevamente. Usted puede descargarlo desde ", + "timeout": "La operación se canceló por inactividad. Por favor inténtelo de nuevo.", + "invalid-address-generated": "Hubo un problema con el generador de direcciones y la operación tuvo que ser cancelada.", + "invalid-address": "Dirección inválida.", + "not-in-bootloader-mode": "Para usar esta opción la Skywallet debe estar en modo bootloader." + }, + "security-warning" : { + "title": "Advertencia de Seguridad", + "text": "La última vez que se conectó esta Skywallet, se encontraron una o más advertencias de seguridad. Le recomendamos que abra las opciones de Skywallet (presionando el enlace de más abajo) mientras el dispositivo está conectado y resuelva los problemas de seguridad antes de continuar.", + "link": "Abrir la ventana de opciones de Skywallet." + }, + "options" : { + "connecting": "Conectando...", + "disconnected": "Skywallet no detectada. Por favor, conecte una Skywallet para usar esta opción.", + "unconfigured-detected-title": "Skywallet No Configurada", + "unconfigured-detected": "Se ha detectado una Skywallet sin semilla. Seleccione \"Configurar Automáticamente\" si desea configurarla como una billetera nueva y comenzar a usarla. Seleccione \"Restaurar Copia de Seguridad\" si desea configurar la Skywallet con la copia de seguridad de una semilla creada anteriormente.", + "configured-detected": "Skywallet detectada. El dispositivo se identifica en la lista de billeteras como:", + "security-warnings-title": "Advertencias de Seguridad", + "security-warning-title": "Advertencia de Seguridad", + "unchecked-version-warning": "No fue posible verificar si el firmware de su Skywallet está actualizado. Esto podría deberse a problemas con su conexión a Internet o a que el servicio esté en mantenimiento.", + "outdated-version-warning": "El firmware de su Skywallet está desactualizado. Le recomendamos que lo actualice lo antes posible para garantizar la seguridad. Para hacer esto, seleccione la opción \"Actualizar Firmware\".", + "backup-warning": "Debe hacer una copia de seguridad de la semilla de su Skywallet o podría perder acceso a los fondos en caso de problemas. Para hacer esto, seleccione la opción \"Crear Copia de Seguridad\".", + "pin-warning": "La Skywallet conectada no tiene un PIN. El código PIN protege la Skywallet de accesos no autorizados. Para crear un código PIN, seleccione la opción \"Crear Código PIN\".", + "options": "Opciones:", + "update-firmware": "Actualizar Firmware", + "configure-automatically": "Configurar Automáticamente", + "restore-backup": "Restaurar Copia de Seguridad", + "create-backup": "Crear Copia de Seguridad", + "wipe": "Borrar el Dispositivo", + "confirm-seed": "Confirmar la Semilla", + "create-pin": "Crear Código PIN", + "change-pin": "Cambiar el Código PIN", + "delete-pin": "Borrar el Código PIN", + "forgotten-pin-part1": "Si no puede acceder a la billetera porque ha olvidado el PIN, puede borrar la Skywallet y luego restaurarla con la semilla haciendo clic", + "forgotten-pin-part2": "aquí.", + "firmware-version": "Versión del firmware del dispositivo:" + }, + "update-firmware-warning" : { + "title": "Firmware Desactualizado", + "text": "ADVERTENCIA: el firmware de su Skywallet está desactualizado. Para mantenerse seguro se le recomienda actualizarlo.", + "update": "Actualizar" + }, + "update-firmware" : { + "title-connecting": "Conectando...", + "title-update": "Actualizar Firmware", + "title-install": "Instalar Firmware", + "text-downloading": "Comprobando el dispositivo y descargando archivos...", + "text-bootloader": "ADVERTENCIA: si ya ha configurado este dispositivo, antes de continuar debe tener una copia de seguridad de su semilla o podría perder permanentemente el acceso a los fondos.", + "text-not-bootloader": "Para actualizar el firmware de su Skywallet debe conectarla en modo bootloader (conéctela al computador mientras presiona los dos botones físicos del dispositivo). ADVERTENCIA: si ya ha configurado este dispositivo, antes de continuar debe tener una copia de seguridad de su semilla o podría perder permanentemente el acceso a los fondos.", + "text-no-firmware": "Le damos la bienvenida. La Skywallet conectada actualmente no tiene un firmware instalado. Ahora se instalará un firmware para que pueda comenzar a usar el dispositivo. NOTA: si ya ha configurado este dispositivo y desea recuperar los fondos, necesitará la semilla.", + "follow": "La actualización del firmware se envió a la Skywallet. Por favor continúe el proceso en el dispositivo.", + "connection-error": "No fue posible descargar el firmware. Esto podría deberse a problemas con su conexión a Internet o a que el servicio esté en mantenimiento.", + "timeout": "La operación se canceló por inactividad. Por favor desconecte el dispositivo, vuelva a conectarlo e intente nuevamente.", + "finished": "Su dispositivo ha sido configurado correctamente. Por favor desconéctelo antes de continuar." + }, + "generate-seed" : { + "text": "Antes de continuar puede seleccionar el número de palabras que desea que tenga la semilla. La semilla es una lista de palabras que se pueden usar para recuperar el acceso a las monedas en caso de problemas. Ambos valores son seguros, por lo que si no tiene una razón especial para seleccionar uno u otro, puede dejar el valor predeterminado.", + "configuring": "Configurando..." + }, + "restore-seed" : { + "text": "Antes de continuar, por favor seleccione la cantidad de palabras de la semilla que desea recuperar.", + "check-text": "Puede usar esta opción para ingresar una semilla y verificar si es igual a la de la Skywallet. Antes de comenzar, seleccione el número de palabras de la semilla que desea verificar.", + "warning" : "ADVERTENCIA: para evitar posibles problemas, use solo semillas creadas con una Skywallet.", + "error-wrong-word": "Error: la palabra introducida no coincide con la solicitada por la Skywallet.", + "error-invalid-seed": "Error: la semilla no es válida. Por favor asegúrese de ingresar las palabras correctas en el orden correcto.", + "error-wrong-seed": "Error: la semilla es válida pero no coincide con la del dispositivo.", + "correct-seed": "La semilla es válida y coincide con la del dispositivo." + }, + "added" : { + "title": "Nueva Skywallet", + "configuring": "Nueva Skywallet detectada. Configurando...", + "done": "Hecho", + "added1": "La Skywallet conectada se ha agregado a la lista de billeteras con el siguiente nombre:", + "added2": "Ahora puede consultar el saldo y las direcciones de la Skywallet incluso cuando no está conectada.", + "added-error-info": "Debe ingresar un nombre.", + "characters-warning": "Si utiliza caracteres no comunes en el idioma inglés, es posible que el nombre no se muestre correctamente en el dispositivo." + }, + "wipe" : { + "warning": "ADVERTENCIA: Todos los datos en la Skywallet serán eliminados. Si no tiene una copia de seguridad, no podrá volver a acceder a sus fondos.", + "confirm-delete-check": "Quitar también de la lista de billeteras" + }, + "create-backup" : { + "warning": "ADVERTENCIA: Solo puede usar esta opción para hacer una copia de seguridad de la semilla de su Skywallet una vez. Si decide continuar, tendrá que escribir un grupo de palabras (en papel, nunca en una computadora) que aparecerán en la pantalla de la Skywallet y almacenar la lista en un lugar seguro. Cualquier persona con acceso a la lista de palabras (la \"semilla\") podrá acceder a los fondos de la billetera, por lo que se recomienda extremar las precauciones.", + "instructions": "Escriba la lista de palabras que aparecen en la pantalla de la Skywallet. Asegúrese de respetar el orden y escribir cada palabra correctamente." + }, + "seed-word" : { + "title": "Ingresar Palabra", + "enter-word": "Introduzca la palabra indicada en el dispositivo", + "info": "Se le pedirá que ingrese las palabras de su semilla de respaldo en orden aleatorio. Adicionalmente, algunas palabras adicionales aleatorias podrían serle solicitadas.", + "word-label": "Palabra solicitada", + "error-invalid-word": "La palabra introducida no es válida.", + "error-loading-words": "Cargando la lista de palabras. Por favor espere." + }, + "change-pin" : { + "pin-mismatch": "No se puede realizar la operación. Los dos PIN que ha introducido no coinciden." + }, + "remove-pin" : { + "warning": "ADVERTENCIA: No se recomienda eliminar el código PIN de su Skywallet, ya que será vulnerable a ser utilizada por terceros no autorizados." + }, + "enter-pin" : { + "title": "Ingresar PIN", + "title-change-current": "Ingrese el PIN Actual", + "title-change-new": "Ingrese el Nuevo PIN", + "title-change-confirm": "Confirme el Nuevo PIN", + "instructions-generic": "El patrón de números del PIN se muestra en la pantalla de la Skywallet.", + "instructions-tx": "Introduzca el PIN para confirmar y firmar la transacción. El patrón de números del PIN se muestra en la pantalla de la Skywallet.", + "instructions-change": "Por favor ingrese un PIN difícil de adivinar de entre 4 y 8 números. El patrón de números del PIN se muestra en la pantalla de la Skywallet.", + "help": "¿Necesita ayuda?" + }, + "pin-help" : { + "title": "Ayuda", + "part1": "Cuando sea necesario ingresar el PIN para continuar, la pantalla de la Skywallet mostrará una matriz de 9 casillas con números en orden aleatorio (el orden cambia cada vez) y se le pedirá que ingrese el PIN en la billetera de software usando una matriz de 9 botones que simplemente muestran el símbolo #.", + "part2": "Para ingresar el PIN, mire la posición de los números del PIN en la matriz de números en la pantalla de la Skywallet y presione los botones correspondientes en la billetera de software. Por ejemplo, si el PIN es \"23\", el número 2 está en la esquina superior izquierda y el número 3 en el centro de la matriz de números de la Skywallet, presione los botones superior izquierdo y central, en ese orden, en la billetera de software.", + "part3": "Si lo desea, también puede usar el teclado numérico para ingresar el PIN. Sin embargo, como en el ejemplo anterior, si el PIN es \"23\", no puede simplemente escribir \"23\" con el teclado numérico, sino que deberá presionar las teclas que están en la posición donde están los números 2 y 3 en la pantalla de la Skywallet." + }, + "create-tx" : { + "title": "Crear Transacción", + "upper-text": "Por favor confirme la operación en la Skywallet después de verificar si los siguientes datos coinciden EXACTAMENTE con la transacción que desea enviar y con los que muestra la Skywallet:", + "lower-text": "Si algún dato no corresponde a lo que muestra la Skywallet o la transacción que desea enviar, cancele la operación en su Skywallet.", + "separator-for-coins-and-hours": "y", + "separator-to-destination": "a" + }, + "confirm-address" : { + "title": "Confirmar Dirección", + "instructions": "Por favor confirme en la Skywallet si la dirección es:", + "short-confirmation": "Dirección confirmada.", + "confirmation": "Dirección confirmada. Por seguridad, puede volver a mostrar la dirección en la Skywallet usando la opción \"Confirmar dirección\", en el menú que puede mostrar presionando el botón a la derecha del balance de la direccion." + } + }, + + "time-from-now": { + "few-seconds": "hace pocos segundos", + "minute": "hace un minuto", + "minutes": "hace {{time}} minutos", + "hour": "hace una hora", + "hours": "hace {{time}} horas", + "day": "hace un día", + "days": "hace {{time}} días" + }, + + "exchange": { + "title-and-button": "Comprar {{ coinName }}", + "label-you-send": "Usted envía", + "label-you-get": "Usted recibe (aprox.)", + "label-to-address": "A la dirección de {{coin}}", + "label-price": "Tasa de cambio", + "label-stimate-transaction-time": "Duración del intercambio", + "exchange-button": "Intercambiar", + "min-amount": "Monto minimo:", + "max-amount": "Monto maximo:", + "agree-part1": "Acepto los", + "agree-part2": "Términos de Uso", + "agree-part3": "y la ", + "agree-part4": "Política de Privacidad", + "powered-by": "Manejado por", + "need-help": "¿Necesita ayuda?", + "support-portal": "Portal de soporte", + "history": "Historial de órdenes", + "order-not-found": "Orden no encontrada", + "label-status": "Estado", + "exchanging": "Intercambiando {{from}} por {{to}}", + "destination-select-from-list-link": "Seleccionar", + "unavailable": "El servicio de intercambio no está disponible en versión portable.", + "offline": "El servicio está temporalmente offline", + "problem-connecting": "No se puede conectar con el servicio. Por favor compruebe su conexión a Internet y vuelva a intentarlo más tarde.", + "invalid-address-error": "Dirección inválida.", + "from-coin-error-info": "Debe seleccionar una moneda.", + "invalid-value-error-info": "Valor inválido.", + "address-error-info": "Por favor introduzca una dirección válida.", + "statuses": { + "user-waiting": "Esperando el deposito. Por favor envíe {{amount}} {{from}} a la dirección de intercambio indicada más abajo", + "user-waiting-info": "El sistema está a la espera de que usted realice el depósito en la dirección de intercambio. El proceso de intercambio comenzará después de que se detecte el depósito y sea confirmado en la cadena de bloques. Si ya ha realizado el depósito, debería ser detectado en breve.", + "market-waiting-confirmations": "Esperando las confirmaciones de la transacción", + "market-waiting-confirmations-info": "El depósito ya ha sido detectado y el sistema está esperando que sea confirmado en la cadena de bloques.", + "market-confirmed": "Transacción aceptada", + "market-confirmed-info": "La transacción ya ha sido confirmada en la cadena de bloques. Haciendo los preparativos para realizar el intercambio pronto.", + "market-exchanged": "{{from}} intercambiado por {{to}}", + "market-exchanged-info": "El intercambio se ha realizado. Los fondos serán transferidos a su dirección en un momento.", + "market-withdraw-waiting": "Enviando {{to}} a su dirección", + "market-withdraw-waiting-info": "Se ha iniciado el proceso para enviar las monedas a su dirección.", + "complete": "¡Intercambio completado!", + "complete-info": "Los fondos han sido enviados con éxito a su dirección.", + "error": "Se produjo un error", + "error-info": "Hubo un error en la operación, puede encontrar más información más abajo. Si necesita ayuda, por favor guarde todos los datos de operación que se muestran más abajo y comuníquese con soporte técnico utilizando el enlace que se encuentra en la parte inferior derecha de esta página.", + "user-deposit-timeout": "Orden cancelada por inactividad", + "user-deposit-timeout-info": "El sistema ha cancelado la orden porque no se detectó ningún depósito, por favor abra una nueva orden. Si necesita ayuda, por favor guarde todos los datos de operación que se muestran más abajo y comuníquese con soporte técnico utilizando el enlace que se encuentra en la parte inferior derecha de esta página." + }, + "history-window": { + "title": "Historial de Órdenes", + "address": "Dirección:", + "date": "Fecha:" + }, + "details": { + "exchange-addr-label": "Dirección de intercambio (válida solo para esta operación de intercambio)", + "exchange-addr-tag-label": "Payment ID o Destination Tag que debe usarse para la transacción", + "tx-id-label": "ID de la transacción", + "order-id-label": "ID de la orden", + "initial-price-label": "Tasa de cambio inicial", + "error-msg-label": "Mensaje de error", + "details-link": "Detalles", + "start-date-label": "Fecha de inicio", + "back-alert": "La operación aún está en progreso. ¿Realmente desea volver al formulario? Puede ver el progreso de esta operación nuevamente presionando el botón \"Historial de pedidos\"" + } + } +} diff --git a/src/gui/static/src/assets/i18n/es_base.json b/src/gui/static/src/assets/i18n/es_base.json new file mode 100644 index 0000000..5c77198 --- /dev/null +++ b/src/gui/static/src/assets/i18n/es_base.json @@ -0,0 +1,876 @@ +{ + "common": { + "usd": "USD", + "loading": "Loading...", + "done-title": "Done", + "warning-title": "Warning", + "error-title": "Error", + "changes-made": "The changes have been made.", + "back-button": "Back", + "create-button": "Create", + "load-button": "Load", + "cancel-button": "Cancel", + "continue-button": "Continue", + "close-button": "Close", + "generic-confirmation-check": "I understand the risks and want to continue", + "copied": "The text has been copied to the clipboard.", + "confirmations": "Confirmations", + "unconfirmed-balance-info": "This balance will be final after your last transactions receive more confirmations from the network. The currently confirmed balance is {{ balance }}. For more information check your pending transactions." + }, + + "errors": { + "window-size": "The window is too narrow for the content." + }, + + "language": { + "title": "Select Language" + }, + + "header": { + "syncing-blocks": "Syncing blocks", + "explorer-link": "{{ coinName }} Explorer", + + "top-bar": { + "updated-label": "Balance updated:", + "updated-time": "{{ time }} min ago", + "less-than": "less than a min ago", + "connection-error-info": "Connection error, press to retry." + }, + + "warnings": { + "update-part1": "Wallet update", + "update-part2": "Not used. The code adds the versión number of the lastest update here.", + "update-part3": "available.", + "synchronizing": "The wallet is synchronizing. Data you see may not be updated.", + "pending-txs-part1": "You have", + "pending-txs-part2": "pending transactions.", + "pending-txs-part3": "The balances and some other data may not be updated.", + "pending-link-error": "You are already in the transaction history page.", + "no-connections": "No connections active, your client is not connected to any other nodes!", + "no-backend-part1": "Cannot reach backend. Please restart the app and/or seek help on our", + "no-backend-part2": "Telegram.", + "no-backend-part3": "", + "csrf": "Security vulnerability: CSRF is not working, please exit immediately." + } + }, + + "password": { + "title": "Enter Password", + "password-label": "Password", + "password-error-info": "You must enter a password.", + "confirm-password-label": "Confirm password", + "confirm-error-info": "The two passwords must match.", + "proceed-button": "Proceed", + "reset-link": "I forgot my password", + "incorrect-password-error": "Incorrect password.", + "decrypting-error": "Error decrypting the wallet." + }, + + "buy": { + "title-and-button": "Buy", + "deposit-address": "Choose an address to generate a BTC deposit link for:", + "select-address": "Select address", + "generate": "Generate", + "deposit-location": "Deposit Location", + "deposit-location-desc": "Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.", + "make-choice": "Make a choice", + "wallets-desc": "Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.", + "send": "Send Bitcoin", + "send-desc": "Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.", + "fraction-warning": "Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!", + "receive": "Receive Sky", + "receive-desc": "After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.", + "status-button": "Status:", + "check-status-button": "Check Status", + "new-order-button": "New Order" + }, + + "wizard": { + "create-title": "Create Wallet", + "create-desc": "If you don't have a wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to \"Load\" and enter your seed.", + "encrypt-title": "Encrypt Wallet", + "encrypt-desc": "Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.", + "hardware-wallet-link": "Using a Skywallet?", + "hardware-wallet-alt-link": "Use a Skywallet", + "new-button": "New", + "load-button": "Load", + "finish-button": "Finish", + + "confirm": { + "title": "Safeguard Your Seed!", + "desc": "We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your wallet!", + "checkbox": "It’s safe, I swear." + } + }, + + "change-coin": { + "title": "Change active coin", + "search": "Search", + "with-wallet": "Coins you have created wallets for:", + "without-wallet": "Coins you have not created wallets for:", + "no-results": "No coins match the search term" + }, + + "wallet": { + "title-and-button": "Wallets", + "no-wallets": "Currently there are no wallets", + "show-empty-button": "Show Empty", + "hide-empty-button": "Hide Empty", + "add-button": "New Wallet", + "load-button": "Load Wallet", + "hardware-wallet-button": "Skywallet", + "encryption-enabled": "Encryption enabled.", + "encryption-disabled": "Encryption disabled.", + "warning-hw-security": "Possible security risk. Access the Skywallet options (by pressing the \"Skywallet\" button below the wallets list) while the device is connected for more information.", + "wallet-table-label": "Wallet", + "hardware-wallet-table-label": "Skywallet", + "legacy-small-label": "Legacy", + "legacy-info": "The wallet was not created with the most up-to-date procedure, but you can continue using it normally. This message is purely informative.", + "xpub-small-label": "xPub", + "xpub-info": "This is a read-only wallet, you can't use it for sending coins.", + "delete-confirmation": "WARNING: The wallet \"{{ name }}\" will be removed from the list. To add it again, you will have to reconnect the device and open the Skywallet options (by pressing the \"Skywallet\" button below the wallets list). Do you want to continue?", + "delete-confirmation-check": "Yeah, I want to delete the wallet", + "max-hardware-wallets-error": "You have already reached the max number of addresses that can be added to the Skywallet.", + "add-many-confirmation": "WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?", + "busy-error": "Please wait for the previous operation to be completed.", + + "new": { + "create-title": "Create Wallet", + "load-title": "Load Wallet", + "not-available-warning": "Sorry, it is not possible to create wallets for this coin at this time.", + "skywallet-only-warning": "You can only create wallets for this coin using a Skywallet.", + "advanced-options-link": "Advanced wallet options", + "advanced-options-close-warning": "The changes you have made will be lost. Are you sure you want to continue?", + "name-label": "Name", + "name-error-info": "You must enter a name.", + "coin-label": "Coin", + "type-label": "Type", + "type-deterministic": "Deterministic (Legacy)", + "type-bip44": "Bip44 (New)", + "type-xpub": "xPub (Read-Only)", + "type-info": "\"Bip44\" is the new recomended method for creating wallets, while \"Deterministic\" is the method used by old versions of the software. \"Bip44\" and \"Deterministic\" wallets are always different, even if you use the same seed.", + "passphrase-label": "Seed passphrase (optional)", + "passphrase-info": "Additional text for the seed. If provided, anyone trying to restore the wallet will need the seed AND the provided passphrase.", + "passphrase-warning-title": "Warning", + "passphrase-warning": "Be extremely cautious with the passphrase. If you need to recover the wallet you will have to enter not only the seed, but also EXACTLY the same passphrase you are entering here, character by character. If you have the seed but not the passphrase, you won't be able to recover access to the funds.", + "words-number-label": "How many words the seed has", + "xpub-label": "xPub key", + "xpub-error-info": "You must enter a valid value.", + "seed-label": "Seed", + "seed-error-info": "You must enter a seed.", + "confirm-seed-label": "Confirm seed", + "confirm-seed-error-info": "The two seeds must match.", + "seed-warning": "Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!", + "12-words": "12 words", + "24-words": "24 words", + "generate-12-help": "Generate a 12 word seed.", + "generate-24-help": "Generate a 24 word seed.", + "encrypt-check": "Encrypt wallet", + "encrypt-warning-non-xpub": "We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.", + "encrypt-warning-xpub": "We suggest that you encrypt each one of your wallets with a password.", + "seed-checking-error": "It was not possible to verify the validity of the seed.", + "unconventional-seed-title": "Possible Error", + "unconventional-seed-text": "You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.", + "unconventional-seed-check": "Continue with the unconventional seed", + "synchronizing-warning-text": "The wallet is still synchronizing and the operation could not restore all the addresses. If some addresses are not restored, you will have to wait for the wallet to be fully synchronized and use the \"Force Rescan\" function or add them again manually.", + "wallet-created": "The wallet has been added to the list.", + + "seed": { + "enter-seed": "Press here to enter the seed", + "change-seed": "Press to change", + "confirm-seed": "Press here to confirm the seed", + "confirmed-seed": "Seed confirmed", + "use-custom-seed-help": "Press here if you want to enter the seed manually.", + "use-normal-seed-help": "Press here if you want to enter the seed using the recommended method.", + "custom-seed-warning-text": "This option is only recommended for advanced users. Making mistakes with the seed could cause you to lose access to the funds in case of a problem.", + "custom-seed-warning-text-recovering": "To avoid possible problems, this option should only be used if you want to recover an unconventional seed.", + "incorrect-word-error": "The word you have entered does not match the requested one.", + "invalid-seed-error": "The seed you have entered is not valid. Please try again.", + "enter-word": "Enter the word #{{number}}", + "word-error-info": "You must enter a word.", + "new-seed-info": "You must enter the words of the seed that was generated by the system, to confirm it.", + "recover-seed-info": "Please be sure to enter the correct words in the correct order." + } + }, + + "rename": { + "title": "Rename Wallet", + "name-label": "Name", + "label-error-info": "You must enter a name.", + "rename-button": "Rename" + }, + + "wallet-options": { + "title": "Options", + "add": "Add Addresses", + "encrypt": "Encrypt Wallet", + "decrypt": "Decrypt Wallet", + "decrypt-warning": "Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.", + "scan": "Force Rescan", + "scan-help": "Use this option to make the system automatically rescan the wallet if the balance is not correct or to retrieve missing addresses.", + "delete": "Delete Wallet", + "cancelled-error": "Operation cancelled." + }, + + "scan-addresses": { + "synchronizing-warning-text": "The wallet is still synchronizing and the process may not be completely effective. Do you want to continue?", + "done-with-new-addresses": "The process has been completed and new addresses have been added to the wallet.", + "done-without-new-addresses": "The process has been completed and no new data was found for the wallet." + }, + + "add-addresses": { + "title": "Select Quantity", + "quantity-label": "How many addresses to create", + "quantity-error-info": "You must enter a value between 1 and 100", + "error": "There was an unexpected error. Please try again." + }, + + "address": { + "show": "Press to show", + "copy": "Copy", + "copy-address": "Copy address", + "copied": "Copied!", + "confirm": "Confirm address", + "outputs": "Unspent outputs", + "history": "History" + } + }, + + "qr": { + "title": "QR Code", + "receive-title": "Receive Coins", + "data-label": "QR data", + "address-label": "Address", + "address-info": "Coins sent to this address will be credited to the wallet.", + "password-info": "To maintain your privacy, the password will be used to create a new address for receiving coins, since the last one has already been used.", + "used-address-warning": "This address has already received coins. To maintain privacy, it is recommended to use the addresses only once. Please enter the password when opening this window if you want a new address to be created.", + "address-history-link": "Wallet addresses", + "unused-addresses-warning": "You have unused addresses before this one. Use this link to check them.", + "request-link": "Request specific amount", + "amount-label": "Requested amount", + "hours-label": "Requested hours", + "message-label": "Message", + "invalid": "(invalid value)" + }, + + "send": { + "title-and-button": "Send", + "unsigned-button": "Unsigned", + "signed-button": "Signed", + "unsigned-confirmation": "The unsigned transactions form does not allow to send transactions normally, but simply creates the text of a transaction, which must be signed before it can be sent to the network. This is useful for creating transactions that will be signed on an always offline device, for security reasons. Are you sure you wish to continue?", + "synchronizing-warning": "The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?", + "available-balance-indication": "Excluding pending balance", + "wallets-updated-warning": "The wallet list has been updated.", + "from-label": "Send from", + "to-label": "Send to", + "amount-label": "Amount", + "personal-note-label": "Personal note", + "gas-price-label": "Gas price", + "gas-limit-label": "Gas limit", + "fee-options": "Fee options", + "fee-label": "Aproximate fee", + "fee-measure": "{{ measure }} per byte", + "fee-problem-warning": "There was a problem trying to get the recommended fee, so it will have to be entered manually before sending the transaction.", + "fee-low-warning": "The fee you entered is lower than recommended, the transaction could take a very long time to be confirmed.", + "fee-high-warning": "The fee you entered is higher than recommended, the cost for sending the transaction could be higher than desired.", + "fee-unknown-warning": "The system is still obtaining the information about the recommended fees, so it is not possible to determine if the fee you entered is convenient.", + "fee-problem-warning2": "There was a problem trying to get the recommended fee, so it is not possible to determine if the fee you entered is convenient.", + "fee-error-info": "The value is too low or invalid.", + "personal-note-help": "Use this field to add a text for allowing you to identify the transaction in the future. This text is saved locally, so it will only be visible from this computer.", + "wallet-label": "Wallet", + "wallet-error-info": "You must select a wallet.", + "invalid-amount": "Please enter a valid amount", + "convert-confirmation": "Do you also want the already introduced amount to be converted from {{from}} to {{to}}?", + "convert-confirmation-plural": "Do you also want the already introduced amounts to be converted from {{from}} to {{to}}?", + "send-all-available-coins-link": "send all", + "precision-error-warning": "A precision error was detected during conversion. Please check the amount that will be sent.", + "invaid-amount-warning": "An invalid value was detected during conversion. Please check the amount that will be sent.", + "precision-errors-warning": "Precision errors were detected during conversion. Please check the amount that will be sent.", + "invaid-amounts-warning": "Invalid values were detected during conversion. Please check the amount that will be sent.", + "multiple-problems-warning": "Some values were not converted because they were invalid or could have been converted with precision errors. Please check the amount that will be sent.", + "addresses-label": "Addresses", + "addresses-error-info": "You must enter at least one valid address.", + "no-available-balance-error": "No available balance has been computed.", + "no-wallet-selected-error": "There are no coins to send.", + "no-coins-left-error": "There are no coins left to send.", + "addresses-help": "Limit the addresses from where the coins and hours could be sent.", + "addresses-manual-help": "List of the addresses from which the coins will be sent, comma separated. All addresses must belong to the same wallet or you will not be able to sign the transaction with the desktop wallet.", + "all-addresses": "All the addresses of the selected wallet", + "outputs-label": "Unspent outputs", + "outputs-help": "Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown.", + "outputs-error": "There was an error trying to get the outputs. Please make sure you have entered valid addresses.", + "all-outputs": "All the outputs of the selected addresses", + "enter-addresses-for-outputs": "Valid addresses must be entered first", + "enter-wallet-for-outputs-and-addresses": "A valid wallet must be selected first", + "invalid-addresses-for-outputs": "No outputs available", + "loading-available": "Loading available balance...", + "waiting-for-available": "Waiting for a valid fee to calculate the available balance...", + "available-funds-without-hours-msg-part1": "You can send up to", + "available-funds-without-hours-msg-part2": "(at least", + "available-funds-without-hours-msg-part3": "must be used as transaction fee for sending all the coins).", + "available-funds-msg-part1": "With your current selection you can send up to", + "available-funds-msg-part2": "and", + "available-funds-msg-part3": "(at least", + "available-funds-msg-part4": "must be used as transaction fee for sending all the coins or hours).", + "change-address-label": "Custom change address", + "change-address-error-info": "The change address is not valid.", + "change-address-select-from-list-link": "Select", + "change-address-help": "Address to receive change. If it's not provided, it will be chosen automatically. Click on the \"Select\" link to choose an address from one of your wallets.", + "destinations-label": "Destinations", + "destinations-help1": "Destination addresses and their coins.", + "destinations-help2": "Destination addresses, their coins and hours.", + "destination-label": "Destination", + "destination-help": "Destination address and the coins that will be sent to it.", + "hours-allocation-check": "Use automatic {{ coinHoursName }} allocation", + "options-link": "Options", + "coin-hours-options-link": "Hours options", + "hours-share-factor-label": "{{ coinHoursName }} share factor", + "hours-share-factor-help": "This control allows to select the factor (percentage) of {{ coinHoursName }} that will be send. The higher the value, the more {{ coinHoursName }} will be sent and less will be retained.", + "close-hours-share-factor-alert": "The option will be resetted to the default value. Are you sure you want to continue?", + "preview-button": "Preview", + "send-button": "Send", + "show-button": "Show", + "simple-form-button": "Simple", + "advanced-form-button": "Advanced", + "select-wallet": "Select wallet", + "saving-note-error": "The transaction was successfully sent, but it was not possible to save the note.", + "sent": "Transaction successfully sent.", + "total-to-send": "Total:", + "sending-all-hours-with-coins-waning": "By sending all the available coins, all the hours in the selected wallet will be sent or burn. If you want to retain hours, you must not send all the coins. Are you sure you want to continue?", + "advanced-sending-all-hours-with-coins-waning": "By sending all the available coins, all the hours in the selected source(s) will be sent or burn. If you want to retain hours, you must not send all the coins. Are you sure you want to continue?", + "sending-all-hours-waning": "You selected to send all the hours. Are you sure you want to continue?", + "high-hours-share-waning": "Your selection may result in sending all the hours in the selected wallet. Are you sure you want to continue?", + "advanced-high-hours-share-waning": "Your selection may result in sending all the hours in the selected source(s). Are you sure you want to continue?", + "invalid-address": "Invalid destination address found: ", + "invalid-addresses": "Invalid destination addresses found: ", + "invalid-address-error": "The destination address is not valid.", + "one-invalid-address-error": "One of the destination addresses is not valid.", + "various-invalid-addresses-error": "Some destination addresses are not valid.", + "all-addresses-invalid-error": "The destination addresses are not valid.", + "invalid-addresses-error": "Please make sure the address is valid.", + "address-error-info": "Please enter a valid address.", + "invalid-value-error-info": "Invalid value.", + "insufficient-funds-error-info": "The entered value is greater than the available balance.", + + "known-node-errors": { + "null-change-address-error": "The null address can't be used as the custom change address. Please enter a valid address.", + "to-required-error": "You must provide a destination address for sending coins. Please enter a valid address.", + "zero-coins-error": "It's not possible to send zero coins. Please enter a valid amount.", + "null-destination-error": "The null address can't be used as destination. Please enter a valid address.", + "duplicate-destination-error": "There are duplicate destinations. Please do not repeat the same address and amount in more than one destination.", + "hours-in-automatic-mode-error": "Specific hour amounts can't be specified while using automatic hour distribution. Please try with different values and contact support if the problem is not solved.", + "hours-allocation-mode-needed-error": "The hour allocation mode is required. Please try with different values and contact support if the problem is not solved.", + "invalid-hours-allocation-mode-error": "Invalid hour allocation mode. Please try with different values and contact support if the problem is not solved.", + "hours-allocation-mode-not-needed-error": "The hour allocation mode can't be specified while using manual hour distribution. Please try with different values and contact support if the problem is not solved.", + "invalid-hours-mode-error": "Invalid hour distribution method. Please try with different values and contact support if the problem is not solved.", + "share-factor-needed-error": "The hours share factor is needed. Please try with different values and contact support if the problem is not solved.", + "share-factor-not-needed-error": "The hours share factor can't be specified while using manual hour distribution. Please try with different values and contact support if the problem is not solved.", + "invalid-share-factor-error": "Invalid share factor. Please try with different values and contact support if the problem is not solved.", + "change-equal-to-destination-error": "The transaction can't be created because a repeated amount of coins would be returned to the same destination address. Please try again with different values.", + "repeated-wallet": "A wallet for the specified seed already exists." + }, + + "fees": { + "very-high": "Very high", + "high": "High", + "Normal": "Normal", + "Low": "Low", + "very-Low": "Very Low", + "custom": "Custom" + }, + + "eth-fees": { + "Normal": "Recommended", + "custom": "Custom" + }, + + "bulk-send": { + "title": "Bulk Send", + "indications": "To send to multiple destinations in a quick way, type each address, coin amount and hour amount (optional) on a line, separated by a comma. Example: if you want to send 10 coins and 5 hours to the \"xyz\" address, type \"xyz,10,5\"; if you want the hours to be calculated automatically, type \"xyz,10\". Decimal values must be separated with a dot.", + "indications-without-hours": "To send to multiple destinations in a quick way, type each address and coin amount on a line, separated by a comma. Example: if you want to send 10 coins to the \"xyz\" address, type \"xyz,10\". Decimal values must be separated with a dot.", + "data-error-info": "You must enter a value.", + "process-button": "Process", + "no-data-error": "There is no text to process.", + "inconsistent-data-error": "If you set how many hours you want to send to a destination, you must do so for all destinations.", + "invalid-data-error": "The entered text has an invalid format." + } + }, + + "select-address": { + "title": "Select Address", + "wallet-addresses": "View Wallet Addresses", + "no-addresses": "There are no confirmed addresses on this wallet." + }, + + "get-address": { + "title": "Get Address", + "password-info": "To maintain your privacy, the password will be used to create a new address for receiving coins, since the last one has already been used.", + "used-address-warning": "An address that has already received coins was generated, as the wallet password was not provided. To maintain privacy, it is recommended to use the addresses only once." + }, + + "offline-transactions": { + "loading-problem": "Error trying to get the necessary data", + "wallet-error-info": "You must select a wallet.", + "tx-error-info": "You must enter a valid transaction text.", + "copy-tx": { + "signed-title": "Signed Transaction", + "unsigned-title": "Unsigned Transaction", + "text-unsigned": "This is the unsigned transaction that has been created with the data that you have entered. Please copy the text to be able to sign it with the \"Sign Transaction\" option.", + "text-signed": "This is the signed transaction. You can send it to the network using the \"Broadcast Transaction\" option.", + "input-label": "Transaction text", + "copy-button": "Copy", + "reset-confirmation": "Do you want the the form to be cleaned, so you can create another transaction?", + "reset-done": "The form has been cleaned." + }, + + "sign-tx": { + "title": "Sign Transaction", + "text": "Use this form to sign a transaction. For the operation to work correctly, you must select the wallet which includes all the inputs/addresses used to send coins in the transaction.", + "wallet-label": "Wallet", + "select-wallet": "Select wallet", + "input-label": "Transaction text", + "sign-button": "Sign", + "signed": "The transaction has been signed." + }, + + "broadcast-tx": { + "title": "Broadcast Transaction", + "text": "Use this form to send a signed transaction to the network.", + "input-label": "Transaction text", + "send-button": "Send", + "sent": "The transaction has been sent." + } + }, + + "reset": { + "title": "Reset Password", + "invalid-wallet": "Invalid wallet", + "wallet-label": "Wallet", + "seed-label": "Wallet seed", + "seed-error-info": "You must enter a seed.", + "enter-seed": "Press here to enter the seed", + "words-number-label": "How many words the seed has", + "12-words": "12 words", + "24-words": "24 words", + "passphrase-label": "Wallet passphrase (if any)", + "password-label": "New password (leave empty if you want the wallet not to be encrypted)", + "confirm-label": "Confirm new password", + "confirm-error-info": "The two passwords must match.", + "reset-button": "Reset", + "done": "Password successfully changed." + }, + + "tx": { + "confirm-transaction-title": "Confirm Transaction", + "from-small-label": "From:", + "to-small-label": "To:", + "wallet-small-label": "Wallet:", + "wallets-small-label": "Wallets:", + "date-small-label": "Date:", + "status-small-label": "Status:", + "amount-small-label": "Amount:", + "coins-small-label": "Coins:", + "hours-small-label": "Hours:", + "fee-small-label": "Fee:", + "balance-to-send-info": "Includes the transaction fee.", + "approximate-fee-warning": " / Approximate", + "approximate-fee-info": "The fee could be less after processing the transaction. Any unused amount will be returned to the source address.", + "id-small-label": "Tx ID:", + "note-small-label": "Note:", + "without-note": "Without note", + "show-more-link": "Show more", + "hours-moved": "moved", + "hours-sent": "sent", + "hours-received": "received", + "hours-burned": "burned", + "inputs-title": "Inputs", + "outputs-title": "Outputs", + "internal": "You own this address", + "confirmed-transaction": "Confirmed", + "pending-transaction": "Pending ({{currentConfirmations}} / {{confirmationsNeeded}})", + "current-rate-help": "Calculated at the current rate.", + "coinbase": "COINBASE (new coins and fees)" + }, + + "edit-note": { + "title": "Edit Note", + "change-button": "Change" + }, + + "backup": { + "title": "Backup Wallet", + "wallet-directory": "Wallet Directory:", + "seed-warning": "BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.", + "desc": "Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.", + "wallet-table-label": "Wallet name", + "filename-table-label": "Filename", + "save-addresses-button": "Save Addresses", + "show-seed-button": "Show Seed", + "no-wallets": "There are no wallets", + "unencrypted-info": "For security reasons, it is not possible to show the seeds of unencrypted wallets. To get the seed, please encrypt the wallet with a password or follow the instruction shown at the top of this page.", + "hw-wallet-info": "For getting the seed of a Skywallet, please use the \"Skywallet\" option at the bottom of the wallets page.", + "xpub-info": "It is not possible to show the seeds of xPub wallets.", + "not-compatible-error": "Your web browser is not compatible with this function.", + + "seed-modal-window": { + "title": "Wallet Seed", + "seed-label": "Seed", + "passphrase-label": "Passphrase", + "type-label": "Wallet type", + "type-deterministic": "Deterministic", + "type-bip44": "Bip44", + "type-xpub": "xPub" + } + }, + + "blockchain": { + "title": "Blockchain", + "blocks-label": "Number of blocks", + "time-label": "Timestamp of last block", + "hash-label": "Hash of last block", + "current-supply-label": "Current {{ coinName }} supply", + "total-supply-label": "Total {{ coinName }} supply", + "current-coinhour-supply-label": "Current {{ coinHoursName }} supply", + "total-coinhour-supply-label": "Total {{ coinHoursName }} supply", + + "select-confirmation": { + "title": "Edit Confirmations Needed", + "confirmations-label": "Confirmations", + "confirmations-error-info": "You must enter a valid integer value between 0 and {{ max }}.", + "apply-button": "Apply" + } + }, + + "network": { + "title": "Networking", + "error-no-connections": "No connections", + "peer-small-table-label": "Peer", + "source-small-table-label": "Source", + "block-height-small-table-label": "Block height", + "block-height-short-small-table-label": "Block", + "last-seen-small-table-label": "Last seen", + "last-received-help": "Last received.", + "last-sent-help": "Last sent.", + "in-help": "Incoming.", + "out-help": "Outgoing.", + + "sources": { + "default": "Default peer", + "exchange": "Peer exchange" + } + }, + + "pending-txs": { + "title": "Pending Transactions", + "timestamp-table-label": "Timestamp", + "txid-table-label": "Transaction ID", + "none": "No pending transactions", + "my-transactions-button": "Mine", + "all-transactions-button": "All", + "unknown-date": "Unknown" + }, + + "outputs": { + "title": "Outputs", + "error-no-outputs": "No unspent outputs" + }, + + "history": { + "title-and-button": "History", + "tx-detail-title": "Transaction Detail", + "failed": "Failed", + "failed-info": "The transaction fee was paid but the funds were not sent.", + "complex-transaction": "Complex transaction", + "moving": "Moving {{ coinName }} between addresses", + "moved": "{{ coinName }} moved between addresses", + "moving-wallet": "Moving {{ coinName }} between wallets", + "moved-wallet": "{{ coinName }} moved between wallets", + "sending": "Sending {{ coinName }}", + "sent": "{{ coinName }} sent", + "receiving": "Receiving {{ coinName }}", + "received": "{{ coinName }} received", + "pending-indication": "Pending ({{currentConfirmations}} / {{confirmationsNeeded}})", + "confirmations-help": "The transaction only has {{currentConfirmations}} of {{confirmationsNeeded}} confirmations needed for being considered completed.", + "transaction-note-small-label": "Note:", + "involved-wallets-small-label": "Involved local wallets:", + "involved-wallet-small-label": "Involved local wallet:", + "no-txs": "You have no transaction history", + "no-txs-filter": "There are no transactions matching the current filter criteria", + "no-filter": "No filter active (press to select wallets/addresses)", + "filter": "Active filter: ", + "filters": "Active filters: ", + "all-addresses": "All addresses", + "other-wallets-title": "Other Wallets", + "wallets-title": "Wallets", + "addresses": "Addresses", + "load-more": "Load more", + "view-all": "View all {{ number }} transactions", + "use-explorer": "Use the blockchain explorer for accessing the full transaction history", + "show-addresses": "Show the addresses", + "hide-addresses": "Hide the addresses", + "balance-help": "Does not include {{ amount }} you paid as fee." + }, + + "address-history": { + "title": "Wallet Addresses", + "omited-addresses-warning": "There was a problem and some addresses were ignored.", + "invalid-wallet": "Invalid wallet", + "add-button": "Add Addresses", + "normal-address-table-label": "Normal address", + "normal-address-info": "Addresses you normally use to receive coins.", + "change-address-table-label": "Change address", + "change-address-info": "Automatically created addresses where any remaining coins are sent when you submit a transaction.", + "unused-table-label": "Unused", + "used-yes": "Yes", + "used-yes-info": "This address has not yet received any coins.", + "used-no": "No", + "used-no-info": "This address has already received coins. To maintain privacy, it is recommended to use the addresses only once.", + "history": "History", + "view-all": "Showing the last {{ current }} addresses. Press to show all {{ total }} addresses" + }, + + "teller": { + "done": "Completed", + "waiting-confirm": "Waiting for confirmation", + "waiting-deposit": "Waiting for Bitcoin deposit", + "waiting-send": "Waiting to send Skycoin", + "unknown": "Unknown" + }, + + "confirmation" : { + "default-title": "Confirmation", + "yes-button": "Yes", + "no-button": "No" + }, + + "service": { + "api" : { + "no-internet-error": "You do not have a internet connection or the node has stopped working.", + "incorrect-password-error": "Incorrect password.", + "unknown-error": "It was not possible to perform the operation.", + "api-disabled-error": "API disabled." + } + }, + + "hardware-wallet": { + "general" : { + "default-wallet-name": "New Skywallet", + "confirm": "Please confirm the operation on the Skywallet.", + "confirm-and-more": "Please confirm the operation on the Skywallet and follow the instructions displayed.", + "follow": "Please follow the instructions displayed on the Skywallet.", + "completed": "Operation completed successfully.", + "name-updated": "The name used to identify this Skywallet in the wallet list has been updated to match the one shown on the device." + }, + "errors": { + "generic-error": "Unable to perform the operation. Make sure you have connected a valid Skywallet and that it is not waiting for input.", + "disconnected": "Unable to perform the operation. The Skywallet is not connected.", + "incorrect-wallet": "Unable to perform the operation. The connected Skywallet is different from the expected one.", + "incorrect-pin": "Unable to perform the operation. The PIN you have entered is incorrect.", + "refused": "The operation was canceled.", + "too-many-inputs-outputs": "The transaction has too many inputs or outputs for the Skywallet. Please try again creating several smaller transactions, each one with a smaller number of recipients (if the current transaction has many) or coins.", + "outdated-daemon": "It was not possible to complete the operation because the Skywallet daemon is outdated. You can download the latest version from ", + "daemon-connection": "Problem connecting to the Skywallet Daemon, please make sure it is running and try again. You can download it from ", + "timeout": "The operation was canceled due to inactivity. Please try again.", + "invalid-address-generated": "There was a problem with the address generator and the operation had to be canceled.", + "invalid-address": "Invalid address.", + "not-in-bootloader-mode": "To use this option the Skywallet must be in bootloader mode." + }, + "security-warning" : { + "title": "Security Warning", + "text": "The last time this Skywallet was connected, one or more security warnings were found. We recommend that you open the Skywallet options (by pressing the link below) while the device is connected and solve the security problems before continuing.", + "link": "Open the Skywallet options window." + }, + "options" : { + "connecting": "Connecting...", + "disconnected": "No Skywallet detected. Please connect a Skywallet to use this option.", + "unconfigured-detected-title": "Unconfigured Skywallet", + "unconfigured-detected": "A seedless Skywallet has been detected. Select \"Configure Automatically\" if you want to configure it as a brand new wallet and start using it. Select \"Restore Backup\" if you want to configure the Skywallet with a previously created seed backup.", + "configured-detected": "Skywallet detected. The device is identified in the wallets list as:", + "security-warnings-title": "Security Warnings", + "security-warning-title": "Security Warning", + "unchecked-version-warning": "It was not possible to verify if the firmware of your Skywallet is up to date. This could be due to problems with your internet connection or because the service is under maintenance.", + "outdated-version-warning": "The firmware of your Skywallet is outdated. We recommend you to update it as soon as possible to ensure safety. To do this, select the \"Update Firmware\" option.", + "backup-warning": "You should backup the Skywallet seed or you could lose access to the funds in case of problems. To do this, select the \"Create a Backup\" option.", + "pin-warning": "The connected Skywallet does not have a PIN. The PIN code protects the Skywallet from unauthorized parties accessing the device. To create a PIN code, select the \"Create PIN Code\" option.", + "options": "Options:", + "update-firmware": "Update Firmware", + "configure-automatically": "Configure Automatically", + "restore-backup": "Restore Backup", + "create-backup": "Create a Backup", + "wipe": "Wipe the Device", + "confirm-seed": "Confirm Seed", + "create-pin": "Create PIN Code", + "change-pin": "Change PIN Code", + "delete-pin": "Delete PIN Code", + "forgotten-pin-part1": "If you cannot access the wallet because you have forgotten the PIN, you can wipe the Skywallet and then restore it with the seed by clicking", + "forgotten-pin-part2": "here.", + "firmware-version": "Device firmware version:" + }, + "update-firmware-warning" : { + "title": "Outdated Firmware", + "text": "WARNING: the firmware in your Skywallet is outdated. To stay safe, it is recommended to update it.", + "update": "Update" + }, + "update-firmware" : { + "title-connecting": "Connecting...", + "title-update": "Update Firmware", + "title-install": "Install Firmware", + "text-downloading": "Checking device and downloading files...", + "text-bootloader": "WARNING: if you have already configured this device, before continuing you must have a backup of your seed or you could permanently lose access to the funds.", + "text-not-bootloader": "To update the firmware of your Skywallet you must connect it in bootloader mode (connect it to the computer while pressing the two physical buttons of the device). WARNING: if you have already configured this device, before continuing you must have a backup of your seed or you could permanently lose access to the funds.", + "text-no-firmware": "Welcome. The currently connected Skywallet does not have a firmware installed. A firmware will now be installed so you can start using the device. NOTE: if you have already configured this device and want to recover the funds, you will need your seed.", + "follow": "The firmware update has been sent to the Skywallet. Please continue the process on the device.", + "connection-error": "It was not possible to download the firmware. This could be due to problems with your internet connection or because the service is under maintenance.", + "timeout": "The operation was canceled due to inactivity. Please disconnect the device, reconnect it and try again.", + "finished": "Your device has been configured correctly. Please unplug it before continuing." + }, + "generate-seed" : { + "text": "Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.", + "configuring": "Configuring..." + }, + "restore-seed" : { + "text": "Before proceeding, please select the number of words that the seed you want to recover has.", + "check-text": "You can use this option to enter a seed and check if it is equal to the one in the Skywallet. Before start, select the number of words the seed you want to check has.", + "warning" : "WARNING: to avoid potential problems, use only seeds created with a Skywallet.", + "error-wrong-word": "Error: the retyped word does not match the one requested by the Skywallet.", + "error-invalid-seed": "Error: the seed is not valid. Please be sure to enter the correct words in the correct order.", + "error-wrong-seed": "Error: the seed is valid but does not match the one in the device.", + "correct-seed": "The seed is valid and matches the one in the device." + }, + "added" : { + "title": "New Skywallet", + "configuring": "New Skywallet detected. Configuring...", + "done": "Done", + "added1": "The connected Skywallet has been added to the wallets list with the following name:", + "added2": "Now you can check the balance and the addresses of the Skywallet even when it is not connected.", + "added-error-info": "You must enter a name.", + "characters-warning": "If you use non-standard English characters, the name may not be displayed correctly on the device." + }, + "wipe" : { + "warning": "WARNING: All the data on the Skywallet will be deleted. If you do not have a backup, you will not be able to access your funds again.", + "confirm-delete-check": "Also remove from the wallets list" + }, + "create-backup" : { + "warning": "WARNING: You can only create a backup of your Skywallet seed once. If you decide to continue, you will have to write down a group of words (on paper, never on a computer) that will appear on the screen of the Skywallet and store the list in a safe place. Anyone with access to the word list (the \"seed\") will be able access the wallet funds, so extreme caution is advised.", + "instructions": "Write down the word list that appear on the screen of the Skywallet. Make sure you respect the order and write each word correctly." + }, + "seed-word" : { + "title": "Enter Word", + "enter-word": "Enter the word shown on the device", + "info": "You will be asked to enter the words of your backup seed in random order. Also, additional random words could be requested.", + "word-label": "Requested word", + "error-invalid-word": "The entered word is not valid.", + "error-loading-words": "Loading the word list. Please wait." + }, + "change-pin" : { + "pin-mismatch": "Unable to perform the operation. The PINs you have entered do not match." + }, + "remove-pin" : { + "warning": "WARNING: It is not recommended to remove the PIN code from your Skywallet, as it will be vulnerable to being used by unauthorized parties." + }, + "enter-pin" : { + "title": "Enter PIN", + "title-change-current": "Enter the Current PIN", + "title-change-new": "Enter the New PIN", + "title-change-confirm": "Confirm the New PIN", + "instructions-generic": "The PIN layout is displayed on the Skywallet screen.", + "instructions-tx": "Enter the PIN to confirm and sign the transaction. The PIN layout is displayed on the Skywallet screen.", + "instructions-change": "Please enter a secure PIN consisting of 4 to 8 numbers. The PIN layout is displayed on the Skywallet screen.", + "help": "Need help?" + }, + "pin-help" : { + "title": "Help", + "part1": "When it is necessary to enter the PIN to continue, the Skywallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol •.", + "part2": "To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the Skywallet and press the corresponding buttons in the software wallet. For example, if the PIN is \"23\" and the number 2 is in the upper left, number 3 in the middle of the Skywallet numbers matrix, press the upper left and middle button in that order in the software wallet.", + "part3": "If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is \"23\", you can not simply type \"23\" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the Skywallet. Taking into account the previous example, you would have to press the \"7\" and \"5\" keys, because those are the keys that you are in the same position as the numbers shown by the Skywallet." + }, + "create-tx" : { + "title": "Create Transaction", + "upper-text": "Please confirm the operation in the Skywallet after verifying if the following data matches EXACTLY with the transaction you wish to send and with those shown by the Skywallet:", + "lower-text": "If any data does not correspond to what the Skywallet shows or the transaction you wish to send, cancel the operation on your Skywallet.", + "separator-for-coins-and-hours": "and", + "separator-to-destination": "to" + }, + "confirm-address" : { + "title": "Confirm Address", + "instructions": "Please confirm on the Skywallet if the address is:", + "short-confirmation": "Address confirmed.", + "confirmation": "Address confirmed. For security, you can re-show the address in the Skywallet using the \"Confirm address\" option, in the menu that you can display by pressing the button at the right of the address balance." + } + }, + + "time-from-now": { + "few-seconds": "a few seconds ago", + "minute": "one minute ago", + "minutes": "{{time}} minutes ago", + "hour": "one hour ago", + "hours": "{{time}} hours ago", + "day": "one day ago", + "days": "{{time}} days ago" + }, + + "exchange": { + "title-and-button": "Buy {{ coinName }}", + "label-you-send": "You send", + "label-you-get": "You get (approx.)", + "label-to-address": "To {{coin}} address", + "label-price": "Exchange rate", + "label-stimate-transaction-time": "Exchange time", + "exchange-button": "Exchange", + "min-amount": "Minimum amount:", + "max-amount": "Maximum amount:", + "agree-part1": "I agree with the", + "agree-part2": "Terms of Use", + "agree-part3": "and the", + "agree-part4": "Privacy Policy", + "powered-by": "Powered by", + "need-help": "Need help?", + "support-portal": "Support portal", + "history": "Order history", + "order-not-found": "Order not found", + "label-status": "Status", + "exchanging": "Exchanging {{from}} for {{to}}", + "destination-select-from-list-link": "Select", + "unavailable": "The exchange service is not available in portable version", + "offline": "Exchange is temporarily offline", + "problem-connecting": "Unable to connect with the service. Please check your Internet connection and try again later", + "invalid-address-error": "Invalid address.", + "from-coin-error-info": "You must select a coin.", + "invalid-value-error-info": "Invalid value.", + "address-error-info": "Please enter a valid address.", + "statuses": { + "user-waiting": "Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below", + "user-waiting-info": "The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.", + "market-waiting-confirmations": "Waiting for transaction confirmations", + "market-waiting-confirmations-info": "The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.", + "market-confirmed": "Transaction accepted", + "market-confirmed-info": "The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.", + "market-exchanged": "Traded {{from}} for {{to}}", + "market-exchanged-info": "The exchange has been made. The funds will be transferred to your address in a moment.", + "market-withdraw-waiting": "Sending {{to}} to your address", + "market-withdraw-waiting-info": "The process for sending the coins to your address has been initiated.", + "complete": "Exchange completed!", + "complete-info": "The funds have been successfully sent to your address.", + "error": "Error occurred", + "error-info": "There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page.", + "user-deposit-timeout": "Order canceled due to inactivity", + "user-deposit-timeout-info": "The system has canceled the order because no deposit was detected, please open a new order. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page." + }, + "history-window": { + "title": "Order History", + "address": "Address:", + "date": "Date:" + }, + "details": { + "exchange-addr-label": "Exchange address (valid for this exchange operation only)", + "exchange-addr-tag-label": "Payment ID or Destination Tag which must be used for the transaction", + "tx-id-label": "Transaction ID", + "order-id-label": "Order ID", + "initial-price-label": "Initial exchange rate", + "error-msg-label": "Error message", + "details-link": "Details", + "start-date-label": "Start date", + "back-alert": "The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the \"Order history\" button" + } + } +} diff --git a/src/gui/static/src/assets/i18n/ru.json b/src/gui/static/src/assets/i18n/ru.json new file mode 100644 index 0000000..69cd50e --- /dev/null +++ b/src/gui/static/src/assets/i18n/ru.json @@ -0,0 +1,250 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "CH", + "loading": "Загрузка...", + "new": "Ðовый", + "load": "Импортировать" + }, + + "errors": { + "fetch-version": "Ðе удалоÑÑŒ получить поÑледнюю верÑию Ñ Github", + "incorrect-password": "Ðеверный пароль", + "api-disabled": "API выключен", + "no-wallet": "Кошелёк не ÑущеÑтвует", + "no-outputs": "Ðе доÑтаточно ÑредÑтв" + }, + + "title": { + "wallets": "Кошельки", + "send": "Отправить", + "history": "ИÑториÑ", + "buy-coin": "Купить Skycoin", + "network": "Сеть", + "blockchain": "Блокчейн", + "outputs": "Выходы (Outputs)", + "transactions": "Транзакции", + "pending-txs": "Ðеподтверждённые транзакции", + "backup": "Резервное копирование", + "explorer": "Skycoin ÑкÑплорер", + "seed": "Фраза воÑтановлениÑ", + "qrcode": "QR-код" + }, + + "header": { + "syncing-blocks": "Идёт ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¾Ð²...", + "update1": "Обновление кошелька", + "update2": "доÑтупно.", + "pending-txs1": "СущеÑтвует", + "pending-txs2": "транзакции, требующие подтверждениÑ.", + "pending-txs3": "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть не актуальной. УбедитеÑÑŒ что у Ð²Ð°Ñ Ð¿Ñ€Ð¸ÑутÑтвует Ñоединение Ñ Ñетью.", + + "errors": { + "no-connections": "Ðет активных Ñоединений, ваш клиент не подключен к другим узлам!", + "no-backend1": "Ðет доÑтупа к ÑервиÑу. ПерезапуÑтите приложение или обратитÑеь за помощью в нашей группе", + "no-backend2": "в телеграмме.", + "no-backend3": "", + "csrf": "Возможные уÑзвимоÑти безопаÑноÑти: CSRF не работает." + } + }, + + "password": { + "title": "Введите пароль", + "label": "Пароль", + "confirm-label": "Подтвердите пароль", + "button": "Продолжить" + }, + + "buy": { + "deposit-address": "Выберите кошелёк Ð´Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ депозитного адреÑа:", + "select-address": "Выберите адреÑ", + "generate": "Сгенерировать", + "deposit-location": "ÐÐ´Ñ€ÐµÑ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ", + "deposit-location-desc": "Выберите кошелёк Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Skycoin, поÑле уÑпешно отправленного депозита.", + "make-choice": "Сделайте выбор", + "wallets-desc": "При выборе адреÑа, каждый раз генерируетÑÑ Ð½Ð¾Ð²Ñ‹Ð¹ Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð´ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð°. Один Ð°Ð´Ñ€ÐµÑ Ð¼Ð¾Ð¶ÐµÑ‚ быть прикреплён к ограниченному количеÑтву адреÑов.", + "send": "Пошлите выбранную криптовалюту", + "send-desc": "Отправьте выбранную вами криптовалюту на Ð°Ð´Ñ€ÐµÑ ÑƒÐºÐ°Ð·Ð°Ð½Ñ‹Ð¹ ниже. По получению и поÑле доÑтаточного Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶ÐµÐ½Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¾Ð², вы получите Skycoin на указаный Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾ курÑу {{ rate }} Skycoin/Selected Coin.", + "fraction-warning": "Рекомендовано поÑылать целые значениÑ.", + "receive": "Получить Skycoin", + "receive-desc": "ПоÑле Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¹ криптавалюты, вы получите Skycoin. Это может занÑÑ‚ÑŒ от неÑкольких Ñекунд до неÑкольких дней, в завиÑимоÑти от выбранного ÑпоÑоба оплаты и загруженноÑти Ñети.", + "status-button": "СтатуÑ:", + "check-status-button": "Проверить ÑтатуÑ", + "new-order-button": "Ðовый заказ", + "refresh": "Обновить", + "available-now": "ДоÑтупно:", + "choose-preference": "Выберите ÑпоÑоб оплаты. Имейте в виду, что некоторые ÑпоÑобы могут быть временно отключены.", + "choose": "Выберите вашу любимую крипту ;)", + "send-coin":"Отправить", + "send-coin-text-1": "на Ð°Ð´Ñ€ÐµÑ Ð½Ð¸Ð¶Ðµ. ПоÑле доÑтаточного количеÑтва подтверждений на блокчейне, вы получите Skycoin на выбранный вами кошелёк по курÑу" + }, + + "wizard": { + "wallet-desc": "ЕÑли у Ð²Ð°Ñ Ð½ÐµÑ‚ кошелька Skycoin, иÑпользуйте Ñгенерированную фразу Ð´Ð»Ñ ÐµÐ³Ð¾ ÑозданиÑ. ЕÑли фраза у Ð²Ð°Ñ ÑƒÐ¶Ðµ еÑÑ‚ÑŒ, нажмите \"Импортирование кошелька\" и введите вашу фразу.", + "encrypt-desc": "Ð”Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐµÐ¹ безопаÑти, рекомендуем добавить пароль Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ. СредÑтва можно будет отправлÑÑ‚ÑŒ только при наличии паролÑ. УбедитеÑÑŒ, что вы его помните.", + "finish-button": "Закончить", + "back-button": "Ðазад", + + "confirm": { + "title": "Держите Ñвою фразу в Ñохраном меÑте!", + "desc": "УбедитеÑÑŒ, что вы запиÑали фразу воÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ держите её в надёжном меÑте. При утере фразы вы потерÑете доÑтуп к вашему кошельку Skycoin!", + "checkbox": "КлÑнуÑÑŒ. Я запиÑал.", + "button": "Продолжить" + } + }, + + "wallet": { + "new-address": "Ðовый адреÑ", + "show-empty": "Показать пуÑтые", + "hide-empty": "Скрыть пуÑтые", + "encrypt": "Зашифровать кошелёк", + "decrypt": "РаÑшифровать кошелёк", + "edit": "Редактирвоать", + "add": "Ðовый кошелёк", + "load": "Импортировать", + "encryption-enabled": "Зашифрован", + "encryption-disabled": "Без шифрованиÑ", + "wallet": "Кошелёк", + + "new": { + "create-title": "Создать кошелёк", + "load-title": "Импортировать кошелёк", + "encrypt-title": "Шифровать кошелёк", + "name-label": "Ð˜Ð¼Ñ ÐºÐ¾ÑˆÐµÐ»ÑŒÐºÐ°", + "seed-label": "Фраза воÑтановлениÑ", + "confirm-seed-label": "Подтвердите фразу", + "seed-warning": "Запомните Ñта фразу или запишите и держите в надежном меÑте, в дали от чужих глаз. При потере фразы вы не Ñможете воÑтановить Skycoin кошелёк!", + "create-button": "Создать", + "load-button": "Импортировать", + "cancel-button": "Отмена", + "12-words": "12 Ñлов", + "24-words": "24 Ñлова", + "generate-12-seed": "Сгенирировать фразу из 12 Ñлов", + "generate-24-seed": "Сгенирировать фразу из 24 Ñлов", + "encrypt": "Включить шифрование", + "encrypt-warning": "Мы рекомендуем шифровать вÑе ваши кашельки при помощи надёжного паролÑ. Так же убедитеÑÑŒ, что фраза воÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñана и хранитÑÑ Ð² надёжном меÑте." + }, + + "rename": { + "title": "Переименование кошелька", + "name-label": "ИмÑ", + "cancel-button": "Отмена", + "rename-button": "Переименовать" + }, + + "address": { + "copy": "Копировать", + "copy-address": "Копировать адреÑ", + "copied": "Скопировано!", + "outputs": "Ðепотраченые выходы (Unspent Outputs)" + } + }, + + "send": { + "from-label": "Отправить Ñ", + "to-label": "Получить на", + "amount-label": "Сумма", + "notes-label": "Заметки", + "wallet-label": "Кошелёк", + "addresses-label": "ÐдреÑ", + "addresses-help": "ÐÐ´Ñ€ÐµÑ ÐºÐ¾ÑˆÐµÐ»ÑŒÐºÐ° Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ", + "change-address-label": "ÐÐ´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¾Ñтатка", + "change-address-help": "ÐÐ´Ñ€ÐµÑ Ð´Ð»Ñ Ñдачи. ЕÑли вы его не укажите, то он будет выбран автоматичеÑки", + "destinations-label": "ÐдреÑа получателей", + "destinations-help1": "ÐдреÑа получателей и Ñумма Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ", + "destinations-help2": "ÐдреÑа получателей, Ñумма Skycoin & CH Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ", + "hours-allocation-label": "ÐвтоматичеÑки подÑчитывать чаÑÑ‹ (CH)", + "options-label": "Дополнительно", + "value-label": "Фактор отправки чаÑов (CH)", + "value-help": "Чем больше фактор, тем больше CH будет отправлено вмеÑте Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸ÐµÐ¹", + "preview-button": "ПредпроÑмотр", + "send-button": "Отправить", + "back-button": "Ðазад", + "simple": "Обычный", + "advanced": "Продвинутый" + }, + + "tx": { + "transaction": "ТранзакциÑ", + "confirm-transaction": "Подтердите транзакцию", + "from": "Отправитель", + "to": "Получатель", + "date": "Дата", + "status": "СтатуÑ", + "coins": "Сумма", + "hours": "ЧаÑÑ‹", + "id": "TX ID", + "show-more": "Инфо", + "hours-sent": "отправлÑем", + "hours-burned": "Ñжигаем", + "inputs": "Входы", + "outputs": "Выходы", + "confirmed": "Подтверждена", + "pending": "Ожидание", + "current-rate": "По текущему курÑу" + }, + + "backup": { + "wallet-directory": "Папка кошелька:", + "seed-warning": "ДЕРЖИТЕ ФРÐЗУ ВОСТÐÐОВЛЕÐИЯ Ð’ ÐÐДÐЖÐОМ МЕСТЕ. ÐРБУМÐГЕ. ОФФЛÐЙÐ. ЕÑли вы держите фразу в надёжном меÑте, и никто не Ñмог её подглÑдеть - вашы токены в безопаÑноÑти.", + "desc": "Из таблицы ниже вы можете получить фразы Ð´Ð»Ñ Ð²Ð°ÑˆÐ¸Ñ… зашифрованных кошельков.
Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ„Ñ€Ð°Ð· воÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð² кошельках без шифрованиÑ, откройте папку указаную выше и найдите в ней файлы Ñ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸ÐµÐ¼ .wlt. Фраза хранитÑÑ Ð² них. Откройте при помощи любого (надёжного) текÑтового редактора", + "close-button": "Закрыть", + "wallet": "Ðазвание кошелька", + "filename": "Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°", + "seed": "Фраза", + "show-seed": "Показать фразу", + "no-wallets": "Кошельков Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸ÐµÐ¼ нет" + }, + + "blockchain": { + "blocks": "КоличеÑтво блоков", + "time": "Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледнего блока", + "hash": "Ð¥Ñш поÑледнего блока", + "current-supply": "Ð’Ñего Skycoin в обращении", + "total-supply": "Ð’Ñего Skycoin ÑущеÑтвует", + "current-coinhour-supply": "Ð’Ñего CH в обращении", + "total-coinhour-supply": "Ð’Ñего CH ÑущеÑтвует" + }, + + "network": { + "peer": "Пир (Peer)", + "source": "ИÑточник", + "block-height": "Ð’Ñ‹Ñота блока", + "last-seen": "ПоÑледний блок", + "last-received": "ПоÑледний полученый", + "last-sent": "ПоÑледний отправленый", + "in": "ВходÑщие", + "out": "ИÑходÑщие", + + "sources": { + "default": "Пир по-умолчанию", + "exchange": "Обмена пирами" + } + }, + + "pending-txs": { + "timestamp": "Метка времени", + "txid": "ID транзакции", + "none": "Ðе найдено траназкций ждущих подтверждений", + "my": "Мой", + "all": "Ð’Ñе" + }, + + "history": { + "tx-detail": "Детали о транзакции", + "sending": "ОтправлÑем", + "sent": "Отправлено", + "received": "Получено", + "receiving": "Получаем", + "pending": "ОжидаетÑÑ", + "no-txs": "У Ð²Ð°Ñ Ð½ÐµÑ‚ иÑтории транзакций" + }, + + "teller": { + "done": "Завершено", + "waiting-confirm": "Ожидаем подтверждений", + "waiting-deposit": "Ожидаем депозит", + "waiting-send": "ПоÑылаем Skycoin", + "unknown": "ÐеизвеÑтно" + } +} diff --git a/src/gui/static/src/assets/i18n/zh.json b/src/gui/static/src/assets/i18n/zh.json new file mode 100644 index 0000000..9990b31 --- /dev/null +++ b/src/gui/static/src/assets/i18n/zh.json @@ -0,0 +1,506 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "å¸æ—¶", + "usd": "美元", + "loading": "加载中...", + "new": "æ–°", + "load": "加载" + }, + + "errors": { + "error": "错误", + "fetch-version": "无法从Github获å–最新版本", + "incorrect-password": "密ç é”™è¯¯", + "error-decrypting": "解密钱包时出错", + "api-disabled": "APIç¦ç”¨", + "no-wallet": "æ— å¯æ”¯ä»˜é’±åŒ…", + "no-outputs": "无未交易输出", + "window-size": "窗å£å¤ªçª„,内容放ä¸ä¸‹" + }, + + "title": { + "language": "选择语言", + "wallets": "钱包", + "send": "å‘é€", + "history": "历å²", + "buy-coin": "ä¹° Skycoin", + "network": "网络", + "blockchain": "区å—链", + "outputs": "未交易输出", + "transactions": "交易", + "pending-txs": "待处ç†äº¤æ˜“", + "backup": "备份钱包", + "explorer": "Skycoin Explorer", + "seed": "钱包ç§å­", + "qrcode": "QR代ç ", + "reset": "é‡ç½®å¯†ç ", + "exchange": "交易", + "select-address": "选择地å€", + "order-history": "订å•åŽ†å²" + }, + + "header": { + "syncing-blocks": "区å—åŒæ­¥ä¸­", + "update1": "钱包更新", + "update2": "å¯èŽ·å–", + "synchronizing": "钱包正在åŒæ­¥ã€‚你看到的数æ®å¯èƒ½ä¸æ˜¯æœ€æ–°çš„。", + "pending-txs1": "这里有一些", + "pending-txs2": "待处ç†äº¤æ˜“.", + "pending-txs3": "你看到的数æ®å¯èƒ½ä¸æ˜¯æœ€æ–°çš„。", + + "errors": { + "no-connections": "没有连接,你的客户端没有连接到任何其他节点", + "no-backend1": "ä¸èƒ½åˆ°è¾¾åŽç«¯ã€‚请é‡æ–°å¯åŠ¨åº”用程åºæˆ–寻求我们的帮助", + "no-backend2": "Telegram", + "no-backend3": "", + "csrf": "安全æ¼æ´ž: CSRF未工作,请立å³é€€å‡ºã€‚" + } + }, + + "password": { + "title": "输入密ç ", + "label": "密ç ", + "confirm-label": "确认密ç ", + "button": "继续", + "reset-link": "我忘记了密ç " + }, + + "buy": { + "deposit-address": "选择一个地å€æ¥ç”ŸæˆBTC充值链接,用于:", + "select-address": "选择地å€", + "generate": "生æˆ", + "deposit-location": "充值ä½ç½®", + "deposit-location-desc": "选择一个钱包,以在我们收到你的比特å¸åŽå……值Skycoin到该钱包", + "make-choice": "åšé€‰æ‹©", + "wallets-desc": "æ¯å½“选择一个新的钱包和地å€ï¼Œä¸€ä¸ªæ–°çš„BTC地å€å°†ä¼šç”Ÿæˆã€‚一个独立的Skycoin地å€æœ€å¤šå¯ç»‘定5个BTC地å€ã€‚", + "send": "å‘é€Bitcoin", + "send-desc": "å‘é€Bitcoin至如下地å€ã€‚一旦收到,我们将会按当å‰æ±‡çŽ‡: {{ rate }} SKY/BTC充值Skycoin到选中钱包的一个新地å€ã€‚", + "fraction-warning": "请按SKY/BTC汇率的å€æ•°å‘é€BTC! Skycoin是以整数å‘é€; SKYçš„å°æ•°ä½å°†ä¸ä¼šå‘é€", + "receive": "接收Sky", + "receive-desc": "收到你的比特å¸åŽï¼Œæˆ‘们将å‘é€Skycoin给你。你å¯èƒ½éœ€è¦20分钟到一个å°æ—¶æ‰èƒ½æ”¶åˆ°è¿™äº›SKY。", + "status-button": "状æ€:", + "check-status-button": "查看状æ€", + "new-order-button": "新订å•" + }, + + "wizard": { + "wallet-desc": "如果你没有Skycoin钱包,请使用生æˆçš„ç§å­æ¥åˆ›å»ºä¸€ä¸ªæ–°é’±åŒ…。如果你已ç»æœ‰ä¸€ä¸ªé’±åŒ…,切æ¢åˆ°\"加载钱包\"并输入你的ç§å­ã€‚", + "encrypt-desc": "通过加密æ¥å¢žåŠ é’±åŒ…的安全性。输入密ç åŽï¼Œä½ çš„钱包会被加密。åªæœ‰è¾“入密ç æ‰å¯ä»¥è®¿é—®çš„钱包或移动资金。", + "hardware-wallet-link": "使用硬件钱包?", + "finish-button": "完æˆ", + "back-button": "åŽé€€", + + "confirm": { + "title": "ä¿æŠ¤ä½ çš„ç§å­!", + "desc": "请确ä¿ä½ å·²ç»å†™ä¸‹ä½ çš„ç§å­å¹¶å°†å®ƒå‚¨å­˜åœ¨äº†ä¸€ä¸ªå®‰å…¨çš„地方。如果你忘记了ç§å­ï¼Œä½ å°†æ— æ³•æ¢å¤ä½ çš„Skycoin钱包", + "checkbox": "它很安全,我å‘誓。", + "button": "继续" + } + }, + + "wallet": { + "new-address": "新地å€", + "new-addresses": "新地å€", + "show-empty": "展示空地å€", + "hide-empty": "éšè—空地å€", + "encrypt": "加密钱包", + "decrypt": "解密钱包", + "decrypt-warning": "警告: 出于安全考虑,建议将钱包加密。建议谨慎一点。", + "delete": "删除钱包", + "edit": "编辑钱包", + "add": "添加钱包", + "load": "加载钱包", + "encryption-enabled": "加密已å¯ç”¨", + "encryption-disabled": "加密已ç¦ç”¨", + "hw-security-warning": "å¯èƒ½çš„安全风险。当硬件设备已连接时(点击钱包列表下的\"硬件钱包\"按钮)访问硬件钱包选项以获å–更多信æ¯", + "wallet": "钱包", + "hardware-wallet": "硬件钱包", + "delete-confirmation": "警告: 钱包\"{{ name }}\"将从列表中删除。若想é‡æ–°æ·»åŠ ï¼Œéœ€é‡æ–°è¿žæŽ¥è®¾å¤‡å¹¶æ‰“开硬件钱包的选项列表(点击钱包列表下的\"硬件钱包\"按钮)。你想继续å—?", + "delete-confirmation-check": "是的,我想è¦åˆ é™¤é’±åŒ…。", + "max-hardware-wallets-error": "你的硬件钱包里的地å€å·²ç»è¾¾åˆ°å…许的最大值。", + "add-many-confirmation": "警告: 如果你在ä¸ä½¿ç”¨å‰ä¸€ä¸ªåœ°å€çš„情况下添加太多地å€ï¼Œæˆ–者如果你使用的是最åŽä¸€ä¸ªåœ°å€è€Œä¸æ˜¯ç¬¬ä¸€ä¸ªåœ°å€ï¼Œé‚£ä¹ˆå¦‚果你å°è¯•ä½¿ç”¨ç§å­æ¢å¤é’±åŒ…,有些地å€å°†å¯èƒ½æ— æ³•è‡ªåŠ¨æ¢å¤ï¼ˆä½ å¿…须手动添加它们)。 你想继续å—?", + + "new": { + "create-title": "创建钱包", + "load-title": "加载钱包", + "encrypt-title": "加密钱包", + "name-label": "å称", + "seed-label": "ç§å­", + "confirm-seed-label": "确认ç§å­", + "seed-warning": "è®°ä½ç§å­! 把它ä¿å­˜åœ¨å®‰å…¨çš„地方。 如果你忘记了你的ç§å­ï¼Œä½ å°†æ— æ³•æ‰¾å›žä½ çš„钱包!", + "create-button": "创建", + "load-button": "加载", + "cancel-button": "删除", + "12-words": "12å­—", + "24-words": "24å­—", + "generate-12-seed": "生æˆ12å­—ç§å­", + "generate-24-seed": "生æˆ24å­—ç§å­", + "encrypt": "加密钱包", + "encrypt-warning": "我们建议你为æ¯ä¸ªé’±åŒ…设置一个独立的密ç ã€‚如果你忘记密ç ï¼Œä½ å¯ä»¥é€šè¿‡ç§å­é‡ç½®é’±åŒ…。在加密你的钱包之å‰ï¼Œç¡®ä¿ä½ çš„ç§å­ä¿å­˜åœ¨å®‰å…¨çš„地方。", + "unconventional-seed-title": "å¯èƒ½é”™è¯¯", + "unconventional-seed-text": "你引进了一ç§éžä¼ ç»Ÿçš„ç§å­ã€‚如果你出于任何特殊原因这样åšï¼Œä½ å¯ä»¥ç»§ç»­(åªæŽ¨è高级用户)。但是,如果你打算使用普通的系统ç§å­ï¼Œåˆ™å¿…须删除所有附加文本和特殊字符。", + "unconventional-seed-check": "继续使用éžä¼ ç»Ÿç§å­ã€‚" + }, + + "rename": { + "title": "é‡å‘½å钱包", + "name-label": "命å", + "cancel-button": "å–消", + "rename-button": "é‡å‘½å" + }, + + "add-addresses": { + "title": "选择数é‡", + "name-quantity": "创建多少地å€", + "cancel-button": "å–消", + "create-button": "创建" + }, + + "address": { + "show": "点击显示", + "copy": "å¤åˆ¶", + "copy-address": "å¤åˆ¶åœ°å€", + "copied": "å·²å¤åˆ¶!", + "confirm": "确认地å€", + "outputs": "未交易输出", + "history": "历å²" + } + }, + + "send": { + "synchronizing-warning":"钱包ä»åœ¨åŒæ­¥æ•°æ®ï¼Œæ‰€ä»¥æ˜¾ç¤ºçš„ä½™é¢å¯èƒ½ä¸æ­£ç¡®ã€‚你确定è¦ç»§ç»­å—?", + "from-label": "å‘é€è‡ª", + "to-label": "å‘é€è‡³", + "amount-label": "总é¢", + "notes-label": "标注", + "wallet-label": "钱包", + "addresses-label": "地å€", + "invalid-amount": "请输入一个有效数值", + "addresses-help": "é™å®šæºå‘é€åœ°å€", + "all-addresses": "所有地å€(所选钱包的)", + "outputs-label": "未交易输出", + "outputs-help": "é™å®šæœªäº¤æ˜“输出", + "all-outputs": "所有未交易输出(所选地å€çš„)", + "available-msg-part1": "æ ¹æ®ä½ å½“å‰çš„选择,你最多å¯ä»¥å‘é€", + "available-msg-part2": "å’Œ", + "available-msg-part3": "(至少", + "available-msg-part4": "将作为必须的交易手续费)。", + "change-address-label": "自定义找零地å€", + "change-address-select": "选择", + "change-address-help": "自定义找零地å€ã€‚如果ä¸æ供,钱包将会自动选择。点击\"选择\" æ¥é€‰æ‹©ä¸€ä¸ªåœ°å€", + "destinations-label": "目标地å€", + "destinations-help1": "目标地å€å’Œå³å°†å‘é€çš„å¸", + "destinations-help2": "目标地å€å’Œå³å°†å‘é€çš„å¸ä»¥åŠå¸æ—¶", + "hours-allocation-label": "自动分é…å¸æ—¶", + "options-label": "选项", + "value-label": "å¸æ—¶åˆ†å‘å› å­", + "value-help": "分å‘å› å­å€¼è¶Šé«˜ï¼Œè¶Šå¤šå¸æ—¶å°†è¢«å‘é€", + "preview-button": "预览", + "send-button": "å‘é€", + "back-button": "åŽé€€", + "simple": "简易", + "advanced": "高级的", + "select-wallet": "选择钱包" + }, + + "reset": { + "wallet-label": "钱包", + "seed-label": "钱包ç§å­", + "password-label": "æ–°å¯†ç  (如果你ä¸å¸Œæœ›é’±åŒ…加密,请将密ç ç•™ç©º)", + "confirm-label": "确认新密ç ", + "reset-button": "é‡ç½®" + }, + + "tx": { + "transaction": "交易", + "confirm-transaction": "确认交易", + "from": "æ¥è‡ª", + "to": "到", + "date": "日期", + "status": "状æ€", + "coins": "å¸", + "hours": "å¸æ—¶", + "id": "交易ID", + "show-more": "展示更多", + "hours-moved": "已转移", + "hours-sent": "å·²å‘é€", + "hours-received": "已接收", + "hours-burned": "已燃烧", + "inputs": "输入", + "outputs": "输出", + "confirmed": "已确认", + "pending": "待处ç†", + "current-rate": "按当å‰æ±‡çŽ‡è®¡ç®—" + }, + + "backup": { + "wallet-directory": "钱包目录:", + "seed-warning": "在纸上备份你的ç§å­ï¼Œå¹¶ä¿å­˜åœ¨ä¸€ä¸ªå®‰å…¨çš„地方。åªè¦æœ‰ç§å­ï¼Œä½ å°±å¯ä»¥æ‰¾å›žä½ çš„å¸ã€‚", + "desc": "使用下表从加密的钱包中得到ç§å­ã€‚
为了从未加密的钱包中获得ç§å­ï¼Œæ‰“开上é¢çš„文件夹,在文本编辑器中打开.wlt文件并æ¢å¤ç§å­ã€‚", + "close-button": "Close", + "wallet": "钱包", + "filename": "文件å", + "seed": "ç§å­", + "show-seed": "显示ç§å­", + "no-wallets": "未加密钱包" + }, + + "blockchain": { + "blocks": "区å—æ•°é‡", + "time": "上一个区å—的时间戳", + "hash": "上一个区å—的哈希值", + "current-supply": "ç›®å‰SKY供应é‡", + "total-supply": "SKY的总供应é‡", + "current-coinhour-supply": "ç›®å‰å¸æ—¶ä¾›åº”é‡", + "total-coinhour-supply": "å¸æ—¶æ€»ä¾›åº”é‡" + }, + + "network": { + "peer": "节点", + "source": "节点æ¥æº", + "block-height": "区å—高度", + "block-height-short": "区å—", + "last-seen": "上一次出现", + "last-received": "上一次接收", + "last-sent": "上一次å‘é€", + "in": "è¿›æ¥çš„", + "out": "出去的", + + "sources": { + "default": "默认节点", + "exchange": "交æ¢èŠ‚点" + } + }, + + "pending-txs": { + "timestamp": "时间戳", + "txid": "交易ID", + "none": "无待处ç†äº¤æ˜“", + "my": "我的", + "all": "全部" + }, + + "history": { + "tx-detail": "交易明细", + "moving": "内部转账中", + "moved": "已内部转账", + "sending": "å‘é€ä¸­", + "sent": "å·²å‘é€", + "received": "已接收", + "receiving": "接收中", + "pending": "待处ç†", + "no-txs": "你没有历å²äº¤æ˜“", + "no-txs-filter": "没有与当å‰ç­›é€‰æ¡ä»¶åŒ¹é…的交易", + "no-filter": "未ç»ç­›é€‰ (点击选择钱包/地å€)", + "filter": "已筛选: ", + "filters": "已筛选: ", + "all-addresses": "所有地å€" + }, + + "teller": { + "done": "完æˆ", + "waiting-confirm": "等待确认", + "waiting-deposit": "等待比特å¸å……值", + "waiting-send": "等待å‘é€Skycoin", + "unknown": "未知" + }, + + "confirmation" : { + "header-text": "确认", + "confirm-button": "是", + "cancel-button": "å¦", + "close": "关闭" + }, + + "service": { + "api" : { + "server-error": "æœåŠ¡å™¨é”™è¯¯" + }, + "wallet": { + "not-enough-hours": "没有足够的å¸æ—¶æ¥æ‰§è¡Œäº¤æ˜“" + } + }, + + "hardware-wallet": { + "general": { + "default-wallet-name": "新硬件钱包", + "error-disconnected": "无法执行该æ“作。硬件钱包未连接。", + "simple-error": "错误,无法执行æ“作。", + "generic-error": "无法执行该æ“作。确ä¿ä½ å·²ç»è¿žæŽ¥äº†ä¸€ä¸ªæœ‰æ•ˆçš„硬件钱包,并且它没有在等待输入。", + "generic-error-internet": "无法执行该æ“作。确ä¿ä½ å·²ç»è¿žæŽ¥äº†ä¸€ä¸ªæœ‰æ•ˆçš„硬件钱包,它ä¸åœ¨ç­‰å¾…输入,并且你已ç»è¿žæŽ¥åˆ°ç½‘络/节点", + "error-incorrect-wallet": "无法执行该æ“作。所连接的硬件钱包与预期ä¸åŒã€‚", + "error-incorrect-pin": "无法执行该æ“作。你输入的密ç ä¸æ­£ç¡®ã€‚", + "confirm": "请在硬件钱包中确认æ“作。", + "confirm-and-more": "请在硬件钱包中确认æ“作并按éµå¾ªæŒ‡ç¤ºã€‚", + "close": "关闭", + "cancel": "å–消", + "continue": "继续", + "completed": "æ“作完æˆã€‚", + "refused": "æ“作失败或被å–消。" + }, + "errors": { + "too-many-inputs": "此笔交易有太多的输入,无法处ç†ã€‚请è”系技术支æŒã€‚", + "too-many-outputs": "此笔交易有太多的输出,无法处ç†ï¼Œè¯·è”系技术支æŒã€‚" + }, + "security-warning": { + "title": "安全警告", + "text": "上次连接此硬件钱包时,å‘现一个或多个安全警告。我们建议你打开硬件钱包选项(点击钱包列表下的\"硬件钱包\"按钮)并ä¿æŒè®¾å¤‡å·²è¿žæŽ¥ï¼Œåœ¨ç»§ç»­ä¹‹å‰ï¼Œè§£å†³å®‰å…¨é—®é¢˜", + "check": "我明白其中的风险,并希望继续下去", + "continue": "继续", + "cancel": "å–消" + }, + "options": { + "connecting": "连接...", + "disconnected": "没有检测到硬件钱包。请连接硬件钱包åŽä½¿ç”¨æ­¤é€‰é¡¹ã€‚", + "unconfigured-detected-title": "未é…置的硬件钱包", + "unconfigured-detected": "检测到无ç§å­çš„硬件钱包。选择\"自动é…ç½®\"如果你想将其é…置为全新的钱包并立å³å¼€å§‹ä½¿ç”¨å®ƒï¼Œæˆ–选择\"æ¢å¤å¤‡ä»½\"如果你想使用先å‰åˆ›å»ºçš„备份ç§å­å¯¹å…¶è¿›è¡Œé…置,从而能够å†æ¬¡è®¿é—®ä½ çš„资产。", + "configured-detected": "检测到硬件钱包。该设备在钱包列表中被识别为:", + "security-warnings-title": "安全警告", + "security-warning-title": "安全警告", + "backup-warning": "你应该备份硬件钱包ç§å­ï¼Œå¦åˆ™ä¸‡ä¸€å‡ºçŽ°é—®é¢˜ï¼Œä½ å¯èƒ½å°†æ— æ³•è®¿é—®ä½ çš„资金,è¦åšåˆ°è¿™ä¸€ç‚¹ã€‚选择\"创建一个备份\"选项。", + "pin-warning": "当å‰è¿žæŽ¥çš„硬件钱包未设置密ç ã€‚密ç å¯ä¿æŠ¤ç¡¬ä»¶é’±åŒ…,以防丢失ã€ç›—窃和黑客入侵。è¦åˆ›å»ºä¸€ä¸ªå¯†ç ï¼Œé€‰æ‹©\"创建PINç \"选项。", + "options": "选项:", + "configure-automatically": "自动é…ç½®", + "restore-backup": "æ¢å¤å¤‡ä»½", + "create-backup": "创建备份", + "wipe": "删除设备", + "confirm-seed": "确认ç§å­", + "create-pin": "创建密ç ", + "change-pin": "更改密ç ", + "forgotten-pin1": "如果你因为忘记密ç è€Œæ— æ³•è¿›å…¥é’±åŒ…,你å¯ä»¥åˆ é™¤ç¡¬ä»¶é’±åŒ…,然åŽé€šè¿‡ç§å­", + "forgotten-pin2": "æ¢å¤" + }, + "generate-seed" : { + "text": "在继续之å‰ï¼Œä½ å¯ä»¥é€‰æ‹©ç”Ÿæˆç§å­çš„å•è¯æ•°ã€‚ç§å­æ˜¯ä¸€ä¸ªå•è¯åˆ—表,出现问题åŽå¯ä»¥ç”¨æ¥æ¢å¤è®¿é—®ä½ çš„å¸ã€‚所有选项都是安全的,如果你没有特殊原因必须选择æŸä¸€é¡¹ï¼Œä½ å¯ä»¥ä½¿ç”¨é»˜è®¤å€¼ã€‚", + "configuring": "é…ç½®..." + }, + "restore-seed" : { + "text": "在继续å‰ï¼Œè¯·é€‰æ‹©ä½ æƒ³è¦æ¢å¤ç§å­çš„å•è¯æ•°é‡ã€‚", + "check-text": "ä½ å¯ä»¥ä½¿ç”¨æ­¤é€‰é¡¹è¾“å…¥ç§å­ï¼Œå¹¶æ£€æŸ¥å®ƒæ˜¯å¦ä¸Žç¡¬ä»¶é’±åŒ…中的一致。在开始之å‰ï¼Œé€‰æ‹©ä½ æƒ³è¦æ£€æŸ¥çš„ç§å­çš„å•è¯æ•°ã€‚", + "warning" : "警告: 为了é¿å…å¯èƒ½å‡ºçŽ°çš„问题,请仅使用åŒä¸€å“牌/åž‹å·çš„硬件钱包创建ç§å­ã€‚", + "error-wrong-word": "错误: é‡æ–°é”®å…¥çš„å•è¯ä¸Žç¡¬ä»¶é’±åŒ…所请求的ä¸åŒ¹é…。", + "error-invalid-seed": "错误: ç§å­æ— æ•ˆã€‚请务必按正确的顺åºè¾“入正确的å•è¯ã€‚", + "error-wrong-seed": "错误: ç§å­æ˜¯æœ‰æ•ˆçš„,但与设备中的ç§å­ä¸åŒ¹é…。" + }, + "added": { + "title": "新硬件钱包", + "configuring": "检测到新的硬件钱包。é…ç½®...", + "done": "已完æˆ", + "added1": "已连接的硬件的钱包已ç»ç”¨å¦‚下å字被添加到钱包列表:", + "added2": "现在你å¯ä»¥æŸ¥çœ‹ç¡¬ä»¶é’±åŒ…中的余é¢å’Œåœ°å€äº†ï¼Œå³ä½¿ç¡¬ä»¶é’±åŒ…并未连接。此外如果你愿æ„,你还å¯ä»¥æ›´æ”¹é’±åŒ…å称或从将其从钱包列表删除。" + }, + "wipe": { + "warning": "警告: 硬件钱包中的所有数æ®å°†è¢«åˆ é™¤ã€‚如果没有备份,你将无法å†æ¬¡è®¿é—®ä½ çš„资金。", + "confirm-delete": "还是将其从钱包列表中删除" + }, + "create-backup": { + "warning": "警告: ä½ åªèƒ½ä½¿ç”¨æ­¤é€‰é¡¹å¤‡ä»½ä½ çš„硬件钱包ç§å­ä¸€æ¬¡ã€‚如果你决定继续,你将ä¸å¾—ä¸å†™ä¸‹ä¸€ç»„å•è¯(建议写在纸上,而ä¸æ˜¯ç”µè„‘上),这些å•è¯å°†å‡ºçŽ°åœ¨ç¡¬ä»¶é’±åŒ…çš„å±å¹•ä¸Šï¼Œå¹¶å°†å…¶å­˜å‚¨åœ¨ä¸€ä¸ªå®‰å…¨çš„地方。任何å¯ä»¥è®¿é—®å•è¯åˆ—表(\"ç§å­\")的人都å¯ä»¥è®¿é—®é’±åŒ…ä½™é¢ï¼Œå› æ­¤å»ºè®®è¯·æ ¼å¤–谨慎。", + "instructions": "写下出现在硬件钱包å±å¹•ä¸Šçš„å•è¯åˆ—表。一定è¦æŒ‰é¡ºåºå¹¶æŠŠæ¯ä¸ªå•è¯éƒ½å†™å¯¹ã€‚" + }, + "seed-word": { + "title": "输入字", + "info1": "输入设备中显示的字", + "info2": "你将被è¦æ±‚以éšæœºçš„顺åºè¾“入你备份的ç§å­ï¼ŒåŠ ä¸Šä¸€äº›é¢å¤–的字。", + "word": "è¦æ±‚çš„å­—", + "error-invalid-word": "输入字无效。", + "error-loading-words": "正在加载字列表。请ç¨ç­‰ã€‚" + }, + "change-pin" : { + "pin-mismatch":"无法执行æ“作。你输入的两个密ç ä¸åŒ¹é…" + }, + "enter-pin" : { + "title": "输入密ç ", + "title-change-current": "输入当å‰å¯†ç ", + "title-change-new": "输入新的密ç ", + "title-change-confirm": "确认新的密ç ", + "instructions": " 密ç å·²æ˜¾ç¤ºåœ¨ç¡¬ä»¶é’±åŒ…çš„å±å¹•ä¸Šã€‚", + "instructions-tx": "进入密ç ä»¥ç¡®è®¤å¹¶ç­¾ç½²äº¤æ˜“。", + "instructions-change": "请输入一个4到8个数字之间的难以被猜中的密ç ã€‚", + "help": "需è¦å¸®åŠ©ï¼Ÿ" + }, + "pin-help" : { + "title": "帮助", + "part1": "当需è¦è¾“入密ç æ‰èƒ½ç»§ç»­æ—¶ï¼Œç¡¬ä»¶é’±åŒ…å±å¹•ä¼šæ˜¾ç¤ºä¸€ä¸ªçŸ©é˜µï¼ŒçŸ©é˜µç”±9个éšæœºæŽ’列的å—组æˆ(æ¯æ¬¡é¡ºåºéƒ½ä¼šæ”¹å˜),你将被è¦æ±‚在软件钱包中输入密ç ï¼Œä½¿ç”¨ä¸€ä¸ªçŸ©é˜µï¼Œæ­¤çŸ©é˜µåŒ…å«9个按钮,åªæ˜¾ç¤ºç¬¦å·#。", + "part2": "è¦è¾“入密ç ï¼Œè¯·åœ¨ç¡¬ä»¶é’±åŒ…å±å¹•ä¸Šä»¥æ•°å­—矩阵查看密ç çš„ä½ç½®ï¼Œç„¶åŽç‚¹å‡»è½¯ä»¶é’±åŒ…中的相应按钮。例如,如果密ç ä¸º\"23\"且数字2ä½äºŽç¡¬ä»¶é’±åŒ…数字矩阵的左上角,数字3ä½äºŽç¡¬ä»¶é’±åŒ…数字矩阵的正中间,则按顺åºç‚¹å‡»è½¯ä»¶é’±åŒ…中的左上角和中间按钮。", + "part3": "如果你愿æ„,还å¯ä»¥ä½¿ç”¨é”®ç›˜ä¸Šçš„å°é”®ç›˜è¾“入密ç ã€‚但是,如之å‰ç¤ºä¾‹æ‰€ç¤ºï¼Œå¦‚果密ç æ˜¯\"23\",你ä¸èƒ½ç®€å•åœ°ç”¨å°é”®ç›˜é”®å…¥\"23\",而是必须选择点击硬件钱包å±å¹•ä¸Š2å’Œ3对应ä½ç½®çš„值。" + }, + "create-tx" : { + "title": "创建交易" + }, + "confirm-address" : { + "title": "确认地å€", + "instructions": "请在硬件钱包上确认,如果地å€ä¸º:", + "short-confirmation": "地å€å·²ç¡®è®¤", + "confirmation": "地å€å·²ç¡®è®¤ã€‚为了安全, 选择 \"确认地å€\" 选项å¯ä»¥åœ¨ç¡¬ä»¶é’±åŒ…上å†æ¬¡æ˜¾ç¤ºåœ°å€ï¼Œåœ¨èœå•ä¸­å¯ç‚¹å‡»åœ°å€ä½™é¢å³ä¾§çš„按钮显示。" + } + }, + + "time-from-now": { + "few-seconds": "几秒钟之å‰", + "minute": "一分钟之å‰", + "minutes": "{{time}} 分钟之å‰", + "hour": "一å°æ—¶ä¹‹å‰", + "hours": "{{time}} å°æ—¶ä¹‹å‰", + "day": "一天之å‰", + "days": "{{time}} 天之å‰" + }, + + "exchange": { + "you-send": "ä½ å‘é€", + "you-get": "你收到 (大约)", + "to-address": "到 {{coin}} 地å€", + "price": "交易汇率", + "time-15": "交易时间", + "exchange-button": "交易", + "min-amount": "最å°æ•°é¢:", + "max-amount": "最大数é¢:", + "agree-1": "我åŒæ„", + "agree-2": "使用æ¡æ¬¾", + "agree-3": "å’Œ", + "agree-4": "éšç§æ”¿ç­–", + "powered-by": "技术支æŒ", + "need-help": "需è¦å¸®åŠ©?", + "support-portal": "帮助入å£", + "history": "订å•åŽ†å²", + "order-not-found": "订å•æœªæ‰¾åˆ°", + "status": "状æ€", + "exchanging": "{{from}}交易{{to}}", + "select": "选择", + "offline": "交易暂时下线", + "problem-connecting": "未能连接到æœåŠ¡å™¨ã€‚请检查你的网络连接并ç¨åŽå†è¯•ã€‚", + "invalid-address": "无效地å€ã€‚", + "statuses": { + "user-waiting": "等待充值。请将{{amount}} {{from}}å‘é€åˆ°ä¸‹é¢æ˜¾ç¤ºçš„交易地å€", + "user-waiting-info": "系统正在等待你充值到交易地å€ã€‚交易将在系统检测到你的充值并在区å—链中确认åŽå¼€å§‹ã€‚如果你已ç»å……值,应该很快就会检测到。", + "market-waiting-confirmations": "等待链上交易确认", + "market-waiting-confirmations-info": "å·²ç»æ£€æµ‹åˆ°å……值,等待区å—链中被确认。", + "market-confirmed": "链上交易已接å—", + "market-confirmed-info": "链上交易已ç»åœ¨åŒºå—链上确认。准备马上执行兑æ¢ã€‚", + "market-exchanged": "完æˆ{{from}}到{{to}}çš„å…‘æ¢", + "market-exchanged-info": "å…‘æ¢å·²ç»å®Œæˆã€‚资金将很快å‘é€åˆ°ä½ çš„地å€ã€‚", + "market-withdraw-waiting": "正在å‘é€{{to}}到你的地å€", + "market-withdraw-waiting-info": "å‘é€{{to}}到你地å€çš„进程已å¯åŠ¨", + "complete": "交易已完æˆ!", + "complete-info": "资金已ç»æˆåŠŸå‘é€åˆ°ä½ çš„地å€ã€‚", + "error": "å‘生错误", + "error-info": "è¿è½¬è¿‡ç¨‹ä¸­å‡ºçŽ°é”™è¯¯ï¼Œä½ å¯ä»¥åœ¨ä¸‹é¢æ‰¾åˆ°æ›´å¤šä¿¡æ¯ã€‚如果你需è¦å¸®åŠ©ï¼Œè¯·ä¿å­˜ä¸‹é¢æ˜¾ç¤ºçš„所有数æ®å¹¶ä½¿ç”¨é¡µé¢å³ä¸‹è§’的帮助链接æ¥è”系技术支æŒã€‚" + }, + "history-window": { + "address": "地å€", + "date": "日期" + }, + "details": { + "exchange-addr": "交易地å€", + "exchange-addr-tag": "支付ID或交易必须用到的目标标签", + "tx-id": "交易ID", + "order-id": "订å•ID", + "initial-price": "åˆå§‹æ±‡çŽ‡", + "error-msg": "é”™è¯¯ä¿¡æ¯ ", + "details": "详情", + "start-date": "开始日期", + "back": "返回", + "back-alert": "æ“作正在执行。你真的想è¦è¿”回到表格å—?你å¯ä»¥é€šè¿‡ç‚¹å‡»\"订å•åŽ†å²\"å†æ¬¡çœ‹åˆ°æ‰§è¡Œè¿‡ç¨‹" + } + } +} diff --git a/src/gui/static/src/assets/i18n/zh_base.json b/src/gui/static/src/assets/i18n/zh_base.json new file mode 100644 index 0000000..402d23c --- /dev/null +++ b/src/gui/static/src/assets/i18n/zh_base.json @@ -0,0 +1,506 @@ +{ + "common": { + "coin-id": "SKY", + "coin-hours": "Coin Hours", + "usd": "USD", + "loading": "Loading...", + "new": "New", + "load": "Load" + }, + + "errors": { + "error": "Error", + "fetch-version": "Unable to fetch latest release version from Github", + "incorrect-password": "Incorrect password", + "error-decrypting": "Error decrypting the wallet", + "api-disabled": "API disabled", + "no-wallet": "Wallet does not exist", + "no-outputs": "No unspent outputs", + "window-size": "The window is too narrow for the content" + }, + + "title": { + "language": "Select Language", + "wallets": "Wallets", + "send": "Send", + "history": "History", + "buy-coin": "Buy Skycoin", + "network": "Networking", + "blockchain": "Blockchain", + "outputs": "Outputs", + "transactions": "Transactions", + "pending-txs": "Pending Transactions", + "backup": "Backup Wallet", + "explorer": "Skycoin Explorer", + "seed": "Wallet Seed", + "qrcode": "QR Code", + "reset": "Reset Password", + "exchange": "Exchange", + "select-address": "Select Address", + "order-history": "Order history" + }, + + "header": { + "syncing-blocks": "Syncing blocks", + "update1": "Wallet update", + "update2": "available.", + "synchronizing": "The wallet is synchronizing. Data you see may not be updated.", + "pending-txs1": "There are some", + "pending-txs2": "pending transactions.", + "pending-txs3": "Data you see may not be updated.", + + "errors": { + "no-connections": "No connections active, your client is not connected to any other nodes!", + "no-backend1": "Cannot reach backend. Please restart the app and/or seek help on our", + "no-backend2": "Telegram.", + "no-backend3": "", + "csrf": "Security vulnerability: CSRF is not working, please exit immediately." + } + }, + + "password": { + "title": "Enter Password", + "label": "Password", + "confirm-label": "Confirm password", + "button": "Proceed", + "reset-link": "I forgot my password" + }, + + "buy": { + "deposit-address": "Choose an address to generate a BTC deposit link for:", + "select-address": "Select address", + "generate": "Generate", + "deposit-location": "Deposit Location", + "deposit-location-desc": "Choose a wallet where you'd like us to deposit your Skycoin after we receive your Bitcoin.", + "make-choice": "Make a choice", + "wallets-desc": "Each time a new wallet and address are selected, a new BTC address is generated. A single Skycoin address can have up to 5 BTC addresses assigned to it.", + "send": "Send Bitcoin", + "send-desc": "Send Bitcoin to the address below. Once received, we will deposit the Skycoin to a new address in the wallet selected above at the current rate of {{ rate }} SKY/BTC.", + "fraction-warning": "Only send multiple of the SKY/BTC rate! Skycoin is sent in whole number; fractional SKY is not sent!", + "receive": "Receive Sky", + "receive-desc": "After receiving your Bitcoin, we'll send you your Skycoin. It may take anywhere between 20 minutes and an hour to receive your SKY.", + "status-button": "Status:", + "check-status-button": "Check Status", + "new-order-button": "New Order" + }, + + "wizard": { + "wallet-desc": "If you don't have a Skycoin wallet, use the generated seed to create a new one. If you already have a wallet, toggle over to \"Load Wallet\" and enter your seed.", + "encrypt-desc": "Increase security of your wallet by encrypting it. By entering a password below, your wallet will be encrypted. Only those with the password will be able access the wallet and remove funds.", + "hardware-wallet-link": "Using a hardware wallet?", + "finish-button": "Finish", + "back-button": "Back", + + "confirm": { + "title": "Safeguard your seed!", + "desc": "We want to make sure that you wrote down your seed and stored it in a safe place. If you forget your seed, you WILL NOT be able to recover your Skycoin wallet!", + "checkbox": "It’s safe, I swear.", + "button": "Continue" + } + }, + + "wallet": { + "new-address": "New Address", + "new-addresses": "New Addresses", + "show-empty": "Show Empty", + "hide-empty": "Hide Empty", + "encrypt": "Encrypt Wallet", + "decrypt": "Decrypt Wallet", + "decrypt-warning": "Warning: for security reasons, it is not recommended to keep the wallets unencrypted. Caution is advised.", + "delete": "Delete Wallet", + "edit": "Edit Wallet", + "add": "Add Wallet", + "load": "Load Wallet", + "encryption-enabled": "Encryption enabled", + "encryption-disabled": "Encryption disabled", + "hw-security-warning": "Possible security risk. Access the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list) while the device is connected for more information.", + "wallet": "Wallet", + "hardware-wallet": "Hardware Wallet", + "delete-confirmation": "WARNING: The wallet \"{{ name }}\" will be removed from the list. To add it again, you will have to reconnect the device and open the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list). Do you want to continue?", + "delete-confirmation-check": "Yeah, I want to delete the wallet.", + "max-hardware-wallets-error": "You have already reached the max number of addresses that can be added to the hardware wallet.", + "add-many-confirmation": "WARNING: If you add too many addresses without using the previous ones or if you use the last ones and not the first ones, some addresses may not be recovered automatically if you try to restore the wallet using the seed (you will have to add them manually). Do you want to continue?", + + "new": { + "create-title": "Create Wallet", + "load-title": "Load Wallet", + "encrypt-title": "Encrypt Wallet", + "name-label": "Name", + "seed-label": "Seed", + "confirm-seed-label": "Confirm seed", + "seed-warning": "Remember this seed! Keep it in a safe place. If you forget your seed, you will not be able to recover your wallet!", + "create-button": "Create", + "load-button": "Load", + "cancel-button": "Cancel", + "12-words": "12 words", + "24-words": "24 words", + "generate-12-seed": "Generate 12 word seed", + "generate-24-seed": "Generate 24 word seed", + "encrypt": "Encrypt wallet", + "encrypt-warning": "We suggest that you encrypt each one of your wallets with a password. If you forget your password, you can reset it with your seed. Make sure you have your seed saved somewhere safe before encrypting your wallet.", + "unconventional-seed-title": "Possible error", + "unconventional-seed-text": "You introduced an unconventional seed. If you did it for any special reason, you can continue (only recommended for advanced users). However, if your intention is to use a normal system seed, you must delete all the additional text and special characters.", + "unconventional-seed-check": "Continue with the unconventional seed." + }, + + "rename": { + "title": "Rename Wallet", + "name-label": "Name", + "cancel-button": "Cancel", + "rename-button": "Rename" + }, + + "add-addresses": { + "title": "Select quantity", + "name-quantity": "How many addresses to create", + "cancel-button": "Cancel", + "create-button": "Create" + }, + + "address": { + "show": "Press to show", + "copy": "Copy", + "copy-address": "Copy address", + "copied": "Copied!", + "confirm": "Confirm address", + "outputs": "Unspent outputs", + "history": "History" + } + }, + + "send": { + "synchronizing-warning": "The wallet is still synchronizing the data, so the balance shown may be incorrect. Are you sure you want to continue?", + "from-label": "Send from", + "to-label": "Send to", + "amount-label": "Amount", + "notes-label": "Notes", + "wallet-label": "Wallet", + "addresses-label": "Addresses", + "invalid-amount": "Please enter a valid amount", + "addresses-help": "Limit the addresses from where the coins and hours could be sent", + "all-addresses": "All the addresses of the selected wallet", + "outputs-label": "Unspent outputs", + "outputs-help": "Limit the unspent outputs from where the coins and hours could be sent. Only the outputs from the selected addresses are shown", + "all-outputs": "All the outputs of the selected addresses", + "available-msg-part1": "With your current selection you can send up to", + "available-msg-part2": "and", + "available-msg-part3": "(at least", + "available-msg-part4": "must be used for the transaction fee).", + "change-address-label": "Custom change address", + "change-address-select": "Select", + "change-address-help": "Address to receive change. If it's not provided, it will be chosen automatically. Click on the \"Select\" link to choose an address from one of your wallets", + "destinations-label": "Destinations", + "destinations-help1": "Destination addresses and their coins", + "destinations-help2": "Destination addresses, their coins and coin hours", + "hours-allocation-label": "Automatic coin hours allocation", + "options-label": "Options", + "value-label": "Coin hours share factor", + "value-help": "The higher the value, the more coin hours will be sent to outputs", + "preview-button": "Preview", + "send-button": "Send", + "back-button": "Back", + "simple": "Simple", + "advanced": "Advanced", + "select-wallet": "Select Wallet" + }, + + "reset": { + "wallet-label": "Wallet", + "seed-label": "Wallet seed", + "password-label": "New password (leave empty if you want the wallet not to be encrypted)", + "confirm-label": "Confirm new password", + "reset-button": "Reset" + }, + + "tx": { + "transaction": "Transaction", + "confirm-transaction": "Confirm Transaction", + "from": "From", + "to": "To", + "date": "Date", + "status": "Status", + "coins": "Coins", + "hours": "Hours", + "id": "Tx ID", + "show-more": "Show more", + "hours-moved": "moved", + "hours-sent": "sent", + "hours-received": "received", + "hours-burned": "burned", + "inputs": "Inputs", + "outputs": "Outputs", + "confirmed": "Confirmed", + "pending": "Pending", + "current-rate": "Calculated at the current rate" + }, + + "backup": { + "wallet-directory": "Wallet Directory:", + "seed-warning": "BACKUP YOUR SEED. ON PAPER. IN A SAFE PLACE. As long as you have your seed, you can recover your coins.", + "desc": "Use the table below to get seeds from your encrypted wallets.
To get seeds from unencrypted wallets, open the folder above, open the .wlt files in a text editor and recover the seeds.", + "close-button": "Close", + "wallet": "Wallet Label", + "filename": "Filename", + "seed": "Seed", + "show-seed": "Show seed", + "no-wallets": "No encrypted wallets" + }, + + "blockchain": { + "blocks": "Number of blocks", + "time": "Timestamp of last block", + "hash": "Hash of last block", + "current-supply": "Current SKY supply", + "total-supply": "Total SKY supply", + "current-coinhour-supply": "Current Coin Hours supply", + "total-coinhour-supply": "Total Coin Hours supply" + }, + + "network": { + "peer": "Peer", + "source": "Source", + "block-height": "Block height", + "block-height-short": "Block", + "last-seen": "Last seen", + "last-received": "Last received", + "last-sent": "Last sent", + "in": "Incoming", + "out": "Outgoing", + + "sources": { + "default": "Default peer", + "exchange": "Peer exchange" + } + }, + + "pending-txs": { + "timestamp": "Timestamp", + "txid": "Transaction ID", + "none": "No pending transactions", + "my": "Mine", + "all": "All" + }, + + "history": { + "tx-detail": "Transaction Detail", + "moving": "Internally moving", + "moved": "Internally moved", + "sending": "Sending", + "sent": "Sent", + "received": "Received", + "receiving": "Receiving", + "pending": "Pending", + "no-txs": "You have no transaction history", + "no-txs-filter": "There are no transactions matching the current filter criteria", + "no-filter": "No filter active (press to select wallets/addresses)", + "filter": "Active filter: ", + "filters": "Active filters: ", + "all-addresses": "All addresses" + }, + + "teller": { + "done": "Completed", + "waiting-confirm": "Waiting for confirmation", + "waiting-deposit": "Waiting for Bitcoin deposit", + "waiting-send": "Waiting to send Skycoin", + "unknown": "Unknown" + }, + + "confirmation" : { + "header-text": "Confirmation", + "confirm-button": "Yes", + "cancel-button": "No", + "close": "Close" + }, + + "service": { + "api" : { + "server-error": "Server error" + }, + "wallet": { + "not-enough-hours": "Not enough available Coin Hours to perform the transaction!" + } + }, + + "hardware-wallet": { + "general" : { + "default-wallet-name": "New hardware wallet", + "error-disconnected": "Unable to perform the operation. The hardware wallet is not connected.", + "simple-error": "Error, Unable to perform the operation.", + "generic-error": "Unable to perform the operation. Make sure you have connected a valid hardware wallet and that it is not waiting for input.", + "generic-error-internet": "Unable to perform the operation. Make sure you have connected a valid hardware wallet that is not waiting for input and that you have a connection to the internet/node.", + "error-incorrect-wallet": "Unable to perform the operation. The connected hardware wallet is different from the expected one.", + "error-incorrect-pin": "Unable to perform the operation. The PIN you have entered is not correct.", + "confirm": "Please, confirm the operation in the hardware wallet.", + "confirm-and-more": "Please, confirm the operation in the hardware wallet and follow the instructions.", + "close": "Close", + "cancel": "Cancel", + "continue": "Continue", + "completed": "Operation completed successfully.", + "refused": "The operation failed or was canceled." + }, + "errors": { + "too-many-inputs": "The transaction has too many inputs and can not be processed. Please contact technical support.", + "too-many-outputs": "The transaction has too many outputs and can not be processed. Please contact technical support." + }, + "security-warning" : { + "title": "Security warning", + "text": "The last time this hardware wallet was connected, one or more security warnings were found. We recommend you to open the hardware wallet options (by pressing the \"Hardware Wallet\" button below the wallets list) while the device is connected and solve the security problems before continuing.", + "check": "I understand the risks and want to continue", + "continue": "Continue", + "cancel": "Cancel" + }, + "options" : { + "connecting": "Connecting...", + "disconnected": "No hardware wallet detected. Please connect a hardware wallet to use this option.", + "unconfigured-detected-title": "Unconfigured hardware wallet", + "unconfigured-detected": "A seedless hardware wallet has been detected. Select \"Configure automatically\" if you want to configure it as a brand new wallet and start using it immediately, or select \"Restore backup\" if you want to configure it with a previously created seed backup and thus be able to access your funds again.", + "configured-detected": "Hardware wallet detected. The device is identified in the wallets list as:", + "security-warnings-title": "Security warnings", + "security-warning-title": "Security warning", + "backup-warning": "You should backup the hardware wallet seed or you could lose access to the funds in case of problems. To do this, select the \"Create a backup\" option.", + "pin-warning": "The connected hardware wallet does not have a PIN. The PIN code protects the hardware wallet in case of loss, theft and hacks. To create a PIN code, select the \"Create PIN code\" option.", + "options": "Options:", + "configure-automatically": "Configure automatically", + "restore-backup": "Restore backup", + "create-backup": "Create a backup", + "wipe": "Wipe the device", + "confirm-seed": "Confirm seed", + "create-pin": "Create PIN code", + "change-pin": "Change PIN code", + "forgotten-pin1": "If you can not access the wallet because you have forgotten the PIN, you can wipe the hardware wallet and then restore it with the seed by clicking", + "forgotten-pin2": "here." + }, + "generate-seed" : { + "text": "Before proceeding, you can select the number of words you want the seed to have. The seed is a list of words that can be used to recover access to the coins in case of problems. Both values are safe, so if you do not have a special reason for selecting one or the other, you can leave the default value.", + "configuring": "Configuring..." + }, + "restore-seed" : { + "text": "Before proceeding, please select the number of words that the seed you want to recover has.", + "check-text": "You can use this option to enter a seed and check if it is equal to the one in the hardware wallet. Before start, select the number of words the seed you want to check has.", + "warning" : "WARNING: to avoid potential problems, use only seeds created with a hardware wallet from the same brand/model.", + "error-wrong-word": "Error: The retyped word does not match the one requested by the hardware wallet.", + "error-invalid-seed": "Error: The seed is not valid. Please be sure to enter the correct words in the correct order.", + "error-wrong-seed": "Error: The seed is valid but does not match the one in the device." + }, + "added" : { + "title": "New Hardware Wallet", + "configuring": "New hardware wallet detected. Configuring...", + "done": "Done", + "added1": "The connected hardware wallet has been added to the wallets list with the following name:", + "added2": "Now you can check the balance and the addresses of the hardware wallet even when it is not connected. Additionally, you can change the name of the wallet or remove it from the wallets list, if you wish." + }, + "wipe" : { + "warning": "WARNING: All the data in the hardware wallet will be deleted. If you do not have a backup, you will not be able to access your funds again.", + "confirm-delete": "Also remove from the wallets list" + }, + "create-backup" : { + "warning": "WARNING: You can only use this option to backup your hardware wallet seed once. If you decide to continue, you will have to write down a group of words (it is recommended to do it on paper and not on a computer) that will appear on the screen of the hardware wallet and store the list in a safe place. Anyone with access to the word list (the \"seed\") will be able access the wallet balance, so extreme caution is advised.", + "instructions": "Write down the word list that appear on the screen of the hardware wallet. Make sure you respect the order and write each word correctly." + }, + "seed-word" : { + "title": "Enter word", + "info1": "Enter the word indicated in the device", + "info2": "You will be asked to enter the words of your backup seed in random order, plus a few additional words.", + "word": "Requested word", + "error-invalid-word": "The entered word is not valid.", + "error-loading-words": "Loading the word list. Please wait." + }, + "change-pin" : { + "pin-mismatch": "Unable to perform the operation. Two PINs you have entered do not match." + }, + "enter-pin" : { + "title": "Enter PIN", + "title-change-current": "Enter the current PIN", + "title-change-new": "Enter the new PIN", + "title-change-confirm": "Confirm the new PIN", + "instructions": "The PIN layout is displayed on the hardware wallet screen.", + "instructions-tx": "Enter the PIN to confirm and sign the transaction.", + "instructions-change": "Please enter a hard-to-guess PIN of between 4 and 8 numbers.", + "help": "Need help?" + }, + "pin-help" : { + "title": "Help", + "part1": "When it is necessary to enter the PIN to continue, the hardware wallet screen will display a matrix of 9 boxes with numbers in random order (the order changes each time) and you will be asked to enter the PIN in the software wallet using a matrix of 9 buttons that simply show the symbol #.", + "part2": "To enter the PIN, look at the position of the PIN numbers in numbers matrix on the screen of the hardware wallet and press the corresponding buttons in the software wallet. For example, if the PIN is \"23\" and the number 2 is in the upper left, number 3 in the middle of the hardware wallet numbers matrix, press the upper left and middle button in that order in the software wallet.", + "part3": "If you wish, you can also use the numpad on your keyboard to enter the PIN. However, as in the previous example, if the PIN is \"23\", you can not simply type \"23\" with the numpad, but you will have to press the keys that are in the position where the numbers 2 and 3 are shown on the screen of the hardware wallet." + }, + "create-tx" : { + "title": "Create transaction" + }, + "confirm-address" : { + "title": "Confirm address", + "instructions": "Please confirm on the hardware wallet if the address is:", + "short-confirmation": "Address confirmed.", + "confirmation": "Address confirmed. For security, you can re-show the address in the hardware wallet using the \"Confirm address\" option, in the menu that you can display by pressing the button at the right of the address balance." + } + }, + + "time-from-now": { + "few-seconds": "a few seconds ago", + "minute": "one minute ago", + "minutes": "{{time}} minutes ago", + "hour": "one hour ago", + "hours": "{{time}} hours ago", + "day": "one day ago", + "days": "{{time}} days ago" + }, + + "exchange": { + "you-send": "You send", + "you-get": "You get (approx.)", + "to-address": "To {{coin}} address", + "price": "Exchange rate", + "time-15": "Exchange time", + "exchange-button": "Exchange", + "min-amount": "Minimum amount:", + "max-amount": "Maximum amount:", + "agree-1": "I agree with", + "agree-2": "Terms of Use", + "agree-3": "and", + "agree-4": "Privacy Policy", + "powered-by": "Powered by", + "need-help": "Need help?", + "support-portal": "Support portal", + "history": "Order history", + "order-not-found": "Order not found", + "status": "Status", + "exchanging": "Exchanging {{from}} for {{to}}", + "select": "Select", + "offline": "Exchange is temporarily offline", + "problem-connecting": "Unable to connect with the service. Please check your Internet connection and try again later.", + "invalid-address": "Invalid address.", + "statuses": { + "user-waiting": "Waiting for deposit. Please send {{amount}} {{from}} to the exchange address shown below", + "user-waiting-info": "The system is waiting for you to make the deposit into the exchange address. The exchange process will start after the deposit is detected and confirmed in the blockchain. If you have already made the deposit, it should be detected shortly.", + "market-waiting-confirmations": "Waiting for transaction confirmations", + "market-waiting-confirmations-info": "The deposit has already been detected and the system is waiting for it to be confirmed in the blockchain.", + "market-confirmed": "Transaction accepted", + "market-confirmed-info": "The transaction has already been confirmed in the blockchain. Preparing to make the exchange soon.", + "market-exchanged": "Traded {{from}} for {{to}}", + "market-exchanged-info": "The exchange has been made. The funds will be transferred to your address in a moment.", + "market-withdraw-waiting": "Sending {{to}} to your address", + "market-withdraw-waiting-info": "The process for sending the coins to your address has been initiated.", + "complete": "Exchange completed!", + "complete-info": "The funds have been successfully sent to your address.", + "error": "Error occurred", + "error-info": "There was an error in the operation, you can find more information below. If you need help, please save all the operation data shown below and contact technical support using the link in the lower right part of this page." + }, + "history-window": { + "address": "Address", + "date": "Date" + }, + "details": { + "exchange-addr": "Exchange address", + "exchange-addr-tag": "Payment ID or Destination Tag which must be used for the transaction", + "tx-id": "Transaction ID", + "order-id": "Order ID", + "initial-price": "Initial exchange rate", + "error-msg": "Error message", + "details": "Details", + "start-date": "Start date", + "back": "Back", + "back-alert": "The operation is still in progress. Do you really want to return to the form? You can see the progress of this operation again by pressing the \"Order history\" button" + } + } +} diff --git a/src/gui/static/src/assets/img/alert-red.png b/src/gui/static/src/assets/img/alert-red.png new file mode 100644 index 0000000..17118ad Binary files /dev/null and b/src/gui/static/src/assets/img/alert-red.png differ diff --git a/src/gui/static/src/assets/img/big-error-icon.png b/src/gui/static/src/assets/img/big-error-icon.png new file mode 100644 index 0000000..bcbda0c Binary files /dev/null and b/src/gui/static/src/assets/img/big-error-icon.png differ diff --git a/src/gui/static/src/assets/img/chevron-right-grey.png b/src/gui/static/src/assets/img/chevron-right-grey.png new file mode 100644 index 0000000..d040458 Binary files /dev/null and b/src/gui/static/src/assets/img/chevron-right-grey.png differ diff --git a/src/gui/static/src/assets/img/delete-grey.png b/src/gui/static/src/assets/img/delete-grey.png new file mode 100644 index 0000000..42ea934 Binary files /dev/null and b/src/gui/static/src/assets/img/delete-grey.png differ diff --git a/src/gui/static/src/assets/img/delete-red.png b/src/gui/static/src/assets/img/delete-red.png new file mode 100644 index 0000000..62175e3 Binary files /dev/null and b/src/gui/static/src/assets/img/delete-red.png differ diff --git a/src/gui/static/src/assets/img/edit-blue.png b/src/gui/static/src/assets/img/edit-blue.png new file mode 100644 index 0000000..de88a9a Binary files /dev/null and b/src/gui/static/src/assets/img/edit-blue.png differ diff --git a/src/gui/static/src/assets/img/edit-grey.png b/src/gui/static/src/assets/img/edit-grey.png new file mode 100644 index 0000000..a5cf11e Binary files /dev/null and b/src/gui/static/src/assets/img/edit-grey.png differ diff --git a/src/gui/static/src/assets/img/hw-configurable.png b/src/gui/static/src/assets/img/hw-configurable.png new file mode 100644 index 0000000..59192cb Binary files /dev/null and b/src/gui/static/src/assets/img/hw-configurable.png differ diff --git a/src/gui/static/src/assets/img/internal-configurable.png b/src/gui/static/src/assets/img/internal-configurable.png new file mode 100644 index 0000000..3a9bc89 Binary files /dev/null and b/src/gui/static/src/assets/img/internal-configurable.png differ diff --git a/src/gui/static/src/assets/img/lang/en.png b/src/gui/static/src/assets/img/lang/en.png new file mode 100644 index 0000000..bb03eaa Binary files /dev/null and b/src/gui/static/src/assets/img/lang/en.png differ diff --git a/src/gui/static/src/assets/img/lang/es.png b/src/gui/static/src/assets/img/lang/es.png new file mode 100644 index 0000000..4590656 Binary files /dev/null and b/src/gui/static/src/assets/img/lang/es.png differ diff --git a/src/gui/static/src/assets/img/lang/ru.png b/src/gui/static/src/assets/img/lang/ru.png new file mode 100644 index 0000000..61c27f9 Binary files /dev/null and b/src/gui/static/src/assets/img/lang/ru.png differ diff --git a/src/gui/static/src/assets/img/lang/zh.png b/src/gui/static/src/assets/img/lang/zh.png new file mode 100644 index 0000000..ba5615b Binary files /dev/null and b/src/gui/static/src/assets/img/lang/zh.png differ diff --git a/src/gui/static/src/assets/img/list-blue.png b/src/gui/static/src/assets/img/list-blue.png new file mode 100644 index 0000000..91838fd Binary files /dev/null and b/src/gui/static/src/assets/img/list-blue.png differ diff --git a/src/gui/static/src/assets/img/list-grey.png b/src/gui/static/src/assets/img/list-grey.png new file mode 100644 index 0000000..0d2632a Binary files /dev/null and b/src/gui/static/src/assets/img/list-grey.png differ diff --git a/src/gui/static/src/assets/img/list-purple.png b/src/gui/static/src/assets/img/list-purple.png new file mode 100644 index 0000000..34f4b3b Binary files /dev/null and b/src/gui/static/src/assets/img/list-purple.png differ diff --git a/src/gui/static/src/assets/img/load-configurable.png b/src/gui/static/src/assets/img/load-configurable.png new file mode 100644 index 0000000..f685c3e Binary files /dev/null and b/src/gui/static/src/assets/img/load-configurable.png differ diff --git a/src/gui/static/src/assets/img/lock-configurable.png b/src/gui/static/src/assets/img/lock-configurable.png new file mode 100644 index 0000000..07aa794 Binary files /dev/null and b/src/gui/static/src/assets/img/lock-configurable.png differ diff --git a/src/gui/static/src/assets/img/lock-green.png b/src/gui/static/src/assets/img/lock-green.png new file mode 100644 index 0000000..236ee16 Binary files /dev/null and b/src/gui/static/src/assets/img/lock-green.png differ diff --git a/src/gui/static/src/assets/img/lock-white.png b/src/gui/static/src/assets/img/lock-white.png new file mode 100644 index 0000000..57ea81e Binary files /dev/null and b/src/gui/static/src/assets/img/lock-white.png differ diff --git a/src/gui/static/src/assets/img/minus-grey.png b/src/gui/static/src/assets/img/minus-grey.png new file mode 100644 index 0000000..b81e568 Binary files /dev/null and b/src/gui/static/src/assets/img/minus-grey.png differ diff --git a/src/gui/static/src/assets/img/minus-red.png b/src/gui/static/src/assets/img/minus-red.png new file mode 100644 index 0000000..6686a98 Binary files /dev/null and b/src/gui/static/src/assets/img/minus-red.png differ diff --git a/src/gui/static/src/assets/img/money-configurable.png b/src/gui/static/src/assets/img/money-configurable.png new file mode 100644 index 0000000..c79654e Binary files /dev/null and b/src/gui/static/src/assets/img/money-configurable.png differ diff --git a/src/gui/static/src/assets/img/otc-background.jpg b/src/gui/static/src/assets/img/otc-background.jpg new file mode 100644 index 0000000..03a8401 Binary files /dev/null and b/src/gui/static/src/assets/img/otc-background.jpg differ diff --git a/src/gui/static/src/assets/img/plus-configurable.png b/src/gui/static/src/assets/img/plus-configurable.png new file mode 100644 index 0000000..3993fb7 Binary files /dev/null and b/src/gui/static/src/assets/img/plus-configurable.png differ diff --git a/src/gui/static/src/assets/img/plus-green.png b/src/gui/static/src/assets/img/plus-green.png new file mode 100644 index 0000000..ab02079 Binary files /dev/null and b/src/gui/static/src/assets/img/plus-green.png differ diff --git a/src/gui/static/src/assets/img/plus-grey.png b/src/gui/static/src/assets/img/plus-grey.png new file mode 100644 index 0000000..35dbfff Binary files /dev/null and b/src/gui/static/src/assets/img/plus-grey.png differ diff --git a/src/gui/static/src/assets/img/qr-code-black.png b/src/gui/static/src/assets/img/qr-code-black.png new file mode 100644 index 0000000..f9a2fab Binary files /dev/null and b/src/gui/static/src/assets/img/qr-code-black.png differ diff --git a/src/gui/static/src/assets/img/received-configurable.png b/src/gui/static/src/assets/img/received-configurable.png new file mode 100644 index 0000000..89bcbe8 Binary files /dev/null and b/src/gui/static/src/assets/img/received-configurable.png differ diff --git a/src/gui/static/src/assets/img/search-gold.png b/src/gui/static/src/assets/img/search-gold.png new file mode 100644 index 0000000..a381073 Binary files /dev/null and b/src/gui/static/src/assets/img/search-gold.png differ diff --git a/src/gui/static/src/assets/img/send-black.png b/src/gui/static/src/assets/img/send-black.png new file mode 100644 index 0000000..f30004b Binary files /dev/null and b/src/gui/static/src/assets/img/send-black.png differ diff --git a/src/gui/static/src/assets/img/sent-configurable.png b/src/gui/static/src/assets/img/sent-configurable.png new file mode 100644 index 0000000..7673438 Binary files /dev/null and b/src/gui/static/src/assets/img/sent-configurable.png differ diff --git a/src/gui/static/src/assets/img/size-alert.png b/src/gui/static/src/assets/img/size-alert.png new file mode 100644 index 0000000..49b639c Binary files /dev/null and b/src/gui/static/src/assets/img/size-alert.png differ diff --git a/src/gui/static/src/assets/img/transactions-black.png b/src/gui/static/src/assets/img/transactions-black.png new file mode 100644 index 0000000..413f223 Binary files /dev/null and b/src/gui/static/src/assets/img/transactions-black.png differ diff --git a/src/gui/static/src/assets/img/unknown-configurable.png b/src/gui/static/src/assets/img/unknown-configurable.png new file mode 100644 index 0000000..69a12c5 Binary files /dev/null and b/src/gui/static/src/assets/img/unknown-configurable.png differ diff --git a/src/gui/static/src/assets/img/unlock-gold.png b/src/gui/static/src/assets/img/unlock-gold.png new file mode 100644 index 0000000..3ecf4ae Binary files /dev/null and b/src/gui/static/src/assets/img/unlock-gold.png differ diff --git a/src/gui/static/src/assets/img/unlock-grey.png b/src/gui/static/src/assets/img/unlock-grey.png new file mode 100644 index 0000000..61a3177 Binary files /dev/null and b/src/gui/static/src/assets/img/unlock-grey.png differ diff --git a/src/gui/static/src/assets/img/unlock-red.png b/src/gui/static/src/assets/img/unlock-red.png new file mode 100644 index 0000000..515a901 Binary files /dev/null and b/src/gui/static/src/assets/img/unlock-red.png differ diff --git a/src/gui/static/src/assets/img/wallet-black.png b/src/gui/static/src/assets/img/wallet-black.png new file mode 100644 index 0000000..cdb2ec8 Binary files /dev/null and b/src/gui/static/src/assets/img/wallet-black.png differ diff --git a/src/gui/static/src/assets/logo-white.png b/src/gui/static/src/assets/logo-white.png new file mode 100644 index 0000000..cd615cf Binary files /dev/null and b/src/gui/static/src/assets/logo-white.png differ diff --git a/src/gui/static/src/assets/scripts/qrcode.min.js b/src/gui/static/src/assets/scripts/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/src/gui/static/src/assets/scripts/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/src/gui/static/src/current-skycoin.json b/src/gui/static/src/current-skycoin.json new file mode 100644 index 0000000..e771960 --- /dev/null +++ b/src/gui/static/src/current-skycoin.json @@ -0,0 +1 @@ +versionData='{ "version": "0.25.0" }'; diff --git a/src/gui/static/src/environments/environment.e2e.ts b/src/gui/static/src/environments/environment.e2e.ts new file mode 100644 index 0000000..57a90d1 --- /dev/null +++ b/src/gui/static/src/environments/environment.e2e.ts @@ -0,0 +1,16 @@ +// This file is for the e2e tests ony. + +export const environment = { + nodeUrl: window['electron'] ? window['electron'].getLocalServerUrl() : '/api/', + production: true, + tellerUrl: '/teller/', + isInE2eMode: true, + ignoreNonFiberNetworIssues: false, + + // NOTE: the Swaplab integration currently works with Skycoin only. + swaplab: { + apiKey: 'w4bxe2tbf9beb72r', // if set to null, integration will be disabled + activateTestMode: true, + endStatusInError: false, + }, +}; diff --git a/src/gui/static/src/environments/environment.prod.ts b/src/gui/static/src/environments/environment.prod.ts new file mode 100644 index 0000000..0dc7673 --- /dev/null +++ b/src/gui/static/src/environments/environment.prod.ts @@ -0,0 +1,14 @@ +export const environment = { + nodeUrl: window['electron'] ? window['electron'].getLocalServerUrl() : '/api/', + production: true, + tellerUrl: 'https://event.skycoin.com/api/', + isInE2eMode: false, + ignoreNonFiberNetworIssues: false, + + // NOTE: the Swaplab integration currently works with Skycoin only. + swaplab: { + apiKey: 'w4bxe2tbf9beb72r', // if set to null, integration will be disabled + activateTestMode: false, + endStatusInError: false, + }, +}; diff --git a/src/gui/static/src/environments/environment.ts b/src/gui/static/src/environments/environment.ts new file mode 100644 index 0000000..46d7882 --- /dev/null +++ b/src/gui/static/src/environments/environment.ts @@ -0,0 +1,23 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +export const environment = { + nodeUrl: window['electron'] ? window['electron'].getLocalServerUrl() : '/api/', + production: false, + tellerUrl: '/teller/', + isInE2eMode: false, + /** + * If true and while using non-fiber coins, the blockchain will always appear as synchronized + * and no error will be shown if the node is not connected to other nodes. + */ + ignoreNonFiberNetworIssues: true, + + // NOTE: the Swaplab integration currently works with Skycoin only. + swaplab: { + apiKey: 'w4bxe2tbf9beb72r', // if set to null, integration will be disabled + activateTestMode: true, + endStatusInError: false, + }, +}; diff --git a/src/gui/static/src/favicon.ico b/src/gui/static/src/favicon.ico new file mode 100644 index 0000000..cc325fd Binary files /dev/null and b/src/gui/static/src/favicon.ico differ diff --git a/src/gui/static/src/index.html b/src/gui/static/src/index.html new file mode 100644 index 0000000..3113303 --- /dev/null +++ b/src/gui/static/src/index.html @@ -0,0 +1,49 @@ + + + + + Skycoin + + + + + + + +
+
+ +
+ +
+
+
+
+ + diff --git a/src/gui/static/src/main.ts b/src/gui/static/src/main.ts new file mode 100644 index 0000000..7cc7463 --- /dev/null +++ b/src/gui/static/src/main.ts @@ -0,0 +1,13 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule, { + preserveWhitespaces: true, +}); diff --git a/src/gui/static/src/polyfills.ts b/src/gui/static/src/polyfills.ts new file mode 100644 index 0000000..6d2c4f2 --- /dev/null +++ b/src/gui/static/src/polyfills.ts @@ -0,0 +1,76 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** Evergreen browsers require these. **/ +import 'core-js/es6/reflect'; + + +/** + * Required to support Web Animations `@angular/animation`. + * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + + +/*************************************************************************************************** + * Zone JS is required by Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/** + * Date, currency, decimal and percent pipes. + * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 + */ +// import 'intl'; // Run `npm install --save intl`. +/** + * Need to import at least one locale-data with intl. + */ +// import 'intl/locale-data/jsonp/en'; + +/*************************************************************************************************** + * ERROR FIX + */ +(window as any).global = window; diff --git a/src/gui/static/src/styles.scss b/src/gui/static/src/styles.scss new file mode 100644 index 0000000..052588e --- /dev/null +++ b/src/gui/static/src/styles.scss @@ -0,0 +1,160 @@ +/********************* +* General styles for the app. +*********************/ +@import 'theme/variables'; +@import 'theme/tables'; +@import 'theme/_modals'; +@import 'theme/fonts'; +@import 'theme/forms'; +@import 'theme/onboarding'; +@import 'theme/buttons'; +@import 'theme/text'; +@import 'theme/menu'; + +@import "~bootstrap/scss/mixins"; +@import '~bootstrap/scss/bootstrap-grid.scss'; +@import '~bootstrap/scss/utilities/_display.scss'; +@import "~bootstrap/scss/utilities/_text.scss"; +@import "~bootstrap/scss/utilities/_spacing.scss"; + +@import 'app/app.theme.scss'; + +body, div, h1, h2, h3, h4, h5, h6, p, span, a, button, option, select, +mat-panel-description, mat-panel-title, mat-option.mat-option { + font-family: $font-family; +} + +// Class for the div which is shown in the background, needed to avoid a problem which makes the +// background color of the element to be shown incorrectly when a modal window is open +// and the content has been scrolled. +.background-fixer { + background-color: $grey-lightest; + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + z-index: -1; +} + +html { + height: 100%; +} + +body { + background-color: $grey-lightest; + margin: 0; + padding: 0; + height: 100%; + color: $black; + font-size: $font-size-standard; +} + +.mat-tooltip { + font-size: 11px !important; + line-height: 1.3; +} + +/** +Coin selection component +**/ + +.no-overflow { + overflow: hidden; +} + +.transparent-background-dialog { + max-width: unset !important; + padding: 0; + + .mat-dialog-container { + background-color: transparent !important; + box-shadow: unset; + overflow: hidden; + padding: 0; + } +} + +.clear-dialog-background { + background-color: rgba(245, 245, 245, 0.976); + margin: -100%; +} + +/** +General Helpers +**/ + +.flex-fill, .-flex-fill { + flex: 1 1 auto; +} + +.link { + cursor: pointer; + text-decoration: none; +} + +/** +Alerts + */ + +.unconfirmed-alert { + display: inline !important; + vertical-align: text-bottom; + font-size: $font-size-standard-plus !important; + animation: alert-blinking 1s linear infinite; +} + +.alert-box { + color: $red; + font-size: $font-size-standard-minus; + padding: 0 10px; + line-height: 1.5; + background-color: $light-red-background; + padding: 15px; + display: flex; + margin-bottom: 20px; + + .title { + font-size: $font-size-very-big; + } + + mat-icon { + margin-top: 5px; + margin-right: 10px; + animation: alert-blinking 1s linear infinite; + } + + mat-checkbox { + margin-top: 10px; + display: inline-block; + } + + .-check { + span { + color: $black !important; + } + } +} + +@keyframes alert-blinking { + 50% { + opacity: 0.2; + } +} + +.red { + color: $red; +} + +.red-field { + border: $red solid 2px !important; + color: $red !important; +} + +.error-tooltip { + background-color: $red !important; +} + +input { + caret-color: black !important; +} diff --git a/src/gui/static/src/test.ts b/src/gui/static/src/test.ts new file mode 100644 index 0000000..0c45c2e --- /dev/null +++ b/src/gui/static/src/test.ts @@ -0,0 +1,32 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/proxy.js'; +import 'zone.js/dist/sync-test'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting, +} from '@angular/platform-browser-dynamic/testing'; + +// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. +declare const __karma__: any; +declare const require: any; + +// Prevent Karma from running prematurely. +__karma__.loaded = function() {}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); +// Finally, start Karma to run the tests. +__karma__.start(); diff --git a/src/gui/static/src/theme/_buttons.scss b/src/gui/static/src/theme/_buttons.scss new file mode 100644 index 0000000..e55bf1e --- /dev/null +++ b/src/gui/static/src/theme/_buttons.scss @@ -0,0 +1,48 @@ +/********************* +* Styles for the buttons. +*********************/ +@import 'variables'; + +// Dark buttons for the wizard. +.dark-button button.enabled { + background-color: $black !important; + span { + color: white; + } +} + +// Buttons without background. +.ghost-button button.enabled { + background-color: transparent !important; + span { + color: black; + } +} + +// Mouse efects for the images used as buttons. +.image-button { + cursor: pointer; + opacity: 0.5; + + &:hover { + opacity: 0.75; + } + + &:active { + opacity: 1; + } +} + +.icon-button { + color: $grey !important; + font-size: $font-size-standard !important; + min-width: 140px !important; + + img { + height: 32px; + margin-left: -4px; + width: 32px; + position: relative; + top: -2px; + } +} diff --git a/src/gui/static/src/theme/_fonts.scss b/src/gui/static/src/theme/_fonts.scss new file mode 100644 index 0000000..2dcafad --- /dev/null +++ b/src/gui/static/src/theme/_fonts.scss @@ -0,0 +1,47 @@ +@font-face { + font-family: 'Skycoin'; + font-style: normal; + font-weight: 300; + src: url('/assets/fonts/skycoin/Skycoin-Light.woff2') format('woff2'), + url('/assets/fonts/skycoin/Skycoin-Light.woff') format('woff'); +} + +@font-face { + font-family: 'Skycoin'; + font-style: italic; + font-weight: 300; + src: url('/assets/fonts/skycoin/Skycoin-LightItalic.woff2') format('woff2'), + url('/assets/fonts/skycoin/Skycoin-LightItalic.woff') format('woff'); +} + +@font-face { + font-family: 'Skycoin'; + font-style: normal; + font-weight: 400; + src: url('/assets/fonts/skycoin/Skycoin-Regular.woff2') format('woff2'), + url('/assets/fonts/skycoin/Skycoin-Regular.woff') format('woff'); +} + +@font-face { + font-family: 'Skycoin'; + font-style: italic; + font-weight: 400; + src: url('/assets/fonts/skycoin/Skycoin-RegularItalic.woff2') format('woff2'), + url('/assets/fonts/skycoin/Skycoin-RegularItalic.woff') format('woff'); +} + +@font-face { + font-family: 'Skycoin'; + font-style: normal; + font-weight: 700; + src: url('/assets/fonts/skycoin/Skycoin-Bold.woff2') format('woff2'), + url('/assets/fonts/skycoin/Skycoin-Bold.woff') format('woff'); +} + +@font-face { + font-family: 'Skycoin'; + font-style: italic; + font-weight: 700; + src: url('/assets/fonts/skycoin/Skycoin-BoldItalic.woff2') format('woff2'), + url('/assets/fonts/skycoin/Skycoin-BoldItalic.woff') format('woff'); +} diff --git a/src/gui/static/src/theme/_forms.scss b/src/gui/static/src/theme/_forms.scss new file mode 100644 index 0000000..507905f --- /dev/null +++ b/src/gui/static/src/theme/_forms.scss @@ -0,0 +1,232 @@ +/********************* +* Styles for the form elements. +*********************/ +@import 'variables'; + +// General container for one label and a form field. +.form-field { + margin-bottom: $form-field-margin; + + label { + color: $black; + display: block; + font-size: $font-size-standard; + line-height: 1.5; + margin-bottom: 2px; + } + + // Base style for the form fields, not to be used directly. + .field-base { + color: $black; + background-color: white; + border: $input-border-size solid $input-border-color; + border-radius: $input-border-radius; + box-sizing: border-box; + display: block; + font-size: $font-size-standard; + line-height: 1.5; + padding: 10px 10px; + width: 100%; + } + + input { + @extend .field-base; + } + + input:disabled { + @extend .element-disabled; + } + + select { + @extend .field-base; + appearance: none; + + option { + color: $black; + } + + option:disabled { + color: $grey-dark; + } + } + + select:disabled { + @extend .element-disabled; + } + + textarea { + @extend .field-base; + } + + textarea:disabled { + @extend .element-disabled; + } + + mat-slider { + @extend .field-base; + padding: 0; + height: 40px; + + .mat-slider-thumb, .mat-slider-thumb-label { + transform: scale(1) !important; + border-width: 0 !important; + } + + .mat-slider-thumb { + right: -6px; + width: 12px; + height: 32px; + border-radius: 3px; + } + + .mat-slider-track-fill, .mat-slider-track-background { + background-color: white !important; + } + } + + mat-select { + @extend .field-base; + padding: 0; + + .mat-select-trigger { + padding: 10px 40px 10px 10px; + display: block; + font-size: $font-size-mini; + height: 100%; + line-height: 1.9; + } + + .mat-select-arrow { + border: none; + } + + .mat-select-placeholder { + color: unset !important; + transition: unset !important; + } + } + + .-not-allowed { + input { + cursor: not-allowed; + } + } +} + +// Styles for the options list of mat-select. +.mat-option-disabled .mat-pseudo-checkbox-disabled { + opacity: 0.5; +} + +// Container for the select elements, it shows the down arrow at the right of the control. +.-select { + position: relative; + + // before is used instead of after to make the arrow to be transparent when necessary. + &::before { + content: ''; + display: block; + position: absolute; + top: 0; + right: 0; + background: url('/assets/img/chevron-right-grey.png') no-repeat; + background-size: $normal-icon-size $normal-icon-size; + width: $normal-icon-size; + height: $normal-icon-size; + margin: 6px; + pointer-events: none; + transform: rotate(90deg); + } +} + +textarea { + resize: none; +} + +// Used for showing a form field disabled. +.element-disabled { + pointer-events: none !important; + opacity: 0.5 !important; +} + +// Adds a top marging for the forms inside modal windows. It is only useful when there is an info text +// at the top of the form. +.modal-form-container { + margin-top: $form-field-margin; +} + +.-check-container { + text-align: center; + margin-top: 25px; +} + +// Style for the check boxes. +.-check { + label { + font-size: $font-size-standard; + max-width: 100%; + color: $black; + white-space: normal; + text-align: left; + + .img-label-container { + position: relative; + top: 2px; + + img { + width: 38px; + height: 38px; + vertical-align: middle; + } + } + } + + .mat-checkbox-label { + position: relative; + top: 2px; + } + + .mat-checkbox-background, .mat-checkbox-frame { + width: 20px; + height: 20px; + background: $grey-very-light !important; + border-radius: 6px; + border-color: transparent; + } + + .mat-checkbox-ripple { + top: -11px !important; + left: -11px !important; + } +} + +.help-icon { + display: inline !important; + font-size: $font-size-standard-plus !important; + color: $grey; + opacity: 0.55; + vertical-align: text-bottom; + padding-left: 5px; + cursor: default; +} + +// Container for inputs which show additional text at the right. +.-input-addon { + display: flex; + + input { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + span { + border: $input-border-size; + border-radius: 0 $input-border-radius $input-border-radius 0; + background: $input-border-color; + padding: 0 10px; + line-height: 44px; + color: $grey; + font-size: $font-size-standard; + flex-shrink: 0; + } +} diff --git a/src/gui/static/src/theme/_menu.scss b/src/gui/static/src/theme/_menu.scss new file mode 100644 index 0000000..c827c1e --- /dev/null +++ b/src/gui/static/src/theme/_menu.scss @@ -0,0 +1,14 @@ +/********************* +* Styles for the menus. +*********************/ +@import 'variables'; + +// Modifies a class added by Angular Material. +.mat-menu-panel { + border-radius: $rounded-element-border-radius !important; + background-color: $white; + + .mat-menu-item { + font-family: $font-family; + } +} diff --git a/src/gui/static/src/theme/_modals.scss b/src/gui/static/src/theme/_modals.scss new file mode 100644 index 0000000..dce1061 --- /dev/null +++ b/src/gui/static/src/theme/_modals.scss @@ -0,0 +1,65 @@ +/********************* +* Styles for the modal windows. +*********************/ +@import 'variables'; + +// Limits the height to show a vertical margin. +// (Modifies an element or class added by Angular Material) +.mat-dialog-content { + max-height: 90vh !important; +} + +@media (max-height: 600px) { + .mat-dialog-content { + max-height: 80vh !important; + } +} + +// Rounds the corners of the modal windows. +// (Modifies an element or class added by Angular Material) +mat-dialog-container { + border-radius: $rounded-element-border-radius !important; + overflow: hidden; +} + +// Removes the default padding. +// (Modifies an element or class added by Angular Material) +.mat-dialog-container { + padding: 0 !important; +} + +// Style of the main area of the modal windows. +.modal { + background-color: $white; + padding: 0px $modal-content-padding; + line-height: 1.5; + font-size: $font-size-standard; + color: $grey-dark; + + .-buttons { + text-align: center; + } + + app-button { + button { + margin-top: 28px; + } + } +} + +// Special class for the modal windows which show lists of elements made of buttons. +.list-button-container { + margin: 0px -10px; + + button.top-line:first-of-type { + border-top: 1px solid $grey-very-light; + } + + button { + width: 100%; + text-align: left; + padding: 10px 10px; + border-bottom: 1px solid $grey-very-light; + cursor: pointer; + } +} diff --git a/src/gui/static/src/theme/_onboarding.scss b/src/gui/static/src/theme/_onboarding.scss new file mode 100644 index 0000000..4fabb2e --- /dev/null +++ b/src/gui/static/src/theme/_onboarding.scss @@ -0,0 +1,47 @@ +@import 'variables'; + +$onboarding-contents-width: 80%; +$onboarding-contents-max-width: 450px; +$wizard-header-font-size: 20px; + +.onboarding-container { + width: 100%; + height: 100%; + overflow-x: hidden; + + .row-container { + max-width: $onboarding-contents-max-width; + width: $onboarding-contents-width; + margin: 0px auto; + } + + label { + color: $white !important; + } + + .-header { + color: $white; + margin-top: $wizard-header-font-size; + margin-bottom: 10px; + text-align: center; + line-height: 1.5; + font-size: 20px; + } + + .-description { + font-size: $font-size-standard-plus; + text-align: center; + color: $white; + opacity: 0.5; + } + + .-buttons-footer { + align-items: center; + flex-flow: column; + margin-bottom: 20px; + + button{ + margin: 2px 10px !important; + } + } +} diff --git a/src/gui/static/src/theme/_paper.scss b/src/gui/static/src/theme/_paper.scss new file mode 100644 index 0000000..65ad386 --- /dev/null +++ b/src/gui/static/src/theme/_paper.scss @@ -0,0 +1,18 @@ +/********************* +* Styles for the main white container used in most of the pages. +*********************/ +@import 'variables'; + +.paper { + background-color: $white; + border-radius: $very-rounded-element-border-radius; + box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.01), 1px 1px 2px 2px rgba(0, 0, 0, 0.01); + padding: $main-containers-padding; + margin: $main-containers-margin; + font-size: $font-size-standard; + overflow: hidden; + + &.small-padding { + padding: $main-containers-small-padding; + } +} diff --git a/src/gui/static/src/theme/_tables.scss b/src/gui/static/src/theme/_tables.scss new file mode 100644 index 0000000..6e40218 --- /dev/null +++ b/src/gui/static/src/theme/_tables.scss @@ -0,0 +1,96 @@ +/********************* +* Styles for the tables. +*********************/ +@import 'variables'; +@import 'paper'; + +// Main table container. +.-table { + &:last-of-type { + margin-bottom: $main-containers-margin; + } + + // Headers container. + .-headers { + color: $grey-light; + display: flex; + font-size: $font-size-standard-minus; + font-weight: 700; + height: 50px; + line-height: 50px; + margin: 0 $main-containers-margin; + + > div { + padding: 0 $main-containers-small-padding; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + // Content area container. + .-body { + @extend .paper; + padding: 0; + margin: 0 $main-containers-margin; + + .-row { + font-size: $font-size-standard; + padding: 15px 0; + display: flex; + align-items: center; + + &:not(:last-child) { + border-bottom: 1px solid $grey-very-light; + } + + > div { + padding: 0 $main-containers-small-padding; + } + } + } + + + /** + Helpers for setting the width of the columns. + **/ + + .-width-50 { + width: 50px; + flex-shrink: 0; + } + + .-width-70 { + width: 70px; + flex-shrink: 0; + } + + .-width-85 { + width: 85px; + flex-shrink: 0; + } + + .-width-130 { + width: 130px; + flex-shrink: 0; + } + + .-width-150 { + width: 150px; + flex-shrink: 0; + } + + .-width-200 { + width: 200px; + flex-shrink: 0; + } + + .-width-250 { + width: 250px; + flex-shrink: 0; + } +} + +.-top-table-margin { + margin-top: 20px; +} diff --git a/src/gui/static/src/theme/_text.scss b/src/gui/static/src/theme/_text.scss new file mode 100644 index 0000000..06f7fca --- /dev/null +++ b/src/gui/static/src/theme/_text.scss @@ -0,0 +1,36 @@ +/********************* +* Styles for the text. +*********************/ +@import 'variables'; + +.white-text { + color: $white !important; +} + +.red-text { + color: $red !important; +} + +.yellow-text { + color: $yellow !important; +} + +.green-text { + color: $green !important; +} + +.grey-light-text { + color: $grey-light !important; +} + +.grey-text { + color: $grey !important; +} + +.black-text { + color: $black !important; +} + +.break-all { + word-break: break-all; +} diff --git a/src/gui/static/src/theme/_variables.scss b/src/gui/static/src/theme/_variables.scss new file mode 100644 index 0000000..729f462 --- /dev/null +++ b/src/gui/static/src/theme/_variables.scss @@ -0,0 +1,91 @@ +/** +General values +**/ + +// Font family used in the whole app. +$font-family: Skycoin, Roboto, 'Helvetica Neue', sans-serif; + + +/** +Colors +**/ + +$black: #1e2227; +$white: #fafafa; +// Used to highlight items on some lists. +$white-hover: #f7f7f7; + +// Colors used for separators, texts, backgrounds and more. +$grey-lightest: #f7f7f7; +$grey-very-light: rgba(30, 34, 39, 0.05); +$grey-light: rgba(30, 34, 39, 0.2); +$grey: rgba(30, 34, 39, 0.5); +$grey-dark: rgba(30, 34, 39, 0.7); + +// Color of the border line used by the form fields. +$input-border-color: $grey-very-light; + +// Used for some icons and error texts. +$red: #ff004e; +// Used for some icons. +$green: #00df80; +// Used for some icons. +$yellow: #ffc125; +// Used for the background of some alert messages. +$light-red-background: #ffdede; + +// Background colors for the double buttons. +$wizard-double-button-background:rgba(255, 255, 255, 0.1); +$internal-double-button-background:rgba(30, 34, 39, 0.065); + + +/** +Sizes +**/ + +// Small radius for elements like mnenus and modal windows. +$rounded-element-border-radius: 6px; +// Big radius for elements like lists. +$very-rounded-element-border-radius: 10px; +// Radius for the form elements. +$input-border-radius: $rounded-element-border-radius; +// Size of the border line used by the form fields. +$input-border-size: 2px; + +// External margin used by big containers, like the main white areas shown by most pages. +$main-containers-margin: 30px; +// Normal internal margin used mainly by the main white areas shown by most pages. +$main-containers-padding: 30px; +// Small internal margin used mainly by the tables. +$main-containers-small-padding: 20px; +// Normal internal margin used in the modal windows. +$modal-content-padding: 24px; +// Vertical margin used by the form fields. +$form-field-margin: 20px; + +// Size of the qr code buttons. +$qr-code-button-size: 17px; + +$normal-icon-size: 32px; + + +/** +Font sizes +**/ + +// $font-size-standard should be used as the prefered size whenever possible. +$font-size-micro: 9px; +$font-size-mini: 11px; +$font-size-standard-minus: 12px; +$font-size-standard: 13px; +$font-size-standard-plus: 14px; +$font-size-big: 15px; +$font-size-very-big: 18px; + + +/** +Responsive sizes +**/ + +$max-xs-width: 767px; +$max-sm-width: 991px; diff --git a/src/gui/static/src/tsconfig.app.json b/src/gui/static/src/tsconfig.app.json new file mode 100644 index 0000000..1d5af50 --- /dev/null +++ b/src/gui/static/src/tsconfig.app.json @@ -0,0 +1,15 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "baseUrl": "./", + "types": [] + }, + "files": [ + "main.ts", + "polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/src/gui/static/src/tsconfig.spec.json b/src/gui/static/src/tsconfig.spec.json new file mode 100644 index 0000000..f1b8301 --- /dev/null +++ b/src/gui/static/src/tsconfig.spec.json @@ -0,0 +1,19 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "baseUrl": "./", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts", "polyfills.ts" + + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/src/gui/static/src/typings.d.ts b/src/gui/static/src/typings.d.ts new file mode 100644 index 0000000..bcc7cff --- /dev/null +++ b/src/gui/static/src/typings.d.ts @@ -0,0 +1,10 @@ +/* SystemJS module definition */ +declare var module: NodeModule; +interface NodeModule { + id: string; +} + +declare var System: System; +interface System { + import(request: string): Promise; +} diff --git a/src/gui/static/test-fixtures/encoded-txs.json b/src/gui/static/test-fixtures/encoded-txs.json new file mode 100644 index 0000000..67a5177 --- /dev/null +++ b/src/gui/static/test-fixtures/encoded-txs.json @@ -0,0 +1,665 @@ +{ + "txs": [ + { + "inputs": [ + { + "hash": "043836eb6f29aaeb8b9bfce847e07c159c72b25ae17d291f32125e7f1912e2a0", + "index": 0 + } + ], + "outputs": [ + { + "address": "R6aHqKWSQfvpdo2fGSrq4F1RYXkBWR9HHJ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2EYM4WFHe4Dgz6kjAdUkM6Etep7ruz2ia6h", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "25aGyzypSA3T9K6rgPUv1ouR13efNPtWP5m", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "ix44h3cojvN6nqGcdpy62X7Rw6Ahnr3Thk", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "AYV8KEBEAPCg8a59cHgqHMqYHP9nVgQDyW", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2Nu5Jv5Wp3RYGJU1EkjWFFHnebxMx1GjfkF", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2THDupTBEo7UqB6dsVizkYUvkKq82Qn4gjf", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "tWZ11Nvor9parjg4FkwxNVcby59WVTw2iL", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "m2joQiJRZnj3jN6NsoKNxaxzUTijkdRoSR", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "8yf8PAQqU2cDj8Yzgz3LgBEyDqjvCh2xR7", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "sgB3n11ZPUYHToju6TWMpUZTUcKvQnoFMJ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2UYPbDBnHUEc67e7qD4eXtQQ6zfU2cyvAvk", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "wybwGC9rhm8ZssBuzpy5goXrAdE31MPdsj", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "JbM25o7kY7hqJZt3WGYu9pHZFCpA9TCR6t", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2efrft5Lnwjtk7F1p9d7BnPd72zko2hQWNi", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "Syzmb3MiMoiNVpqFdQ38hWgffHg86D2J4e", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2g3GUmTQooLrNHaRDhKtLU8rWLz36Beow7F", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "D3phtGr9iv6238b3zYXq6VgwrzwvfRzWZQ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "gpqsFSuMCZmsjPc6Rtgy1FmLx424tH86My", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2EUF3GPEUmfocnUc1w6YPtqXVCy3UZA4rAq", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "TtAaxB3qGz5zEAhhiGkBY9VPV7cekhvRYS", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2fM5gVpi7XaiMPm4i29zddTNkmrKe6TzhVZ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "ix3NDKgxfYYANKAb5kbmwBYXPrkAsha7uG", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2RkPshpFFrkuaP98GprLtgHFTGvPY5e6wCK", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "Ak1qCDNudRxZVvcW6YDAdD9jpYNNStAVqm", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2eZYSbzBKJ7QCL4kd5LSqV478rJQGb4UNkf", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "KPfqM6S96WtRLMuSy4XLfVwymVqivdcDoM", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "5B98bU1nsedGJBdRD5wLtq7Z8t8ZXio8u5", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2iZWk5tmBynWxj2PpAFyiZzEws9qSnG3a6n", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "XUGdPaVnMh7jtzPe3zkrf9FKh5nztFnQU5", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "hSNgHgewJme8uaHrEuKubHYtYSDckD6hpf", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2DeK765jLgnMweYrMp1NaYHfzxumfR1PaQN", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "orrAssY5V2HuQAbW9K6WktFrGieq2m23pr", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "4Ebf4PkG9QEnQTm4MVvaZvJV6Y9av3jhgb", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "7Uf5xJ3GkiEKaLxC2WmJ1t6SeekJeBdJfu", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "oz4ytDKbCqpgjW3LPc52pW2CaK2gxCcWmL", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2ex5Z7TufQ5Z8xv5mXe53fSQRfUr35SSo7Q", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "WV2ap7ZubTxeDdmEZ1Xo7ufGMkekLWikJu", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "ckCTV4r1pNuz6j2VBRHhaJN9HsCLY7muLV", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "MXJx96ZJVSjktgeYZpVK8vn1H3xWP8ooq5", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "wyQVmno9aBJZmQ99nDSLoYWwp7YDJCWsrH", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2cc9wKxCsFNRkoAQDAoHke3ZoyL1mSV14cj", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "29k9g3F5AYfVaa1joE1PpZjBED6hQXes8Mm", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2XPLzz4ZLf1A9ykyTCjW5gEmVjnWa8CuatH", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "iH7DqqojTgUn2JxmY9hgFp165Nk7wKfan9", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "RJzzwUs3c9C8Y7NFYzNfFoqiUKeBhBfPki", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2W2cGyiCRM4nwmmiGPgMuGaPGeBzEm7VZPn", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "ALJVNKYL7WGxFBSriiZuwZKWD4b7fbV1od", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "tBaeg9zE2sgmw5ZQENaPPYd6jfwpVpGTzS", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2hdTw5Hk3rsgpZjvk8TyKcCZoRVXU5QVrUt", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "A1QU6jKq8YgTP79M8fwZNHUZc7hConFKmy", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "q9RkXoty3X1fuaypDDRUi78rWgJWYJMmpJ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2Xvm6is5cAPA85xnSYXDuAqiRyoXiky5RaD", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "4CW2CPJEzxhn2PS4JoSLoWGL5QQ7dL2eji", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "24EG6uTzL7DHNzcwsygYGRR1nfu5kco7AZ1", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "KghGnWw5fppTrqHSERXZf61yf7GkuQdCnV", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2WojewRA3LbpyXTP9ANy8CZqJMgmyNm3MDr", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2BsMfywmGV3M2CoDA112Rs7ZBkiMHfy9X11", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "kK1Q4gPyYfVVMzQtAPRzL8qXMqJ67Y7tKs", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "28J4mx8xfUtM92DbQ6i2Jmqw5J7dNivfroN", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "gQvgyG1djgtftoCVrSZmsRxr7okD4LheKw", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "3iFGBKapAWWzbiGFSr5ScbhrEPm6Esyvia", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "NFW2akQH2vu7AqkQXxFz2P5vkXTWkSqrSm", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2MQJjLnWRp9eHh6MpCwpiUeshhtmri12mci", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2QjRQUMyL6iodtHP9zKmxCNYZ7k3jxtk49C", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "USdfKy7B6oFNoauHWMmoCA7ND9rHqYw2Mf", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "cA49et9WtptYHf6wA1F8qqVgH3kS5jJ9vK", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "qaJT9TjcMi46sTKcgwRQU8o5Lw2Ea1gC4N", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "22pyn5RyhqtTQu4obYjuWYRNNw4i54L8xVr", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "22dkmukC6iH4FFLBmHne6modJZZQ3MC9BAT", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "z6CJZfYLvmd41GRVE8HASjRcy5hqbpHZvE", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "GEBWJ2KpRQDBTCCtvnaAJV2cYurgXS8pta", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "oS8fbEm82cprmAeineBeDkaKd7QownDZQh", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "rQpAs1LVQdphyj9ipEAuukAoj9kNpSP8cM", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "6NSJKsPxmqipGAfFFhUKbkopjrvEESTX3j", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "cuC68ycVXmD2EBzYFNYQ6akhKGrh3FGjSf", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "bw4wtYU8toepomrhWP2p8UFYfHBbvEV425", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "HvgNmDz5jD39Gwmi9VfDY1iYMhZUpZ8GKz", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "SbApuZAYquWP3Q6iD51BcMBQjuApYEkRVf", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2Ugii5yxJgLzC59jV1vF8GK7UBZdvxwobeJ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "21N2iJ1qnQRiJWcEqNRxXwfNp8QcmiyhtPy", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "9TC4RGs6AtFUsbcVWnSoCdoCpSfM66ALAc", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "oQzn55UWG4iMcY9bTNb27aTnRdfiGHAwbD", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2GCdwsRpQhcf8SQcynFrMVDM26Bbj6sgv9M", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2NRFe7REtSmaM2qAgZeG45hC8EtVGV2QjeB", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "25RGnhN7VojHUTvQBJA9nBT5y1qTQGULMzR", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "26uCBDfF8E2PJU2Dzz2ysgKwv9m4BhodTz9", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "Wkvima5cF7DDFdmJQqcdq8Syaq9DuAJJRD", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "286hSoJYxvENFSHwG51ZbmKaochLJyq4ERQ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "FEGxF3HPoM2HCWHn82tyeh9o7vEQq5ySGE", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "h38DxNxGhWGTq9p5tJnN5r4Fwnn85Krrb6", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2c1UU8J6Y3kL4cmQh21Tj8wkzidCiZxwdwd", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2bJ32KuGmjmwKyAtzWdLFpXNM6t83CCPLq5", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2fi8oLC9zfVVGnzzQtu3Y3rffS65Hiz6QHo", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "TKD93RxFr2Am44TntLiJQus4qcEwTtvEEQ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "zMDywYdGEDtTSvWnCyc3qsYHWwj9ogws74", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "25NbotTka7TwtbXUpSCQD8RMgHKspyDubXJ", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "2ayCELBERubQWH5QxUr3cTxrYpidvUAzsSw", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "RMTCwLiYDKEAiJu5ekHL1NQ8UKHi5ozCPg", + "coins": 1000000000000, + "hours": 1 + }, + { + "address": "ejJjiCwp86ykmFr5iTJ8LxQXJ2wJPTYmkm", + "coins": 1000000000000, + "hours": 1 + } + ], + "signatures": [ + "be602113fe288f750001ab65f254ceedd8b05b1becc456a0a52a0bea10b8280e38d950933992ad3265e1f81d197036fa634b316f08b3b319ffce081aa43f3bb600" + ], + "innerHash": "0f7019627886818d2501af189bbac18e21b8e959891c5b2726f89e29355aa10a", + "block": 1, + "raw": "060f0000000f7019627886818d2501af189bbac18e21b8e959891c5b2726f89e29355aa10a01000000be602113fe288f750001ab65f254ceedd8b05b1becc456a0a52a0bea10b8280e38d950933992ad3265e1f81d197036fa634b316f08b3b319ffce081aa43f3bb60001000000043836eb6f29aaeb8b9bfce847e07c159c72b25ae17d291f32125e7f1912e2a064000000003be2537f8c0893fddcddc878518f38ea493d949e0010a5d4e8000000010000000000000000b1cb2d1f0f4cae81aaba5b7bac6cd0825d836d860010a5d4e80000000100000000000000009b82664a2791ff0b713c054f0c8297b5d4b85a300010a5d4e80000000100000000000000006840be5c4574ebd2964d3b8480d9e68c9c04e4010010a5d4e800000001000000000000000017b74f4f9d84f265b849247786397241b31b435f0010a5d4e8000000010000000000000000c69047802c2eee1d3209fdc7a1f00387fb5ea1450010a5d4e8000000010000000000000000d17417e9ba3a0ab4c41b06dcba12fe1b7ad1cef50010a5d4e800000001000000000000000080032d0848e465ffb34336656390f4a781cc02310010a5d4e80000000100000000000000006d6c91562619265ff1b6ae7ae308511cfe3fcf3b0010a5d4e800000001000000000000000013d30014b79aee9b709eb17d202ad74cc6fdb8d80010a5d4e80000000100000000000000007df08027c2c47e2df1ed3fd93746c0f9d7a5fcd60010a5d4e8000000010000000000000000d496adb8bd0af7187b844243cfb436ba6d1ee18d0010a5d4e800000001000000000000000088a08c6fdd118b1a4bade4079b832d6415b4cb420010a5d4e80000000100000000000000002bb86985bfef99483e6d53c85febdf147472ff030010a5d4e8000000010000000000000000edc2beafb906a7362037c7b8d7c68bbcd50b5d250010a5d4e800000001000000000000000040929a5c060aa1665a78f68e687b2fc8e23aa8340010a5d4e8000000010000000000000000f129d1542ced1edd34800d5c2b781c8975aa37270010a5d4e80000000100000000000000001df18d79bd317911b14337ccc9caa7d0e26365b30010a5d4e800000001000000000000000062f93858c3201e2098bf5bfb8ffe35be1e0ef70e0010a5d4e8000000010000000000000000b19e29169074d369b6a61e718c70379737e4cccc0010a5d4e800000001000000000000000042cedc2e80c7ee2ca2855a06fd3ba0159bbff0d70010a5d4e8000000010000000000000000ef7101839457ea9bc50790171fd852bc006896390010a5d4e800000001000000000000000068409c9234c735fb2483d50bfcae0c62a3be08b10010a5d4e8000000010000000000000000cda5b71ce21c6a82bd7c24c63ce2f0ac69a400770010a5d4e80000000100000000000000001835c74c2fc92121d7435290bc14b272c7ea13b30010a5d4e8000000010000000000000000ed7d7b5c69cbcbd9932da5fb4c1ac95a535fef480010a5d4e80000000100000000000000002db48e3fe7f2050154bb72fcd8a810569c837c040010a5d4e80000000100000000000000000a60181b51e57912c8a7c9043cd7766fff2c8ddf0010a5d4e8000000010000000000000000f76e064dad995a22c9589c2ac78a0e21ae032cca0010a5d4e80000000100000000000000004bb99ae026d8ce7ced17cd314dcb392db209329d0010a5d4e8000000010000000000000000647ef87e6bf1c89c422134c6d36d8f96b17f03ce0010a5d4e8000000010000000000000000af9067e7b6c3691892bb7b8de7050dbdcbe355900010a5d4e80000000100000000000000007474ba61b2a67955667becc2de0f18ed2209fca90010a5d4e80000000100000000000000000809cd6f137e6a187a636fa7e369403511972aa50010a5d4e80000000100000000000000001018ab1c3cfa510be3fe6e2e29542771b3a6186f0010a5d4e800000001000000000000000074c3ef7e006a15baf6a33af6a1bf6e9434dc4efe0010a5d4e8000000010000000000000000ee74b074b2f5e6ffcce85da4a7e172cc911b90170010a5d4e80000000100000000000000004945b3bb36d9dc89df6f88e155d82503ee5feb9c0010a5d4e800000001000000000000000058d5676ed8fc30fa344ff9bfe224a4f94c098d750010a5d4e80000000100000000000000003300cac841a4acf1fd7527f4e76a173e8bc9ad550010a5d4e8000000010000000000000000889e62956a764db1143a4b588b4e4e886f79ef430010a5d4e8000000010000000000000000e8a1b38eb944d4501eb2ab60588a00d3a9c739a20010a5d4e8000000010000000000000000a5df92d314b2e133286a7cc0036bb836bc384df00010a5d4e8000000010000000000000000dba81d12c864e678c0a910f49d1e9d100f765ac30010a5d4e800000001000000000000000066958a5798c6f07a75ecc259866972c7db30fe930010a5d4e80000000100000000000000003c6aa14df1ceb2d3d90a72993124c4aee438dcf20010a5d4e8000000010000000000000000d8486eba19a2ec0a76bc7b5a6e729c28989c02dd0010a5d4e80000000100000000000000001731aacce97b0fcae9b3915d798a31e0bcdbecd20010a5d4e80000000100000000000000007f331280a851eab18e40a4f2e01e0423a61c88d20010a5d4e8000000010000000000000000f51d276fd69c55c5ae75617455bba63576eb55380010a5d4e8000000010000000000000000166261d8e0f4d7199137547f9d983093b8a83e010010a5d4e800000001000000000000000077a6cd82676ea569c2e29637bf021440f83c1b590010a5d4e8000000010000000000000000dd00b7bedd4b2c17e33c9f759c817751e5a03bac0010a5d4e800000001000000000000000007f2cc54dd0a7f9f9f8990765a160056e34cfe5c0010a5d4e8000000010000000000000000982aa1d396453abf15c827ef803d3d1fa42780750010a5d4e80000000100000000000000002e6f4e09ebf69c38051e82d47ff4f30ecb01636d0010a5d4e8000000010000000000000000da3771a1702dd6bd74e27ff495635e9fd5cfc8b90010a5d4e8000000010000000000000000ab270f3d713326ea04bbb76a40567ec9b68a0fdc0010a5d4e80000000100000000000000006ba2cf38a2e4e4490ef2aa6a13d334afe08e274b0010a5d4e8000000010000000000000000a2453b1d2c51e7e46576809e432e1d0f796c17cc0010a5d4e800000001000000000000000061f2ded3c11aa8cbff5428071deaaddd122b3d420010a5d4e800000001000000000000000006bcde3dcddf5eddbf36699de5edee76ae5381080010a5d4e800000001000000000000000034cf985956e53c3642ff24204510c09d2ec1f4160010a5d4e8000000010000000000000000c2d87e5ad2284c4b20b0630278b1b2afa51c8e4d0010a5d4e8000000010000000000000000cb1ed1ca9a81c76c138b733c1dba907cf2f6226f0010a5d4e80000000100000000000000004432ff17249de4f481203271f2433d0ff15963c20010a5d4e8000000010000000000000000575ee0f1bc6da3e3f5e1fdb2c30fe19289706b380010a5d4e800000001000000000000000078b7a73acfb87248b4a9b0313b4a258fc02568780010a5d4e800000001000000000000000094af09440255b4fe091e6087b18ebb3cd0b51d950010a5d4e80000000100000000000000009433ea55cb302024be8bde7bdff6ee614250899f0010a5d4e80000000100000000000000008de14bb4e87c177c14dfdd24d02c20e374bf05980010a5d4e800000001000000000000000025d7d3adff155dbfe0a8bb14a0efce72f82c8f530010a5d4e800000001000000000000000073659ddc6abd6d650ea735217e270f2cdf8f8e130010a5d4e80000000100000000000000007acbcc273b744075aeda6d93eeaa0ca3254b9dc30010a5d4e80000000100000000000000000d5837faf1dfab11e677852f1a004d5d2baa42fa0010a5d4e800000001000000000000000059380ebef923f2ec486888b0c6995655674e040d0010a5d4e800000001000000000000000056d06de791cface3fd12b262d4d1423eb11c1e6a0010a5d4e80000000100000000000000002a1045c8658b31d4be807a3734392d6f57cde1240010a5d4e80000000100000000000000003f98366594201e7641d404f2b5ae39ccb0e8840f0010a5d4e8000000010000000000000000d4f20c5eecf2159b66f9f3589cbb867a4979379e0010a5d4e8000000010000000000000000910b34a9fc34d4e9e4bdcd6b74017b376594b5a90010a5d4e80000000100000000000000001501051031afb8c1d978f8a6321dad9da114eee80010a5d4e8000000010000000000000000735927d116e5525d7f838a80cfaf4e41bbb5ce800010a5d4e8000000010000000000000000b5eb6ababe63206afefe9d69fe992162fa153a640010a5d4e8000000010000000000000000c55f1829761cd09dcbc117773fba906d3725eb1e0010a5d4e80000000100000000000000009b1fa3b8c4384fdae6ebf8adea1e327e74e649500010a5d4e80000000100000000000000009ece1f4291d35085f591333e497c1cec1183fc180010a5d4e800000001000000000000000049f419e3b8f22decc8ee51028016eb55e985f7540010a5d4e8000000010000000000000000a1c88901f123e1db30e01f632751d399d65371230010a5d4e8000000010000000000000000235ca41ff24d9ff52eda3dd948d976f167a868e80010a5d4e8000000010000000000000000637ff1cbb8c3989e4b5db6d687d5ebebb1eaeb440010a5d4e8000000010000000000000000e725485a2470e78c1ce948fcb475b6e58776b1b10010a5d4e8000000010000000000000000e55ebb425ff92f8f7d58f9bd4aa0a0df525c43fa0010a5d4e8000000010000000000000000f057f31ba7e6637669ed7039890d1cf3f07cd9c80010a5d4e800000001000000000000000041655ba68f745889e3ef649da6a26a3aae9169890010a5d4e80000000100000000000000008e8626e13f0393501cb2d25d4bbf4ae0afa4313f0010a5d4e80000000100000000000000009b02543dfce6942233a949eef327456039a145b40010a5d4e8000000010000000000000000e4900ea254300601620bda6af3a6cfe75b9ae1640010a5d4e80000000100000000000000003c858662d8b1f9460e6ddb5c30d368570a66c9390010a5d4e80000000100000000000000005dc40df06b99f88042a9d03999e10c17c86fc5db0010a5d4e80000000100000000000000" + }, + { + "inputs": [ + { + "hash": "e3e72ee077c8b0c3f87da7cf50cad8876bd3f489f373d9fe82fc2e971df56f76", + "index": 0 + } + ], + "outputs": [ + { + "address": "R6aHqKWSQfvpdo2fGSrq4F1RYXkBWR9HHJ", + "coins": 999990000000, + "hours": 1 + }, + { + "address": "qxmeHkwgAMfwXyaQrwv9jq3qt228xMuoT5", + "coins": 10000000, + "hours": 0 + } + ], + "signatures": [ + "f4482e0781e0d94c8c4773940e1f811405681844a9dc3c1938243442e1cbd5463d5e251880abbf8ff1ed85b4b2659e83ee30f06cc4c5dc9913aa6a9630fbe3de01" + ], + "innerHash": "4daff2831f5bc2877a98a49b0ef75f8ff01bcb35082fd4018c77707dfca31849", + "block": 2, + "raw": "dc000000004daff2831f5bc2877a98a49b0ef75f8ff01bcb35082fd4018c77707dfca3184901000000f4482e0781e0d94c8c4773940e1f811405681844a9dc3c1938243442e1cbd5463d5e251880abbf8ff1ed85b4b2659e83ee30f06cc4c5dc9913aa6a9630fbe3de0101000000e3e72ee077c8b0c3f87da7cf50cad8876bd3f489f373d9fe82fc2e971df56f7602000000003be2537f8c0893fddcddc878518f38ea493d949e80790cd4e800000001000000000000000079ae1e8799c65b4c01e18b3b4135410c5b711f3680969800000000000000000000000000" + }, + { + "inputs": [ + { + "hash": "af0b2c1cc882a56b6c0c06e99e7d2731413b988329a2c47a5c2aa8be589b707a", + "index": 0 + } + ], + "outputs": [ + { + "address": "R6aHqKWSQfvpdo2fGSrq4F1RYXkBWR9HHJ", + "coins": 10000000, + "hours": 0 + } + ], + "signatures": [ + "ce8fd47e2044ed17998f92621e90329f673a746c802d67f639ca083705dd199f6ee346781497b44132434922879244d819694b5903093f784570c55d293ab4af01" + ], + "innerHash": "ea6adee3180c7f9d73d1e693822d5d1c2bba85067f89a873355bc771a078faa1", + "block": 3, + "raw": "b700000000ea6adee3180c7f9d73d1e693822d5d1c2bba85067f89a873355bc771a078faa101000000ce8fd47e2044ed17998f92621e90329f673a746c802d67f639ca083705dd199f6ee346781497b44132434922879244d819694b5903093f784570c55d293ab4af0101000000af0b2c1cc882a56b6c0c06e99e7d2731413b988329a2c47a5c2aa8be589b707a01000000003be2537f8c0893fddcddc878518f38ea493d949e80969800000000000000000000000000" + }, + { + "inputs": [ + { + "hash": "9eb7954461ba0256c9054fe38c00c66e60428dccf900a62e74b9fe39310aea13", + "index": 0 + }, + { + "hash": "706f82c481906108880d79372ab5c126d32ecc98cf3f7c74cf33f5fda49dcf70", + "index": 0 + } + ], + "outputs": [ + { + "address": "R6aHqKWSQfvpdo2fGSrq4F1RYXkBWR9HHJ", + "coins": 999890000000, + "hours": 4073 + }, + { + "address": "2fGC7kwAM9yZyEF1QqBqp8uo9RUsF6ENGJF", + "coins": 100000000, + "hours": 0 + } + ], + "signatures": [ + "056ed0f74367fb1370d7e98689953983d9cf34eb6669854f1645c8a16c93d85075661e7d4f6df0ce5ca8eb9852eff6a12fbac2caafee03bb8c616f847c61416800", + "8aaa7f320a7b01169d3217a600100cb27c55e4ce56cd3455814f56d8e4e65be746e0e20e776087af6f19361f0b898edc2123a5f9bd35d24ef8b8669ca85b142601" + ], + "innerHash": "fe123ca954a82bb1ce2cc9ef9c56d6b649a4cbaf5b17394b0ffda651ed32327e", + "block": 5, + "raw": "3d01000000fe123ca954a82bb1ce2cc9ef9c56d6b649a4cbaf5b17394b0ffda651ed32327e02000000056ed0f74367fb1370d7e98689953983d9cf34eb6669854f1645c8a16c93d85075661e7d4f6df0ce5ca8eb9852eff6a12fbac2caafee03bb8c616f847c614168008aaa7f320a7b01169d3217a600100cb27c55e4ce56cd3455814f56d8e4e65be746e0e20e776087af6f19361f0b898edc2123a5f9bd35d24ef8b8669ca85b142601020000009eb7954461ba0256c9054fe38c00c66e60428dccf900a62e74b9fe39310aea13706f82c481906108880d79372ab5c126d32ecc98cf3f7c74cf33f5fda49dcf7002000000003be2537f8c0893fddcddc878518f38ea493d949e809816cee8000000e90f00000000000000ef3b60779f014b3c7acf27c16c9acc3ff3bea61600e1f505000000000000000000000000" + }, + { + "inputs": [ + { + "hash": "182b4c32bb5fe0e6809a19db63eecbeefde97a6c043b9248da94d428ab5a94c2", + "index": 0 + }, + { + "hash": "20900f1d317e0b10ebab7190a34265f52783ff4f85675398b497ab8eb3723a3c", + "index": 0 + } + ], + "outputs": [ + { + "address": "Kb9SqqTVA3XyQjZYb4wYrBVUeZWRKEQyzZ", + "coins": 2000000, + "hours": 0 + } + ], + "signatures": [ + "fa3ccaecf3a01525fd617fe74971ff2f7270e88f92f17a0f7748c1b258e007fd0fd10a582cc406d7806fd7794e20c4a3178b71cc1cb9f59c3c7d36a4e34d962100", + "23530a4d36d65cb37fc366a8c4a61d47dfd4fbf3b268bd66fd960bcff1b91db419d039049b8f816bedbd73d6baeaea77c5907c0df5b47724ad07420dd225cdaf01" + ], + "innerHash": "02b721422fcadeb8c3217d9b972c81fe9042a32871a180fb1237e213a543cc9d", + "block": 24, + "raw": "180100000002b721422fcadeb8c3217d9b972c81fe9042a32871a180fb1237e213a543cc9d02000000fa3ccaecf3a01525fd617fe74971ff2f7270e88f92f17a0f7748c1b258e007fd0fd10a582cc406d7806fd7794e20c4a3178b71cc1cb9f59c3c7d36a4e34d96210023530a4d36d65cb37fc366a8c4a61d47dfd4fbf3b268bd66fd960bcff1b91db419d039049b8f816bedbd73d6baeaea77c5907c0df5b47724ad07420dd225cdaf0102000000182b4c32bb5fe0e6809a19db63eecbeefde97a6c043b9248da94d428ab5a94c220900f1d317e0b10ebab7190a34265f52783ff4f85675398b497ab8eb3723a3c01000000002e32707e91eb71a2dc7517c70a877fed9faf7a6080841e00000000000000000000000000" + }, + { + "inputs": [ + { + "hash": "2987e7c89d353ad5d63cea2bf2724dc5f7a5ef5fb81f5ea160a307f0726ac2f5", + "index": 0 + }, + { + "hash": "a52408daa8ce7026c70b61d4df4212fb577462060f340bfce779225b3e18193d", + "index": 0 + }, + { + "hash": "dc73aac74348dd285a1456c1fae2204d7c2039d50a765bdaae0c31f7c7e059db", + "index": 0 + }, + { + "hash": "e4e375b9dc55ff53d6de9120f1a87ff00e00a779835f8320f2c6b3090d0466e6", + "index": 0 + }, + { + "hash": "d11b05345917d171f60c31bd2634041b73b97eae364724369ddb8d53369397fb", + "index": 0 + } + ], + "outputs": [ + { + "address": "R6aHqKWSQfvpdo2fGSrq4F1RYXkBWR9HHJ", + "coins": 50000000, + "hours": 7510 + } + ], + "signatures": [ + "efb713e6a1e5d328e94a51fbeb0f73e2a3b7a54e15db75797f0b709f698b16eb26e522f187a98144807e0e6cd294686ff19037975abb6d44b20b2899968954f400", + "b5d011c60020ce591a21db15823c06188515a63ca95d573c36b3af83d634fc6f1c1125db197f6283510ee33890ac168513254ad37524c77294bb5a12e8ff23f300", + "00d87b91eda33f627f6cd28cc673daf929fbec36e7bcfdf894f7491618a68b5755b5baadedc106d53d2da924fcbedbd106eadc50ec611d426720f67426c7286500", + "e64cf7e74363cfd381a3aa6fd17d7c415d6034b26b93017acaf9cf3475ccdffc53c3714d1d13409323cf77ccc81596f6e6edcec11d890979a436ef960bcb5f6900", + "fc2eb05241afdd15cdbd28cc7158d7eb4442f21a678c52332762b23ac6c2fcc76b0f79731987df0ba84d82044cd474d4cda9afda778a21b78a0659c5b588664301" + ], + "innerHash": "02e9a06b0ca7f91255107993e00f09e9ef983559088c5febff264c17952033c4", + "block": 99, + "raw": "3b0200000002e9a06b0ca7f91255107993e00f09e9ef983559088c5febff264c17952033c405000000efb713e6a1e5d328e94a51fbeb0f73e2a3b7a54e15db75797f0b709f698b16eb26e522f187a98144807e0e6cd294686ff19037975abb6d44b20b2899968954f400b5d011c60020ce591a21db15823c06188515a63ca95d573c36b3af83d634fc6f1c1125db197f6283510ee33890ac168513254ad37524c77294bb5a12e8ff23f30000d87b91eda33f627f6cd28cc673daf929fbec36e7bcfdf894f7491618a68b5755b5baadedc106d53d2da924fcbedbd106eadc50ec611d426720f67426c7286500e64cf7e74363cfd381a3aa6fd17d7c415d6034b26b93017acaf9cf3475ccdffc53c3714d1d13409323cf77ccc81596f6e6edcec11d890979a436ef960bcb5f6900fc2eb05241afdd15cdbd28cc7158d7eb4442f21a678c52332762b23ac6c2fcc76b0f79731987df0ba84d82044cd474d4cda9afda778a21b78a0659c5b588664301050000002987e7c89d353ad5d63cea2bf2724dc5f7a5ef5fb81f5ea160a307f0726ac2f5a52408daa8ce7026c70b61d4df4212fb577462060f340bfce779225b3e18193ddc73aac74348dd285a1456c1fae2204d7c2039d50a765bdaae0c31f7c7e059dbe4e375b9dc55ff53d6de9120f1a87ff00e00a779835f8320f2c6b3090d0466e6d11b05345917d171f60c31bd2634041b73b97eae364724369ddb8d53369397fb01000000003be2537f8c0893fddcddc878518f38ea493d949e80f0fa0200000000561d000000000000" + } + ] +} \ No newline at end of file diff --git a/src/gui/static/tsconfig.base.json b/src/gui/static/tsconfig.base.json new file mode 100644 index 0000000..b51dc29 --- /dev/null +++ b/src/gui/static/tsconfig.base.json @@ -0,0 +1,26 @@ +{ + "compileOnSave": false, + "angularCompilerOptions": { + "preserveWhitespaces": true + }, + "compilerOptions": { + "downlevelIteration": true, + "importHelpers": true, + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2016", + "dom" + ], + "module": "es2020", + "baseUrl": "./" + } +} \ No newline at end of file diff --git a/src/gui/static/tsconfig.json b/src/gui/static/tsconfig.json new file mode 100644 index 0000000..26abde9 --- /dev/null +++ b/src/gui/static/tsconfig.json @@ -0,0 +1,17 @@ +/* + This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience. + It is not intended to be used to perform a compilation. + + To learn more about this file see: https://angular.io/config/solution-tsconfig. +*/ +{ + "files": [], + "references": [ + { + "path": "./src/tsconfig.app.json" + }, + { + "path": "./src/tsconfig.spec.json" + } + ] +} \ No newline at end of file diff --git a/src/gui/static/tslint.json b/src/gui/static/tslint.json new file mode 100644 index 0000000..cc97d51 --- /dev/null +++ b/src/gui/static/tslint.json @@ -0,0 +1,160 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "deprecation": { + "severity": "warning" + }, + "eofline": true, + "forin": true, + "import-blacklist": [ + true + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 200 + ], + "member-access": false, + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + }, + { + "call-signature": "onespace", + "index-signature": "onespace", + "parameter": "onespace", + "property-declaration": "onespace", + "variable-declaration": "onespace" + } + ], + "typeof-compare": true, + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-module", + "check-separator", + "check-type", + "check-typecast", + "check-preblock" + ], + "directive-selector": [ + true, + "attribute", + "app", + "camelCase" + ], + "component-selector": [ + true, + "element", + "app", + "kebab-case" + ], + "no-inputs-metadata-property": true, + "no-outputs-metadata-property": true, + "no-host-metadata-property": true, + "no-input-rename": true, + "no-output-rename": true, + "use-lifecycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true, + "trailing-comma": [ + true, + { + "multiline": "always", + "esSpecCompliant": true + } + ], + "newline-before-return": true, + "space-before-function-paren": [true, "never"], + "prefer-method-signature": true + } +}