diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b12bd55 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +*.asar diff --git a/README.md b/README.md index f76b972..101b037 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,17 @@ ## Goals - **Hotpluggable** - just swap the asar file, nothing else needed - **Lightweight** - it should be at least as fast or lightweight, hopefully more -- **No Tracking** - no crash reporting, etc +- **No Tracking** - no crash reporting, error tracking, etc - **Minimal** - generally only doing what is needed (see: implementation) ## Implementation Below is a list in order of priority, marked as complete when finished: -- [ ] Stub everything -- [ ] Bootstrapping -- [ ] Splash screen +- [X] Bootstrapping +- [X] Splash screen +- [X] Error handling +- [ ] A bunch of specific minor fixes / features + - [ ] Handle hardware acceleration - [ ] Auto start -- [ ] Updating - - [ ] Updater v1 - - [ ] Updater v2 \ No newline at end of file +- [ ] First run +- [ ] Self-write updater code (currently mostly copied) +- [ ] Self-write some small parts of internals \ No newline at end of file diff --git a/src/Constants.js b/src/Constants.js new file mode 100644 index 0000000..2f0f862 --- /dev/null +++ b/src/Constants.js @@ -0,0 +1,34 @@ +// Bootstrap consts, heavily copied as don't want to mess with it +const { releaseChannel } = require('./utils/buildInfo'); + +const { getSettings } = require('./appSettings'); + +const settings = getSettings(); + +function capitalizeFirstLetter(s) { + return s.charAt(0).toUpperCase() + s.slice(1); +} + +const appNameSuffix = releaseChannel === 'stable' ? '' : capitalizeFirstLetter(releaseChannel); +const APP_COMPANY = 'Discord Inc'; +const APP_DESCRIPTION = 'Discord - https://discord.com'; +const APP_NAME = 'Discord' + appNameSuffix; +const APP_NAME_FOR_HUMANS = 'Discord' + (appNameSuffix !== '' ? ' ' + appNameSuffix : ''); +const APP_ID_BASE = 'com.squirrel'; +const APP_ID = `${APP_ID_BASE}.${APP_NAME}.${APP_NAME}`; +const APP_PROTOCOL = 'Discord'; +const API_ENDPOINT = settings.get('API_ENDPOINT') || 'https://discord.com/api'; +const UPDATE_ENDPOINT = settings.get('UPDATE_ENDPOINT') || API_ENDPOINT; +const NEW_UPDATE_ENDPOINT = settings.get('NEW_UPDATE_ENDPOINT') || 'https://discord.com/api/updates/'; + +module.exports = { + APP_COMPANY, + APP_DESCRIPTION, + APP_NAME, + APP_NAME_FOR_HUMANS, + APP_ID, + APP_PROTOCOL, + API_ENDPOINT, + NEW_UPDATE_ENDPOINT, + UPDATE_ENDPOINT +}; \ No newline at end of file diff --git a/src/GPUSettings.js b/src/GPUSettings.js new file mode 100644 index 0000000..6012783 --- /dev/null +++ b/src/GPUSettings.js @@ -0,0 +1,6 @@ +// Idk why Discord has to use this +exports.replace = (GPUSettings) => { + for (const name of Object.keys(GPUSettings)) { + exports[name] = GPUSettings[name]; + } +}; \ No newline at end of file diff --git a/src/appSettings.js b/src/appSettings.js new file mode 100644 index 0000000..509014a --- /dev/null +++ b/src/appSettings.js @@ -0,0 +1,7 @@ +const Settings = require('./utils/Settings'); +const paths = require('./paths'); + +const settings = new Settings(paths.getUserData()); + +exports.getSettings = () => settings; +exports.init = () => {}; // Stub as we setup on require \ No newline at end of file diff --git a/src/autoStart/index.js b/src/autoStart/index.js new file mode 100644 index 0000000..5ad5088 --- /dev/null +++ b/src/autoStart/index.js @@ -0,0 +1,6 @@ +// Stub for now at least + +exports.install = (callback) => { callback(); }; +exports.update = (callback) => { callback(); }; +exports.uninstall = (callback) => { callback(); }; +exports.isInstalled = (callback) => { callback(true); }; // Stub to true or false? \ No newline at end of file diff --git a/src/bootstrap.js b/src/bootstrap.js new file mode 100644 index 0000000..50c9940 --- /dev/null +++ b/src/bootstrap.js @@ -0,0 +1,63 @@ +const { join } = require('path'); +const NodeModule = require('module'); +const { app } = require('electron'); + +const log = require('./utils/log'); +const requireNative = require('./utils/requireNative'); +const paths = require('./paths'); +const buildInfo = require('./utils/buildInfo'); + +// Just required for startup +const appSettings = require('./appSettings'); +const GPUSettings = require('./GPUSettings'); +const crashReporterSetup = require('./crashReporterSetup'); +const splashScreen = require('./splash/splashScreen'); +const Constants = require('./Constants'); +const autoStart = require('./autoStart'); + +const updater = require('./updater/updater'); +const moduleUpdater = require('./updater/moduleUpdater'); +const appUpdater = require('./updater/appUpdater'); + +let desktopCore; +const startCore = () => { + desktopCore = requireNative('discord_desktop_core'); + log('Bootstrap', 'Required desktop_core:', desktopCore); + + desktopCore.startup({ + paths, + splashScreen, + moduleUpdater, + autoStart, + buildInfo, + appSettings, + Constants, + GPUSettings, + updater, + crashReporterSetup + }); +}; + +const startUpdate = () => { + appUpdater.update(false, () => { + startCore(); + }, () => { + desktopCore.setMainWindowVisible(true); + }); +}; + +module.exports = () => { + // Paths logging + log('Paths', `Init! Returns: +getUserData: ${paths.getUserData()} +getUserDataVersioned: ${paths.getUserDataVersioned()} +getResources: ${paths.getResources()} +getModuleDataPath: ${paths.getModuleDataPath()} +getInstallPath: ${paths.getInstallPath()}`); + + if (app.isReady()) { + startUpdate(); + } else { + app.once('ready', startUpdate); + } +}; \ No newline at end of file diff --git a/src/crashReporterSetup.js b/src/crashReporterSetup.js new file mode 100644 index 0000000..119c733 --- /dev/null +++ b/src/crashReporterSetup.js @@ -0,0 +1,5 @@ +// Much crash reporting, such wow +exports.init = () => {}; +exports.isInitialized = () => true; + +exports.metadata = {}; \ No newline at end of file diff --git a/src/errorHandler.js b/src/errorHandler.js new file mode 100644 index 0000000..b19f545 --- /dev/null +++ b/src/errorHandler.js @@ -0,0 +1,40 @@ +const { app } = require("electron"); + +const log = require('./utils/log'); + +exports.init = () => { + /* process.on('uncaughtException', error => { + const stack = error.stack ? error.stack : String(error); + const message = `Uncaught exception:\n ${stack}`; + console.warn(message); + + if (!isErrorSafeToSuppress(error)) { + _electron.dialog.showErrorBox('A JavaScript error occurred in the main process', message); + } + }); */ +}; + + +exports.fatal = (err) => { + const options = { + type: 'error', + message: 'A fatal Javascript error occured', + detail: err && err.stack ? err.stack : String(err) + }; + + const callback = _ => app.quit(); + + const electronMajor = parseInt(process.versions.electron.split('.')[0]); + + if (electronMajor >= 6) { + _electron.dialog.showMessageBox(null, options).then(callback); + } else { + _electron.dialog.showMessageBox(options, callback); + } + + log('ErrorHandler', 'Fatal:', err); +}; + +exports.handled = (err) => { + log('ErrorHandler', 'Handled:', err); +}; \ No newline at end of file diff --git a/src/firstRun/index.js b/src/firstRun/index.js new file mode 100644 index 0000000..e51a75c --- /dev/null +++ b/src/firstRun/index.js @@ -0,0 +1,3 @@ +// Stub for now at least + +exports.update = (callback) => { callback(); }; \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..3505e7d --- /dev/null +++ b/src/index.js @@ -0,0 +1,7 @@ +const log = require('./utils/log'); + +log('', 'Initing...'); + +const bootstrap = require('./bootstrap'); + +bootstrap(); // Start bootstrap \ No newline at end of file diff --git a/src/ipcMain.js b/src/ipcMain.js new file mode 100644 index 0000000..a8a663e --- /dev/null +++ b/src/ipcMain.js @@ -0,0 +1,5 @@ +// Discord's wrapper around ipcMain +const { ipcMain } = require('electron'); + +exports.on = (event, callback) => ipcMain.on('DISCORD_' + event, callback); +exports.removeListener = (event, callback) => ipcMain.removeListener('DISCORD_' + event, callback); \ No newline at end of file diff --git a/src/package-lock.json b/src/package-lock.json new file mode 100644 index 0000000..43c94eb --- /dev/null +++ b/src/package-lock.json @@ -0,0 +1,873 @@ +{ + "name": "openasar", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "openasar", + "dependencies": { + "mkdirp": "^0.5.1", + "request": "2.88.0", + "yauzl": "^2.10.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/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=", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "engines": { + "node": "*" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/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=" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "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" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dependencies": { + "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" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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==", + "dependencies": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "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=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "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=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "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=" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "requires": { + "mime-db": "1.51.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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" + } + }, + "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" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/src/package.json b/src/package.json index c8d0056..7810b7f 100644 --- a/src/package.json +++ b/src/package.json @@ -1,9 +1,12 @@ { "name": "openasar", - "description": "Discord Client for Desktop - Bootstrapper", + "description": "Open-source alternative of Discord desktop's app.asar", "main": "index.js", "dependencies": { + "mkdirp": "^0.5.1", + "request": "2.88.0", + "yauzl": "^2.10.0" } } \ No newline at end of file diff --git a/src/paths.js b/src/paths.js new file mode 100644 index 0000000..bdae911 --- /dev/null +++ b/src/paths.js @@ -0,0 +1,25 @@ +const { join, dirname, basename } = require('path'); +const { app } = require('electron'); + +const log = require('./utils/log'); +const buildInfo = require('./utils/buildInfo'); + + +const appDir = 'discord' + (buildInfo.releaseChannel === 'stable' ? '' : buildInfo.releaseChannel); // Clean channel naming up later to util? +const userData = join(app.getPath('appData'), appDir); +const userDataVersioned = join(userData, buildInfo.version); + +const exeDir = dirname(app.getPath('exe')); +const installPath = /^app-[0-9]+\.[0-9]+\.[0-9]+/.test(basename(exeDir)) ? join(exeDir, '..') : null; + +const moduleData = buildInfo.newUpdater ? join(userData, 'module_data') : join(userDataVersioned, 'modules'); + + +exports.getUserData = () => userData; +exports.getUserDataVersioned = () => userDataVersioned; + +exports.getResources = () => process.resourcesPath; // Discord uses path and require.main.filename here because ?? +exports.getModuleDataPath = () => moduleData; +exports.getInstallPath = () => installPath; + +exports.init = () => {}; // Stub as we setup on require \ No newline at end of file diff --git a/src/splash/index.html b/src/splash/index.html new file mode 100644 index 0000000..9066141 --- /dev/null +++ b/src/splash/index.html @@ -0,0 +1,89 @@ +
openasar go brr
+ +
+
+ + + + + \ No newline at end of file diff --git a/src/splash/preload.js b/src/splash/preload.js new file mode 100644 index 0000000..a475675 --- /dev/null +++ b/src/splash/preload.js @@ -0,0 +1,36 @@ +"use strict"; + +const { + app, + contextBridge, + ipcRenderer +} = require('electron'); + +const { + saferShellOpenExternal +} = require('../utils/securityUtils'); + +contextBridge.exposeInMainWorld('DiscordSplash', { + getReleaseChannel: () => { + const buildInfo = require('../utils/buildInfo'); + + return buildInfo.releaseChannel; + }, + signalReady: () => { + ipcRenderer.send('DISCORD_SPLASH_SCREEN_READY'); + }, + onStateUpdate: callback => { + ipcRenderer.on('DISCORD_SPLASH_UPDATE_STATE', (_, state) => { + callback(state); + }); + }, + onQuoteUpdate: callback => { + ipcRenderer.on('DISCORD_SPLASH_SCREEN_QUOTE', (_, quote) => { + callback(quote); + }); + }, + openUrl: saferShellOpenExternal, + quitDiscord: () => { + ipcRenderer.send('DISCORD_SPLASH_SCREEN_QUIT'); + } +}); \ No newline at end of file diff --git a/src/splash/splashScreen.js b/src/splash/splashScreen.js new file mode 100644 index 0000000..b647cba --- /dev/null +++ b/src/splash/splashScreen.js @@ -0,0 +1,486 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.initSplash = initSplash; +exports.focusWindow = focusWindow; +exports.pageReady = pageReady; +exports.events = exports.APP_SHOULD_SHOW = exports.APP_SHOULD_LAUNCH = void 0; + +var _electron = require("electron"); + +var _events = require("events"); + +var _fs = _interopRequireDefault(require("fs")); + +var _path = _interopRequireDefault(require("path")); + +var _url = _interopRequireDefault(require("url")); + +var _Backoff = _interopRequireDefault(require("../utils/Backoff")); + +var moduleUpdater = _interopRequireWildcard(require("../updater/moduleUpdater")); + +var paths = _interopRequireWildcard(require("../paths")); + +var _securityUtils = require("../utils/securityUtils"); + +var _updater = require("../updater/updater"); + +var _ipcMain = _interopRequireDefault(require("../ipcMain")); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const UPDATE_TIMEOUT_WAIT = 10000; +const RETRY_CAP_SECONDS = 60; // citron note: atom seems to add about 50px height to the frame on mac but not windows +// TODO: see if we can eliminate fudge by using useContentSize BrowserWindow option + +const LOADING_WINDOW_WIDTH = 300; +const LOADING_WINDOW_HEIGHT = process.platform === 'darwin' ? 300 : 350; // TODO: addModulesListener events should use Module's constants + +const CHECKING_FOR_UPDATES = 'checking-for-updates'; +const UPDATE_CHECK_FINISHED = 'update-check-finished'; +const UPDATE_FAILURE = 'update-failure'; +const LAUNCHING = 'launching'; +const DOWNLOADING_MODULE = 'downloading-module'; +const DOWNLOADING_UPDATES = 'downloading-updates'; +const DOWNLOADING_MODULES_FINISHED = 'downloading-modules-finished'; +const DOWNLOADING_MODULE_PROGRESS = 'downloading-module-progress'; +const DOWNLOADED_MODULE = 'downloaded-module'; +const NO_PENDING_UPDATES = 'no-pending-updates'; +const INSTALLING_MODULE = 'installing-module'; +const INSTALLING_UPDATES = 'installing-updates'; +const INSTALLED_MODULE = 'installed-module'; +const INSTALLING_MODULE_PROGRESS = 'installing-module-progress'; +const INSTALLING_MODULES_FINISHED = 'installing-modules-finished'; +const UPDATE_MANUALLY = 'update-manually'; +const APP_SHOULD_LAUNCH = 'APP_SHOULD_LAUNCH'; +exports.APP_SHOULD_LAUNCH = APP_SHOULD_LAUNCH; +const APP_SHOULD_SHOW = 'APP_SHOULD_SHOW'; +exports.APP_SHOULD_SHOW = APP_SHOULD_SHOW; +const events = new _events.EventEmitter(); +exports.events = events; + +function webContentsSend(win, event, ...args) { + if (win != null && win.webContents != null) { + win.webContents.send(`DISCORD_${event}`, ...args); + } +} + +let splashWindow; +let modulesListeners; +let updateTimeout; +let updateAttempt; +let splashState; +let launchedMainWindow; +let quoteCachePath; +let restartRequired = false; +let newUpdater; +const updateBackoff = new _Backoff.default(1000, 30000); // TODO(eiz): some of this logic should probably not live in the splash. +// +// Disabled because Rust interop stuff is going on in here. + +/* eslint-disable camelcase */ + +class TaskProgress { + constructor() { + this.inProgress = new Map(); + this.finished = new Set(); + this.allTasks = new Set(); + } + + recordProgress(progress, task) { + this.allTasks.add(task.package_sha256); + + if (progress.state !== _updater.TASK_STATE_WAITING) { + this.inProgress.set(task.package_sha256, progress.percent); + + if (progress.state === _updater.TASK_STATE_COMPLETE) { + this.finished.add(task.package_sha256); + } + } + } + + updateSplashState(newState) { + if (this.inProgress.size > 0 && this.inProgress.size > this.finished.size) { + let totalPercent = 0; + + for (const item of this.inProgress.values()) { + totalPercent += item; + } + + totalPercent /= this.allTasks.size; + splashState = { + current: this.finished.size + 1, + total: this.allTasks.size, + progress: totalPercent + }; + updateSplashState(newState); + return true; + } + + return false; + } + +} + +async function updateUntilCurrent() { + const retryOptions = { + skip_host_delta: false, + skip_module_delta: {} + }; + + while (true) { + updateSplashState(CHECKING_FOR_UPDATES); + + try { + let installedAnything = false; + const downloads = new TaskProgress(); + const installs = new TaskProgress(); + await newUpdater.updateToLatestWithOptions(retryOptions, progress => { + const task = progress.task; + const downloadTask = task.HostDownload || task.ModuleDownload; + const installTask = task.HostInstall || task.ModuleInstall; + installedAnything = true; + + if (downloadTask != null) { + downloads.recordProgress(progress, downloadTask); + } + + if (installTask != null) { + installs.recordProgress(progress, installTask); + + if (progress.state.Failed != null) { + if (task.HostInstall != null) { + retryOptions.skip_host_delta = true; + } else if (task.ModuleInstall != null) { + retryOptions.skip_module_delta[installTask.version.module.name] = true; + } + } + } + + if (!downloads.updateSplashState(DOWNLOADING_UPDATES)) { + installs.updateSplashState(INSTALLING_UPDATES); + } + }); + + if (!installedAnything) { + await newUpdater.startCurrentVersion(); + newUpdater.setRunningInBackground(); + newUpdater.collectGarbage(); + launchMainWindow(); + updateBackoff.succeed(); + updateSplashState(LAUNCHING); + return; + } + } catch (e) { + console.error('Update failed', e); + await new Promise(resolve => { + const delayMs = updateBackoff.fail(resolve); + splashState.seconds = Math.round(delayMs / 1000); + updateSplashState(UPDATE_FAILURE); + }); + } + } +} +/* eslint-enable camelcase */ + + +function initOldUpdater() { + modulesListeners = {}; + addModulesListener(CHECKING_FOR_UPDATES, () => { + startUpdateTimeout(); + updateSplashState(CHECKING_FOR_UPDATES); + }); + addModulesListener(UPDATE_CHECK_FINISHED, ({ + succeeded, + updateCount, + manualRequired + }) => { + stopUpdateTimeout(); + + if (!succeeded) { + scheduleUpdateCheck(); + updateSplashState(UPDATE_FAILURE); + } else if (updateCount === 0) { + moduleUpdater.setInBackground(); + launchMainWindow(); + updateSplashState(LAUNCHING); + } + }); + addModulesListener(DOWNLOADING_MODULE, ({ + name, + current, + total + }) => { + stopUpdateTimeout(); + splashState = { + current, + total + }; + updateSplashState(DOWNLOADING_UPDATES); + }); + addModulesListener(DOWNLOADING_MODULE_PROGRESS, ({ + name, + progress + }) => { + splashState.progress = progress; + updateSplashState(DOWNLOADING_UPDATES); + }); + addModulesListener(DOWNLOADED_MODULE, ({ + name, + current, + total, + succeeded + }) => { + delete splashState.progress; + + if (name === 'host') { + restartRequired = true; + } + }); + addModulesListener(DOWNLOADING_MODULES_FINISHED, ({ + succeeded, + failed + }) => { + if (failed > 0) { + scheduleUpdateCheck(); + updateSplashState(UPDATE_FAILURE); + } else { + process.nextTick(() => { + if (restartRequired) { + moduleUpdater.quitAndInstallUpdates(); + } else { + moduleUpdater.installPendingUpdates(); + } + }); + } + }); + addModulesListener(NO_PENDING_UPDATES, () => moduleUpdater.checkForUpdates()); + addModulesListener(INSTALLING_MODULE, ({ + name, + current, + total + }) => { + splashState = { + current, + total + }; + updateSplashState(INSTALLING_UPDATES); + }); + addModulesListener(INSTALLED_MODULE, ({ + name, + current, + total, + succeeded + }) => delete splashState.progress); + addModulesListener(INSTALLING_MODULE_PROGRESS, ({ + name, + progress + }) => { + splashState.progress = progress; + updateSplashState(INSTALLING_UPDATES); + }); + addModulesListener(INSTALLING_MODULES_FINISHED, ({ + succeeded, + failed + }) => moduleUpdater.checkForUpdates()); + addModulesListener(UPDATE_MANUALLY, ({ + newVersion + }) => { + splashState.newVersion = newVersion; + updateSplashState(UPDATE_MANUALLY); + }); +} + +function initSplash(startMinimized = false) { + splashState = {}; + launchedMainWindow = false; + updateAttempt = 0; + newUpdater = (0, _updater.getUpdater)(); + + if (newUpdater == null) { + initOldUpdater(); + } + + launchSplashWindow(startMinimized); + quoteCachePath = _path.default.join(paths.getUserData(), 'quotes.json'); + + _ipcMain.default.on('UPDATED_QUOTES', (_event, quotes) => cacheLatestQuotes(quotes)); +} + +function destroySplash() { + stopUpdateTimeout(); + + if (splashWindow) { + splashWindow.setSkipTaskbar(true); // defer the window hiding for a short moment so it gets covered by the main window + + const _nukeWindow = () => { + if (splashWindow != null) { + splashWindow.hide(); + splashWindow.close(); + splashWindow = null; + } + }; + + setTimeout(_nukeWindow, 100); + } +} + +function addModulesListener(event, listener) { + if (newUpdater != null) return; + modulesListeners[event] = listener; + moduleUpdater.events.addListener(event, listener); +} + +function removeModulesListeners() { + if (newUpdater != null) return; + + for (const event of Object.keys(modulesListeners)) { + moduleUpdater.events.removeListener(event, modulesListeners[event]); + } +} + +function startUpdateTimeout() { + if (!updateTimeout) { + updateTimeout = setTimeout(() => scheduleUpdateCheck(), UPDATE_TIMEOUT_WAIT); + } +} + +function stopUpdateTimeout() { + if (updateTimeout) { + clearTimeout(updateTimeout); + updateTimeout = null; + } +} + +function updateSplashState(event) { + if (splashWindow != null && !splashWindow.isDestroyed() && !splashWindow.webContents.isDestroyed()) { + webContentsSend(splashWindow, 'SPLASH_UPDATE_STATE', { + status: event, + ...splashState + }); + } +} + +function launchSplashWindow(startMinimized) { + const windowConfig = { + width: LOADING_WINDOW_WIDTH, + height: LOADING_WINDOW_HEIGHT, + transparent: false, + frame: false, + resizable: false, + center: true, + show: false, + webPreferences: { + nodeIntegration: false, + enableRemoteModule: false, + contextIsolation: true, + preload: _path.default.join(__dirname, 'preload.js') + } + }; + splashWindow = new _electron.BrowserWindow(windowConfig); // prevent users from dropping links to navigate in splash window + + splashWindow.webContents.on('will-navigate', e => e.preventDefault()); + splashWindow.webContents.on('new-window', (e, windowURL) => { + e.preventDefault(); + (0, _securityUtils.saferShellOpenExternal)(windowURL); // exit, but delay half a second because openExternal is about to fire + // some events to things that are freed by app.quit. + + setTimeout(_electron.app.quit, 500); + }); + + if (process.platform !== 'darwin') { + // citron note: this causes a crash on quit while the window is open on osx + splashWindow.on('closed', () => { + splashWindow = null; + + if (!launchedMainWindow) { + // user has closed this window before we launched the app, so let's quit + _electron.app.quit(); + } + }); + } + + _ipcMain.default.on('SPLASH_SCREEN_READY', () => { + const cachedQuote = chooseCachedQuote(); + + if (cachedQuote) { + webContentsSend(splashWindow, 'SPLASH_SCREEN_QUOTE', cachedQuote); + } + + if (splashWindow && !startMinimized) { + splashWindow.show(); + } + + if (newUpdater != null) { + updateUntilCurrent(); + } else { + moduleUpdater.installPendingUpdates(); + } + }); + + _ipcMain.default.on('SPLASH_SCREEN_QUIT', () => { + _electron.app.quit(); + }); + + const splashUrl = _url.default.format({ + protocol: 'file', + slashes: true, + pathname: _path.default.join(__dirname, 'index.html') + }); + + splashWindow.loadURL(splashUrl); +} + +function launchMainWindow() { + removeModulesListeners(); + + if (!launchedMainWindow && splashWindow != null) { + launchedMainWindow = true; + events.emit(APP_SHOULD_LAUNCH); + } +} + +function scheduleUpdateCheck() { + // TODO: can we use backoff here? + updateAttempt += 1; + const retryInSeconds = Math.min(updateAttempt * 10, RETRY_CAP_SECONDS); + splashState.seconds = retryInSeconds; + setTimeout(() => moduleUpdater.checkForUpdates(), retryInSeconds * 1000); +} + +function focusWindow() { + if (splashWindow != null) { + splashWindow.focus(); + } +} + +function pageReady() { + destroySplash(); + process.nextTick(() => events.emit(APP_SHOULD_SHOW)); +} + +function cacheLatestQuotes(quotes) { + _fs.default.writeFile(quoteCachePath, JSON.stringify(quotes), e => { + if (e) { + console.warn('Failed updating quote cache with error: ', e); + } + }); +} + +function chooseCachedQuote() { + let cachedQuote = null; + + try { + const cachedQuotes = JSON.parse(_fs.default.readFileSync(quoteCachePath)); + cachedQuote = cachedQuotes[Math.floor(Math.random() * cachedQuotes.length)]; + } catch (_err) {} + + return cachedQuote; +} \ No newline at end of file diff --git a/src/splash/splashScreen.js.self b/src/splash/splashScreen.js.self new file mode 100644 index 0000000..d76e875 --- /dev/null +++ b/src/splash/splashScreen.js.self @@ -0,0 +1,95 @@ +const { BrowserWindow, app } = require('electron'); + +const { format } = require('url'); +const { join } = require('path'); + +const ipcMain = require('../ipcMain'); + + +const LOADING_WINDOW_WIDTH = 300; +const LOADING_WINDOW_HEIGHT = process.platform === 'darwin' ? 300 : 350; // TODO: addModulesListener events should use Module's constants + +let window; + +const APP_SHOULD_LAUNCH = 'APP_SHOULD_LAUNCH'; +exports.APP_SHOULD_LAUNCH = APP_SHOULD_LAUNCH; +const APP_SHOULD_SHOW = 'APP_SHOULD_SHOW'; +exports.APP_SHOULD_SHOW = APP_SHOULD_SHOW; +const events = new (require('events')).EventEmitter(); + +exports.events = events; + +exports.initSplash = (startMinimized = false) => { // Make splash window + const windowConfig = { + width: LOADING_WINDOW_WIDTH, + height: LOADING_WINDOW_HEIGHT, + transparent: false, + frame: false, + resizable: false, + center: true, + show: false, + webPreferences: { + nodeIntegration: false, + enableRemoteModule: false, + contextIsolation: true, + preload: join(__dirname, 'preload.js') + } + }; + + window = new BrowserWindow(windowConfig); + + window.on('closed', () => { // Quit app on splash screen close + app.quit(); + window = null; + }); + + + // IPC "handlers" + ipcMain.on('SPLASH_SCREEN_READY', () => { + if (!startMinimized && window) window.show(); + + // Update and stuff + + events.emit(APP_SHOULD_LAUNCH); + }); + + if (!startMinimized && window) window.show(); + + // Update and stuff + + events.emit(APP_SHOULD_LAUNCH); + + ipcMain.on('SPLASH_SCREEN_QUIT', () => { + app.quit(); + }); + + const splashUrl = format({ + protocol: 'file', + slashes: true, + pathname: join(__dirname, 'index.html') + }); + + window.loadURL(splashUrl); +}; + +exports.focusWindow = () => { // Focus splash window + if (window) window.focus(); +}; + +const killWindow = () => { + if (!window) return; + + window.setSkipTaskbar(true); + + setTimeout(() => { + window.hide(); + window.close(); + window = null; + }, 100); +}; + +exports.pageReady = () => { // Kill splash window, emit + killWindow(); + + process.nextTick(() => events.emit(APP_SHOULD_SHOW)); +}; \ No newline at end of file diff --git a/src/splash/web/a934ab008c7f6a2274ec441f6be0696a.woff b/src/splash/web/a934ab008c7f6a2274ec441f6be0696a.woff new file mode 100644 index 0000000..98aa239 Binary files /dev/null and b/src/splash/web/a934ab008c7f6a2274ec441f6be0696a.woff differ diff --git a/src/splash/web/abddffb32a4a35627c3857a06c751424.png b/src/splash/web/abddffb32a4a35627c3857a06c751424.png new file mode 100644 index 0000000..909b729 Binary files /dev/null and b/src/splash/web/abddffb32a4a35627c3857a06c751424.png differ diff --git a/src/splash/web/d153359b5d87601d2b9c708b7ae2db02.woff b/src/splash/web/d153359b5d87601d2b9c708b7ae2db02.woff new file mode 100644 index 0000000..2a2f65a Binary files /dev/null and b/src/splash/web/d153359b5d87601d2b9c708b7ae2db02.woff differ diff --git a/src/splash/web/index.html b/src/splash/web/index.html new file mode 100644 index 0000000..5dec1de --- /dev/null +++ b/src/splash/web/index.html @@ -0,0 +1,11 @@ + + + + + Discord Updater + + +
+ + + diff --git a/src/splash/web/index.js b/src/splash/web/index.js new file mode 100644 index 0000000..9ea6c28 --- /dev/null +++ b/src/splash/web/index.js @@ -0,0 +1,41 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=27)}([function(e,t,n){e.exports=n(25)()},function(e,t,n){"use strict";e.exports=n(18)},function(e,t,n){"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE){0;try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}}(),e.exports=n(19)},function(e,t,n){var r; +/*! + Copyright (c) 2018 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}(this.props,[]);return function(e){c.forEach((function(t){return delete e[t]}))}(a),a.className=this.props.inputClassName,a.id=this.state.inputId,a.style=n,l.default.createElement("div",{className:this.props.className,style:t},this.renderStyles(),l.default.createElement("input",r({},a,{ref:this.inputRef})),l.default.createElement("div",{ref:this.sizerRef,style:s},e),this.props.placeholder?l.default.createElement("div",{ref:this.placeHolderSizerRef,style:s},this.props.placeholder):null)}}]),t}(o.Component);h.propTypes={className:i.default.string,defaultValue:i.default.any,extraWidth:i.default.oneOfType([i.default.number,i.default.string]),id:i.default.string,injectStyles:i.default.bool,inputClassName:i.default.string,inputRef:i.default.func,inputStyle:i.default.object,minWidth:i.default.oneOfType([i.default.number,i.default.string]),onAutosize:i.default.func,onChange:i.default.func,placeholder:i.default.string,placeholderIsMinWidth:i.default.bool,style:i.default.object,value:i.default.any},h.defaultProps={minWidth:1,injectStyles:!0},t.default=h},function(e,t,n){var r=n(10);"string"==typeof r&&(r=[[e.i,r,""]]);var a={hmr:!0,transform:void 0};n(16)(r,a);r.locals&&(e.exports=r.locals)},function(e,t,n){var r=n(11);(t=e.exports=n(6)(!1)).i(n(12),""),t.push([e.i,"@font-face {\n font-family: Whitney;\n font-style: normal;\n font-weight: 400;\n src: url("+r(n(13))+") format('woff');\n}\n@font-face {\n font-family: Whitney;\n font-style: medium;\n font-weight: 600;\n src: url("+r(n(14))+') format(\'woff\');\n}\n* {\n box-sizing: border-box;\n -webkit-user-select: none;\n cursor: default;\n}\nbody,\nhtml {\n -webkit-app-region: drag;\n padding: 0;\n margin: 0;\n overflow: hidden;\n width: 300px;\n height: 300px;\n}\n#splash {\n -webkit-app-region: drag;\n background: #282b30;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 3000;\n transform: translateZ(0);\n padding-bottom: 10px;\n}\n#splash .splash-inner {\n text-align: center;\n}\n#splash .splash-inner img,\n#splash .splash-inner video {\n size: 200px;\n}\n#splash .splash-inner video {\n visibility: hidden;\n}\n#splash .splash-inner video.loaded {\n visibility: visible;\n}\n#splash .splash-inner .splash-text {\n position: relative;\n top: -30px;\n}\n#splash .splash-inner .splash-text > span {\n color: #8a8e94;\n font-size: 12px;\n font-family: Whitney, "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;\n font-weight: 600;\n text-transform: uppercase;\n display: block;\n}\n#splash .splash-inner .splash-text > span.splash-status {\n color: #fff;\n font-weight: 400;\n font-style: italic;\n font-size: 16px;\n}\n#splash .splash-inner-dl .dice-image {\n position: absolute;\n left: 77px;\n top: 45px;\n width: 146px;\n height: 100px;\n background: url('+r(n(15))+') center center no-repeat;\n background-size: 146px 100px;\n}\n#splash .splash-inner-dl .dl-update-message {\n font-family: Whitney, "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;\n font-style: medium;\n font-size: 18px;\n color: #fff;\n padding-left: 20px;\n padding-right: 20px;\n top: 169px;\n left: 0;\n margin: 0;\n position: absolute;\n text-align: center;\n}\n#splash .splash-inner-dl .dl-version-message {\n font-family: Whitney, "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;\n font-style: medium;\n font-size: 12px;\n color: #8a8e94;\n text-transform: uppercase;\n position: absolute;\n width: 100%;\n bottom: 12px;\n left: 0;\n margin: 0;\n text-align: center;\n}\n#splash .splash-inner-dl .dl-select-frame {\n -webkit-app-region: no-drag;\n font-family: Whitney, "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;\n overflow: hidden;\n position: absolute;\n width: 100%;\n height: 130px;\n top: 220px;\n left: 0;\n margin: 0;\n}\n#splash .splash-inner-dl .dl-select-frame .Select {\n position: absolute;\n left: 0;\n top: 0;\n width: 165px;\n height: 44px;\n margin-left: 20px;\n margin-right: 10px;\n color: #fff;\n}\n#splash .splash-inner-dl .dl-select-frame .Select-control {\n border: 1px solid;\n border-color: rgba(255,255,255,0.3);\n border-radius: 3px;\n background: #282b30;\n height: 44px;\n}\n#splash .splash-inner-dl .dl-select-frame .Select-menu-outer {\n background: #282b30;\n}\n#splash .splash-inner-dl .dl-select-frame .Select-menu {\n max-height: 80px;\n}\n#splash .splash-inner-dl .dl-select-frame .Select-option {\n color: #8a8e94;\n line-height: 15px;\n padding: 5px 10px;\n}\n#splash .splash-inner-dl .dl-select-frame .Select-option.is-focused {\n color: #fff;\n background-color: #4e59e0;\n}\n#splash .splash-inner-dl .dl-select-frame .Select-value {\n color: #fff;\n bottom: 0;\n align-items: center;\n display: flex;\n}\n#splash .splash-inner-dl .dl-select-frame .Select-input {\n outline: none;\n}\n#splash .splash-inner-dl .dl-select-frame .dl-button {\n position: absolute;\n left: 195px;\n top: 0;\n width: 85px;\n height: 44px;\n background-color: #5865f2;\n color: #fff;\n font-size: 14px;\n font-weight: 600;\n border-radius: 3px;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n#splash .splash-inner-dl .dl-select-frame .dl-button:hover {\n background-color: #4e59e0;\n}\n.progress {\n display: flex;\n justify-content: center;\n margin-top: 10px;\n}\n.progress .progress-bar {\n height: 8px;\n border-radius: 4px;\n width: 180px;\n background-color: rgba(255,255,255,0.1);\n}\n.progress .progress-bar .complete {\n border-radius: 4px;\n box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.1), inset 0px 1px 0px 0px rgba(255,255,255,0.1);\n height: 100%;\n background-color: #737f8d;\n}\n.progress-placeholder {\n margin-top: 10px;\n height: 8px;\n}\n',""])},function(e,t){e.exports=function(e){return"string"!=typeof e?e:(/^['"].*['"]$/.test(e)&&(e=e.slice(1,-1)),/["'() \t\n]/.test(e)?'"'+e.replace(/"/g,'\\"').replace(/\n/g,"\\n")+'"':e)}},function(e,t,n){(e.exports=n(6)(!1)).push([e.i,"/**\n * React Select\n * ============\n * Created by Jed Watson and Joss Mackison for KeystoneJS, http://www.keystonejs.com/\n * https://twitter.com/jedwatson https://twitter.com/jossmackison https://twitter.com/keystonejs\n * MIT License: https://github.com/keystonejs/react-select\n*/\n.Select {\n position: relative;\n}\n.Select,\n.Select div,\n.Select input,\n.Select span {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n.Select.is-disabled > .Select-control {\n background-color: #f6f6f6;\n}\n.Select.is-disabled .Select-arrow-zone {\n cursor: default;\n pointer-events: none;\n}\n.Select-control {\n background-color: #fff;\n border-color: #d9d9d9 #ccc #b3b3b3;\n border-radius: 4px;\n border: 1px solid #ccc;\n color: #333;\n cursor: default;\n display: table;\n height: 36px;\n outline: none;\n overflow: hidden;\n position: relative;\n width: 100%;\n}\n.Select-control:hover {\n box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);\n}\n.is-searchable.is-open > .Select-control {\n cursor: text;\n}\n.is-open > .Select-control {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n background: #fff;\n border-color: #b3b3b3 #ccc #d9d9d9;\n}\n.is-open > .Select-control > .Select-arrow {\n border-color: transparent transparent #999;\n border-width: 0 5px 5px;\n}\n.is-searchable.is-focused:not(.is-open) > .Select-control {\n cursor: text;\n}\n.is-focused:not(.is-open) > .Select-control {\n border-color: #08c #0099e6 #0099e6;\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 0 5px -1px rgba(0, 136, 204, 0.5);\n}\n.Select-placeholder {\n bottom: 0;\n color: #aaa;\n left: 0;\n line-height: 34px;\n padding-left: 10px;\n padding-right: 10px;\n position: absolute;\n right: 0;\n top: 0;\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.has-value > .Select-control > .Select-placeholder {\n color: #333;\n}\n.Select-value {\n color: #aaa;\n left: 0;\n padding: 8px 52px 8px 10px;\n position: absolute;\n right: -15px;\n top: 0;\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.has-value > .Select-control > .Select-value {\n color: #333;\n}\n.Select-input {\n height: 34px;\n padding-left: 10px;\n padding-right: 10px;\n vertical-align: middle;\n}\n.Select-input > input {\n background: none transparent;\n border: 0 none;\n box-shadow: none;\n cursor: default;\n display: inline-block;\n font-family: inherit;\n font-size: inherit;\n height: 34px;\n margin: 0;\n outline: none;\n padding: 0;\n -webkit-appearance: none;\n}\n.is-focused .Select-input > input {\n cursor: text;\n}\n.Select-control:not(.is-searchable) > .Select-input {\n outline: none;\n}\n.Select-loading-zone {\n cursor: pointer;\n display: table-cell;\n position: relative;\n text-align: center;\n vertical-align: middle;\n width: 16px;\n}\n.Select-loading {\n -webkit-animation: Select-animation-spin 400ms infinite linear;\n -o-animation: Select-animation-spin 400ms infinite linear;\n animation: Select-animation-spin 400ms infinite linear;\n width: 16px;\n height: 16px;\n box-sizing: border-box;\n border-radius: 50%;\n border: 2px solid #ccc;\n border-right-color: #333;\n display: inline-block;\n position: relative;\n vertical-align: middle;\n}\n.Select-clear-zone {\n -webkit-animation: Select-animation-fadeIn 200ms;\n -o-animation: Select-animation-fadeIn 200ms;\n animation: Select-animation-fadeIn 200ms;\n color: #999;\n cursor: pointer;\n display: table-cell;\n position: relative;\n text-align: center;\n vertical-align: middle;\n width: 17px;\n}\n.Select-clear-zone:hover {\n color: #d0021b;\n}\n.Select-clear {\n display: inline-block;\n font-size: 18px;\n line-height: 1;\n}\n.Select--multi .Select-clear-zone {\n width: 17px;\n}\n.Select-arrow-zone {\n cursor: pointer;\n display: table-cell;\n position: relative;\n text-align: center;\n vertical-align: middle;\n width: 25px;\n padding-right: 5px;\n}\n.Select-arrow {\n border-color: #999 transparent transparent;\n border-style: solid;\n border-width: 5px 5px 2.5px;\n display: inline-block;\n height: 0;\n width: 0;\n}\n.is-open .Select-arrow,\n.Select-arrow-zone:hover > .Select-arrow {\n border-top-color: #666;\n}\n@-webkit-keyframes Select-animation-fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes Select-animation-fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.Select-menu-outer {\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n background-color: #fff;\n border: 1px solid #ccc;\n border-top-color: #e6e6e6;\n box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);\n box-sizing: border-box;\n margin-top: -1px;\n max-height: 200px;\n position: absolute;\n top: 100%;\n width: 100%;\n z-index: 1000;\n -webkit-overflow-scrolling: touch;\n}\n.Select-menu {\n max-height: 198px;\n overflow-y: auto;\n}\n.Select-option {\n box-sizing: border-box;\n color: #666666;\n cursor: pointer;\n display: block;\n padding: 8px 10px;\n}\n.Select-option:last-child {\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.Select-option.is-focused {\n background-color: #f2f9fc;\n color: #333;\n}\n.Select-option.is-disabled {\n color: #cccccc;\n cursor: not-allowed;\n}\n.Select-noresults,\n.Select-search-prompt,\n.Select-searching {\n box-sizing: border-box;\n color: #999999;\n cursor: default;\n display: block;\n padding: 8px 10px;\n}\n.Select--multi .Select-input {\n vertical-align: middle;\n margin-left: 10px;\n padding: 0;\n}\n.Select--multi.has-value .Select-input {\n margin-left: 5px;\n}\n.Select-item {\n background-color: #f2f9fc;\n border-radius: 2px;\n border: 1px solid #c9e6f2;\n color: #08c;\n display: inline-block;\n font-size: 0.9em;\n margin-left: 5px;\n margin-top: 5px;\n vertical-align: top;\n}\n.Select-item-icon,\n.Select-item-label {\n display: inline-block;\n vertical-align: middle;\n}\n.Select-item-label {\n border-bottom-right-radius: 2px;\n border-top-right-radius: 2px;\n cursor: default;\n padding: 2px 5px;\n}\n.Select-item-label .Select-item-label__a {\n color: #08c;\n cursor: pointer;\n}\n.Select-item-icon {\n cursor: pointer;\n border-bottom-left-radius: 2px;\n border-top-left-radius: 2px;\n border-right: 1px solid #c9e6f2;\n padding: 1px 5px 3px;\n}\n.Select-item-icon:hover,\n.Select-item-icon:focus {\n background-color: #ddeff7;\n color: #0077b3;\n}\n.Select-item-icon:active {\n background-color: #c9e6f2;\n}\n.Select--multi.is-disabled .Select-item {\n background-color: #f2f2f2;\n border: 1px solid #d9d9d9;\n color: #888;\n}\n.Select--multi.is-disabled .Select-item-icon {\n cursor: not-allowed;\n border-right: 1px solid #d9d9d9;\n}\n.Select--multi.is-disabled .Select-item-icon:hover,\n.Select--multi.is-disabled .Select-item-icon:focus,\n.Select--multi.is-disabled .Select-item-icon:active {\n background-color: #f2f2f2;\n}\n@keyframes Select-animation-spin {\n to {\n transform: rotate(1turn);\n }\n}\n@-webkit-keyframes Select-animation-spin {\n to {\n -webkit-transform: rotate(1turn);\n }\n}\n",""])},function(e,t,n){e.exports=n.p+"d153359b5d87601d2b9c708b7ae2db02.woff"},function(e,t,n){e.exports=n.p+"a934ab008c7f6a2274ec441f6be0696a.woff"},function(e,t,n){e.exports=n.p+"abddffb32a4a35627c3857a06c751424.png"},function(e,t,n){var r,a,o={},l=(r=function(){return window&&document&&document.all&&!window.atob},function(){return void 0===a&&(a=r.apply(this,arguments)),a}),i=function(e){var t={};return function(n){if(void 0===t[n]){var r=e.call(this,n);if(r instanceof window.HTMLIFrameElement)try{r=r.contentDocument.head}catch(e){r=null}t[n]=r}return t[n]}}((function(e){return document.querySelector(e)})),u=null,s=0,c=[],f=n(17);function p(e,t){for(var n=0;n=0&&c.splice(t,1)}function v(e){var t=document.createElement("style");return e.attrs.type="text/css",g(t,e.attrs),h(e,t),t}function g(e,t){Object.keys(t).forEach((function(n){e.setAttribute(n,t[n])}))}function y(e,t){var n,r,a,o;if(t.transform&&e.css){if(!(o=t.transform(e.css)))return function(){};e.css=o}if(t.singleton){var l=s++;n=u||(u=v(t)),r=w.bind(null,n,l,!1),a=w.bind(null,n,l,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return e.attrs.type="text/css",e.attrs.rel="stylesheet",g(t,e.attrs),h(e,t),t}(t),r=S.bind(null,n,t),a=function(){m(n),n.href&&URL.revokeObjectURL(n.href)}):(n=v(t),r=k.bind(null,n),a=function(){m(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else a()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||(t.singleton=l()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=d(e,t);return p(n,t),function(e){for(var r=[],a=0;a