{"version":3,"sources":["jsdelivr-header.js","/npm/@aladas-org/cryptocalc@0.4.25/www/js/_main/electron_main.js"],"names":[],"mappings":"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","file":"/npm/@aladas-org/cryptocalc@0.4.25/www/js/_main/electron_main.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@aladas-org/cryptocalc@0.4.25/www/js/_main/electron_main.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// ====================================================================================\r\n// ===============================   electron_main.js   ===============================\r\n// ====================================================================================\r\n// https://www.electronjs.org/docs/latest/tutorial/quick-start\r\n\"use strict\";\r\n\r\n// ===============================  ElectronMain class  ===============================\r\n// NB: \"Singleton\" class\r\n// * static GetInstance()\r\n//          createBrowserWindow( url )\r\n// *        getMainWindow()\r\n// *        getMenuTemplate()\r\n// *        createWindow()\r\n//          updateWindowTitle()\r\n//\r\n// * async  doFileNew()\r\n// *        doFileSave()\r\n// * async  doFileOpen()\r\n// * async  doFileRead( json_data )\r\n//\r\n//          showFolderInExplorer()\r\n//\r\n// *        getNewFortuneCookie()\r\n// *        toggleDebugPanel()\r\n// *        getUserSelectedFile()\r\n//\r\n//          readOptionsFile()\r\n// * async  loadOptions()\r\n// * async  setDefaultOptions()\r\n// * async  updateOptions( options_data )\r\n// * async  saveOptions( options_data )\r\n// * async  resetOptions()\r\n//\r\n// *        setCallbacks()\r\n// ------------------------------------------------------\r\nconst MAIN_WINDOW_WIDTH  = 1040; // NB: 'width' is wider because of 'Cardano'\r\nconst MAIN_WINDOW_HEIGHT = 651; \r\n\r\nconst { app, Menu, BrowserWindow, ipcMain, \r\n        shell, remote, dialog } = require('electron');\t\r\n\t\t// https://stackoverflow.com/questions/35916158/how-to-prevent-multiple-instances-in-electron\r\n\r\nrequire('v8-compile-cache');\r\n\r\nconst os       = require('os');\r\nconst { exec } = require('child_process');\r\n\r\n// https://nodejs.org/api/os.html#os_os_platform\r\n// 'aix', 'darwin', 'freebsd', 'linux', 'openbsd', 'sunos', 'win32'\r\nconst WINDOWS  = \"win32\"; \r\nconst LINUX    = \"linux\";\r\nconst FREE_BSD = \"freebsd\";\r\nconst OPEN_BSD = \"openbsd\";\r\n\r\nconst fs               = require('fs');\r\nconst path             = require('path');\r\nconst { v4: uuidv4 }   = require('uuid');\r\n\r\nconst checkInternetConnected = require('check-internet-connected');\r\n\r\nconst PasswordGenerator = require('generate-password');\r\n\r\nconst { _CYAN_, _RED_, _PURPLE_, _YELLOW_, _END_ \r\n\t  }                = require('../util/color/color_console_codes.js');\r\n\t  \r\nconst { pretty_func_header_log,\r\n        pretty_log }   = require('../util/log/log_utils.js');\r\n\t\t\r\nconst { Skribi }       = require('../util/log/skribi.js');\t\t\r\n\t  \r\nconst { APP_VERSION, \r\n        PROGRAM, ELECTRON_LAUNCHER, EXE_LAUNCHER, \r\n\t\tWITS_PATH, PATH, ARGS,\r\n      }                = require('../const_keywords.js');\r\n\r\nconst { CMD_OPEN_WALLET,\r\n        VIEW_TOGGLE_DEVTOOLS, \r\n\t\t\r\n\t\tTOOLS_OPTIONS, TOOLS_BIP38_ENCRYPTER_DECRYTER, TOOLS_SECRET_PHRASE_TRANSLATOR,\r\n\t\t\r\n        ToMain_RQ_QUIT_APP, \r\n\t\tToMain_RQ_LOG_2_MAIN, ToMain_RQ_LOG_2_MAIN_SYNC,\r\n\t\t\r\n\t\tToMain_RQ_EXEC_CMD,\r\n\t\t\r\n\t\tToMain_RQ_SET_WINDOW_TITLE, ToMain_RQ_TOGGLE_DEBUG_PANEL,\r\n\t\t\r\n\t\tToMain_RQ_NEW_WALLET_INFO, ToMain_RQ_OPEN_WALLET_INFO, ToMain_RQ_SAVE_WALLET_INFO, \r\n\t\t\r\n\t\tToMain_RQ_OPEN_URL, ToMain_RQ_SHOW_OUTPUT_FOLDER_IN_EXPLORER,\r\n\t\tToMain_RQ_LOAD_IMG_FROM_FILE, ToMain_RQ_DRAW_RND_CRYPTO_LOGO,\r\n\t\t\r\n\t\tToMain_RQ_MNEMONICS_TO_ENTROPY_INFO, \r\n\t\t\r\n\t\tToMain_RQ_MNEMONICS_TO_HD_WALLET_INFO, \r\n\t\tToMain_RQ_GET_SIMPLE_WALLET,\t\t\r\n\t\t\r\n\t\tToMain_RQ_ENTROPY_TO_MNEMONICS, ToMain_RQ_ENTROPY_TO_CHECKSUM,\r\n\t\tToMain_RQ_ENTROPY_SRC_TO_ENTROPY,\t\r\n\r\n\t\tToMain_RQ_MNEMONICS_AS_4LETTER, ToMain_RQ_MNEMONICS_AS_TWO_PARTS,\r\n        ToMain_RQ_GET_UUID, \r\n\t\t\r\n\t\tToMain_RQ_GET_L10N_KEYPAIRS, ToMain_RQ_GET_L10N_MSG, \r\n\t\t\r\n\t\tToMain_RQ_SET_MENU_ITEM_STATE,\r\n\t\t\r\n\t\tToMain_RQ_CHECK_MNEMONICS, \r\n\t\t\r\n\t\tToMain_RQ_WORD_INDEXES_TO_MNEMONICS,\r\n\t\tToMain_RQ_MNEMONICS_TO_WORD_INDEXES, \r\n\t\t\r\n\t\tToMain_RQ_GUESS_MNEMONICS_LANG,\t\t\r\n\t\tToMain_RQ_SAVE_OPTIONS, ToMain_RQ_RESET_OPTIONS, ToMain_RQ_UPDATE_OPTIONS,\r\n\t\tToMain_RQ_GET_FORTUNE_COOKIE,\t\r\n\r\n        ToMain_RQ_GENERATE_PASSWORD,\t\t\r\n\t\t\r\n\t\tToMain_RQ_GET_HD_WALLET,\t\r\n\t\t\r\n\t\tToMain_RQ_BIP38_ENCRYPT, ToMain_RQ_BIP38_DECRYPT,\r\n\t\t\r\n\t\tToMain_RQ_GET_PASSWORD_STRENGTH,\r\n\t\t\r\n\t\tFromMain_DID_FINISH_LOAD, FromMain_EXEC_CMD,\r\n\t\t\r\n\t\tFromMain_FILE_NEW, FromMain_FILE_OPEN, FromMain_FILE_SAVE, \r\n\t\tFromMain_HELP_ABOUT,\r\n\r\n\t\tFromMain_TOOLS_OPTIONS_DIALOG, FromMain_TOOLS_BIP38_ENCRYPT_DECRYPT_DIALOG,\r\n\t\tFromMain_TOOLS_SECRET_PHRASE_TRANSLATOR_DIALOG,\r\n\t\t\r\n\t\tFromMain_UPDATE_OPTIONS, \r\n\t\tFromMain_SEND_IMG_URL,\r\n\t\tFromMain_SET_FORTUNE_COOKIE, \r\n        FromMain_SET_VARIABLE,\r\n\t\tFromMain_INTERNET_CONNECTED\t\t\r\n\t  }                                 = require('../const_events.js');\r\n\t  \r\nconst { ENTROPY_SOURCE_IMG_ID\r\n      }                                 = require('../view/const_gui.js');\r\n\r\nconst { DEFAULT_OPTIONS\r\n      }                                 = require('../crypto/const_default_options.js');\r\n\t  \r\nconst { getShortenedString }            = require('../util/values/string_utils.js');\t  \r\nconst { FileUtils }                     = require('../util/system/file_utils.js');\r\n\r\nconst { Bip39Utils }                    = require('../crypto/bip39_utils.js');\r\nconst { Bip38Utils }                    = require('../crypto/bip38_utils.js');\r\n\r\nconst { PasswordStrengthEvaluator }     = require('../crypto/password_strength_evaluator.js');\r\n\r\nconst { getRandomInt  }                 = require('../crypto/hex_utils.js');\r\nconst { getFortuneCookie }              = require('../util/fortune/fortune.js');\r\nconst { L10nUtils }                     = require('../L10n/L10n_utils.js');\r\n\r\nconst { Bip32Utils }                    = require('../crypto/HDWallet/bip32_utils.js');\r\nconst { HDWallet }                      = require('../crypto/HDWallet/hd_wallet.js');\r\nconst { SimpleWallet }                  = require('../crypto/SimpleWallet/simple_wallet.js');\r\n\r\nconst { MainModel }                     = require('../model/main_model.js');\r\n\r\nconst DEFAULT_APP_CONFIG = {\r\n\t\"ToFile\": true\r\n}; // DEFAULT_APP_CONFIG\r\n\r\nconst gotTheLock = app.requestSingleInstanceLock();\r\n\r\nconst error_handler = (err) => { \r\n\tif (err) return Skribi.log(\"error: \" + err);\r\n\tSkribi.log('saving file... '+ filename); \r\n}; // error_handler()\r\n\r\nclass ElectronMain {\r\n\tstatic #Key = Symbol();\r\n\tstatic #Singleton = new ElectronMain( this.#Key );\r\n\tstatic #InstanceCount = 0;\r\n\t\r\n\t// Note: KO static get This() {\r\n\tstatic GetInstance() {\r\n\t\tif ( ElectronMain.#Singleton == undefined ) {\r\n\t\t\tthis.#Singleton = new ElectronMain( this.#Key );\r\n\t\t\tif ( this.#InstanceCount > 0 ) {\r\n\t\t\t\tthrow new TypeError(\"'ElectronMain' constructor called more than once\");\r\n\t\t\t}\r\n\t\t\tthis.#InstanceCount++;\r\n        }\r\n        return ElectronMain.#Singleton;\r\n    } // ElectronMain.GetInstance() \r\n\r\n    // ** Private constructor **\r\n\tconstructor( key ) {\r\n\t\tif ( key !== ElectronMain.#Key ) {\r\n\t\t\tthrow new TypeError(\"'ElectronMain' constructor is private\");\r\n\t\t}\r\n\t\t\t\t\r\n\t\tthis.cryptowallet_version      = \"x.x.x\";\r\n\t\t\r\n\t\tthis.app_config                = DEFAULT_APP_CONFIG;\r\n\r\n        this.cmd_line\t               = {};\r\n\t\tthis.cmd_line[PROGRAM]         = ELECTRON_LAUNCHER;\r\n\t\tthis.cmd_line[PATH]            = \".\";\r\n\t\tthis.cmd_line[ARGS]            = \"\";\r\n\t\t\r\n\t\tthis.DidFinishLoad_FiredCount  = 0;\r\n\t\tthis.Show_DebugPanel           = false;\r\n\t\t\r\n\t\tthis.MainWindow                = undefined;\r\n\t    this.Options                   = {};\r\n        this.SupportedBlockchains      = {};\t\t\r\n\t    this.FirstImageAsEntropySource = true;\r\n\t\t\r\n\t\tthis.output_path = \"\";\r\n\t} // ** Private constructor **\r\n\t\r\n\tcreateBrowserWindow( url ) {\r\n\t   const win = new BrowserWindow(\r\n\t     { height: 900, width:  1200 } \r\n\t   );\r\n\r\n\t   win.loadURL( url );\r\n    } // createBrowserWindow\r\n\r\n    getMainWindow() {\r\n\t\treturn this.MainWindow;\r\n\t} // getMainWindow()\r\n\t\r\n\tisLaunchedFromExe() {\r\n\t\tif ( this.cmd_line[PROGRAM] == EXE_LAUNCHER )  return true;\r\n\t\treturn false;\r\n\t} // isLaunchedFromExe()\r\n\t\r\n\tgetCmdLineArgs() {\r\n\t\tlet nb_args = process.argv.length;\r\n\t\t\r\n\t\tif ( nb_args > 0 ) {\r\n\t\t\tthis.cmd_line[PROGRAM] = path.basename( process.argv[0] );\r\n\t\t};\r\n\t\t\r\n\t\tif ( nb_args > 1 ) {\r\n\t\t\tthis.cmd_line[PATH]  = process.argv[1];\r\n\t\t};\r\n\t\t\r\n\t\tif ( nb_args > 2 ) {\r\n\t\t\tthis.cmd_line[ARGS] = process.argv[2];\r\n\t\t};\r\n\t\t\r\n\t\tlet msg =  \"nb_args: \"     + nb_args\r\n\t\t          + PROGRAM + \": \" + this.cmd_line[PROGRAM]\r\n\t\t\t\t  + PATH + \": \"    + this.cmd_line[PATH]\r\n\t\t\t\t  + ARGS + \": \"    + this.cmd_line[ARGS]; \r\n\t\treturn msg;\r\n\t} // getCmdLineArgs()\r\n\t\r\n\t// https://github.com/electron/electron/issues/19775\r\n\t// https://stackoverflow.com/questions/44391448/electron-require-is-not-defined\r\n\tgetMenuTemplate() {\r\n\t\tlet ELECTRON_MAIN_MENU_TEMPLATE = [\r\n\t\t\t{ \tlabel: L10nUtils.GetLocalizedMsg(\"File\"),\r\n\t\t\t\tsubmenu: [ {  label:  L10nUtils.GetLocalizedMsg(\"New\"), \r\n\t\t\t\t\t\t\t  async click() { await ElectronMain.GetInstance().doFileNew(); }\r\n\t\t\t\t\t\t   },\r\n\t\t\t\t           {  label:  L10nUtils.GetLocalizedMsg(\"Open\"), \r\n\t\t\t\t\t\t\t  async click() { await ElectronMain.GetInstance().doFileOpen(); }\r\n\t\t\t\t\t\t   },\r\n\t\t\t\t           {  label:  L10nUtils.GetLocalizedMsg(\"Save\"), \r\n\t\t\t\t\t\t\t  click() { ElectronMain.GetInstance().doFileSave(); },\r\n\t\t\t\t\t\t\t  id: \"file_save_menu_item_id\"\r\n\t\t\t\t\t\t   },\r\n\t\t\t\t\t\t   {  label:  L10nUtils.GetLocalizedMsg(\"SaveAs\"), \r\n\t\t\t\t\t\t\t  click() { ElectronMain.GetInstance().doFileSaveAs(); },\r\n\t\t\t\t\t\t\t  id: \"file_save_as_menu_item_id\"\r\n\t\t\t\t\t\t   },\r\n\t\t\t\t\t\t   {  label: L10nUtils.GetLocalizedMsg(\"Quit\"), \r\n\t\t\t\t\t\t\t  click() { app.quit(); }\r\n\t\t\t\t\t\t   }\r\n\t\t\t\t\t\t ]\r\n\t\t\t},\r\n\t\t\t{ \tlabel: L10nUtils.GetLocalizedMsg(\"View\"),\r\n\t\t\t\tsubmenu: [ {  label: L10nUtils.GetLocalizedMsg(\"ToggleDebug\"), type: 'checkbox',\r\n\t\t\t\t\t\t\t  click() {\r\n\t\t\t\t\t\t\t\t  pretty_func_header_log( \"[Electron]\", VIEW_TOGGLE_DEVTOOLS );\t\t\t\t\t\t\t\t  \r\n\t\t\t\t\t\t\t\t  ElectronMain.GetInstance().toggleDebugPanel(); }  \r\n\t\t\t\t\t\t   }\t\t\t\t\t\t  \r\n\t\t\t\t\t\t ]\r\n\t\t\t},\r\n\t\t\t{ \tlabel: L10nUtils.GetLocalizedMsg(\"Tools\"),\r\n\t\t\t\tsubmenu: [ {  label: \"Options...\",\r\n\t\t\t\t\t\t\t  click() {\r\n                                  pretty_func_header_log( \"[Electron]\", TOOLS_OPTIONS );\t\t\t\t\t\t\t\t  \r\n\t\t\t\t\t\t\t\t  ElectronMain.GetInstance().getMainWindow()\r\n\t\t\t\t\t\t\t\t    .webContents.send\r\n\t\t\t\t\t\t\t\t\t( 'fromMain', \r\n\t\t\t\t\t\t\t\t\t  [ FromMain_TOOLS_OPTIONS_DIALOG, \r\n\t\t\t\t\t\t\t\t\t    ElectronMain.GetInstance().Options ] \r\n\t\t\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\t  }\t\t \r\n\t\t\t\t\t\t   },\r\n\t\t\t\t\t\t   {  label: L10nUtils.GetLocalizedMsg(\"SecretPhraseTranslatorTool\"),\r\n\t\t\t\t\t\t\t  click() {\r\n                                  pretty_func_header_log( \"[Electron]\", TOOLS_SECRET_PHRASE_TRANSLATOR );\t\t\t\t\t\t\t\t  \r\n\t\t\t\t\t\t\t\t  ElectronMain.GetInstance().getMainWindow()\r\n\t\t\t\t\t\t\t\t    .webContents.send\r\n\t\t\t\t\t\t\t\t\t( 'fromMain', \r\n\t\t\t\t\t\t\t\t\t  [ FromMain_TOOLS_SECRET_PHRASE_TRANSLATOR_DIALOG, \r\n\t\t\t\t\t\t\t\t\t    ElectronMain.GetInstance().Options ] \r\n\t\t\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\t  }\t\t \r\n\t\t\t\t\t\t   },\r\n\t\t\t\t\t\t   {  label: L10nUtils.GetLocalizedMsg(\"Bip38EncryptDecryptTool\"),\r\n\t\t\t\t\t\t\t  click() {\r\n                                  pretty_func_header_log( \"[Electron]\", TOOLS_BIP38_ENCRYPTER_DECRYTER );\t\t\t\t\t\t\t\t  \r\n\t\t\t\t\t\t\t\t  ElectronMain.GetInstance().getMainWindow()\r\n\t\t\t\t\t\t\t\t    .webContents.send\r\n\t\t\t\t\t\t\t\t\t( 'fromMain', \r\n\t\t\t\t\t\t\t\t\t  [ FromMain_TOOLS_BIP38_ENCRYPT_DECRYPT_DIALOG, \r\n\t\t\t\t\t\t\t\t\t    ElectronMain.GetInstance().Options ] \r\n\t\t\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\t  }\t\t \r\n\t\t\t\t\t\t   }\r\n\t\t\t\t\t\t ]\r\n\t\t\t},\r\n\t\t\t{   label: L10nUtils.GetLocalizedMsg(\"Help\"), //\"Help\"\r\n\t\t\t\tsubmenu: [ { label: L10nUtils.GetLocalizedMsg(\"Resources\"),\r\n\t\t\t\t\t\t\t submenu: \t\t\t\t\t\t\t \r\n\t\t\t\t\t\t\t [\r\n\t\t\t\t\t\t\t   { label: \"Setup guide and User's Manual\",\r\n\t\t\t\t\t\t\t\t  click() { \r\n\t\t\t\t\t\t\t\t\t ElectronMain.GetInstance()\r\n\t\t\t\t\t\t\t\t\t     .createBrowserWindow(\"https://github.com/ALADAS-org/cryptowallet/blob/master/README.md\");\r\n\t\t\t\t\t\t\t\t  }\r\n\t\t\t\t\t\t\t   },\r\n\t\t\t\t\t\t\t   { label: \"Ian Coleman BIP39\",\r\n\t\t\t\t\t\t\t\t  click() { \r\n\t\t\t\t\t\t\t\t\t // https://stackoverflow.com/questions/53390798/opening-new-window-electron\r\n\t\t\t\t\t\t\t\t\t ElectronMain.GetInstance()\r\n\t\t\t\t\t\t\t\t\t     .createBrowserWindow(\"https://iancoleman.io/bip39/\");\r\n\t\t\t\t\t\t\t\t  }\r\n\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t{ label: \"Guarda\",\r\n\t\t\t\t\t\t\t\t  click() { \r\n\t\t\t\t\t\t\t\t\t // https://stackoverflow.com/questions/53390798/opening-new-window-electron\r\n\t\t\t\t\t\t\t\t\t ElectronMain.GetInstance()\r\n\t\t\t\t\t\t\t\t\t     .createBrowserWindow(\"https://guarda.com/\");\r\n\t\t\t\t\t\t\t\t  }\r\n\t\t\t\t\t\t\t\t}\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t ]\r\n\t\t\t\t\t\t   },\r\n\t\t\t\t\t\t   {  label: L10nUtils.GetLocalizedMsg(\"About\"), //'About...',\r\n\t\t\t\t\t\t\t  click() { \r\n\t\t\t\t\t\t\t\t  ElectronMain.GetInstance().getMainWindow()\r\n\t\t\t\t\t\t\t\t      .webContents.send('fromMain', [ FromMain_HELP_ABOUT ]);\r\n\t\t\t\t\t\t\t  }\r\n\t\t\t\t\t\t   }\r\n\t\t\t\t\t\t ]\r\n\t\t\t}\r\n\t\t]; // menu_template\r\n\t\t\r\n\t\treturn ELECTRON_MAIN_MENU_TEMPLATE;\r\n\t} // getMenuTemplate()\r\n\t\r\n\t//==================== createWindow() ====================\r\n\t// https://stackoverflow.com/questions/44391448/electron-require-is-not-defined\r\n\tcreateWindow() {\r\n\t\tpretty_func_header_log( \"ElectronMain.createWindow\" );\r\n\r\n\t\t// Hide 'Security Warning'\r\n\t\tprocess.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';\r\n\t\t\r\n\t\tthis.MainWindow = new BrowserWindow(\r\n\t\t\t{ width:  MAIN_WINDOW_WIDTH, \r\n\t\t\t  height: MAIN_WINDOW_HEIGHT,\r\n\t\t\t  icon:   path.join(__dirname, \"../../icons/Cryptocalc_Icon.png\"),\r\n\t\t\t  webPreferences: {\r\n\t\t\t\tcontextIsolation: true, // NB: 'true' is default value but keep it there anyway\r\n\t\t\t\tpreload:          path.join(__dirname, \"./preload.js\")\r\n\t\t\t  }\r\n\t\t\t}\r\n\t\t);\r\n\t\t\r\n\t\tconsole.log( \"ElectronMain.createWindow()  this.MainWindow: \" + typeof this.MainWindow );\r\n\t\tMainModel.This.setMainWindow( this.MainWindow );\r\n\t\t\t\r\n\t\tconst menu_bar = Menu.buildFromTemplate( this.getMenuTemplate() );\r\n\t\tMenu.setApplicationMenu( menu_bar );\t\r\n\t\t\r\n\t\t// https://www.electronjs.org/docs/latest/api/web-contents#instance-events\r\n\t\t// https://stackoverflow.com/questions/42284627/electron-how-to-know-when-renderer-window-is-ready\r\n\t\t// Note: index.html loaded twice (first index.html redirect)\r\n\t\t// ==================== 'did-finish-load' event handler ====================\r\n\t\tthis.MainWindow.webContents.on( 'did-finish-load', \r\n\t\t\tasync () => {\r\n\t\t\t\tSkribi.Initialize( this.app_config );\r\n\t\t\t\t//Skribi.log(\">> \" + _CYAN_ + \"[*Electron*] \" + _YELLOW_ + \" did-finish-load --\" + _END_);\r\n\t\t\t\t\r\n\t\t\t\tthis.app_config = this.readAppConfig();\r\n\t\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"eMain.evtH('did-finish-load')> FiredCount: \" + this.DidFinishLoad_FiredCount + _END_ );\r\n\r\n\t\t\t\tthis.getCmdLineArgs();\t\r\n\t\t\t\t// Skribi.log(\"  ** this.cmd_line: \" + JSON.stringify(this.cmd_line) );\r\n\t\t\t\tSkribi.log(\">> \" + _CYAN_ + \"eMain.evtH('\" + _YELLOW_ + \"'did-finish-load'\"\r\n\t\t\t\t\t\t\t\t + _CYAN_ + \")> this.cmd_line[PROGRAM]: \" + _END_ + this.cmd_line[PROGRAM]);\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t//---------- Set 'Cryptowallet_version' in Renderer GUI ----------\r\n\t\t\t\tthis.cryptowallet_version = MainModel.This.getAppVersion();\t\r\n\t\t\t\t//Skribi.log(\">> \" + _CYAN_ + \"eMain.evtH('\" + _YELLOW_ + \"'did-finish-load'\"\r\n\t\t\t\t//                 + _CYAN_ + \")> cryptowallet_version: \" + _END_ + this.cryptowallet_version);\t\t\t\t\t\r\n\t\t\t\tthis.updateWindowTitle();\r\n\t\t\t\t//---------- Set 'this.cryptowallet_version' in Renderer GUI\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\tthis.MainWindow.webContents.send\r\n\t\t\t\t\t( \"fromMain\", [ FromMain_DID_FINISH_LOAD ] );\r\n\t\t\t\t\r\n\t\t\t\tthis.MainWindow.webContents.send\r\n\t\t\t\t\t( \"fromMain\", [ FromMain_SET_VARIABLE, APP_VERSION, this.cryptowallet_version ] );\r\n\t\t\t\t\r\n\t\t\t\t// https://stackoverflow.com/questions/31749625/make-a-link-from-electron-open-in-browser\r\n\t\t\t\t// Open urls in the user's browser\r\n\t\t\t\t// nB: Triggered by 'MainGUI.OnExploreWallet()'\r\n\t\t\t\tthis.MainWindow.webContents.setWindowOpenHandler( (edata) => {\r\n\t\t\t\t\tshell.openExternal(edata.url);\r\n\t\t\t\t\treturn { action: \"deny\" };\r\n\t\t\t\t} );\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\tthis.setCallbacks();\r\n\t\t\t\tthis.Options = await this.loadOptions();\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t// =================== Open file by association ===================\r\n\t\t\t\tlet wits_path = this.cmd_line[PATH];\r\n\t\t\t\t\r\n\t\t\t\tif ( wits_path.endsWith(\".wits\") ) {\r\n\t\t\t\t\tSkribi.log(\">> \" + _CYAN_ + \"eMain.evtH('\" + _RED_ + \"'did-finish-load'\"\r\n\t\t\t\t\t\t\t\t\t + _CYAN_ + \")> SET_VARIABLE(\" + WITS_PATH + \") in Renderer\" + _END_ + wits_path);\t\t \r\n\t\t\t\t\t// await this.openWits( wits_path ); \r\n\t\t\t\t\tawait this.MainWindow.webContents.send\r\n\t\t\t\t\t\t( \"fromMain\", [ FromMain_SET_VARIABLE, WITS_PATH, wits_path ] );\r\n\t\t\t\t}\r\n\t\t\t\t// =================== Open file by association\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t// Note: will require 'Main' to 'Open Wits' if:\r\n\t\t\t\t// - 'wits_path' in Renderer is not empty \r\n\t\t\t\t// and \r\n\t\t\t\t// - not 'first_time' in Renderer  \r\n\t\t\t\tawait this.doFileNew();\t\t\t\t\t\t\r\n\r\n\t\t\t} // 'did-finish-load' callback\r\n\t\t); // ==================== 'did-finish-load' event handler\r\n\t\t\r\n\t\tthis.MainWindow.loadFile( './www/index.html' );\r\n\t} // createWindow()\r\n\t\r\n\tasync openWits( wits_path ) {\r\n\t\tif ( wits_path == undefined ) { \r\n\t\t     throw new Error(\"**ERROR** in Cryptowallet: '.wits' path is undefined\");\r\n\t\t}\r\n\t\t\r\n\t\tSkribi.log(\">> \" + _CYAN_ + \"eMain.evtH('\" + _YELLOW_ + \"'openWits'\"\r\n\t\t\t\t\t\t + _CYAN_ + \")> *TEST* Trying to Open '.wits': \" + _END_ + wits_path);\t\t\t\t\t\t\t \r\n\r\n\t\tif ( wits_path.endsWith(\".wits\") ) {\r\n\t\t\tconst json_data_str = fs.readFileSync( wits_path, { encoding: 'utf8', flag: 'r' });\r\n\t\t\tlet wits_json_data = JSON.parse( json_data_str );\r\n\t\t\t\r\n\t\t\tthis.Options = await this.loadOptions();\r\n\t\t\t\r\n\t\t\tawait this.MainWindow.webContents.send\r\n\t\t\t\t  ( \"fromMain\", [ FromMain_EXEC_CMD, CMD_OPEN_WALLET, wits_json_data ] );\t\r\n\t\t}\r\n\t} // openWits()\r\n\t\r\n\tupdateWindowTitle( coin, wallet_mode ) {\r\n\t\t//pretty_func_header_log( \"ElectronMain.updateWindowTitle\" );\t\r\n\t\tlet window_title = 'Cryptowallet ' + this.cryptowallet_version;\r\n\t\tif ( wallet_mode != undefined  &&  wallet_mode != \"\" )   window_title += \" - \" + wallet_mode;\r\n\t\tif ( coin != undefined  &&  coin != \"\" ) \t             window_title += \": \" + coin;\r\n\t\t\r\n        this.MainWindow.setTitle( window_title );\r\n\t} // updateWindowTitle()\r\n\t\r\n\tasync doFileNew() {\r\n\t\tSkribi.log( \">> \" + _CYAN_ + \"ElectronMain.doFileNew\" + _END_ );\t\r\n        //this.Options = this.readOptionsFile();\r\n        this.Options = await this.loadOptions();\r\n        await this.MainWindow.webContents\r\n\t\t          .send( \"fromMain\", [ FromMain_FILE_NEW, this.Options ] );\t\t\r\n\t} // doFileNew()\r\n\t\r\n\tdoFileSave() {\r\n\t\t// pretty_func_header_log( \"ElectronMain.doFileSave\" );\r\n        Skribi.log( \">> \" + _CYAN_ + \"ElectronMain.doFileSave\" + _END_ );\t\t\r\n\t\tthis.MainWindow.webContents.send( \"fromMain\", [ FromMain_FILE_SAVE ] );\r\n\t} // doFileSave()\r\n\t\r\n\tdoFileSaveAs() {\r\n\t\t// pretty_func_header_log( \"ElectronMain.doFileSaveAs\" );\r\n        Skribi.log( \">> \" + _CYAN_ + \"ElectronMain.doFileSaveAs\" + _END_ );\t\t\r\n\t\tthis.MainWindow.webContents.send( \"fromMain\", [ FromMain_FILE_SAVE ] );\r\n\t} // doFileSaveAs()\r\n\t\r\n\tasync doFileOpen( in_file_path ) {\r\n\t\t// pretty_func_header_log( \"ElectronMain.doFileOpen\" );\r\n\t\tSkribi.log( \">> \" + _CYAN_ + \"ElectronMain.doFileOpen\" + _END_ );\r\n\t\t\r\n\t\tif ( in_file_path == undefined ) {\t\t\r\n\t\t\tlet input_path = app.getAppPath() + \"\\\\_output\";\r\n\t\t\tin_file_path = await this.selectFileWithDialogBox( input_path, \"Wallet Informations\", \"wits\" );\r\n\t\t\tpretty_log( \"in_file_path\", in_file_path );\r\n\t\t\tif ( in_file_path == \"\" ) return;\r\n\t\t}\r\n\t\tconst json_data_str = fs.readFileSync( in_file_path, { encoding: 'utf8', flag: 'r' });\r\n\t\t//pretty_log( \"json_data_str\", json_data_str );\r\n\t\tlet json_data = JSON.parse( json_data_str );\r\n\t\tawait this.MainWindow.webContents\r\n\t\t          .send( \"fromMain\", [ FromMain_FILE_OPEN, json_data ] );\t\r\n\t} // doFileOpen()\r\n\t\r\n\tasync selectFileWithDialogBox( input_path, label, extension ) {\r\n\t\tpretty_func_header_log( \"ElectronMain.selectFileWithDialogBox\" );\r\n\t\t\r\n\t\tlet in_file_path = \"\";\r\n\t\t//                     Modal window\r\n\t\tlet result = await dialog.showOpenDialog( this.MainWindow, {\r\n\t\t\tdefaultPath: input_path,\r\n\t\t\tfilters:     [ { name: label, extensions: [extension] } ],\r\n\t\t\tproperties:  ['openFile']\r\n\t\t});\r\n\t\t//.then( result => {\r\n\t\t\t//pretty_log( \"result\", JSON.stringify(result));\r\n\t\t\tif ( result.filePaths.length > 0 ) {\r\n\t\t\t\t//pretty_log( \"filePaths\", JSON.stringify(result.filePaths));\r\n\t\t\t\tin_file_path = result.filePaths[0];\r\n\t\t\t\t// pretty_log( \"in_file_path\", in_file_path);\r\n\t\t\t}\r\n\t\t//}).catch(err => {\r\n\t\t//\tSkribi.log(err)\r\n\t\t//});\r\n\t\t\r\n\t\t// pretty_log( \"in_file_path\", in_file_path);\r\n\t\treturn in_file_path;\r\n\t} // selectFileWithDialogBox()\r\n\t\r\n\t// https://stackoverflow.com/questions/43991267/electron-open-file-directory-in-specific-application\r\n\tshowFolderInExplorer() {\r\n\t\tpretty_func_header_log( \"ElectronMain.showFolderInExplorer\" );\r\n\r\n\t\t// Detect OS\r\n\t\t// https://www.freecodecamp.org/news/how-to-write-os-specific-code-in-electron-bf6379c62ff6/\r\n\t\tlet os_platform = os.platform();\r\n\t\t// console.log(\"OS: \" + os.platform());\r\n\t\t\r\n\t\t// console.log(\"this.output_path: '\" + this.output_path + \"'\");\r\n\r\n        let path_separator = '/';\r\n\t\t\r\n\t\tlet output_path = this.output_path;\r\n\t\tif (os_platform == WINDOWS) {\r\n\t\t\tpath_separator = '\\\\';\r\n\t\t}\r\n        else if (os_platform == LINUX) {\r\n\t\t\tpath_separator = '/';\r\n        }\r\n\r\n\t\toutput_path = this.output_path.replaceAll('\\\\','\\0').replaceAll('/','\\0');\t\t\r\n        let output_path_items = output_path.split('\\0');\r\n\t\t// console.log(\"output_path_items: '\" + JSON.stringify(output_path_items) + \"'\");\r\n\t\tlet popped = output_path_items.pop();\r\n\t\t\r\n\t\toutput_path = output_path_items.join(path_separator); \r\n        // console.log(\"output_path: '\" + output_path + \"'\");\t\t\r\n\r\n\t\tconst open_folder_LINUX = (path) => {\r\n\t\t\texec(`xdg-open \"${path}\"`, (error) => {\r\n\t\t\t\tif (error) {\r\n\t\t\t\t\tconsole.error(`Error opening folder: ${error}`);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}; // open_folder_LINUX()\r\n\t\t\r\n\t\t// console.log(\"output_path:  1: '\" + output_path + \"'\");\r\n\t\r\n\t\tif (os_platform == WINDOWS) {\t\t\r\n\t\t    // console.log(\"output_path:  '\" + output_path + \"'\");\r\n\t\t\tshell.openPath( output_path );\r\n\t\t}\r\n\t\telse if (os_platform == LINUX) {\r\n            output_path = output_path.replaceAll('\\\\','/');\r\n            // console.log(\"output_path:  '\" + output_path + \"'\");\t\t\t\r\n\t\t\topen_folder_LINUX( output_path );\r\n\t\t}\r\n    } // showFolderInExplorer()\r\n\t\r\n\t// File/Import/Random Fortune Cookie\r\n\tgetNewFortuneCookie() {\r\n\t\tpretty_func_header_log( \"ElectronMain.getNewFortuneCookie\" );\r\n\t\tlet fortune_cookie = getFortuneCookie();\r\n\t\tSkribi.log(\"   fortune_cookie: \" + getShortenedString( fortune_cookie) );\r\n\t\tthis.MainWindow.webContents\r\n\t\t\t.send( \"fromMain\", [ FromMain_SET_FORTUNE_COOKIE, fortune_cookie ] );\r\n\t} // getNewFortuneCookie()\r\n\t\r\n\ttoggleDebugPanel() {\r\n\t\tpretty_func_header_log( \"ElectronMain.toggleDebugPanel\" );\r\n\t\tthis.Show_DebugPanel = ! this.Show_DebugPanel;\r\n\t\t\r\n\t\tif ( this.Show_DebugPanel )\r\n\t\t\tthis.MainWindow.webContents.openDevTools();\r\n\t\telse\r\n\t\t\tthis.MainWindow.webContents.closeDevTools();\r\n\t} // toggleDebugPanel()\r\n\t\r\n\treadAppConfig() {\r\n\t\tpretty_func_header_log( \"ElectronMain.readAppConfig\" );\r\n\t\t\r\n\t\tlet app_config = DEFAULT_APP_CONFIG;\r\n\t\t\r\n\t\tlet config_path = app.getAppPath() + '/www/config';\r\n\t\t\r\n\t\tlet app_config_path = config_path + '/app_config.json';\r\n\t\tif ( fs.existsSync( app_config_path ) ) {\r\n\t\t\tconst app_config_str = fs.readFileSync( app_config_path );\r\n\t\t\tif ( app_config_str != \"\" &&  app_config_str != \"[]\" && app_config_str != \"{}\" ) { \r\n\t\t\t\tapp_config = JSON.parse( app_config_str );\t\t\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\treturn app_config;\t\t\r\n\t} // readAppConfig()\r\n\t\r\n\treadOptionsFile() {\r\n\t\tpretty_func_header_log( \"ElectronMain.readOptionsFile\" );\r\n\t\t\r\n\t\tlet current_options = DEFAULT_OPTIONS;\r\n\t\t\r\n\t\tlet config_path = app.getAppPath() + '/www/config';\r\n\t\t//Skribi.log(\"config_path: \" + config_path);\r\n\t\t\r\n\t\tlet options_path = config_path + '/options.json';\r\n\t\tif ( fs.existsSync( options_path ) ) {\r\n\t\t\tconst options_str = fs.readFileSync( options_path );\r\n\t\t\t//Skribi.log(\"   options_str: \" + options_str);\r\n\t\t\tif ( options_str != \"\" &&  options_str != \"[]\" && options_str != \"{}\" ) { \r\n\t\t\t\tcurrent_options = JSON.parse( options_str );\t\t\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\treturn current_options;\t\t\r\n\t} // readOptionsFile()\r\n\r\n\tasync loadOptions() {\r\n\t\tpretty_func_header_log( \"ElectronMain.loadOptions\" );\r\n\t\t\r\n\t\tthis.Options = this.readOptionsFile();\r\n\t\t\r\n\t\t//Skribi.log(\" A this.Options: \" + JSON.stringify( this.Options ));\r\n\t\tawait this.MainWindow.webContents\r\n\t\t\t      .send('fromMain', [ FromMain_UPDATE_OPTIONS, this.Options ]);\r\n        return this.Options; \t\t\t\t  \r\n\t} // async loadOptions()\r\n\t\r\n\tasync setDefaultOptions() {\r\n\t\tpretty_func_header_log( \"ElectronMain.setDefaultOptions\" );\r\n\t\t\r\n\t\tthis.Options = DEFAULT_OPTIONS;\r\n\t\tawait this.saveOptions( this.Options );\r\n\t} // async setDefaultOptions()\r\n\t\r\n\tasync updateOptions( options_data ) {\r\n\t\tpretty_func_header_log( \"ElectronMain.updateOptions\" );\r\n\t\tthis.Options = options_data;\r\n\t\tSkribi.log(\"   this.Options: \" + JSON.stringify( this.Options ));\r\n\t} // async updateOptions()\r\n\t\r\n\tasync saveOptions( options_data ) {\r\n\t\tpretty_func_header_log( \"ElectronMain.saveOptions\" );\r\n\t\t\r\n\t\tthis.Options = options_data;\r\n\t\tlet config_path  = app.getAppPath() + '/www/config';\t\t\r\n\t\tlet options_path = config_path + '/options.json';\r\n\t\tfs.writeFileSync( options_path, JSON.stringify( this.Options ) );\r\n\t\t\r\n\t\tSkribi.log(\" B this.Options: \" + JSON.stringify( this.Options ));\r\n\t\tawait this.MainWindow.webContents\r\n\t\t\t      .send('fromMain', [ FromMain_UPDATE_OPTIONS, options_data ]);\r\n\t} // async saveOptions()\r\n\t\r\n\tasync resetOptions() {\r\n\t\tpretty_func_header_log( \"ElectronMain.resetOptions\" );\r\n\t\t\r\n\t\tlet config_path  = app.getAppPath() + '/www/config';\t\t\r\n\t\tlet default_options_path = config_path + '/defaults/options.json';\r\n\t\tlet default_options_str  = fs.readFileSync( default_options_path ).toString();\r\n\t\tSkribi.log(\"   default_options_str: \" + default_options_str);\r\n\t\tthis.Options = JSON.parse( default_options_str );\r\n\t\tawait this.saveOptions( this.Options );\r\n\t} // async resetOptions()\r\n\t\r\n\tsetCallbacks() {\r\n\t\tSkribi.log(\">> \" + _CYAN_ + \"ElectronMain.setCallbacks\" + _END_);\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_QUIT_APP ======================\r\n\t\t//Skribi.log(\">> register: \" + ToMain_RQ_QUIT_APP);\r\n\t\t// called like this by Renderer: await window.ipcMain.QuitApp(data)\r\n\t\tipcMain.handle( ToMain_RQ_QUIT_APP, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_QUIT_APP );\r\n\t\t\tapp.quit();\r\n\t\t}); // \"ToMain:Request/quit_app\" event handler\r\n\r\n\t\t// ====================== ToMain_RQ_EXEC_CMD ======================\r\n\t\t// called like this by Renderer: await window.ipcMain.ExecuteCommand(data)\r\n\t\tipcMain.handle( ToMain_RQ_EXEC_CMD, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_EXEC_CMD );\r\n\t\t\tconst { cmd_name, cmd_args } = data;\r\n\t\t\tSkribi.log( \"eMain.evtH('ExecCmd')> cmd_name: \" + cmd_name );\r\n\t\t\tSkribi.log( \"eMain.evtH('ExecCmd')> cmd_args: \" + cmd_args );\r\n\t\t\t\r\n\t\t\tif ( cmd_name == CMD_OPEN_WALLET ) {\r\n\t\t\t\tawait ElectronMain.GetInstance().openWits( cmd_args );\r\n\t\t\t}\r\n\t\t}); // \"ToMain:Request/ExecCmd\" event handler\t\t\r\n\r\n\t\t// ====================== ToMain_RQ_LOG_2_MAIN_SYNC ======================\r\n\t\t// called like this by Renderer: window.ipcMain.logToMain(data)\r\n\t\tipcMain.on( ToMain_RQ_LOG_2_MAIN, (event, data) => {\r\n\t\t\tSkribi.log( data );\r\n\t\t}); // \"ToMain:Request/log2main\" event handler\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_LOG_2_MAIN_SYNC ======================\r\n\t\t// called like this by Renderer: await window.ipcMain.logToMainSync(data)\r\n\t\tipcMain.handle( ToMain_RQ_LOG_2_MAIN_SYNC, async (event, data) => {\r\n\t\t\tSkribi.log( data );\r\n\t\t}); // \"ToMain:Request/log2main_sync\" event handler\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_SET_WINDOW_TITLE ======================\r\n\t\t// called like this by Renderer: window.ipcMain.SetWindowTitle(data)\r\n\t\tipcMain.on( ToMain_RQ_SET_WINDOW_TITLE, (event, data) => {\r\n\t\t\t// pretty_func_header_log( \"[Electron]\", ToMain_RQ_SET_WINDOW_TITLE );\r\n\t\t\tconst { coin, wallet_mode } = data;\r\n\t\t\tElectronMain.GetInstance().updateWindowTitle( coin, wallet_mode );\r\n\t\t}); // \"ToMain:Request/set_window_title\" event handler\r\n\t\t\r\n\t\t// ========================== ToMain_RQ_TOGGLE_DEBUG_PANEL ==========================\r\n\t\t// called like this by Renderer: window.ipcMain.ToggleDebugPanel(data)\r\n\t\tipcMain.on( ToMain_RQ_TOGGLE_DEBUG_PANEL, (event, data) => {\r\n\t\t\tElectronMain.GetInstance().toggleDebugPanel();\r\n\t\t}); // \"ToMain:Request/toggle_debug_panel\" event handler\r\n\t\t\r\n\t\t// ==================== ToMain_RQ_SHOW_OUTPUT_FOLDER_IN_EXPLORER ====================\r\n\t\t// called like this by Renderer: window.ipcMain.ShowOutputFolderInExplorer()\r\n\t\tipcMain.on( ToMain_RQ_SHOW_OUTPUT_FOLDER_IN_EXPLORER, (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_SHOW_OUTPUT_FOLDER_IN_EXPLORER );\r\n      \t    // let output_path = app.getAppPath() + \"\\\\_output\";\r\n\t\t\tthis.showFolderInExplorer();\r\n\t\t}); // \"ToMain:Request/show_output_folder_in_explorer\" event handler\t\t\t\t\t\t\t\t\t\t  \r\n\t\t\r\n\t\t// ====================== ToMain_RQ_OPEN_URL ======================\r\n\t\t// called like this by Renderer: window.ipcMain.OpenURL(url)\r\n\t\tipcMain.on( ToMain_RQ_OPEN_URL, (event, url) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_OPEN_URL );\r\n\t\t\tSkribi.log(\"eMain.evtH('OpnURL')> \" + url);\r\n\t\t\t\r\n\t\t\t// https://stackoverflow.com/questions/31749625/make-a-link-from-electron-open-in-browser\r\n\t\t\tthis.MainWindow.location = url;\r\n\t\t}); // \"ToMain:Request/open_URL\" event handler\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_NEW_WALLET_INFO ======================\r\n\t\t//Skribi.log(\">> register: \" + ToMain_RQ_NEW_WALLET_INFO);\r\n\t\t// called like this by Renderer: await window.ipcMain.NewWalletInfo( data )\r\n\t\tipcMain.handle( ToMain_RQ_NEW_WALLET_INFO, async ( event, data ) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_NEW_WALLET_INFO );\r\n\t\t\tSkribi.log( \"eMain.evtH('NewWinf')>\" );\r\n\t\t\tawait ElectronMain.GetInstance().doFileNew();\t\t\t\r\n\t\t}); // \"ToMain:Request/new_wallet_info\" event handler\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_OPEN_WALLET_INFO ======================\r\n\t\t// called like this by Renderer: await window.ipcMain.OpenWalletInfo( data )\r\n\t\tipcMain.handle( ToMain_RQ_OPEN_WALLET_INFO, async ( event, data ) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_OPEN_WALLET_INFO );\r\n\t\t\tawait ElectronMain.GetInstance().doFileOpen();\t\t\t\r\n\t\t}); // \"ToMain:Request/open_wallet_info\" event handler\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_SAVE_WALLET_INFO ======================\r\n\t\t//Skribi.log(\">> register: \" + ToMain_RQ_SAVE_WALLET_INFO);\r\n\t\t// called like this by Renderer: window.ipcMain.SaveWalletInfo( data )\r\n\t\tipcMain.handle( ToMain_RQ_SAVE_WALLET_INFO, async ( event, crypto_info ) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_SAVE_WALLET_INFO );\r\n\t\t\tSkribi.log( \"eMain.evtH('SaveWinf')>\" );\t\r\n\t\t\tthis.output_path = await MainModel.This.saveWalletInfo( crypto_info );\r\n\t\t}); // \"ToMain:Request/save_wallet_info\" event handler\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_RESET_OPTIONS ======================\r\n\t\t// called like this by Renderer: await window.ipcMain.ResetOptions( data )\r\n\t\tipcMain.handle( ToMain_RQ_RESET_OPTIONS, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_RESET_OPTIONS );\t\r\n            Skribi.log( \"eMain.evtH('RstOpt')>\" );\t\t\t\r\n\t\t\tElectronMain.GetInstance().resetOptions();\r\n\t\t}); // \"ToMain:Request/reset_options\" event handler\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_UPDATE_OPTIONS ======================\r\n\t\t// called like this by Renderer: await window.ipcMain.UpdateOptions( options_data )\r\n\t\tipcMain.handle( ToMain_RQ_UPDATE_OPTIONS, async (event, options_data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_UPDATE_OPTIONS );\r\n\t\t\t\r\n\t\t\tif ( options_data == undefined ) {\r\n\t\t\t\tSkribi.log(\">> \" + _RED_ + ToMain_RQ_QUIT_APP + _END_);\r\n\t\t\t    app.quit();\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t// Skribi.log( \"eMain.evtH('UpOpt')> options_data: \" + JSON.stringify(options_data));\r\n\t\t\tthis.Options = options_data;\r\n\t\t\tSkribi.log( \"eMain.evtH('UpOpt')> this.Options: \" + JSON.stringify( this.Options ));\r\n\t\t\tawait this.MainWindow.webContents\r\n\t\t\t          .send('fromMain', [ FromMain_UPDATE_OPTIONS, this.Options ]);\r\n\t\t}); // \"ToMain:Request/update_options\" event handler\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_SAVE_OPTIONS ======================\r\n\t\t//Skribi.log(\">> register: \" + ToMain_RQ_SAVE_OPTIONS);\r\n\t\t// called like this by Renderer: await window.ipcMain.SaveOptions( options_data )\r\n\t\tipcMain.handle( ToMain_RQ_SAVE_OPTIONS, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_SAVE_OPTIONS );\r\n\t\t\t\r\n\t\t\tlet options_data = data;\r\n\t\t\tpretty_log( \"eMain.evtH('SaveOpt')> options_data: \" + JSON.stringify(options_data) ); \r\n\t\t\tElectronMain.GetInstance().saveOptions( options_data );\r\n\t\t\t\r\n\t\t\tpretty_log( \"eMain.evtH('SaveOpt')> this.Options: \" + JSON.stringify( this.Options ) );\r\n\t\t\tawait this.MainWindow.webContents\r\n\t\t\t          .send( 'fromMain', [ FromMain_UPDATE_OPTIONS, options_data ] );\r\n\t\t}); // \"ToMain:Request/save_options\" event handler\r\n\t\t\r\n\t\tconst loadImageFromFile = ( image_file_path ) => {\t\t\t\r\n\t\t\tlet img_data_asURL = fs.readFileSync( image_file_path, {encoding: 'base64'} );\r\n\t\t\tlet image_file_path_items = image_file_path.split('.');\r\n\t\t\t\r\n\t\t\tlet image_file_extension  = \"png\";\r\n\t\t\tlet items_count = image_file_path_items.length;\r\n\t\t\tif (items_count > 1) {\r\n\t\t\t\timage_file_extension = image_file_path_items[items_count-1].toLowerCase();\r\n\t\t\t    if (image_file_extension == \"jpg\") {\r\n\t\t\t\t\timage_file_extension = \"jpeg\";\r\n\t\t\t\t}\r\n\t\t\t    else if (image_file_extension == \"svg\") {\r\n\t\t\t\t\timage_file_extension = \"svg+xml\";\r\n\t\t\t\t}\t\t\t\t\r\n\t\t\t}\t\r\n\t\t\t//Skribi.log(\"   image_file_extension: \" + image_file_extension);\r\n\t\t\t//Skribi.log(\"   img_data_asURL:\\n\" + img_data_asURL);\r\n\t\t\tthis.MainWindow.webContents\r\n\t\t\t            .send('fromMain', \r\n\t\t\t\t\t\t      [ FromMain_SEND_IMG_URL, ENTROPY_SOURCE_IMG_ID, \r\n\t\t\t\t\t\t\t    img_data_asURL, image_file_extension ]);\r\n\t\t\treturn img_data_asURL;\r\n\t\t}; // loadImageFromFile\r\n\t\t\r\n\t\t// ====================== ToMain_RQ_LOAD_IMG_FROM_FILE ======================\r\n\t\t// called like this by Renderer: await window.ipcMain.LoadImageFromFile(data)\r\n\t\tipcMain.handle( ToMain_RQ_LOAD_IMG_FROM_FILE, async (event, image_file_path) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_LOAD_IMG_FROM_FILE );\r\n\t\t\tlet img_data_asURL = loadImageFromFile( image_file_path );\r\n\t\t\treturn img_data_asURL;\r\n\t\t}); // \"ToMain:Request/load_image_from_file\" event handler\r\n\r\n\t\t// ====================== ToMain_RQ_DRAW_RND_CRYPTO_LOGO ======================\r\n\t\t//Skribi.log(\">> register: \" + ToMain_RQ_DRAW_RND_CRYPTO_LOGO);\r\n\t\t// called like this by Renderer: await window.ipcMain.DrawRandomCryptoLogo(data)\r\n\t\tipcMain.handle( ToMain_RQ_DRAW_RND_CRYPTO_LOGO, (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_DRAW_RND_CRYPTO_LOGO );\r\n\t\t\t\r\n\t\t\tlet app_path = app.getAppPath();\r\n\t\t\t//Skribi.log(\"   app_path: \" + app_path);\r\n\t\t\t\r\n\t\t\tlet crypto_logos_path = app_path + \"/www/img/CryptoCurrency\";\r\n\t\t\t\r\n\t\t\tlet crypto_logos = FileUtils.GetFilesInFolder( crypto_logos_path );\r\n\t\t\t//Skribi.log(\"   crypto_logos.length: \" + crypto_logos.length);\r\n\t\t\t\r\n\t\t\tlet image_file_path = crypto_logos_path + \"/\";\r\n\t\t\tlet crypto_logo_filename = \"Zilver_64px.svg\";\r\n\t\t\tif (! this.FirstImageAsEntropySource ) {\r\n\t\t\t\tlet\trandom_index = getRandomInt( crypto_logos.length );\r\n\t\t        crypto_logo_filename = crypto_logos[random_index];\t\t\t\r\n\t\t\t}\r\n\t\t\tthis.FirstImageAsEntropySource = false;\r\n\t\t\timage_file_path += crypto_logo_filename;\r\n\t\t\t\r\n\t\t\tlet img_data_asURL = loadImageFromFile( image_file_path );\r\n            return img_data_asURL;\t\t\t\r\n\t\t}); // \"ToMain:Request/drop_rnd_crypto_logo\" event handler\t\t\r\n\t\t\r\n\t\t// ================== ToMain_RQ_GENERATE_PASSWORD ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.GeneratePassword( data )\r\n\t\t// https://www.npmjs.com/package/generate-password\r\n\t\tipcMain.handle( ToMain_RQ_GENERATE_PASSWORD, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_GENERATE_PASSWORD );\r\n\t\t\t// const {} = data;\r\n\t\t\tlet new_password = PasswordGenerator.generate({\r\n\t\t\t\tlength:                    24,\r\n\t\t\t\tnumbers:                   true,\r\n\t\t\t\tsymbols:                   true,\r\n\t\t\t\tuppercase:                 true,\r\n\t\t\t\tlowercase:                 true,\r\n\t\t\t\texcludeSimilarCharacters : true,\r\n\t\t\t\tstrict:                    true\r\n\t\t\t});\r\n\r\n\t\t\treturn new_password;\r\n\t\t}); // \"ToMain:Request/GeneratePassword event handler\r\n\t\t\r\n\t\t// ========================= ToMain_RQ_BIP38_ENCRYPT =========================\r\n\t\t// called like this by Renderer: await window.ipcMain.Bip38Encrypt( data )\r\n\t\tipcMain.handle( ToMain_RQ_BIP38_ENCRYPT, async ( event, data ) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_BIP38_ENCRYPT );\r\n\t\t\tconst { private_key, passphrase } = data;\r\n\t\t\t// Skribi.log(\"   options: \" + JSON.stringify(options));\r\n\t\t\tlet bip38_encrypted_pk = await Bip38Utils.This.encrypt( private_key, passphrase, this.getMainWindow() );\r\n\t\t\treturn bip38_encrypted_pk;\r\n\t\t}); // \"ToMain:Request/bip38_encrypt\" event handler\t\r\n\t\t\r\n\t\t// ========================= ToMain_RQ_BIP38_DECRYPT =========================\r\n\t\t// called like this by Renderer: await window.ipcMain.Bip38Decrypt( data )\r\n\t\tipcMain.handle( ToMain_RQ_BIP38_DECRYPT, async ( event, data ) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_BIP38_DECRYPT );\r\n\t\t\tconst { bip38_encrypted_pk, passphrase } = data;\r\n\t\t\t// Skribi.log(\"   options: \" + JSON.stringify(options));\r\n\t\t\tlet decrypted_pk = await Bip38Utils.This.decrypt( bip38_encrypted_pk, passphrase, this.getMainWindow() );\r\n\t\t\treturn decrypted_pk;\r\n\t\t}); // \"ToMain:Request/bip38_decrypt\" event handler\t\r\n\t\t\r\n\t\t// ========================= ToMain_RQ_GET_PASSWORD_STRENGTH =========================\r\n\t\t// called like this by Renderer: await window.ipcMain.GetPasswordStrength( data )\r\n\t\tipcMain.handle( ToMain_RQ_GET_PASSWORD_STRENGTH, async ( event, data ) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_GET_PASSWORD_STRENGTH );\r\n\t\t\tconst password_str = data;\r\n\t\t\tlet password_strength_info = PasswordStrengthEvaluator.This.getPasswordStrengthInfo( password_str );\r\n\t\t\treturn password_strength_info;\r\n\t\t}); // \"ToMain:Request/get_password_strength\" event handler\t\r\n\t\t\r\n\t\t// ================== ToMain_RQ_GET_HD_WALLET ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.GetHDWallet( data )\r\n\t\tipcMain.handle( ToMain_RQ_GET_HD_WALLET, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_GET_HD_WALLET );\r\n\t\t\tconst { entropy_hex, salt_uuid, blockchain, crypto_net, bip32_passphrase, account, address_index } = data;\r\n\t\t\t// pretty_log( \"eMain.evtH('getHDW')> blockchain\", blockchain );\r\n\t\t\t// pretty_log( \"account\", account );\r\n\t\t\t// pretty_log( \"address_index\", address_index );\r\n\t\t\t// Skribi.log(\"   options: \" + JSON.stringify(options));\r\n\t\t\tlet wallet = await HDWallet.GetWallet\r\n\t\t\t                   ( entropy_hex, salt_uuid, blockchain, crypto_net, bip32_passphrase, account, address_index );\r\n\t\t\treturn wallet;\r\n\t\t}); // \"ToMain:Request/get_hd_wallet\" event handler\r\n\t\t\r\n\t\t// ================== ToMain_RQ_GET_SIMPLE_WALLET ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.GetSimpleWallet( data )\r\n\t\tipcMain.handle( ToMain_RQ_GET_SIMPLE_WALLET, async ( event, data ) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_GET_SIMPLE_WALLET );\r\n\t\t\tconst { private_key, salt_uuid, blockchain, crypto_net } = data;\r\n\t\t\t// pretty_log( \"eMain.evtH('getSW')> private_key\", private_key );\r\n\t\t\t// pretty_log( \"eMain.evtH('getSW')> salt_uuid\", salt_uuid );\r\n\t\t\t// pretty_log( \"eMain.evtH('getSW')> blockchain\", blockchain );\r\n\t\t\t// pretty_log( \"eMain.evtH('getSW')> crypto_net\", crypto_net );\r\n\t\t\tif ( private_key == undefined || private_key == \"\" ) {\r\n\t\t\t\tthrow new Error(\"ElectronMain ToMain_RQ_GET_SIMPLE_WALLET handler: 'private_key' NOT DEFINED\");\r\n\t\t\t} \r\n\t\t\t// Skribi.log(\"   options: \" + JSON.stringify(options));\r\n\t\t\tlet wallet = await SimpleWallet\r\n\t\t\t                   .GetWallet( private_key, salt_uuid, \r\n\t\t\t\t\t\t\t               blockchain, crypto_net );\r\n\t\t\treturn wallet;\r\n\t\t}); // \"ToMain:Request/get_simple_wallet\" event handler\t\r\n\t\t\r\n\t\t// ================== ToMain_RQ_MNEMONICS_TO_HD_WALLET_INFO ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.MnemonicsToHDWalletInfo( data )\r\n\t\tipcMain.handle( ToMain_RQ_MNEMONICS_TO_HD_WALLET_INFO, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_MNEMONICS_TO_HD_WALLET_INFO );\r\n\t\t\tconst { mnemonics, options } = data;\r\n\t\t\t// Skribi.log(\"   options: \" + JSON.stringify(options));\r\n\t\t\tlet hdwallet_info = await Bip32Utils.MnemonicsToHDWalletInfo( mnemonics, options );\r\n\t\t\treturn hdwallet_info;\r\n\t\t}); // \"ToMain:Request/mnemonics_to_hd_wallet_info\" event handler\t\r\n\t\t\r\n\t\t// ================== ToMain_RQ_MNEMONICS_TO_ENTROPY_INFO ===================\r\n\t\t// called like this by Renderer: await window.ipcMain.MnemonicsToEntropyInfo( data )\r\n\t\tipcMain.handle( ToMain_RQ_MNEMONICS_TO_ENTROPY_INFO, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_MNEMONICS_TO_ENTROPY_INFO );\r\n\t\t\tconst { mnemonics, lang } = data;\r\n\t\t\t// Skribi.log(\"   lang: \" + lang);\r\n\t\t\tlet entropy_info = Bip39Utils.MnemonicsToEntropyInfo( mnemonics, lang );\r\n\t\t\treturn entropy_info;\r\n\t\t}); // \"ToMain:Request/mnemonics_to_entropy_info\" event handler\r\n\r\n\t\t// ================== ToMain_RQ_ENTROPY_TO_MNEMONICS ===================\r\n\t\t// called like this by Renderer: await window.ipcMain.EntropyToMnemonics( data )\r\n\t\tipcMain.handle( ToMain_RQ_ENTROPY_TO_MNEMONICS, async (event, data) => {\r\n\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_ENTROPY_TO_MNEMONICS + _END_);\r\n\t\t\tconst { entropy, lang } = data;\r\n\t\t\t// Skribi.log(\"   data_hex: \" + data_hex);\r\n\t\t\t// Skribi.log(\"   options: \" + JSON.stringify(options));\r\n\t\t\tlet mnemonics = Bip39Utils.EntropyToMnemonics( entropy, lang );\r\n\t\t\t// Skribi.log(\">> mnemonics: \" + mnemonics); \r\n\t\t\treturn mnemonics;\r\n\t\t}); // \"ToMain:Request/entropy_to_mnemonics\" event handler\r\n\t\t\r\n\t\t// ================== ToMain_RQ_ENTROPY_TO_CHECKSUM ===================\r\n\t\t// called like this by Renderer: await window.ipcMain.EntropyToChecksum( data )\r\n\t\tipcMain.handle( ToMain_RQ_ENTROPY_TO_CHECKSUM, async (event, data) => {\r\n\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_ENTROPY_TO_CHECKSUM + _END_);\r\n\t\t\tconst { entropy, options } = data;\r\n\t\t\tlet checksum = Bip39Utils.EntropyToChecksum( entropy, options );\r\n\t\t\treturn checksum;\r\n\t\t}); // \"ToMain:Request/entropy_to_checksum\" event handler\r\n\t\t\r\n\t\t// ================== ToMain_RQ_ENTROPY_SRC_TO_ENTROPY ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.EntropySourceToEntropy( data )\r\n\t\tipcMain.handle( ToMain_RQ_ENTROPY_SRC_TO_ENTROPY, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_ENTROPY_SRC_TO_ENTROPY );\r\n\t\t\tconst { salted_entropy_src_str, options } = data;\r\n\t\t\tlet entropy = Bip39Utils.EntropySourceToEntropy( salted_entropy_src_str, options );\r\n\t\t\treturn entropy;\r\n\t\t}); // \"ToMain:Request/entropy_src_to_entropy\" event handler\t\r\n\r\n\t\t// ================== ToMain_RQ_MNEMONICS_AS_4LETTER ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.MnemonicsAs4letter( data )\r\n\t\tipcMain.handle( ToMain_RQ_MNEMONICS_AS_4LETTER, async (event, mnemonics) => {\r\n\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_MNEMONICS_AS_4LETTER + _END_);\r\n\t\t\t// Skribi.log(\">> data: \" + data); \r\n\t\t\tlet mnemonics_as_4letter = Bip39Utils.MnemonicsAs4letter( mnemonics );\r\n\t\t\t// Skribi.log(\">> mnemonics: \" + mnemonics); \r\n\t\t\treturn mnemonics_as_4letter;\r\n\t\t}); // \"ToMain:Request/mnemonics_as_4letter\" event handler\r\n\t\t\r\n\t\t// ================== ToMain_RQ_MNEMONICS_AS_TWO_PARTS ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.MnemonicsAsTwoParts( data )\r\n\t\tipcMain.handle( ToMain_RQ_MNEMONICS_AS_TWO_PARTS, async (event, mnemonics) => {\r\n\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_MNEMONICS_AS_TWO_PARTS + _END_);\r\n\t\t\t// Skribi.log(\">> data: \" + data); \r\n\t\t\tlet mnemonics_as_two_parts = Bip39Utils.MnemonicsAsTwoParts( mnemonics );\r\n\t\t\t// Skribi.log(\">> mnemonics: \" + mnemonics); \r\n\t\t\treturn mnemonics_as_two_parts;\r\n\t\t}); // \"ToMain:Request/mnemonics_as_two_parts\" event handler\r\n\r\n\t\t// ================== ToMain_RQ_GET_SECP256K1 ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.GetSecp256k1( entropy )\r\n\t\t//ipcMain.handle( ToMain_RQ_GET_SECP256K1, (event, entropy) => {\r\n\t\t//\tSkribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_GET_SECP256K1 + _END_);\r\n\t\t//\tlet entropy_is_hex = isHexString( entropy );\r\n\t\t//\tSkribi.log(\"   entropy_is_hex: \" + entropy_is_hex);\r\n\t\t//\tlet entropy_bytes = entropy.length/2;\r\n\t\t//\tSkribi.log(\"   entropy(\" + entropy_bytes + \"):    \" + entropy);\r\n\t\t//\tlet result = getSecp256k1PK( entropy );\r\n\t\t//\treturn result;\r\n\t\t//}); // \"ToMain:Request/get_Secp256k1\" event handler\r\n\t\t\r\n\t\t// =================== ToMain_RQ_GET_FORTUNE_COOKIE ==================\r\n\t\t// called like this by Renderer: await window.ipcMain.GetFortuneCookie()\r\n\t\tipcMain.handle( ToMain_RQ_GET_FORTUNE_COOKIE, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_GET_FORTUNE_COOKIE );\r\n\t\t\tlet fortune_cookie = this.getNewFortuneCookie();\r\n\t\t\treturn fortune_cookie;\r\n\t\t}); // \"ToMain:Request/get_FortuneCookie\"\r\n\t\t\r\n\t\t// =============== ToMain_RQ_WORD_INDEXES_TO_MNEMONICS ===============\r\n\t\t// called like this by Renderer: await window.ipcMain.WordIndexesToMnemonics( data )\r\n\t\tipcMain.handle( ToMain_RQ_WORD_INDEXES_TO_MNEMONICS, async (event, data) => {\r\n\t\t\tSkribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_WORD_INDEXES_TO_MNEMONICS + _END_);\r\n\t\t\tconst { word_indexes, lang } = data;\r\n\t\t\tlet mnemonics = Bip39Utils.WordIndexesToMnemonics( word_indexes, lang );\r\n\t\t\t\t\t\t\r\n\t\t\treturn mnemonics;\r\n\t\t}); // \"ToMain:Request/word_indexes_to_mnemonics\" event handler\r\n\t\t\r\n\r\n\t\t// =============== ToMain_RQ_MNEMONICS_TO_WORD_INDEXES ===============\r\n\t\t// called like this by Renderer: await window.ipcMain.MnemonicsToWordIndexes( data )\r\n\t\tipcMain.handle( ToMain_RQ_MNEMONICS_TO_WORD_INDEXES, async (event, data) => {\r\n\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_MNEMONICS_TO_WORD_INDEXES + _END_);\r\n\t\t\tconst { mnemonics, options } = data;\r\n\t\t\tlet word_indexes = Bip39Utils.GetWordIndexes( mnemonics, options );\r\n\t\t\t\t\t\t\r\n\t\t\treturn word_indexes;\r\n\t\t}); // \"ToMain:Request/mnemonics_to_word_indexes\" event handler\r\n\r\n\t\t// =============== ToMain_RQ_GUESS_MNEMONICS_LANG ===============\r\n\t\t// called like this by Renderer: await window.ipcMain.GuessMnemonicsLang( data )\r\n\t\tipcMain.handle( ToMain_RQ_GUESS_MNEMONICS_LANG, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_GUESS_MNEMONICS_LANG );\r\n\t\t\tconst { mnemonics } = data;\r\n\t\t\tlet lang = Bip39Utils.GuessMnemonicsLang( mnemonics );\r\n\r\n\t\t\treturn lang;\r\n\t\t}); // \"ToMain:Request/guess_mnemonics_lang\" event handler\t\t\r\n\t\t\r\n\t\t// =================== ToMain_RQ_CHECK_MNEMONICS ====================\r\n\t\t// called like this by Renderer: await window.ipcMain.CheckMnemonics(data)\r\n\t\tipcMain.handle( ToMain_RQ_CHECK_MNEMONICS, async (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_CHECK_MNEMONICS );\r\n\t\t\tconst { mnemonics, options } = data;\r\n\t\t\tlet check_result = Bip39Utils.CheckMnemonics( mnemonics, options );\r\n\t\t\treturn check_result;\r\n\t\t}); // \"ToMain:Request/check_mnemonics\" event handler\r\n\r\n\t\t// ====================== ToMain_RQ_GET_UUID =======================\r\n\t\t// called like this by Renderer: await window.ipcMain.GetUUID(data)\r\n\t\tipcMain.handle( ToMain_RQ_GET_UUID, async (event, data) => {\r\n\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_GET_UUID + _END_);\r\n\t\t\tlet new_uuidv4 = uuidv4();\r\n\t\t\treturn new_uuidv4;\r\n\t\t}); // \"ToMain:Request/get_UUID\" event handler\r\n\t\t\r\n\t\t// ==================== ToMain_RQ_GET_L10N_KEYPAIRS =====================\r\n\t\t// called like this by Renderer: await window.ipcMain.GetL10nKeyPairs()\r\n\t\tipcMain.handle( ToMain_RQ_GET_L10N_KEYPAIRS, (event, data) => {\r\n\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_GET_L10N_KEYPAIRS + _END_);\r\n\t\t\tlet L10n_keypairs = L10nUtils.GetKeyPairs();\r\n\t\t\treturn L10n_keypairs;\r\n\t\t}); // \"ToMain:Request/get_L10n_keypairs\" event handler\t\r\n\r\n\t\t// ==================== ToMain_RQ_GET_L10N_MSG =====================\r\n\t\t// called like this by Renderer: await window.ipcMain.GetLocalizedMsg(msg_id)\r\n\t\tipcMain.handle( ToMain_RQ_GET_L10N_MSG, (event, msg_id) => {\r\n\t\t\t// Skribi.log(\">> \" + _CYAN_ + \"[Electron] \" + _YELLOW_ + ToMain_RQ_GET_L10N_MSG + _END_);\r\n\t\t\tlet L10n_msg = L10nUtils.GetLocalizedMsg( msg_id );\r\n\t\t\treturn L10n_msg;\r\n\t\t}); // \"ToMain:Request/get_L10n_Msg\" event handler\t\r\n\t\t\r\n\t\t// https://chasingcode.dev/blog/electron-toggle-menu-item-dynamically/\r\n\t\t// called like this by Renderer: window.ipcMain.SetMenuItemState( data )\r\n\t\tipcMain.on( ToMain_RQ_SET_MENU_ITEM_STATE, (event, data) => {\r\n\t\t\tpretty_func_header_log( \"[Electron]\", ToMain_RQ_SET_MENU_ITEM_STATE );\r\n\t\t\tconst { menu_item_id, enabled } = data;\r\n\t\t\t// pretty_log( \"eMain.evtH('setMenuItemState')> menu_item_id(state)\", menu_item_id + \"(\" + enabled + \")\" );\r\n\t\t\tlet menu_elt = Menu.getApplicationMenu().getMenuItemById( menu_item_id );\r\n\t\t\t// pretty_log( \"eMain.evtH('setMenuItemState')> menu_elt\", menu_elt );\r\n\t\t\tmenu_elt.enabled = enabled;\r\n\t\t}); // \"ToMain:Request/set_menu_item_state\" event handler\t\r\n\t} // setCallbacks()\r\n} // ElectronMain class\r\n\r\n\r\n// ========== Prevent Multiple instances of Electron main process ==========\r\n// https://stackoverflow.com/questions/35916158/how-to-prevent-multiple-instances-in-electron\r\nif ( ! gotTheLock ) {\r\n\tapp.quit();\r\n} \r\nelse {\r\n\tapp.on('second-instance', (event, commandLine, workingDirectory) => {\r\n\t\t// Someone tried to run a second instance, we should focus our window.\r\n\t\tlet main_window = ElectronMain.GetInstance().getMainWindow();\r\n\t\t\r\n\t\t// Skribi.log(\"   >> 1. process.argv: \" + JSON.stringify(process.argv));\r\n\t\t\r\n\t\tif ( main_window != null ) {\r\n\t\t\tif ( main_window ) {\r\n\t\t\t\t main_window.restore(); \r\n\t\t\t}\r\n\t\t\tmain_window.focus()\r\n\t\t}\r\n\t}); // Manage case of second instance\r\n\t\r\n\t//ipcMain.on( 'get-file-data', (event, data) => {\r\n\t//\tSkribi.log(\"   >> 'get-file-data': $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\");\r\n    //    this.getCmdLineArgs();\t\t\t\r\n\t//} ); // 'get-file-data'\r\n\t\r\n\t// Create Electron main window, load the rest of the app, etc...\r\n\tapp.whenReady().then( async () => {\r\n\t\tif (   process.platform.startsWith('win') \r\n\t\t\t&& process.argv.length >= 2 ) {\r\n\t\t\tconst in_file_path = process.argv[1];\r\n\t\t\t// Skribi.log( \"   2. process.argv: \"     + JSON.stringify(process.argv) );\r\n\t\t\t// Skribi.log( \"   >>> in_file_path: \" + in_file_path );\r\n\t\t}\r\n\t\tElectronMain.GetInstance().createWindow();\r\n\t\t\r\n\t\tconst TIME_OUT = 1250;\r\n\t\tlet test_internet_connection_count = 0;\r\n\t\tlet internet_connected = true;\r\n\t\t\r\n\t\tconst check_internet_connection_fn = async () => {\r\n\t\t\t// https://stackoverflow.com/questions/44663864/correct-try-catch-syntax-using-async-await\t\t\t\r\n\t\t\tinternet_connected = true;\r\n\t\t\tawait checkInternetConnected().catch( error => {\r\n\t\t\t\t  internet_connected = false;\r\n            });\r\n\t\t\t\t\t\t              \r\n\t\t\t// console.log(\"> test_internet_connection_count: \" + test_internet_connection_count++ + \"  internet_connected = \" + internet_connected);\r\n\t\t\t\t\t\t\r\n\t\t\tElectronMain.GetInstance().getMainWindow().webContents.send\r\n\t\t\t\t\t\t( \"fromMain\", [ FromMain_INTERNET_CONNECTED, internet_connected ] );\r\n\t\t\t\t\t\t\r\n\t\t\tsetTimeout( check_internet_connection_fn, TIME_OUT );\r\n\t\t}; // check_internet_connection_fn()\r\n\r\n\t\tawait check_internet_connection_fn();\r\n\t});\r\n}\r\n// ========== Prevent Multiple instances of Electron main process\r\n// ====================================================================================="]}