diff --git a/.gitignore b/.gitignore index dbf08213..2d5f8049 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -node_modules/* \ No newline at end of file +node_modules/* +tbin/* +.vscode/* \ No newline at end of file diff --git a/main.js b/main.js index f895a5ee..87e6f757 100644 --- a/main.js +++ b/main.js @@ -1,62 +1,314 @@ -const {app, BrowserWindow} = require('electron') -const path = require('path') -const url = require('url') -const ipc = require('electron').ipcMain +const {app, BrowserWindow, dialog, Tray, Menu} = require('electron'); +const path = require('path'); +const url = require('url'); +//const ipc = require('electron').ipcMain; +const https = require('https'); +const os = require('os'); +const crypto = require('crypto'); +const fs = require('fs'); +const Store = require('electron-store'); +const settings = new Store({name: 'Settings'}); -// 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 +const platform = os.platform; +const defaultFallbackNodes = [ + '127.0.0.1:11898', + 'public.turtlenode.io:11898', + 'public.turtlenode.net:11898', +]; +const defaultTitle = 'TurtleCoin Wallet'; +const isDebug = (process.argv[1] === 'debug' || process.argv[2] === 'debug'); +const publicNodesUrl = 'https://raw.githubusercontent.com/turtlecoin/turtlecoin-nodes-json/master/turtlecoin-nodes.json'; + +const binFilename = (platform === 'win32' ? 'turtle-service.exe' : 'turtle-service' ); +const defaultServiceBin = path.join(process.resourcesPath, binFilename); +console.log(`default turtle-service bin: ${defaultServiceBin}`); + +// default settings +var DEFAULT_SETTINGS = { + service_bin: defaultServiceBin, + service_host: '127.0.0.1', + service_port: 8070, + service_password: crypto.randomBytes(32).toString('hex'), + daemon_host: '127.0.0.1', + daemon_port: 11898, + pubnodes_date: null, + pubnodes_data: defaultFallbackNodes, + pubnodes_custom: [], + tray_minimize: false, + tray_close: false +} + +let win; +app.prompExit = true; +app.needToExit = false; function createWindow () { // Create the browser window. win = new BrowserWindow({ - title:'WalletShell', - icon: 'assets/walletshell_icon.png', - frame: false, - width: 800, - height: 600 - }) - - //load the index.html of the app. - win.loadURL(url.format({ - pathname: path.join(__dirname, 'src/html/index.html'), - protocol: 'file:', - slashes: true - })) - - // Open the DevTools. - // uncomment this line to enable dev tools, useful for debugging - //win.webContents.openDevTools() - - // Emitted when the window is closed. - win.on('closed', () => { - // Dereference the window object, usually you would store windows - // in an array if your app supports multi windows, this is the time - // when you should delete the corresponding element. - win = null - }) - - win.setMenu(null) + title: defaultTitle, + icon: path.join(__dirname,'src/assets/walletshell_icon.png'), + frame: true,//frame: false, + width: 800, + height: 680, + minWidth: 800, + minHeight: 680, + show: false, + backgroundColor: '#02853e', + }); + + const tray = new Tray(path.join(__dirname,'src/assets/trtl_tray.png')); + tray.setTitle(defaultTitle); + tray.setToolTip('Slow and steady wins the race!'); + let contextMenu = Menu.buildFromTemplate([ + { label: 'Minimize to tray', click: () => { win.hide(); }}, + { label: 'Quit', click: ()=> { + // if(!win.isVisible()) win.show(); + // if(win.isMinimized()) win.restore(); + // win.focus(); + app.needToExit = true; + win.close(); + } + } + ]); + tray.setContextMenu(contextMenu); + + tray.on('click', () => { + win.isVisible() ? win.hide() : win.show(); + }); + + win.on('show', () => { + tray.setHighlightMode('always'); + contextMenu = Menu.buildFromTemplate([ + { label: 'Minimize to tray', click: () => { win.hide();} }, + { label: 'Quit', click: ()=> { + // if(!win.isVisible()) win.show(); + // if(win.isMinimized()) win.restore(); + // win.focus(); + app.needToExit = true; + win.close(); + } + } + ]); + tray.setContextMenu(contextMenu); + }); + + win.on('hide', () => { + tray.setHighlightMode('never'); + contextMenu = Menu.buildFromTemplate([ + { label: 'Restore', click: () => { win.show();} }, + { label: 'Quit', click: ()=> { + // if(!win.isVisible()) win.show(); + // if(win.isMinimized()) win.restore(); + // win.focus(); + app.needToExit = true; + win.close(); + } + } + ]); + tray.setContextMenu(contextMenu); + }); + + win.on('minimize', (event) => { + if(settings.get('tray_minimize')){ + event.preventDefault(); + win.hide(); + } + }); + + //load the index.html of the app. + win.loadURL(url.format({ + pathname: path.join(__dirname, 'src/html/index.html'), + protocol: 'file:', + slashes: true + })); + + // open devtools + if(isDebug ) win.webContents.openDevTools(); + + // show windosw + win.once('ready-to-show', () => { + win.show(); + win.setTitle(defaultTitle); + }) + + win.on('close', (e) => { + if(settings.get('tray_close') && !app.needToExit){ + e.preventDefault(); + win.hide(); + }else if(app.prompExit){ + e.preventDefault(); + let msg = 'Are you sure?'; + if(wsession.loadedWalletAddress !== ''){ + msg = 'Close your wallet and exit?'; + } + dialog.showMessageBox({ + type: 'question', + buttons: ['Yes', 'No'], + title: 'Confirm', + message: msg + }, function (response) { + if (response === 0) { + app.prompExit = false; + win.webContents.send('cleanup','Clean it up, Dad!'); + }else{ + app.prompExit = true; + app.needToExit = false; + } + }); + } + }); + + win.on('closed', () => { + win = null; + }); + win.setMenu(null); + + // misc handler + win.webContents.on('crashed', (event, killed) => { + if(isDebug) console.log('webcontent was crashed', event, killed); + }); + + win.on('unresponsive', (even) => { + if(isDebug) console.log('unresponsive!'); + }); +} + +function storeNodeList(pnodes){ + pnodes = pnodes || settings.get('pubnodes_data'); + if( pnodes.hasOwnProperty('nodes')){ + global.wsession.nodeChoices = ['127.0.0.1:11898']; + pnodes.nodes.forEach(element => { + let item = `${element.url}:${element.port}`; + global.wsession.nodeChoices.push(item); + }); + } + settings.set('pubnodes_data', global.wsession.nodeChoices); +} + +function doNodeListUpdate(){ + https.get(publicNodesUrl, (res) => { + var result = ''; + res.setEncoding('utf8'); + + res.on('data', (chunk) => { + result += chunk; + }); + + res.on('end', () => { + try{ + var pnodes = JSON.parse(result); + let today = new Date(); + storeNodeList(pnodes); + if(isDebug) console.log('nodelist has been updated'); + let mo = (today.getMonth()+1); + settings.set('pubnodes_date', `${today.getFullYear()}-${mo}-${today.getDate()}`); + }catch(e){ + if(isDebug) console.log('failed to parse json data', e); + if(isDebug) console.log('type of input', typeof d); + if(isDebug) console.log(JSON.stringify(d)); + storeNodeList(); + } + }); + }).on('error', (e) => { + console.error(e); + }); +} + +function initSettings(){ + Object.keys(DEFAULT_SETTINGS).forEach((k) => { + if(!settings.has(k) || settings.get(k) === null){ + settings.set(k, DEFAULT_SETTINGS[k]); + } + }); } -// 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', createWindow) + +const silock = app.requestSingleInstanceLock() +app.on('second-instance', (commandLine, workingDirectory) => { + if (win) { + if (win.isMinimized()) win.restore(); + win.focus(); + } +}); +if (!silock) app.quit(); + +app.on('ready', () => { + initSettings(); + + global.wsession = { + loadedWalletAddress: '', + walletHash: '', + synchronized: false, + syncStarted: false, + serviceReady: false, + txList: [], + txLen: 0, + txLastHash: '', + txLastTimestamp: '', + tmpPath: app.getPath('temp'), + dataPath: app.getPath('userData'), + nodeFee: null, + nodeChoices: settings.get('pubnodes_data'), + servicePath: settings.get('service_bin'), + configUpdated: false, + uiStateChanged: false, + defaultTitle: defaultTitle, + debug: isDebug + }; + + if(isDebug) console.log('Running in debug mode'); + + let today = new Date(); + let last_checked = new Date(settings.get('pubnodes_date')); + diff_d = parseInt((today-last_checked)/(1000*60*60*24),10); + if(diff_d >= 1){ + console.log('Performing daily node list update.'); + doNodeListUpdate(); + }else{ + console.log('Node list is up to date.'); + storeNodeList(false); // from local cache + } + + createWindow(); +}); + +// app.on('before-quit', () => { +// connection.terminateWallet(); +// }) // Quit when all windows are closed. app.on('window-all-closed', () => { - // On macOS 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() - } -}) + // On macOS 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 macOS 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() - } -}) + // On macOS 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(); +}); + +process.on('uncaughtException', function (err) { + if(isDebug) console.log(err); + process.exit(1); +}); + +process.on('beforeExit', (code) => { + if(isDebug) console.log(`beforeExit code: ${code}`); +}); + +process.on('exit', (code) => { + if(isDebug) console.log(`exit with code: ${code}`); +}); + +process.on('warning', (warning) => { + if(isDebug){ + console.warn(warning.name); + console.warn(warning.message); + console.warn(warning.code); + console.warn(warning.stack); + console.warn(warning.detail); + } +}); + diff --git a/package-lock.json b/package-lock.json index e9185efe..a5ae1432 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,34 +1,36 @@ { "name": "walletshell", - "version": "0.1.0", + "version": "0.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@types/node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.2.tgz", - "integrity": "sha512-A6Uv1anbsCvrRDtaUXS2xZ5tlzD+Kg7yMRlSLFDy3z0r7KlGXDzL14vELXIAgpk2aJbU3XeZZQRcEkLkowT92g==", + "version": "8.10.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.29.tgz", + "integrity": "sha512-zbteaWZ2mdduacm0byELwtRyhYE40aK+pAanQk415gr1eRuu67x7QGOLmn8jz5zI8LDK7d0WI/oT6r5Trz4rzQ==", "dev": true }, - "JSONStream": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", - "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", - "requires": { - "jsonparse": "1.3.1", - "through": "2.3.8" - } + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accessibility-developer-tools": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz", + "integrity": "sha1-PaDM6dbsY3OWS4TzXbfPw996tRQ=", + "dev": true }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "ansi-regex": { @@ -43,35 +45,70 @@ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, + "asar": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/asar/-/asar-0.14.3.tgz", + "integrity": "sha512-+hNnVVDmYbv05We/a9knj/98w171+A94A9DNHj+3kXUr3ENTQoSEcfbJRvBBRHyOh4vukBYWujmHvvaMmQoQbg==", + "dev": true, + "requires": { + "chromium-pickle-js": "^0.2.0", + "commander": "^2.9.0", + "cuint": "^0.2.1", + "glob": "^6.0.4", + "minimatch": "^3.0.3", + "mkdirp": "^0.5.0", + "mksnapshot": "^0.3.0", + "tmp": "0.0.28" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "author-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", + "integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=", "dev": true }, "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 + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "balanced-match": { "version": "1.0.0", @@ -80,34 +117,74 @@ "dev": true }, "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", "dev": true, "requires": { - "hoek": "4.2.1" + "buffers": "~0.1.1", + "chainsaw": "~0.1.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 + }, "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", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "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 + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "dev": true + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -126,26 +203,34 @@ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" } }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=" + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true, + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, + "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 }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "code-point-at": { "version": "1.1.0", @@ -157,15 +242,21 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==" + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=", + "dev": true }, "concat-map": { "version": "0.0.1", @@ -174,14 +265,15 @@ "dev": true }, "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "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": { - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "typedarray": "0.0.6" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" }, "dependencies": { "isarray": { @@ -196,13 +288,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "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.2" + "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": { @@ -211,36 +303,33 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } } } }, + "conf": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-2.0.0.tgz", + "integrity": "sha512-iCLzBsGFi8S73EANsEJZz0JnJ/e5VZef/kSaxydYZLAvw0rFNAUx5R7K5leC/CXXR2mZfXWhUvcZOO/dM2D5xg==", + "requires": { + "dot-prop": "^4.1.0", + "env-paths": "^1.0.0", + "make-dir": "^1.0.0", + "pkg-up": "^2.0.0", + "write-file-atomic": "^2.3.0" + } + }, "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 + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "dev": true, - "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "dev": true, - "requires": { - "hoek": "4.2.1" - } - } - } + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=", + "dev": true }, "currently-unhandled": { "version": "0.4.1", @@ -248,16 +337,15 @@ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "1.0.2" + "array-find-index": "^1.0.1" } }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "debug": { @@ -275,137 +363,291 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decompress-zip": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz", + "integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=", + "dev": true, + "requires": { + "binary": "^0.3.0", + "graceful-fs": "^4.1.3", + "mkpath": "^0.1.0", + "nopt": "^3.0.1", + "q": "^1.1.2", + "readable-stream": "^1.1.8", + "touch": "0.0.3" + } + }, "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "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 }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "devtron": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/devtron/-/devtron-1.4.0.tgz", + "integrity": "sha1-tedIvW6Vu+cL/MaKrm/mlhGUQeE=", "dev": true, + "requires": { + "accessibility-developer-tools": "^2.11.0", + "highlight.js": "^9.3.0", + "humanize-plus": "^1.8.1" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "requires": { + "is-obj": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, "electron": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/electron/-/electron-1.8.4.tgz", - "integrity": "sha512-2f1cx0G3riMFODXFftF5AHXy+oHfhpntZHTDN66Hxtl09gmEr42B3piNEod9MEmw72f75LX2JfeYceqq1PF8cA==", + "version": "3.0.0-beta.8", + "resolved": "https://registry.npmjs.org/electron/-/electron-3.0.0-beta.8.tgz", + "integrity": "sha512-J5pPdqRFsaePNUJzKMlaqj9cLOlQ6W2Acmie7yviEh7D7Yjzi85dCaJ4IxmNxPtKAMgc4w1cQDwWyZ01uOhyjg==", "dev": true, "requires": { - "@types/node": "8.10.2", - "electron-download": "3.3.0", - "extract-zip": "1.6.6" + "@types/node": "^8.0.24", + "electron-download": "^4.1.0", + "extract-zip": "^1.0.3" } }, "electron-download": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-3.3.0.tgz", - "integrity": "sha1-LP1U1pZsAZxNSa1l++Zcyc3vaMg=", - "dev": true, - "requires": { - "debug": "2.6.9", - "fs-extra": "0.30.0", - "home-path": "1.0.5", - "minimist": "1.2.0", - "nugget": "2.0.1", - "path-exists": "2.1.0", - "rc": "1.2.6", - "semver": "5.5.0", - "sumchecker": "1.3.1" - } - }, - "electron-settings": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/electron-settings/-/electron-settings-3.1.4.tgz", - "integrity": "sha512-5AVJGE7+5Fwbui3PKs365vp/vGVpGGXlN1elBx/hAXVazmAtbY2jS0DOD7fBsVxzgCUiRCtR3tQvTF4cYLq/Sw==", - "requires": { - "clone": "2.1.1", - "jsonfile": "4.0.0" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.1.tgz", + "integrity": "sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==", + "dev": true, + "requires": { + "debug": "^3.0.0", + "env-paths": "^1.0.0", + "fs-extra": "^4.0.1", + "minimist": "^1.2.0", + "nugget": "^2.0.1", + "path-exists": "^3.0.0", + "rc": "^1.2.1", + "semver": "^5.4.1", + "sumchecker": "^2.0.2" + }, + "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" + } + }, + "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 + } + } + }, + "electron-osx-sign": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.10.tgz", + "integrity": "sha1-vk87ibKnWh3F8eckkIGrKSnKOiY=", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "compare-version": "^0.1.2", + "debug": "^2.6.8", + "isbinaryfile": "^3.0.2", + "minimist": "^1.2.0", + "plist": "^2.1.0" + } + }, + "electron-packager": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-12.1.1.tgz", + "integrity": "sha512-wBXmQjaMousBCA9JRikCtW1lj+kjJox6Ls+4V+AiUNX0DTgPG1oc1UfKBdwjbsgFuRIckvTZqucPk+Wdn0jV3A==", + "dev": true, + "requires": { + "asar": "^0.14.0", + "debug": "^3.0.0", + "electron-download": "^4.1.1", + "electron-osx-sign": "^0.4.1", + "extract-zip": "^1.0.3", + "fs-extra": "^5.0.0", + "galactus": "^0.2.1", + "get-package-info": "^1.0.0", + "nodeify": "^1.0.1", + "parse-author": "^2.0.0", + "pify": "^3.0.0", + "plist": "^2.0.0", + "rcedit": "^1.0.0", + "resolve": "^1.1.6", + "sanitize-filename": "^1.6.0", + "semver": "^5.3.0", + "yargs-parser": "^10.0.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" + } + }, + "electron-download": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.1.tgz", + "integrity": "sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==", + "dev": true, + "requires": { + "debug": "^3.0.0", + "env-paths": "^1.0.0", + "fs-extra": "^4.0.1", + "minimist": "^1.2.0", + "nugget": "^2.0.1", + "path-exists": "^3.0.0", + "rc": "^1.2.1", + "semver": "^5.4.1", + "sumchecker": "^2.0.2" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, + "fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "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" + } + }, + "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 + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "sumchecker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-2.0.2.tgz", + "integrity": "sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4=", + "dev": true, "requires": { - "graceful-fs": "4.1.11" + "debug": "^2.2.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" + } + } } } } }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, + "electron-store": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-2.0.0.tgz", + "integrity": "sha512-1WCFYHsYvZBqDsoaS0Relnz0rd81ZkBAI0Fgx7Nq2UWU77rSNs1qxm4S6uH7TCZ0bV3LQpJFk7id/is/ZgoOPA==", "requires": { - "is-arrayish": "0.2.1" + "conf": "^2.0.0" } }, - "es6-promise": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.2.tgz", - "integrity": "sha512-LSas5vsuA6Q4nEdf9wokY5/AJYXry98i0IzXsv49rYsgDGDNDPbqAYR1Pe23iFxygfbGZNR/5VrHXBCh2BhvUQ==" + "env-paths": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz", + "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=" }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "requires": { - "es6-promise": "4.2.2" + "is-arrayish": "^0.2.1" } }, "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extract-zip": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", - "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", + "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", "dev": true, "requires": { - "concat-stream": "1.6.0", + "concat-stream": "1.6.2", "debug": "2.6.9", - "mkdirp": "0.5.0", + "mkdirp": "0.5.1", "yauzl": "2.4.1" } }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" }, "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=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fd-slicer": { "version": "1.0.1", @@ -413,7 +655,7 @@ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "dev": true, "requires": { - "pend": "1.2.0" + "pend": "~1.2.0" } }, "find-up": { @@ -422,38 +664,86 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "flora-colossus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.0.tgz", + "integrity": "sha1-VHKcNh7ezuAU3UQWeeGjfB13OkU=", + "dev": true, + "requires": { + "debug": "^3.1.0", + "fs-extra": "^4.0.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" + } + }, + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "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" + } + } } }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "dev": true, "requires": { - "asynckit": "0.4.0", + "asynckit": "^0.4.0", "combined-stream": "1.0.6", - "mime-types": "2.1.18" + "mime-types": "^2.1.12" } }, "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.6.2" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "dependencies": { + "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" + } + } } }, "fs.realpath": { @@ -462,6 +752,119 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "galactus": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz", + "integrity": "sha1-y+0tIKQMH1Z5o1kI4rlBVzPnjbk=", + "dev": true, + "requires": { + "debug": "^3.1.0", + "flora-colossus": "^1.0.0", + "fs-extra": "^4.0.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" + } + }, + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "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" + } + } + } + }, + "get-package-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", + "integrity": "sha1-ZDJ5ZWPigRPNlHTbvQAFKYWkmZw=", + "dev": true, + "requires": { + "bluebird": "^3.1.1", + "debug": "^2.2.0", + "lodash.get": "^4.0.0", + "read-pkg-up": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -472,23 +875,22 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "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": { @@ -499,67 +901,57 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "ajv": "^5.3.0", + "har-schema": "^2.0.0" } }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "dev": true, - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.1", - "sntp": "2.1.0" - } - }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - }, - "home-path": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.5.tgz", - "integrity": "sha1-eIspgVsS1Tus9XVkhHbm+QQdEz8=", + "highlight.js": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz", + "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=", "dev": true }, "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==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", "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.4.1", - "sshpk": "1.14.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, + "humanize-plus": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/humanize-plus/-/humanize-plus-1.8.2.tgz", + "integrity": "sha1-pls0RZrWNnrbs3B6gqPJ+RYWcDA=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "inflight": { @@ -568,8 +960,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -596,7 +988,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-finite": { @@ -605,7 +997,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { @@ -614,14 +1006,24 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-promise": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", + "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=", + "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 + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", @@ -635,43 +1037,35 @@ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, + "isbinaryfile": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", + "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", + "dev": true, + "requires": { + "buffer-alloc": "^1.2.0" + } + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jayson": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-2.0.5.tgz", - "integrity": "sha512-ktzv96vpLjO0OXxHnlxyw9CIolAWau3InwdFnEfb4ctTD40HeEiLjIJbe3GGMmh3gwN2PjGAzPJuaAPmi8KYpw==", - "requires": { - "JSONStream": "1.3.2", - "commander": "2.13.0", - "es6-promisify": "5.0.0", - "eyes": "0.1.8", - "json-stringify-safe": "5.0.1", - "lodash": "4.17.4" - } + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, "optional": true }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" }, "json-stringify-safe": { "version": "5.0.1", @@ -684,19 +1078,13 @@ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" - }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -710,7 +1098,7 @@ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.9" } }, "load-json-file": { @@ -719,17 +1107,39 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } } }, "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true }, "loud-rejection": { "version": "1.6.0", @@ -737,8 +1147,23 @@ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } } }, "map-obj": { @@ -753,31 +1178,29 @@ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" + "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" } }, "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==" }, "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", + "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", "requires": { - "mime-db": "1.33.0" + "mime-db": "~1.36.0" } }, "minimatch": { @@ -786,7 +1209,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -796,9 +1219,9 @@ "dev": true }, "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" @@ -812,22 +1235,73 @@ } } }, + "mkpath": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", + "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=", + "dev": true + }, + "mksnapshot": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.3.1.tgz", + "integrity": "sha1-JQHAVldDbXQs6Vik/5LHfkDdN+Y=", + "dev": true, + "requires": { + "decompress-zip": "0.3.0", + "fs-extra": "0.26.7", + "request": "^2.79.0" + }, + "dependencies": { + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "nodeify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nodeify/-/nodeify-1.0.1.tgz", + "integrity": "sha1-ZKtpp7268DzhB7TwM1yHwLnpGx0=", + "dev": true, + "requires": { + "is-promise": "~1.0.0", + "promise": "~1.3.0" + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, "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==", "dev": true, "requires": { - "hosted-git-info": "2.6.0", - "is-builtin-module": "1.0.0", - "semver": "5.5.0", - "validate-npm-package-license": "3.0.3" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "nugget": { @@ -836,12 +1310,12 @@ "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=", "dev": true, "requires": { - "debug": "2.6.9", - "minimist": "1.2.0", - "pretty-bytes": "1.0.4", - "progress-stream": "1.2.0", - "request": "2.85.0", - "single-line-log": "1.1.2", + "debug": "^2.1.3", + "minimist": "^1.1.0", + "pretty-bytes": "^1.0.2", + "progress-stream": "^1.1.0", + "request": "^2.45.0", + "single-line-log": "^1.1.2", "throttleit": "0.0.2" } }, @@ -852,10 +1326,9 @@ "dev": true }, "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-assign": { "version": "4.1.1", @@ -875,7 +1348,43 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" + } + }, + "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=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "parse-author": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", + "integrity": "sha1-00YL8d3Q367tQtp1QkLmX7aEqB8=", + "dev": true, + "requires": { + "author-regex": "^1.0.0" } }, "parse-json": { @@ -884,7 +1393,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-exists": { @@ -893,7 +1402,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-is-absolute": { @@ -902,15 +1411,21 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "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 + }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pend": { @@ -922,8 +1437,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "2.3.0", @@ -943,7 +1457,44 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + } + } + }, + "plist": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-2.1.0.tgz", + "integrity": "sha1-V8zbeggh3yGDEhejytVOPhRqECU=", + "dev": true, + "requires": { + "base64-js": "1.2.0", + "xmlbuilder": "8.2.2", + "xmldom": "0.1.x" + }, + "dependencies": { + "base64-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz", + "integrity": "sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE=", + "dev": true + } } }, "pretty-bytes": { @@ -952,8 +1503,8 @@ "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", "dev": true, "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" + "get-stdin": "^4.0.1", + "meow": "^3.1.0" } }, "process-nextick-args": { @@ -968,43 +1519,72 @@ "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=", "dev": true, "requires": { - "speedometer": "0.1.4", - "through2": "0.2.3" + "speedometer": "~0.1.2", + "through2": "~0.2.3" } }, + "promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-1.3.0.tgz", + "integrity": "sha1-5cyaTIJ45GZP/twBx9qEhCsEAXU=", + "dev": true, + "requires": { + "is-promise": "~1" + } + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, + "qr-image": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz", + "integrity": "sha1-n6gpW+rlDEoUnPn5CaHbRkqGcug=" + }, "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "rc": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", - "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", + "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.4.2", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" } }, + "rcedit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-1.1.0.tgz", + "integrity": "sha512-JkXJ0IrUcdupLoIx6gE4YcFaMVSGtu7kQf4NJoDJUnfBZGuATmJ2Yal2v55KTltp+WV8dGr7A0RtOzx6jmtM6Q==", + "dev": true + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -1013,8 +1593,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "readable-stream": { @@ -1023,10 +1603,10 @@ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "redent": { @@ -1035,8 +1615,8 @@ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" } }, "repeating": { @@ -1045,37 +1625,61 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "request": { - "version": "2.85.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", - "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "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" + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "^4.13.1" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" + } + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", "dev": true, "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.2.1" + "path-parse": "^1.0.5" } }, "rimraf": { @@ -1084,26 +1688,38 @@ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sanitize-filename": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz", + "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=", + "dev": true, + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", "dev": true }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "single-line-log": { "version": "1.1.2", @@ -1111,16 +1727,7 @@ "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=", "dev": true, "requires": { - "string-width": "1.0.2" - } - }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", - "dev": true, - "requires": { - "hoek": "4.2.1" + "string-width": "^1.0.1" } }, "spdx-correct": { @@ -1129,8 +1736,8 @@ "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-expression-parse": "3.0.0", - "spdx-license-ids": "3.0.0" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { @@ -1145,8 +1752,8 @@ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { - "spdx-exceptions": "2.1.0", - "spdx-license-ids": "3.0.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { @@ -1162,20 +1769,25 @@ "dev": true }, "sshpk": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", - "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", - "dev": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - } + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, "string-width": { "version": "1.0.2", @@ -1183,9 +1795,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -1194,19 +1806,13 @@ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -1215,7 +1821,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "strip-indent": { @@ -1224,7 +1830,7 @@ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "4.0.1" + "get-stdin": "^4.0.1" } }, "strip-json-comments": { @@ -1234,13 +1840,12 @@ "dev": true }, "sumchecker": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-1.3.1.tgz", - "integrity": "sha1-ebs7RFbdBPGOvbwNcDodHa7FEF0=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-2.0.2.tgz", + "integrity": "sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4=", "dev": true, "requires": { - "debug": "2.6.9", - "es6-promise": "4.2.2" + "debug": "^2.2.0" } }, "throttleit": { @@ -1249,50 +1854,87 @@ "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, "through2": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", "dev": true, "requires": { - "readable-stream": "1.1.14", - "xtend": "2.1.2" + "readable-stream": "~1.1.9", + "xtend": "~2.1.1" } }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "tmp": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz", + "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "touch": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", + "integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=", "dev": true, "requires": { - "punycode": "1.4.1" + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "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" } }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "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-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { - "safe-buffer": "5.1.1" + "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=", - "dev": true, "optional": true }, "typedarray": { @@ -1301,6 +1943,18 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "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 + }, + "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", @@ -1308,30 +1962,28 @@ "dev": true }, "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", - "dev": true + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "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==", + "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" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "wrappy": { @@ -1340,13 +1992,52 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "xmlbuilder": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", + "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=", + "dev": true + }, + "xmldom": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", + "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=", + "dev": true + }, "xtend": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", "dev": true, "requires": { - "object-keys": "0.4.0" + "object-keys": "~0.4.0" + } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } } }, "yauzl": { @@ -1355,7 +2046,7 @@ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", "dev": true, "requires": { - "fd-slicer": "1.0.1" + "fd-slicer": "~1.0.1" } } } diff --git a/package.json b/package.json index 685b6e2d..8bca2f31 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,25 @@ { "name": "walletshell", - "version": "0.1.0", + "productName": "trtlwalletshell", + "version": "0.3.0", "description": "", "main": "main.js", "scripts": { - "start": "electron ." + "start": "electron .", + "debug": "electron . debug" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { - "electron": "^1.8.4" + "devtron": "^1.4.0", + "electron": "^3.0.0-beta.8", + "electron-packager": "^12.1.1" }, "dependencies": { - "electron-settings": "^3.1.4", - "jayson": "^2.0.5" + "electron-store": "^2.0.0", + "qr-image": "^3.2.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5" } } diff --git a/assets/background.png b/src/assets/background.png similarity index 100% rename from assets/background.png rename to src/assets/background.png diff --git a/assets/fonts/roboto-v18-latin-ext_latin-italic.woff b/src/assets/fonts/roboto-v18-latin-ext_latin-italic.woff similarity index 100% rename from assets/fonts/roboto-v18-latin-ext_latin-italic.woff rename to src/assets/fonts/roboto-v18-latin-ext_latin-italic.woff diff --git a/assets/fonts/roboto-v18-latin-ext_latin-italic.woff2 b/src/assets/fonts/roboto-v18-latin-ext_latin-italic.woff2 similarity index 100% rename from assets/fonts/roboto-v18-latin-ext_latin-italic.woff2 rename to src/assets/fonts/roboto-v18-latin-ext_latin-italic.woff2 diff --git a/assets/fonts/roboto-v18-latin-ext_latin-regular.woff b/src/assets/fonts/roboto-v18-latin-ext_latin-regular.woff similarity index 100% rename from assets/fonts/roboto-v18-latin-ext_latin-regular.woff rename to src/assets/fonts/roboto-v18-latin-ext_latin-regular.woff diff --git a/assets/fonts/roboto-v18-latin-ext_latin-regular.woff2 b/src/assets/fonts/roboto-v18-latin-ext_latin-regular.woff2 similarity index 100% rename from assets/fonts/roboto-v18-latin-ext_latin-regular.woff2 rename to src/assets/fonts/roboto-v18-latin-ext_latin-regular.woff2 diff --git a/assets/logo_translucent.png b/src/assets/logo_translucent.png similarity index 100% rename from assets/logo_translucent.png rename to src/assets/logo_translucent.png diff --git a/src/assets/tray.png b/src/assets/tray.png new file mode 100644 index 00000000..d39552f5 Binary files /dev/null and b/src/assets/tray.png differ diff --git a/src/assets/trtl_tray.png b/src/assets/trtl_tray.png new file mode 100644 index 00000000..a12b20be Binary files /dev/null and b/src/assets/trtl_tray.png differ diff --git a/assets/turtle_shield.svg b/src/assets/turtle_shield.svg similarity index 100% rename from assets/turtle_shield.svg rename to src/assets/turtle_shield.svg diff --git a/src/assets/walletshell_icon.icns b/src/assets/walletshell_icon.icns new file mode 100644 index 00000000..5b8e4d1d Binary files /dev/null and b/src/assets/walletshell_icon.icns differ diff --git a/assets/walletshell_icon.png b/src/assets/walletshell_icon.png similarity index 100% rename from assets/walletshell_icon.png rename to src/assets/walletshell_icon.png diff --git a/src/css/about.css b/src/css/about.css deleted file mode 100644 index 280881e8..00000000 --- a/src/css/about.css +++ /dev/null @@ -1,12 +0,0 @@ -.div-about-address { - position: relative; - top: 15px; - left: 2.5%; - width: 95%; -} - -#text-about-address { - font-size: 0.86em; - bottom: 15px; - width: 100%; -} \ No newline at end of file diff --git a/src/css/auto-complete.css b/src/css/auto-complete.css new file mode 100644 index 00000000..4261b1d0 --- /dev/null +++ b/src/css/auto-complete.css @@ -0,0 +1,9 @@ +.autocomplete-suggestions { + text-align: left; cursor: default; border: 1px solid #ccc; border-top: 0; background: #fff; box-shadow: -1px 1px 3px rgba(0,0,0,.1); + + /* core styles should not be changed */ + position: absolute; display: none; z-index: 9999; max-height: 254px; overflow: hidden; overflow-y: auto; box-sizing: border-box; +} +.autocomplete-suggestion { position: relative; padding: 0 .6em; line-height: 23px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 1.02em; color: #333; } +.autocomplete-suggestion b { font-weight: normal; color: #1f8dd6; } +.autocomplete-suggestion.selected { background: #f0f0f0; } diff --git a/src/css/common.css b/src/css/common.css index b072cb63..dd5efae9 100644 --- a/src/css/common.css +++ b/src/css/common.css @@ -1,23 +1,222 @@ -/* Title */ -/* used for the overview sub tabs */ -.div-title { - width: 90%; +/* Style page content */ +html, body{ + overflow: hidden; + height: 100%; +} +body { + transition: all 0.15s ease; + color: white; +} + +.main { + margin-left: 200px; + padding: 0px 10px; +} + +body { + min-width: 800px; + min-height: 400px; + background-image: url("../assets/background.png"); + background-size: cover; + font-family: 'Roboto', sans-serif; + margin: 0; +} +::placeholder { + color: rgba(234, 234, 234, 0.35); + } +@keyframes fade { + 0%,100% { opacity: 0 } + 50% { opacity: 1 } +} + +.image-container { + position: relative; + width: 75%; + top: 220px; + left: 12.5%; + text-align: center; +} + +.image-container img { + vertical-align: middle; + width: 75%; + height: auto; + max-width: 600px; + text-align: center; +} + +/* The titlebar */ +.titlebar { + z-index: 1; + position: fixed; + top: 0; + left: 0; + right: 0; + width: 100%; height: 30px; + /* Make it draggable */ + -webkit-user-select: none; + -webkit-app-region: drag; + cursor: default; + pointer-events: none; + background-color: #101310; + border-bottom: 1px solid #ffffff78; } -.title { - left: 2%; +.titlebar-title { + bottom: 11px; position: relative; - text-align: left; + text-align: center; font-weight: bold; font-family: 'Roboto', sans-serif; + color: #ffffff; + -webkit-user-select: none; + -webkit-app-region: drag; +} + +/* Titlebar buttons */ +.titlebar-button { + top: 3px; + width: 24px; + height: 24px; + position: absolute; + cursor: default; + pointer-events: all; + -webkit-app-region: no-drag; + text-align: center; color: white; + font-size: 115%; + transition: color 0.2s; + background:transparent; + border:none; + -webkit-user-select: none; +} + +.titlebar-button:focus { + outline: none; +} + +.titlebar-button:hover { + color: #b3b3b3; +} + +.titlebar-button:active { + color: #fffb00; +} + +#titlebar-button-minimize { + right: 75px; +} + +#titlebar-button-maximize { + right: 40px; +} + +#titlebar-button-restore { + right: 40px; +} + +#titlebar-button-close { + right: 5px; +} + +#titlebar-button-settings { + left: 5px; +} + +#titlebar-button-about { + left: 40px; +} + +#titlebar-button-help { + left: 75px; +} + +/* Top navigation bar */ +.navbar { + z-index: 1; + position: fixed; + /* top: 31px; */ + top: 0px; + height: 45px; + width: 100%; + margin: 0; + padding: 0; + overflow: hidden; + background-color: #212721; +} + +#navbar-div-sync { + display: inline; + position: relative; + color: #ff0000; + top: 15px; + left: 10px; +} + +.navbar-button { + height: 45px; + /* width: 140px; */ + padding: 0 14px; + float: right; + color: white; + display: block; + text-align: center; + font-size: 0.98rem; + font-family: 'Roboto', sans-serif; + text-transform: uppercase; + /* padding: 10px 2px; */ + background-color: #212721; + /* transition: background-color 0.2s; */ + + border: none; + text-shadow: -1px -1px 0 #333; +} + +.navbar-button:hover { + background-color: #4d524d; +} + +.navbar-button:focus { + outline: none; +} + +.navbar-button:active, +.navbar-button.btn-active{ + background-color: #4d524d; +} + +.navbar-button .navbar-label{ + display: none; +} +.navbar-button.btn-active .navbar-label{ + display: inline-block; +} + + +#main-div { + width: 99.6%; + height: 88.5%; + position: relative; + top:0; + /* margin: -130px 0 0 0; */ + /* margin: -14.5% 0 0 0; */ + margin: -15.5% 0 0 0; + padding: 0; +} + +.title { + font-weight: normal; + font-family: 'Roboto', sans-serif; + color: #fff; + font-size: 1.85rem; + text-shadow: 0px -1px 1px #333; + margin-top: 0; } /* Text */ .text-block { font-family: 'Roboto', sans-serif; - position: relative; padding: 12px 20px; margin: 8px 0; display: block; @@ -28,52 +227,108 @@ background-color: rgba(255,255,255,0.25); } + +input, textarea{ + width: 98.5%; +} +textarea{ + resize: none; +} +input.short-number{ + width: auto; + max-width: 200px; +} + +.input-wrap h4{ + margin-bottom: 0rem; +} +.default-textarea{ + font-family: 'Roboto', sans-serif; + padding: 12px 20px; + margin: 8px 0; + display: block; + border: 1px solid #ccc; + border-radius: 4px; + box-sizing: border-box; + color: white; + background-color: rgba(255,255,255,0.25); + font-size: 1rem; +} + .text-block:disabled { border: 1px solid rgba(204,204,204,0.5); background-color: rgba(255,255,255,0.125); color: rgba(255,255,255,0.5); } + +.form-ew{ + text-shadow: -1px 0 0 #333; + line-height: 150%; + display: inline-block; + color: #fff; + /* -webkit-transition: opacity 3s ease-in-out; + -moz-transition: opacity 3s ease-in-out; + -ms-transition: opacity 3s ease-in-out; + -o-transition: opacity 3s ease-in-out; */ + opacity: 1; + visibility: visible; + font-size: 0.9rem; + padding: 2px 4px; + margin-top: 0.5rem; +} + + +.form-ew.fade{ + visibility: hidden; + opacity: 0; + -webkit-transition: visibility 0s 2s, opacity 2s ease-out; + transition: visibility 0s 2s, opacity 2s ease-out; +} + .text-spaced { margin: 8px 0px; letter-spacing: 1px; } + + .text-spaced-bold { letter-spacing: 1px; font-weight: bold; - text-shadow: 1px 2px #000000; + } .text-spaced-error { letter-spacing: 1px; - color: #ff0000; + background:rgba(203, 0, 0, 1); font-weight: bold; - text-shadow: 1px 2px #000000; + padding: 2px 3px; + opacity: 1; } .text-spaced-warning { letter-spacing: 1px; - color: #fffb00; - font-weight: bold; - text-shadow: 1px 2px #000000; + background:#d14500; + font-weight: bold; + display: inline-grid; + opacity: 1; } .text-spaced-success { letter-spacing: 1px; - color: #79ff2c; + background: #00662f; font-weight: bold; - text-shadow: 1px 2px #000000; + opacity: 1; } /* Buttons */ .div-panel-buttons { white-space: nowrap; - display: inline; - position: fixed; - top: 90%; - left: 50%; - transform: translate(-50%, -50%); + display: block; + text-align:right; + margin: 1rem 0 0 0; + } .div-buttons { @@ -83,8 +338,12 @@ top: 95%; left: 50%; transform: translate(-50%, -50%); + margin-right: .5rem; } +.div-buttons button{ + margin-right: 0.35rem; +} .button-green { padding: 8px 12px; border: 2px solid #ccc; @@ -110,6 +369,8 @@ .button-green:focus { outline: none; + transition: all 0.15s ease; + box-shadow: 4px 4px 4px rgba(0,0,0,.29), inset 0px 0px 4px rgba(0,0,0, .5); } .button-red { @@ -126,7 +387,7 @@ transition: all 0.15s ease; } -.button-red:hover { +.button-red:hover, .button-red:focus { transition: all 0.15s ease; box-shadow: 4px 4px 4px rgba(0,0,0,.29), inset 0px 0px 4px rgba(0,0,0, .5); } @@ -193,10 +454,10 @@ bottom: 0; overflow: hidden; font-family: 'Roboto', sans-serif; - height: 95%; - min-width: 800px; /* maybe 800px is too much? */ + height: 99%; + min-width: 797.3px; /* maybe 800px is too much? */ min-height: 400px; - + padding: 0; /* Hidden by default */ pointer-events: none; visibility: hidden; @@ -213,6 +474,50 @@ transition: visibility 0s 0s linear , opacity .36s ease-out, transform .36s ease-out; } +.section > div{ + position: relative; + width: 87.7%; + margin: 0 auto; + height: 92.9%; +} +.section-contents{ + padding: 1rem 3rem 0 3rem; +} +.welcome-box{ +width: 80%; +margin: 0 auto; +text-align: center; +} + +.div-welcome-top{ +margin-top: 0.5rem; +text-align: center; +} + +.welcome-intro-title{ +font-weight: normal; +font-size: 3rem !important; +text-shadow: 0px -1px 1px #333; +} + +.welcome-intro{ +font-size: 1.5rem; +text-shadow: 0px -1px 0px #333; +} + +.dev-welcome-bottom{ +position: absolute; +bottom: 18%; +left: 0; +width: 100%; +text-align: center; + +} +.welcome-buttons{ +display: block; +margin: 1rem auto 0 auto; +} + /* Fields */ .div-fields { position: relative; @@ -226,11 +531,14 @@ padding: 0px; table-layout: fixed; width: 100%; - border-spacing: 5px; + border-spacing: 3px; + background: rgba(255,255,255,0.2); + border: none; + border-radius: 3px; } .custom-table td { - padding: 2px; + padding: 4px 8px; } .custom-table tr:nth-child(odd) { @@ -241,27 +549,33 @@ background-color: rgba(0, 0, 0, 0.5); } +.custom-table tr th{ + background: rgba(0,0,0,0.5); + padding: 0.35rem 0; +} + /* Controllers */ /* Checkbox */ .checkbox-container { display: inline-block; position: relative; padding-left: 35px; - margin-bottom: 12px; + margin:0; cursor: pointer; user-select: none; } .checkbox-container .checkbox-text { position: relative; - bottom: 4px; + bottom: 5px; } -/* Hide the browser's default checkbox */ .checkbox-container input { position: absolute; opacity: 0; cursor: pointer; + top: 6px; + left: -50px; } .checkmark { @@ -272,7 +586,7 @@ width: 22px; background-color: #ccc; border-radius: 5px; - border: 2px solid #212721; + border: 1px solid rgba(255,255,255,0.5); transition: background-color 0.2s; } @@ -305,6 +619,7 @@ } /* Combo Box */ +/* .combo { position: relative; bottom: 3px; @@ -323,3 +638,535 @@ font-size: 15px; height: 25px; } +*/ + +.input-wrap{ + margin: 1rem 0 0 0; + clear: both; +} + +.input-wrap.button-wrap{ + text-align: center; + margin-top: 2.2rem; + padding:0; /* 1.6rem 0; */ + clear: both; +} +.input-wrap h2{ + margin-bottom: 0; +} + +.input-wrap input{ + margin-bottom: 0 !important; + line-height: normal !important; +} +.form-help{ + font-size: 0.9rem; + font-style: italic; + display: inline-block; + color: rgba(255,255,255,0.75); + margin: 0.2rem 0 0 0; +} + +.help-hl{ + color: rgba(255,255,255,1.0); +} + +.float-wrap{ + overflow: hidden; + height: 100%; +} +.float-col{ + float:left; + width: 45%; +} +.qr-wrap{ +display: block; +} + +.qr-col{ + margin-top: 0.5rem; + text-align: right; + padding: 1rem 1rem 0 0; + float: right; +} + +.qr-col img{ + max-width: 350px; + height: auto; +} + +span.form-help-qr{ + display: block; + color: rgba(255,255,255,0.85); + margin-top: 0; +} + + +.default-dialog{ + width: 500px; + max-width: 80%; + background: #004720; + color: #fff; + border: 2px solid #fff; + padding: 0 1rem; + transition: visibility 0s 2s, opacity 2s linear; + border-radius:4px; +} + +.default-dialog.dialog-warning{ + background: #d67c2e; +} + +.default-dialog h5{ + margin: 0.5rem 0; + font-size: 1.5rem; +} +.default-dialog p{ + line-height: 150%; +} + +.tx-dialog{ + background-color: #004720; + background-image: url("../assets/background.png"); + background-size: cover; + width: 90%; + max-width: 1000px; + border: 1px solid #ccc; + border-radius:4px; + + +} +.tx-dialog table{ + font-size:0.85rem; +} +.tx-dialog table th[scope="col"]{ + width: 18%; + text-align:left; + padding: 0.25rem 1rem; + color: #fff; + font-weight:normal; +} + +.tx-dialog table th, +.tx-dialog table td{ + white-space:pre-wrap; + overflow:hidden; + text-overflow:ellipsis; + color: #fff; +} +.tx-dialog h4{ + margin: 0rem 0 0.5rem 0; + font-size: 1.2rem; + color: #fff; + text-shadow: 0px -1px 1px #333; +} + +dialog::backdrop{ + background: rgba(0,25,15,0.70); +} + + + + + +span.form-help-qr.hidden{ + display: none; +} + +.status-node-info{ + width: 100%; + padding: 0.25rem 2rem; + font-size: 0.85rem; + color: #fefefe; + background: rgba(0,25,15,0.70); + position: absolute; + /* top: 75px; */ + top: 45px; + left: 0; +} +.status-node-info.conn-warning{ + background: rgba(255, 0, 0, 0.7); +} +#status-node-addr, #status-node-fee{ + font-weight: 600; + color: #fff; +} + + +/* from import */ + +.path-input { + width: 90%; + display: inline-block; + margin-right: 0.25rem; +} + +.path-input-button,.button-browse { + display: inline-block; +} + +.inline-block-div { + display: inline-block; + position: relative; +} + +.inline-block-div.half-width{ + width: 47.7%; + height: 70px; +} + +.inline-block-div.half-width-end{ + left: 12px; +} + +.inline-block-div.half-width > input{ + width:100%; + font-size: 1 +} + +.section-wrap{ + padding: 1.5rem 2rem 1rem 2rem; +} + + +.div-half-width{ + float:left; + width: 47%; + margin-right: 1.2rem; +} +.div-half-width:last-child{ + margin-right: 0; + float:right; +} + +.div-half-width > input{ + width: 100%; +} + +.float-wrap > h3{ + margin-bottom: 0; +} + + +/* syncsyncsync */ +#navbar-div-sync{ + color: #fefefe; + letter-spacing: 1px; + font-weight: bold; +} + +#navbar-div-sync.failed{ + color: #ff0000; +} + +#navbar-div-sync.syncing{ + color: #fffb00; +} +#navbar-div-sync.synced{ + color: #79ff2c; + /* #54ff54 */ +} + +#datoaste{ + max-width: 300px !important; +} + +.hidden{ + opacity: 0; + display: none; + visibility: hidden; +} + + +/** TRX **/ +.transaction-header-wrap h4{ + text-shadow: 0px -1px 1px #333; +} +.div-transactions-page { + float:left; + width: 45%; + height: 30px; +} + +.div-transactions-sort { + float: right; + width: 40%; + height: 30px; +} + +.trx-sort-label{ + display: inline-block; +} + +.trx-sort-select{ + display: inline-block; + border: 1px solid rgba(255, 255, 255, 0.5); + border-radius: 3px; + background-color: rgba(84, 255, 84, 0.1); + padding: 0px 0px 1px 6px; +} + +.trx-sort-select select{ + font-family: 'Roboto', sans-serif; + background: transparent; + border: none; + font-size: 1rem; + font-weight: 500; + color: #194725; +} +.trx-sort-button{ + padding: 0px 4px; +} +/* +#button-transactions-sort { + position: relative; + float: right; + height: 25px; + width: 25px; + left: 41%; + bottom: 1px; + font-size: 1.35em; +} + +#icon-transactions-sort { + position: relative; + margin: 0; + padding: 0; + right: 9px; + bottom: 10px; +} +*/ + +.div-transactions-table { + width: 100%; + margin-top: 5rem; + padding: 0; + clear: both; +} + +#transactions-table:hover { + cursor: pointer; +} + +.div-transactions-row-txamount, +.div-transactions-row-txdate{ + display: inline-block; + width: 25%; +} +.div-transactions-row-txdate { + font-size: 0.83em; +} + +.div-transactions-row-txhash, +.div-transactions-row-txpayid{ + display: inline-block; + width: 73%; + font-size: 0.83em; + display: inline-block; + width: 73%; + font-size: 0.83em; + text-overflow:ellipsis; + overflow:hidden; + white-space: nowrap +} + +.div-transactions-row-txamount{ + font-size: 0.9rem; +} + + +.tx-in .div-transactions-row-txamount{ + color: #88e000; + font-weight: bold; + +} + + +.tx-out .div-transactions-row-txamount{ + color: #FF9800; + font-weight: bold; +} + +.noborder{ + border: none !important; +} + +.progfiller{ + text-align: center; + width: 90%; + margin: 0.25rem auto; +} + +.progfiller span{ + display: block; + font-size: 0.75rem; +} + +.scroll-list-wrap{ + min-height: 300px; + +} + +.address-table-wrapper{ + +} + +.addressbook-list .search{ + width: 100%; + font-size: 1rem; + padding: 0.3rem 0.5em; +} + +.addressbook-list .pagination{ + margin: 0.25rem 0 0 0; + text-align:right; +} + +.addressbook-list .pagination li{ + display: inline-block; + background-color: #00632e; + color: #fff; + padding: 0px 8px; + margin: 0 4px 0 0; + text-align: center; + line-height: normal !important; + border-radius: 4px; + border: 1px solid rgba(255,255,255,0.5); +} + +.addressbook-list .pagination li.active{ + background-color: #212721; +} + + +.addressbook-list .pagination li a{ + color: #fff; + font-size: 1.2rem; + font-weight: 600; + text-decoration: none; + +} + + +.pagination.single-page{ + display: none !important; +} + +.addressbook-table th{ + cursor: pointer; +} +.addressbook-table tr td{ + /* word-wrap: break-word; */ +} + +.addressbook-table tr[data-hash="null"]{ + display: none; +} + +.addressbook-table td.addressName{ + font-weight: 600; + cursor: pointer; + width: 15%; + word-wrap:break-word; +} +.addressbook-table td.addressWallet, +.addressbook-table td.addressPaymentId{ + text-overflow:ellipsis; + overflow:hidden; + font-size: 0.75rem; +} + +.address-book-dialog{ + max-height: 95%; + width: 90%; + max-width: 1280px; + padding-bottom: 1rem; + border: 1px solid #ccc; + border-radius:4px; + +} + +.address-book-dialog .addressBookDetail{ + overflow:hidden; + height:100%; + padding-bottom: 1rem; +} + +.address-book-dialog .div-panel-buttons{ + +} + +.addressBookDetail-qr{ + float:left; + width: 25%; + margin-right: 1rem; +} +.addressBookDetail-qr img{ + width:100%; + height: auto; + + border-radius: 3px; +} +.addressBookDetail-data{ + float: left; + width: 72%; + word-wrap: break-word; +} + +.addressBookDetail-data dl{ + margin: 0; + padding: 0; + font-size:0.85rem + +} + +.addressBookDetail-data dt{ + font-weight: normal; + margin:0; + padding:0; + +} + +.addressBookDetail-data dd{ + margin: 0 0 1rem 0; + overflow:hidden; + text-overflow: ellipsis; + font-weight:600 +} + +.autocomplete-wallet-addr{ + font-size:0.7rem; + display:inline-block; + padding-bottom:0.2rem; +} + +div.about-links{ + margin-top: 2rem; +} + +div.about-links a{ + color: #fefefe; + text-decoration:none; + font-weight:600; + font-size: 1rem; + border:1px solid #fefefe; + padding: 8px 8px; + border-radius: 4px; + background: #004720; + line-height:normal; +} + + +@media only screen and (max-width : 780px) { + .section > div, .section-contents{ + width: 81.4%; + padding: 2rem 1rem 0 1rem; + margin: 0; + } +} + +@media only screen and (min-width : 1400px) { + .section-contents{ + padding: 10% 3rem 0 3rem; + } +} \ No newline at end of file diff --git a/src/css/font-Roboto.css b/src/css/font-Roboto.css index 6335a117..737ebf27 100644 --- a/src/css/font-Roboto.css +++ b/src/css/font-Roboto.css @@ -7,8 +7,8 @@ all credits to him and Google for the font */ font-style: normal; font-weight: 400; src: local('Roboto'), local('Roboto-Regular'), - url('../../assets/fonts/roboto-v18-latin-ext_latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ - url('../../assets/fonts/roboto-v18-latin-ext_latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ + url('../assets/fonts/roboto-v18-latin-ext_latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ + url('../assets/fonts/roboto-v18-latin-ext_latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ } /* roboto-italic - latin-ext_latin */ @@ -17,6 +17,6 @@ all credits to him and Google for the font */ font-style: italic; font-weight: 400; src: local('Roboto Italic'), local('Roboto-Italic'), - url('../../assets/fonts/roboto-v18-latin-ext_latin-italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ - url('../../assets/fonts/roboto-v18-latin-ext_latin-italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ + url('../assets/fonts/roboto-v18-latin-ext_latin-italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ + url('../assets/fonts/roboto-v18-latin-ext_latin-italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ } diff --git a/src/css/index.css b/src/css/index.css deleted file mode 100644 index 13291ff4..00000000 --- a/src/css/index.css +++ /dev/null @@ -1,174 +0,0 @@ -/* Style page content */ -body { - transition: all 0.15s ease; - color: white; -} - -.main { - margin-left: 200px; - padding: 0px 10px; -} - -body { - min-width: 800px; - min-height: 400px; - background-image: url("../../assets/background.png"); - background-size: cover; - font-family: 'Roboto', sans-serif; - margin: 0; -} - -.image-container { - position: relative; - width: 75%; - height: 75%; - top: 200px; - left: 12.5%; - text-align: center; -} - -.image-container img { - vertical-align: middle; - width: 75%; - height: 75%; -} - -/* The titlebar */ -.titlebar { - z-index: 1; - position: fixed; - top: 0; - left: 0; - right: 0; - width: 100%; - height: 30px; - /* Make it draggable */ - -webkit-user-select: none; - -webkit-app-region: drag; - cursor: default; - pointer-events: none; - background-color: #000000; - border-bottom: 1px solid white; -} - -.titlebar-title { - bottom: 10px; - position: relative; - text-align: center; - font-weight: bold; - font-family: 'Roboto', sans-serif; - color: #ffffff; -} - -/* Titlebar buttons */ -.titlebar-button { - top: 2px; - width: 25px; - height: 25px; - position: absolute; - cursor: default; - pointer-events: all; - -webkit-app-region: no-drag; - text-align: center; - color: white; - font-size: 115%; - transition: color 0.2s; - background: #000000; - border: #000000; -} - -.titlebar-button:focus { - outline: none; -} - -.titlebar-button:hover { - color: #b3b3b3; -} - -.titlebar-button:active { - color: #fffb00; -} - -#titlebar-button-minimize { - right: 75px; -} - -#titlebar-button-maximize { - right: 40px; -} - -#titlebar-button-restore { - right: 40px; -} - -#titlebar-button-close { - right: 5px; -} - -#titlebar-button-settings { - left: 5px; -} - -#titlebar-button-about { - left: 40px; -} - -#titlebar-button-help { - left: 75px; -} - -/* Top navigation bar */ -.navbar { - z-index: 1; - position: fixed; - top: 31px; - height: 45px; - width: 100%; - margin: 0; - padding: 0; - overflow: hidden; - background-color: #212721; -} - -#navbar-div-sync { - display: inline; - position: relative; - color: #ff0000; - top: 15px; - left: 10px; -} - -.navbar-button { - height: 45px; - width: 140px; - float: right; - color: white; - display: block; - text-align: center; - font-size: 1em; - font-family: 'Roboto', sans-serif; - text-transform: uppercase; - padding: 10px 2px; - background-color: #212721; - transition: background-color 0.2s; - border: none; -} - -.navbar-button:hover { - background-color: #4d524d; -} - -.navbar-button:focus { - outline: none; -} - -.navbar-button:active { - background-color: #00843d; -} - -#main-div { - width: 100%; - height: 85%; - position: absolute; - top: 75px; -} \ No newline at end of file diff --git a/src/css/overview.css b/src/css/overview.css deleted file mode 100644 index 750cf810..00000000 --- a/src/css/overview.css +++ /dev/null @@ -1,62 +0,0 @@ -/* Address */ -.div-overview-address { - position: relative; - top: 15px; - left: 5%; - width: 90%; -} - -#wallet-address { - font-size: 0.75em; - bottom: 15px; - width: 100%; -} - -/* Balance */ -.div-overview-balance { - position: relative; - top: 25px; - left: 5%; - width: 35%; -} - -#balance-available { - bottom: 15px; - width: 35%; - min-width: 240px; -} - -#balance-locked { - bottom: 15px; - width: 35%; - min-width: 240px; -} - -/* Text */ -.div-overview-text { - position: relative; - top: 25px; - left: 5%; - width: 90%; -} - -/* Buttons */ -#button-overview-loadwallet { - position: relative; - left: -6%; -} - -#button-overview-showkeys { - position: relative; - left: -2%; -} - -#button-overview-createwallet { - position: relative; - right: -2%; -} - -#button-overview-importwallet { - position: relative; - right: -6%; -} \ No newline at end of file diff --git a/src/css/overview_create.css b/src/css/overview_create.css deleted file mode 100644 index 7d23d8ca..00000000 --- a/src/css/overview_create.css +++ /dev/null @@ -1,64 +0,0 @@ -/* Fields */ -.div-create-fields { - position: relative; - left: 5%; - width: 90%; -} - -#input-create-path { - display: inline; - font-size: 1em; - bottom: 5px; - width: 90%; -} - -#button-create-browse { - position: relative; - display: inline; - bottom: 5px; - left: 15px; -} - -.div-create-name { - display: inline-block; - position: relative; - width: 44%; - height: 70px; -} - -.div-create-password { - display: inline-block; - position: relative; - width: 44%; - height: 70px; - left: 12px; -} - -#input-create-name { - font-size: 1em; - width: 100%; -} - -#input-create-password { - font-size: 1em; - width: 100%; -} - -/* Messages */ -.div-create-messages { - position: relative; - top: 25px; - left: 5%; - width: 90%; -} - -/* Buttons */ -#button-create-import { - position: relative; - right: 10%; -} - -#button-create-back { - position: relative; - left: 10%; -} diff --git a/src/css/overview_import.css b/src/css/overview_import.css deleted file mode 100644 index f8b8574d..00000000 --- a/src/css/overview_import.css +++ /dev/null @@ -1,58 +0,0 @@ -#input-import-path { - display: inline; - font-size: 1em; - bottom: 5px; - width: 90%; -} - -#button-import-browse { - position: relative; - display: inline; - bottom: 5px; - left: 15px; -} - -.div-import-name { - display: inline-block; - position: relative; - width: 44%; - height: 70px; -} - -.div-import-password { - display: inline-block; - position: relative; - width: 44%; - height: 70px; - left: 12px; -} - -#input-import-name { - font-size: 1em; - width: 100%; -} - -#input-import-password { - font-size: 1em; - width: 100%; -} - -#key-import-view { - font-size: 1em; - width: 90%; -} - -#key-import-spend { - font-size: 1em; - width: 90%; -} - -#button-import-import { - position: relative; - right: 10%; -} - -#button-import-back { - position: relative; - left: 10%; -} \ No newline at end of file diff --git a/src/css/overview_load.css b/src/css/overview_load.css deleted file mode 100644 index e732a589..00000000 --- a/src/css/overview_load.css +++ /dev/null @@ -1,36 +0,0 @@ -/* Input fields */ -.div-input { - position: relative; - top: 25px; - left: 5%; - width: 90%; -} - -#input-load-path { - display: inline; - font-size: 0.88em; - bottom: 5px; - width: 90%; -} - -#button-load-browse { - position: relative; - display: inline; - bottom: 5px; - left: 15px; -} - -#input-load-password { - font-size: 1em; - width: 90%; -} - -#button-load-load { - position: relative; - right: 10%; -} - -#button-load-cancel { - position: relative; - left: 10%; -} \ No newline at end of file diff --git a/src/css/overview_show.css b/src/css/overview_show.css deleted file mode 100644 index 9f5295b4..00000000 --- a/src/css/overview_show.css +++ /dev/null @@ -1,19 +0,0 @@ -#key-show-view { - font-size: 1em; - width: 90%; -} - -#key-show-spend { - font-size: 1em; - width: 90%; -} - -#button-show-reveal { - position: relative; - right: 10%; -} - -#button-show-back { - position: relative; - left: 10%; -} \ No newline at end of file diff --git a/src/css/save-panel.css b/src/css/save-panel.css deleted file mode 100644 index 4bd00c88..00000000 --- a/src/css/save-panel.css +++ /dev/null @@ -1,16 +0,0 @@ -body { - white-space: nowrap; - background-color: #000000; - font-family: 'Roboto', sans-serif; - margin: 0; - color: white; - font-size: 1.5em; -} - -.div-save-main { - display: inline; - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} diff --git a/src/css/send.css b/src/css/send.css deleted file mode 100644 index d1728491..00000000 --- a/src/css/send.css +++ /dev/null @@ -1,90 +0,0 @@ -/* Fields */ -.div-send-fields { - position: relative; - left: 5%; - width: 90%; -} - -#input-send-address { - padding: 12px 8px; - font-size: 0.8em; - bottom: 5px; - width: 100%; -} - -.div-send-amount { - display: inline-block; - position: relative; - width: 48%; - height: 80px; -} - -#input-send-amount { - font-size: 1em; - width: 100%; -} - -.div-send-payid { - display: inline-block; - position: relative; - width: 50%; - height: 80px; - left: 12px; -} - -#input-send-payid { - font-size: 1em; - width: 100%; -} - -.div-send-fee { - display: inline-block; - position: relative; - width: 48%; - height: 70px; -} - -#input-send-fee { - font-size: 1em; - width: 100%; -} - -.div-send-fee-text { - display: inline-block; - position: relative; - width: 48%; - height: 50px; - top: 12px; - left: 12px; -} - -.div-send-mixin { - display: inline-block; - position: relative; - width: 48%; - height: 70px; -} - -#input-send-mixin { - font-size: 1em; - width: 100%; -} - -.div-send-mixin-text { - display: inline-block; - position: relative; - width: 48%; - height: 60px; - top: 12px; - left: 12px; -} - -#button-import-import { - position: relative; - right: 10%; -} - -#button-import-back { - position: relative; - left: 10%; -} \ No newline at end of file diff --git a/src/css/settings.css b/src/css/settings.css deleted file mode 100644 index 425b5753..00000000 --- a/src/css/settings.css +++ /dev/null @@ -1,61 +0,0 @@ -/* Input fields */ -.div-settings-input { - position: relative; - top: 25px; - left: 5%; - width: 90%; -} - -#input-settings-path { - display: inline; - font-size: 0.88em; - bottom: 5px; - width: 90%; -} - -#button-settings-browse { - position: relative; - display: inline; - bottom: 5px; - left: 15px; -} - -#input-settings-rpcpass { - font-size: 1em; - width: 90%; -} - -.div-settings-daemon-address { - display: inline-block; - position: relative; - left: 12px; - width: 45%; - height: 80px; -} - -#input-settings-daemon-address { - font-size: 1em; - width: 90%; -} - -.div-settings-daemon-port { - display: inline-block; - position: relative; - width: 25%; - height: 80px; -} - -#input-settings-daemon-port { - font-size: 1em; - width: 90%; -} - -/* Buttons */ -.div-settings-buttons { - white-space: nowrap; - display: inline; - position: fixed; - top: 85%; - left: 50%; - transform: translate(-50%, -50%); -} diff --git a/src/css/transactions-panel.css b/src/css/transactions-panel.css deleted file mode 100644 index f9f95dfb..00000000 --- a/src/css/transactions-panel.css +++ /dev/null @@ -1,23 +0,0 @@ -body { - word-wrap: break-word; - min-width: 640px; - min-height: 480px; - /*background-color: #00632e;*/ - background: -webkit-linear-gradient(left, #00632e 0%,#41bd51 50%, #00632e 100%); - - font-family: 'Roboto', sans-serif; - margin: 0; - color: white; -} - -.div-transactions-panel { - position: relative; - top: 15px; - left: 5%; - width: 90%; -} - -#text-transactions-panel-extra, #text-transactions-panel-payid, - #text-transactions-panel-hash, #text-transactions-panel-address { - font-size: 0.83em; -} \ No newline at end of file diff --git a/src/css/transactions.css b/src/css/transactions.css deleted file mode 100644 index a05a49df..00000000 --- a/src/css/transactions.css +++ /dev/null @@ -1,67 +0,0 @@ -.div-transactions-page { - position: relative; - display: inline-block; - width: 45%; - height: 30px; - left: 25px; -} - -.div-transactions-sort { - position: relative; - display: inline-block; - width: 40%; - height: 30px; - left: 30px; -} - -#button-transactions-sort { - position: relative; - float: right; - height: 25px; - width: 25px; - left: 41%; - bottom: 1px; - font-size: 1.35em; -} - -#icon-transactions-sort { - position: relative; - margin: 0; - padding: 0; - right: 9px; - bottom: 10px; -} - -/* Table */ -.div-transactions-table { - position: relative; - top: 15px; - left: 5%; - width: 90%; -} - -#transactions-table:hover { - cursor: pointer; -} - -.div-transactions-row-txamount { - display: inline-block; - width: 20%; -} - -.div-transactions-row-txhash { - display: inline-block; - width: 78%; - font-size: 0.83em; -} - -.div-transactions-row-txdate { - display: inline-block; - width: 20%; -} - -.div-transactions-row-txpayid { - display: inline-block; - width: 78%; - font-size: 0.83em; -} diff --git a/src/html/about.html b/src/html/about.html index f94dfee8..0196c804 100644 --- a/src/html/about.html +++ b/src/html/about.html @@ -1,34 +1,41 @@ diff --git a/src/html/address_book.html b/src/html/address_book.html new file mode 100644 index 00000000..d775d27e --- /dev/null +++ b/src/html/address_book.html @@ -0,0 +1,50 @@ + + + \ No newline at end of file diff --git a/src/html/address_book_add.html b/src/html/address_book_add.html new file mode 100644 index 00000000..cad40ad8 --- /dev/null +++ b/src/html/address_book_add.html @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/src/html/help.html b/src/html/help.html deleted file mode 100644 index c4c7336f..00000000 --- a/src/html/help.html +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/src/html/index.html b/src/html/index.html index 9e5ecf6c..ada19974 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -2,70 +2,100 @@ - + + + + - - - - - - - - - - + - + + - + + + + -
-

WalletShell

- - - - - - + `; + }, + onSelect: function(e, term, item){ + document.getElementById('input-send-payid').value = item.getAttribute('data-paymentid'); + //document.getElementById('input-send-payid').focus(); + } + }); + } + + initSettingVal(); + initNodeCompletion(); + initAddressCompletion(); + + settingsSaveButton.addEventListener('click', function(){ + formStatusClear(); + + if(!settingsServiceBinField.value + || !settingsDaemonHostField.value + || !settingsDaemonPortField.value + ) { + formStatusMsg('settings','error',"Settings can't be saved, please check your input"); + return false; + } + let vals = { + service_bin: settingsServiceBinField.value.trim(), + daemon_host: settingsDaemonHostField.value.trim(), + daemon_port: settingsDaemonPortField.value.trim(), + tray_minimize: settingsMinToTrayField.checked, + tray_close: settingsCloseToTrayField.checked + } + initSettingVal(vals); + formStatusMsg('settings','success', "Settings has been updated."); + }); + /** ------------------ END settings ------------------------- */ + + /** ------------------ BEGIN address book ------------------- */ + // insert sample address :) + if(abook.size <= 0){ + let myName = 'rixombea labaylabay'; + let myAddress = 'TRTLv1A26ngXApin33p1JsSE9Yf6REj97Xruz15D4JtSg1wuqYTmsPj5Geu2kHtBzD8TCsfd5dbdYRsrhNXMGyvtJ61AoYqLXVS'; + let myPaymentId = 'DF794857BC4587ECEC911AF6A6AB02513FEA524EC5B98DA8702FAC92195A94B2'; + let myHash = gutils.b2sSum(myAddress + myPaymentId); + let myQr = gutils.genQrDataUrl(myAddress); + let myData = { + name: myName, + address: myAddress, + paymentId: myPaymentId, + qrCode: myQr + } + abook.set(myHash, myData); + } + const addressBookNameField = document.getElementById('input-addressbook-name'); + const addressBookWalletField = document.getElementById('input-addressbook-wallet'); + const addressBookPaymentIdField = document.getElementById('input-addressbook-paymentid'); + const addressBookSaveButton = document.getElementById('button-addressbook-save'); + addressBookSaveButton.addEventListener('click', (event) => { + formStatusClear(); + let nameValue = addressBookNameField.value ? addressBookNameField.value.trim() : ''; + let walletValue = addressBookWalletField.value ? addressBookWalletField.value.trim() : ''; + let paymentIdValue = addressBookPaymentIdField.value ? addressBookPaymentIdField.value.trim() : ''; + + if( !nameValue || !walletValue ){ + formStatusMsg('addressbook','error',"Name and wallet address can not be left empty!"); + return; + } + + if(!gutils.validateTRTLAddress(walletValue)){ + formStatusMsg('addressbook','error',"Invalid TurtleCoin address"); + return; + } + + + if( paymentIdValue.length){ + if( !gutils.validatePaymentId(paymentIdValue) ){ + formStatusMsg('addressbook','error',"Invalid Payment ID"); + return; + } + } + + let entryName = nameValue.trim(); + let entryAddr = walletValue.trim(); + let entryPaymentId = paymentIdValue.trim(); + let entryHash = gutils.b2sSum(entryAddr + entryPaymentId); + + if(abook.has(entryHash)){ + formStatusMsg('addressbook','error',"This combination of address and payment ID already exist, please enter new address or different payment id."); + return; + } + + try{ + abook.set(entryHash, { + name: entryName, + address: entryAddr, + paymentId: entryPaymentId, + qrCode: gutils.genQrDataUrl(entryAddr) + }); + }catch(e){ + formStatusMsg('addressbook','error',"Address book entry can not be saved, please try again"); + return; + } + addressBookNameField.value = ''; + addressBookWalletField.value = ''; + addressBookPaymentIdField.value = ''; + initAddressCompletion(); + formStatusMsg('addressbook','success', 'Address book entry has been saved.'); + }); + /** ------------------ END address book ------------------- */ + + /** ------------------ BEGIN OPEN WALLET --------------------- */ + const openWalletPathField = document.getElementById('input-load-path'); + const openWalletPasswordField = document.getElementById('input-load-password'); + const openWalletButton = document.getElementById('button-load-load'); + //const openWalletScanHeightField = document.getElementById('input-creation-height'); + + function initOpenWallet(){ + if(settings.has('recentWallet')){ + openWalletPathField.value = settings.get('recentWallet'); + } + } + + initOpenWallet(); + openWalletButton.addEventListener('click', (event) => { + formStatusClear(); + if(!openWalletPathField.value){ + formStatusMsg('load','error', "Invalid wallet file path"); + return; + } + + function onError(err){ + formStatusClear(); + formStatusMsg('load','error', err); + return false; + } + + function onSuccess(theWallet, scanHeight){ + formStatusClear(); + //scanHeight = scanHeight || 0; + document.getElementById('wallet-address').value = remote.getGlobal('wsession').loadedWalletAddress; + //let newWl = `(${path.basename(theWallet) })`; + //document.getElementById('tt-wallet').innerHTML = '(' + + ')'; + //gutils.innerHTML(document.getElementById('tt-wallet'), newWl); + document.getElementById('button-section-overview').click(); + + // if(scanHeight > 1024){ + // //perform reset, delay to wait for settled connection to the service + // setTimeout(() => { + // svcmain.resetFromHeight(scanHeight); + // },3000); + // } + let thefee = svcmain.getNodeFee(); + //svcmain.startWorker(); + } + + //let walletFile = path.basename(openWalletPathField.value); + let walletFile = openWalletPathField.value; + let walletPass = openWalletPasswordField.value; + let scanHeight = 0;//openWalletScanHeightField.value; + fs.access(walletFile, fs.constants.R_OK, (err) => { + if(err){ + formStatusMsg('load','error', "Invalid wallet file path"); + return false; + } + + settings.set('recentWallet', walletFile); + + formStatusMsg('load','warning', "Starting wallet service..."); + svcmain.stopService(true).then((v) => { + setTimeout(() => { + formStatusMsg('load','warning', "Opening wallet, please be patient..."); + svcmain.startService(walletFile, walletPass, scanHeight, onError, onSuccess); + },1200); + + }).catch((err) => { + formStatusMsg('load','error', "Unable to start service"); + return false; + }); + }); + }); + + document.getElementById('button-overview-closewallet').addEventListener('click', () => { + let dialog = document.getElementById('main-dialog'); + let htmlStr = '
Saving & closing your wallet...
'; + gutils.innerHTML(dialog, htmlStr); + + dialog = document.getElementById('main-dialog'); + dialog.showModal(); + // save + SIGTERMed wallet daemon + svcmain.stopWorker(); + svcmain.stopService(true).then((k) => { + setTimeout(function(){ + // cleare form err msg + formStatusClear(); + document.getElementById('button-section-overview').click(); + // clear tx + document.getElementById('button-transactions-refresh').click(); + // send fake blockUpdated event + let resetdata = { + type: 'blockUpdated', + data: {blockCount: -100, knownBlockCount: -100} + }; + svcmain.handleWorkerUpdate(resetdata); + dialog = document.getElementById('main-dialog'); + if(dialog.hasAttribute('open')) dialog.close(); + gutils.clearChild(dialog); + }, 1200); + }).catch((err) => { + console.log(err); + }); + }); + /** ------------------ END OPEN WALLET ----------------------- */ + + /** ------------------ BEGIN SHOWKEYS ------------------------ */ + // reveal button + const showKeyButton = document.getElementById('button-show-reveal'); + const showKeyViewKeyField = document.getElementById('key-show-view'); + const showKeySpendKeyField = document.getElementById('key-show-spend'); + const showKeySeedField = document.getElementById('seed-show'); + const addressField = document.getElementById('wallet-address'); + showKeyButton.addEventListener('click', (event) => { + formStatusClear(); + if(!addressField.value) return; + svcmain.getSecretKeys(addressField.value).then((keys) => { + showKeyViewKeyField.value = keys.viewSecretKey; + showKeySpendKeyField.value = keys.spendSecretKey; + showKeySeedField.value = keys.mnemonicSeed; + }).catch((err) => { + formStatusMsg('secret','error', "Failed to get key, please try again in a few seconds"); + }); + }); + /** ------------------ END SHOWKEYS ------------------------ */ + + /** ------------------ BEGIN SEND -------------------------- */ + const sendAddress = document.getElementById('input-send-address'); + const sendAmount = document.getElementById('input-send-amount'); + const sendPayID = document.getElementById('input-send-payid'); + const sendFee = document.getElementById('input-send-fee'); + sendFee.value = 0.1; + const sendButton = document.getElementById('button-send-send'); + + sendButton.addEventListener('click', (event) => { + formStatusClear(); + + function precision(a) { + if (!isFinite(a)) return 0; + let e = 1, p = 0; + while (Math.round(a * e) / e !== a) { e *= 10; p++; } + return p; + } + + let amount = parseFloat(sendAmount.value); + if (isNaN(amount) || amount <= 0) { + formStatusMsg('send','error','Invalid amount value!'); + return; + } + + if (precision(amount) > 2) { + formStatusMsg('send','error',"Amount can't have more than 2 decimal places"); + return; + } + // adjust amount for the rpc transaction + amount *= 100; + + // validate fee + let fee = parseFloat(sendFee.value); + if (isNaN(fee) || fee < 0.10) { + formStatusMsg('send','error','Invalid fee amount!'); + return; + } + + if (precision(fee) > 2) { + formStatusMsg('send','error',"Fee can't have more than 2 decimal places"); + return; + } + fee *= 100; + + let recAddress = sendAddress.value ? sendAddress.value.trim() : ''; + if(!recAddress.length || !validateAddress(recAddress)){ + formStatusMsg('send','error','Invalid address'); + return; + } + + let recPayId = sendPayID.value ? sendPayID.value.trim() : ''; + if(recPayId.length){ + if(!validatePaymentId(recPayId)){ + formStatusMsg('send','error','Invalid Payment ID'); + return; + } + } + + let tx = { + address: sendAddress.value, + fee: fee, + amount: amount + } + + // let tpl = ` + //
+ //

Send Transfer Confirmation

+ //
+ + //
+ //
+ //
+ // + // + //
+ // `; + let nodeFee = remote.getGlobal('wsession').nodeFee || 0; + let confirmText =`Please confirm that you have everything correctly entered. +Send to: ${sendAddress.value} +Payment ID: ${recPayId.length ? recPayId : 'N/A'} +Amount: ${parseFloat(sendAmount.value).toFixed(2)} TRTL +Tx Fee: ${(fee/100).toFixed(2)} TRTL | Node Fee: ${(nodeFee > 0 ? (nodeFee/100).toFixed(2) : '0.00')} TRTL +Send this transfer?`; + + if(!confirm(confirmText)){ + return; + } + + if(recPayId.length) tx.paymentId = recPayId; + formStatusMsg('send', 'warning', 'Sending transaction, please wait...'); + svcmain.sendTransaction(tx).then((result) => { + formStatusClear(); + let okMsg = `Transaction sent!
Tx. hash: ${result.transactionHash}.
Your balance may appear incorrect while transaction not fully confirmed.` + formStatusMsg('send', 'success', okMsg); + // check if its new address, if so save it + let newId = gutils.b2sSum(recAddress + recPayId); + if(!abook.has(newId)){ + let newBuddy = { + name: `New address (${new Date().toUTCString()})`, + address: recAddress, + paymentId: recPayId, + qrCode: gutils.genQrDataUrl(recAddress) + }; + abook.set(newId,newBuddy); + } + }).catch((err) => { + formStatusClear(); + formStatusMsg('send','error','Failed to send transaction, check that you have enough balance to transfer and paying fees
Error code: ' + err) + ''; + }); + }); + /** ------------------ END SEND ---------------------------- */ + + /** ------------------ BEGIN NEW WALLET -------------------- */ + const createButton = document.getElementById('button-create-create'); + const createPathField = document.getElementById('input-create-path'); + const createFileField = document.getElementById('input-create-name'); + const createPasswordField = document.getElementById('input-create-password'); + createButton.addEventListener('click', (event) => { + formStatusClear(); + if(!createPathField.value || !createFileField.value){ + formStatusMsg('create', 'error', 'Please check your path input'); + return; + } + + svcmain.createWallet( + createPathField.value, + createFileField.value, + createPasswordField.value + ).then((walletFile) => { + settings.set('recentWallet', walletFile); + settings.set('recentWalletDir', createPathField.value); + document.getElementById('input-load-path').value = walletFile; + document.getElementById('button-welcome-openwallet').click(); + iqwerty.toast.Toast('Wallet has been created, you can now open your wallet!', {settings: {duration:8000}}); + }).catch((err) => { + formStatusMsg('create', 'error', err); + return; + }); + }); + + /** ------------------ END NEW WALLET ---------------------- */ + + /** ------------------ BEGIN IMPORT KEY -------------------- */ + const importKeyButton = document.getElementById('button-import-import'); + const importKeyPathField = document.getElementById('input-import-path'); + const importKeyFileField = document.getElementById('input-import-name'); + const importKeyPasswordField = document.getElementById('input-import-password'); + const importKeyViewKeyField = document.getElementById('key-import-view'); + const importKeySpendKeyField = document.getElementById('key-import-spend'); + const importKeyScanHeightField = document.getElementById('key-import-height'); + + importKeyButton.addEventListener('click', (event) => { + formStatusClear(); + svcmain.importFromKey( + importKeyPathField.value, + importKeyFileField.value, + importKeyPasswordField.value, + importKeyViewKeyField.value, + importKeySpendKeyField.value, + importKeyScanHeightField.value + ).then((walletFile) => { + settings.set('recentWallet', walletFile); + settings.set('recentWalletDir', importKeyPathField.value); + document.getElementById('input-load-path').value = walletFile; + document.getElementById('button-welcome-openwallet').click(); + iqwerty.toast.Toast('Wallet has been imported, you can now open your wallet!', {settings: {duration:8000}}); + }).catch((err) => { + formStatusMsg('import', 'error',err); + return; + }); + }); + + /** ------------------ END IMPORT KEY -----------------------*/ + + /** ------------------ BEGIN IMPORT SEED ------------------- */ + const importSeedButton = document.getElementById('button-import-seed-import'); + //const textSuccess = document.getElementById('text-import-seed-success'); + //const textError = document.getElementById('text-import-seed-error'); + const importSeedPathField = document.getElementById('input-import-seed-path'); + const importSeedFileField = document.getElementById('input-import-seed-name'); + const importSeedPasswordField = document.getElementById('input-import-seed-password'); + const importSeedMnemonicField = document.getElementById('key-import-seed'); + const importSeedScanHeightField = document.getElementById('key-import-seed-height'); + importSeedButton.addEventListener('click', (event) => { + formStatusClear(); + svcmain.importFromSeed( + importSeedPathField.value, + importSeedFileField.value, + importSeedPasswordField.value, + importSeedMnemonicField.value, + importSeedScanHeightField.value + ).then((walletFile) => { + settings.set('recentWallet', walletFile); + settings.set('recentWalletDir', importSeedPathField.value); + document.getElementById('input-load-path').value = walletFile; + document.getElementById('button-welcome-openwallet').click(); + iqwerty.toast.Toast('Wallet has been imported, you can now open your wallet!', {settings: {duration:8000}}); + }).catch((err) => { + formStatusMsg('import-seed', 'error',err); + return; + }); + }); + /** ------------------ END IMPORT SEED --------------------- */ + + /** ------------------ BEGIN Transaction ------------------- */ + // TODO: rethink this one to use List class + const pageText = document.getElementById('text-transactions-page'); + const table = document.getElementById('transactions-table-body'); + const refreshButton = document.getElementById('button-transactions-refresh'); + const nextButton = document.getElementById('button-transactions-next'); + const lastButton = document.getElementById('button-transactions-last'); + const previousButton = document.getElementById('button-transactions-prev'); + const firstButton = document.getElementById('button-transactions-first'); + + const selectSort = document.getElementById('select-transactions-sort'); + const sortButton = document.getElementById('button-transactions-sort'); + const transactionsPerPage = 6; + + let sortIcon; + let blockNumber = document.getElementById('navbar-text-sync-count'); + let currentPage = 1; + // by default, the transactions list is ordered by date due to how it's filled + let currentSortBy = 'date'; + // sorting order is 1 for ascending, -1 for descending + let currentSortOrder = 1; + + function showPage(pageNumber) { + let transactionsList = remote.getGlobal('wsession').txList; + let totalPages = Math.ceil(transactionsList.length / transactionsPerPage); + // check if page number is valid + if (pageNumber < 1 || pageNumber > totalPages){ + return; + } + // clear the table + while(table.childElementCount > 1) { + table.removeChild(table.lastChild); + } + // if the transactions list is empty, we display a message + if(transactionsList.length == 0) { + table.insertRow(-1).insertCell(0).innerHTML = 'No transactions found, yet :('; + return; + } + // set current page + currentPage = pageNumber; + // fill table with the transactions of the page + let i = transactionsPerPage * (currentPage - 1); + // loop until there are transactionsPerPage transactions in the page or until there are no more + while(i - transactionsPerPage * (currentPage - 1) < transactionsPerPage && i < transactionsList.length) { + let transaction = transactionsList[i]; + let row = table.insertRow(-1); + let cell = row.insertCell(0); + let txType = (transaction.amount > 0 ? 'tx-in' : 'tx-out'); + row.className = txType; + + // Amount + let divAmount = document.createElement('div'); + if (transaction.amount > 0){ + divAmount.innerHTML = '+' + (transaction.amount / 100).toFixed(2) + ' TRTL'; + }else{ + divAmount.innerHTML = (transaction.amount / 100).toFixed(2) + ' TRTL'; + } + + divAmount.classList.add('div-transactions-row-txamount'); + cell.appendChild(divAmount); + + // Hash + let divHash = document.createElement('div'); + divHash.innerHTML = 'Tx. Hash: ' + transaction.transactionHash; + divHash.classList.add('div-transactions-row-txhash'); + cell.appendChild(divHash); + + // Date + let divDate = document.createElement('div'); + divDate.innerHTML = new Date(transaction.timestamp * 1000).toDateString(); + divDate.classList.add('div-transactions-row-txdate'); + cell.appendChild(divDate); + + // Payment Id + let divPayId = document.createElement('div'); + divPayId.innerHTML = `Payment ID: ${(transaction.paymentId ? transaction.paymentId : '-')}`; + divPayId.classList.add('div-transactions-row-txpayid'); + cell.appendChild(divPayId); + + // upon clicking on the row, a panel will pop up + // showing the transaction's details + let dialogTpl = ` +
+

Transaction Detail

+ + + + + + + + + + + + + + + + + + + + + + + + +
Address_ADDRESS_
Amount_AMOUNT_
Fee_FEE_
Timestamp_TIMESTAMP_
Payment Id_PAYMENTID_
Hash_HASH_
Block Index_BLOCKINDEX_
Is Base?_ISBASE_
Unlock Time_UNLOCKTIME_
Extra_EXTRA_
+
+
+ +
+ `; + + row.addEventListener('click', function(event) { + const dialog = document.getElementById('tx-dialog'); + let txDate = new Date(transaction.timestamp * 1000).toString(); + let txDetail = dialogTpl + .replace('_ADDRESS_',transaction.transfers[0].address) + .replace('_AMOUNT_', (transaction.amount / 100).toFixed(2)) + .replace('_TIMESTAMP_', `${transaction.timestamp} (${txDate}) `) + .replace('_HASH_', transaction.transactionHash) + .replace('_BLOCKINDEX_', transaction.blockIndex) + .replace('_ISBASE_', transaction.isBase) + .replace('_UNLOCKTIME_', transaction.unlockTime) + .replace('_FEE_', (transaction.fee / 100).toFixed(2)) + .replace('_EXTRA_', transaction.extra) + .replace('_PAYMENTID_', (transaction.paymentId ? transaction.paymentId : '-')); + + dialog.innerHTML = txDetail; + dialog.showModal(); + + document.getElementById('button-transactions-panel-close').addEventListener('click', (event) => { + let txdialog = document.getElementById('tx-dialog'); + //txdialog.innerHTML = ''; + gutils.clearChild(txdialog); + txdialog.close(); + }); + }); + i++; + } + // show the current page and the total number of pages + pageText.innerHTML = 'Page ' + currentPage + ' of ' + totalPages; + } + + // refresh transaction table + refreshButton.addEventListener('click', (event) => { + let txlist = remote.getGlobal('wsession').txList; + if(!txlist.length){ + while(table.childElementCount > 1) { + table.removeChild(table.lastChild); + } + table.insertRow(-1).insertCell(0).innerHTML = '
Collecting transaction data...
'; + }else{ + showPage(1); + } + }); + + nextButton.addEventListener('click', (event) => { + showPage(currentPage + 1); + }) + + previousButton.addEventListener('click', (event) => { + showPage(currentPage - 1); + }); + + firstButton.addEventListener('click', (event) => { + showPage(1); + }); + + lastButton.addEventListener('click', (event) => { + showPage(Math.ceil(remote.getGlobal('wsession').txLen / transactionsPerPage)); + }); + + // table headers + // const amountHeader = document.getElementById('header-transactions-amount'); + // const addressHeader = document.getElementById('header-transactions-address'); + // const dateHeader = document.getElementById('header-transactions-date'); + + // function that sorts the transactions list and refreshes the page + function sortTransactionsList (sortBy) { + let sortFunction; + switch (sortBy) { + case 'date': + sortFunction = function (a, b) { + if (a.timestamp > b.timestamp) return 1; + if (a.timestamp < b.timestamp) return -1; + return 0; + } + break; + case 'hash': + sortFunction = function (a, b) { + let str1 = a.transactionHash; + let str2 = b.transactionHash; + return str1.localeCompare(str2); + } + break; + case 'amount': + sortFunction = function (a, b) { + if (a.amount > b.amount) return 1; + if (a.amount < b.amount) return -1; + return 0; + } + break; + case 'payid': + sortFunction = function (a, b) { + let str1 = a.paymentId; + let str2 = b.paymentId; + return str1.localeCompare(str2); + } + } + let rTxList = remote.getGlobal('wsession').txList; + rTxList.sort((a, b) => currentSortOrder * sortFunction(a, b)); + remote.getGlobal('wsession').txList = rTxList; + showPage(currentPage); + } + + // assing to each option the ability to call the sort function + // passing a specific compare function + selectSort.addEventListener('change', function(event) { + currentSortBy = event.target.value; + sortTransactionsList(currentSortBy); + }); + + // sort button + // allows the user to sort in descending or ascending order + sortButton.addEventListener('click', function(event) { + sortIcon = document.getElementById('icon-transactions-sort'); + // change the icon everytime the user clicks + if (currentSortOrder == 1) { + sortIcon.classList.toggle('fa-chevron-up'); + sortIcon.classList.toggle('fa-chevron-down'); + } else { + sortIcon.classList.toggle('fa-chevron-down'); + sortIcon.classList.toggle('fa-chevron-up'); + } + currentSortOrder *= -1; + sortTransactionsList(currentSortBy); + }); + /** ------------------ END Transaction --------------------- */ + BASE_INIT_DONE = true; +} +initBaseEvent(); \ No newline at end of file diff --git a/src/js/ui_updater.js b/src/js/ui_updater.js new file mode 100644 index 00000000..558a4317 --- /dev/null +++ b/src/js/ui_updater.js @@ -0,0 +1,435 @@ +const electron = require('electron'); +const remote = electron.remote; +const Store = require('electron-store'); +const settings = new Store({name: 'Settings'}); +const abook = new Store({ + name: 'AddressBook', + encryptionKey: ['79009fb00ca1b7130832a42d','e45142cf6c4b7f33','3fe6fba5'].join('') +}); + +const gutils = require('./gutils'); +const brwin = remote.getCurrentWindow(); + +//const genQrcode = require('./svc_main').getQrDataUrl; + + + +/* sync progress ui */ +const syncDiv = document.getElementById('navbar-div-sync'); +const syncText = document.getElementById('navbar-text-sync'); +const syncCountText = document.getElementById('navbar-text-sync-count'); +const syncSlash = document.getElementById('navbar-text-sync-slash'); +const syncKnownText= document.getElementById('navbar-text-sync-known'); +const syncPercent= document.getElementById('navbar-text-sync-percent'); + +const connInfoDiv = document.getElementById('conn-info'); +const connAddrText = document.getElementById('status-node-addr'); +const connFeeText = document.getElementById('status-node-fee'); +const connWarnText = document.getElementById('status-node-warning'); + +// const titleWalletFileDiv = document.getElementById('tt-wallet'); +// const titleBalanceDiv = document.getElementById('tt-balance'); + +function setWinTitle(title){ + let defaultTitle = remote.getGlobal('wsession').defaultTitle; + let newTitle = defaultTitle; + if(title){ + newTitle = `${defaultTitle} ${title}`; + } + brwin.setTitle(newTitle); +} + +function updateSyncProgres(data){ + const iconSync = document.getElementById('navbar-icon-sync'); + let blockCount = data['blockCount']; + let knownBlockCount = data['knownBlockCount']; + + // restore/reset + if(knownBlockCount === -100){ + syncDiv.className = ''; + syncText.innerHTML = 'IDLE'; + //syncCountText.innerHTML = ''; + gutils.clearChild(syncCountText); + //syncKnownText.innerHTML = ''; + gutils.clearChild(syncKnownText); + //syncSlash.innerHTML = ''; + gutils.clearChild(syncSlash); + //syncPercent.innerHTML = ''; + gutils.clearChild(syncPercent); + + iconSync.setAttribute('data-icon', 'pause-circle'); + iconSync.classList.remove('fa-spin'); + + connInfoDiv.classList.remove('conn-warning'); + connInfoDiv.classList.add('hidden'); + connAddrText.innerHTML = 'N/A'; + connFeeText.innerHTML = 'N/A'; + //connWarnText.innerHTML = ''; + gutils.clearChild(connWarnText); + //gutils.clearChild(titleWalletFileDiv); + //gutils.clearChild(titleBalanceDiv); + setWinTitle(); + }else if(knownBlockCount <=1){ + // not connected + syncDiv.className = 'failed'; + syncText.innerHTML = 'NOT CONNECTED'; + //syncCountText.innerHTML = ''; + gutils.clearChild(syncCountText); + //syncKnownText.innerHTML = ''; + gutils.clearChild(syncKnownText); + //syncSlash.innerHTML = ''; + gutils.clearChild(syncSlash); + //syncPercent.innerHTML = ''; + gutils.clearChild(syncPercent); + + iconSync.setAttribute('data-icon', 'times'); + iconSync.classList.remove('fa-spin'); + connInfoDiv.classList.remove('hidden'); + connInfoDiv.classList.add('conn-warning'); + connAddrText.innerHTML = 'N/A'; + connFeeText.innerHTML = 'N/A'; + connWarnText.innerHTML = '- Connection failed, try switching to another Node in settings page, close and reopen your wallet'; + }else{ + //document.getElementById('status-node-warning').innerHTML = ''; + gutils.clearChild(connWarnText); + let dispKnownBlockCount = (knownBlockCount-1); + let dispBlockCount = (blockCount > dispKnownBlockCount ? dispKnownBlockCount : blockCount); + + syncCountText.innerHTML = dispBlockCount; + syncSlash.innerHTML = ' / '; + syncKnownText.innerHTML = dispKnownBlockCount; + + remote.getGlobal('wsession').syncStarted = true; + + if(blockCount+1 >= knownBlockCount && knownBlockCount != 0) { + syncDiv.classList = 'synced'; + syncText.innerHTML = 'SYNCED '; + //syncPercent.innerHTML = ''; + gutils.clearChild(syncPercent); + iconSync.setAttribute('data-icon', 'check'); + iconSync.classList.remove('fa-spin'); + remote.getGlobal('wsession').synchronized = true; + remote.getGlobal('wsession').syncStarted = true; + + } else { + syncDiv.className = 'syncing'; + syncText.innerHTML = 'SYNCING '; + let synchedPercent = ((dispBlockCount / dispKnownBlockCount) * 100).toFixed(2); + syncPercent.innerHTML = `(${synchedPercent}%)`; + iconSync.setAttribute('data-icon', 'sync'); + iconSync.classList.add('fa-spin'); + remote.getGlobal('wsession').syncStarted = true; + remote.getGlobal('wsession').synchronized = false; + } + + let nFee = remote.getGlobal('wsession').nodeFee; + document.getElementById('conn-info').classList.remove('conn-warning'); + connAddrText.innerHTML = `${settings.get('daemon_host')}:${settings.get('daemon_port')}`; + document.getElementById('status-node-fee').innerHTML = (nFee ? "TRTL " + nFee : '-'); + } +} + + +function updateBalance(data){ + const balanceAvailableField = document.querySelector('#balance-available > span'); + const balanceLockedField = document.querySelector('#balance-locked > span'); + if(!data || !data.availableBalance) return; + if(data.availableBalance <= 0) return; + + let bUnlocked = (data.availableBalance / 100).toFixed(2); + let bLocked = (data.lockedAmount / 100).toFixed(2); + balanceAvailableField.innerHTML = bUnlocked; + balanceLockedField.innerHTML = bLocked; + let walletFile = require('path').basename(settings.get('recentWallet')); + let wintitle = `(${walletFile}) - ${bUnlocked} TRTL`; + setWinTitle(wintitle); + //document.getElementById('tt-balance').innerHTML = "- TRTL " + bUnlocked; +} + +var FIRST_TX_CHECK = true; +function updateTransactions(data){ + //const result = data.result; + const blocks = data.items; + const newTxLen = blocks.length; + const currentTxLen = remote.getGlobal('wsession').txLen; + + if(!newTxLen || newTxLen <= currentTxLen) return; + + let txlist = []; + Array.prototype.forEach.call(blocks, block => { + Array.prototype.forEach.call(block.transactions, transaction => { + if(transaction.amount !== 0){ + txlist.unshift(transaction); + } + }); + }); + + if(!txlist.length) return; + + let oldLastHash = remote.getGlobal('wsession').txLastHash; + let oldLastTimestamp = remote.getGlobal('wsession').txLastTimestamp; + let latestTx = txlist[0]; + let newLastHash = latestTx.transactionHash; + let newLastTimestamp = latestTx.timestamp; + let newTxAmount = latestTx.amount; + + // store it + remote.getGlobal('wsession').txLastHash = newLastHash; + remote.getGlobal('wsession').txLastTimestamp = newLastTimestamp; + remote.getGlobal('wsession').txList = txlist; + remote.getGlobal('wsession').txLen = newTxLen; + // date to compare + let currentDate = new Date(); + currentDate = `${currentDate.getUTCFullYear()}-${currentDate.getUTCMonth()+1}-${currentDate.getUTCDate()}` + let lastTxDate = new Date(newLastTimestamp*1000); + lastTxDate = `${lastTxDate.getUTCFullYear()}-${lastTxDate.getUTCMonth()+1}-${lastTxDate.getUTCDate()}` + // amount to check + let theAmount = (newTxAmount/100); + + let notify = true; + if(lastTxDate !== currentDate){ + notify = false; + }else if(theAmount < 0){ + notify = false; + }else if(oldLastHash === newLastHash){ + notify = false; + } + + if(notify){ + let notiOptions = { + 'body': `Amount: ${(theAmount).toFixed(2)} TRTL
Hash: ${newLastHash.substring(24,-0)}...`, + 'icon': '../assets/walletshell_icon.png' + }; + new Notification('Incoming Transfer', notiOptions); + } + document.getElementById('button-transactions-refresh').click(); +} + +function showFeeWarning(fee){ + let dialog = document.getElementById('main-dialog'); + if(dialog.hasAttribute('open')) return; + + dialog.classList.add('dialog-warning'); + fee = fee || 0; + if(fee <=0) return; + + let htmlStr = ` +
Fee Warning (${settings.get('daemon_host')}:${settings.get('daemon_port')})
+

You are connected to a public node that charges a fee to send transactions.

+

The fee for sending transactions is: ${fee} TRTL .
+ If you don't want to pay the node fee, please close your wallet, and update your settings to use different public node or your own node. +

+

+ `; + + //dialog.innerHTML = htmlStr; + gutils.innerHTML(dialog, htmlStr); + let dialogEnd = document.getElementById('dialog-end'); + dialogEnd.addEventListener('click', (event) => { + try{ + dialog.classList.remove('dialog-warning'); + document.getElementById('main-dialog').close(); + }catch(e){} + }); + dialog = document.getElementById('main-dialog'); + dialog.showModal(); + dialog.addEventListener('close', function(){ + //dialog.innerHTML = ''; + gutils.clearChild(dialog); + const overviewBtn = document.getElementById('button-section-overview'); + const connectedNodeAddr = settings.get('daemon_host'); + const connectedNodePort = settings.get('daemon_port'); + document.getElementById('status-node-addr').innerHTML = `${connectedNodeAddr}:${connectedNodePort}`; + document.getElementById('status-node-fee').innerHTML = `TRTL ${fee}`; + overviewBtn.click(); + //dialog.removeEventListener('close'); + }); +} + +function updateQr(address){ + if(!address){ + document.getElementById('button-transactions-refresh').click(); + return; + } + + let walletHash = gutils.b2sSum(address); + remote.getGlobal('wsession').walletHash = walletHash; + + let oldImg = document.getElementById('qr-gen-img'); + if(oldImg) oldImg.remove(); + + let qr_base64 = gutils.genQrDataUrl(address); + if(qr_base64.length){ + let qrBox = document.getElementById('div-w-qr'); + let qrImg = document.createElement("img"); + qrImg.setAttribute('id', 'qr-gen-img'); + qrImg.setAttribute('src', qr_base64); + qrBox.prepend(qrImg); + document.getElementById('scan-qr-help').classList.remove('hidden'); + }else{ + document.getElementById('scan-qr-help').classList.add('hidden'); + } +} + +function displayAddressBookEntry(event){ + let dialog = document.getElementById('ab-dialog'); + if(dialog.hasAttribute('open')) dialog.close(); + let tpl = ` +
+

Address Detail

+
+
+ +
+
+
+
Name:
+
${this.dataset.nameval}
+
Wallet Address:
+
${this.dataset.walletval}
+
Payment Id:
+
${this.dataset.paymentidval ? this.dataset.paymentidval : '-'}
+
+
+
+
+
+ + +
+ `; + //dialog.innerHTML = tpl; + gutils.innerHTML(dialog, tpl); + // get new dialog + dialog = document.getElementById('ab-dialog'); + dialog.showModal(); + document.getElementById('button-addressbook-panel-close').addEventListener('click', (event) => { + let abdialog = document.getElementById('ab-dialog'); + abdialog.close(); + //abdialog.innerHTML = ''; + gutils.clearChild(abdialog); + }); + + let deleteBtn = document.getElementById('button-addressbook-panel-delete'); + deleteBtn.addEventListener('click', (event) => { + let tardel = this.dataset.nameval; + let tarhash = this.dataset.hash; + if(!confirm(`Are you sure wan to delete ${tardel} from addres book?`)){ + return; + }else{ + abook.delete(tarhash); + let abdialog = document.getElementById('ab-dialog'); + abdialog.close(); + gutils.clearChild(abdialog); + listAddressBook(true); + if(!document.getElementById('datoaste')){ + iqwerty.toast.Toast("Address book entry was deleted.", {settings: {duration:1800}}); + } + } + }); +} + +gutils.liveEvent('.addressbook-item','click',displayAddressBookEntry); +function listAddressBook(force){ + force = force || false; + //let currentLength = document.querySelectorAll('.addressbook-item').length; + let currentLength = document.querySelectorAll('.addressbook-item:not([data-hash="fake-hash"])').length + let abookLength =abook.size; + let perPage = 9; + + if(currentLength >= abookLength && !force) return; + + let listOpts = { + valueNames: [ + {data: ['hash', 'nameval','walletval','paymentidval','qrcodeval']}, + 'addressName','addressWallet','addressPaymentId' + ], + indexAsync: true + }; + + if(abookLength > perPage){ + listOpts.page = perPage; + listOpts.pagination = true; + } + + const addressList = new List('addressbooks', listOpts); + addressList.clear(); + Object.keys(abook.get()).forEach((key) => { + let et = abook.get(key); + addressList.add({ + hash: key, + addressName: et.name, + addressWallet: et.address, + addressPaymentId: et.paymentId || '-', + nameval: et.name, + walletval: et.address, + paymentidval: et.paymentId || '-', + qrcodeval: et.qrCode || '' + }); + }); + + addressList.remove('hash', 'fake-hash'); +} + +function resetFormState(initiator){ + const allFormInputs = document.querySelectorAll('.section input,.section textarea'); + Array.from(allFormInputs).forEach((el) => { + if(el.dataset.initial){ + if(!el.dataset.noclear){ + el.value = settings.has(el.dataset.initial) ? settings.get(el.dataset.initial) : ''; + if(el.getAttribute('type') === 'checkbox'){ + el.checked = settings.get(el.dataset.initial); + } + } + }else{ + if(!el.dataset.noclear) el.value = ''; + } + }); + + const connInfo = document.getElementById('conn-info'); + const settingsBackBtn = document.getElementById('button-settings-back'); + if(remote.getGlobal('wsession').serviceReady){ + connInfo.classList.remove('hidden'); + settingsBackBtn.dataset.section = 'section-welcome'; + }else{ + connInfo.classList.add('hidden'); + settingsBackBtn.dataset.section = 'section-overview'; + } + + // address book + if(initiator.trim() === 'button-addressbook-back' || initiator.trim() === 'button-section-addressbook'){ + listAddressBook(); + } +} + + + +// update ui state, push from svc_main +function updateUiState(msg){ + // do something with msg + switch (msg.type) { + case 'blockUpdated': + updateSyncProgres(msg.data); + break; + case 'balanceUpdated': + updateBalance(msg.data); + break; + case 'transactionUpdated': + updateTransactions(msg.data); + break; + case 'nodeFeeUpdated': + if(parseInt(msg.data,10) >= 1) showFeeWarning(msg.data); + break; + case 'addressUpdated': + updateQr(msg.data); + break; + case 'sectionChanged': + resetFormState(msg.data); + break; + default: + console.log('invalid command received by ui', msg); + break; + } +} + +module.exports = {updateUiState}; \ No newline at end of file diff --git a/src/js/unused.js b/src/js/unused.js deleted file mode 100644 index bcedbed3..00000000 --- a/src/js/unused.js +++ /dev/null @@ -1,110 +0,0 @@ -/* this file contains functions that were used at some point but I ended up removing them. -I'll keep them here so I know where to grab them if I ever need them again. */ - -/* is running -This function will evaluate to true or false if wether certain exe is running with a given name. -I actually found this thing on the internet, I modified it a little bit. What it does is it -calls a process which depends of the operative system installed that returns a list of the -programs that are running. I am not sure if this is the best way to do this, however it seems that -node.js has no "built-in" way of telling if a program is running with a given name. -There is a npm package called ps-node which contains functions to manipulate everythign related to -other processes, I tried it but the execution time of the function was way too much. Either I was -doing something wrong or the package just behaves like that. -A problem I have with this is that I never used Linux nor "darwin" so I lack the means to test this.*/ -function isRunning(win, mac, linux) { - return new Promise(function(resolve, reject) { - const plat = process.platform - switch(plat) { - case 'win32': - cmd = 'tasklist' - proc = win - break; - case 'darwin': - cmd = 'ps -ax | grep ' - proc = mac - break; - case 'linux': - cmd = 'ps -A' - proc = linux - break; - default: - console.log('os not supported heh') - } - - if(cmd === '' || proc === '') { - resolve(false) - } else { - exec(cmd, function(err, stdout, stderr) { - resolve(stdout.toLowerCase().indexOf(proc.toLowerCase()) > -1) - }) - } - /* - a modification I did to this function to return the PID of the process - I removed it because it ended up being unnecesary but I keep it here - just in case. Keep in mind that this commented code segment only works - for windows... - exec(cmd, function(err, stdout, stderr) { - // now we split the output into lines and see - // if we find our process - let lines = stdout.toLowerCase().split('\n') - lines.forEach(function(line) { - if(line.indexOf(proc.toLowerCase()) > -1) { - // now that we found it, we search for the pid - // it should be the first number that pops up - let lines2 = line.split(' ') - lines2.forEach(function(part) { - if(part != '' && !isNaN(part)) { - resolve(part) - } - }) - } - }) - // if the process wasnt found, resolve to -1 - resolve(-1) - })*/ - }) -} - -/* terminate process -Works similar to isRunning, but this time it runs a command to kill a process */ -function terminateProcess (win, mac, linux) { - return new Promise(function(resolve, reject) { - const plat = process.platform - let proc - let cmd - switch(plat) { - case 'win32': - cmd = 'taskkill /T /IM ' - proc = win - break; - case 'darwin': - cmd = 'killall ' - proc = mac - break; - case 'linux': - cmd = 'pkill ' - proc = linux - break; - default: - console.log('os not supported heh') - } - if(cmd === '' || proc === '') { - resolve(false) - } else { - // attach the process name to the command - cmd += proc - // attempt to terminate it - exec(cmd, function(err, stdout, stderr) { - // will resolve to false if nothing happened, most of the time this isn't - // bad since walletd probably wasn't running when the user loaded a wallet. - if (err) { - console.log(stderr) - resolve(false) - } else { - console.log('killed') - resolve(true) - } - }) - } - }) -}