@aladas-org/cryptocalc
Version:
Cryptocurrency wallet generator
1,239 lines (1,008 loc) • 59.8 kB
JavaScript
// =======================================================================================================================
// ==================================== entropy_converter_dialog.js =======================================
// =======================================================================================================================
"use strict";
const ECONVERTER_DIALOG_LABEL_ID = "econverter_dialog_label_id";
const ECONVERTER_ENTROPY_SIZE_VALUE_ID = "econverter_entropy_size_value_id";
const ECONVERTER_ENTROPY_WORD_COUNT_ID = "econverter_entropy_word_count_id";
const ECONVERTER_ENTROPY_SIZE_SELECT_ID = "econverter_entropy_size_select_id";
const ECONVERTER_RAWTEXT_INPUT_ID = "econverter_rawtext_input_id";
const ECONVERTER_RAWTEXT_COPY_BTN_ID = "econverter_rawtext_copy_btn_id";
const ECONVERTER_HEXADECIMAL_INPUT_ID = "econverter_hexadecimal_input_id";
const ECONVERTER_GENERATE_ENTROPY_BTN_ID = "econverter_generate_random_entropy_btn_id";
const ECONVERTER_HEXADECIMAL_COPY_BTN_ID = "econverter_hexadecimal_copy_btn_id";
const ECONVERTER_BASE64_INPUT_ID = "econverter_base64_input_id";
const ECONVERTER_BASE64_COPY_BTN_ID = "econverter_base64_copy_btn_id";
const ECONVERTER_BASE58_INPUT_ID = "econverter_base58_input_id";
const ECONVERTER_BASE58_COPY_BTN_ID = "econverter_base58_copy_btn_id";
const ECONVERTER_SECRET_PHRASE_INPUT_ID = "econverter_secret_phrase_input_id";
const ECONVERTER_SECRET_PHRASE_COPY_BTN_ID = "econverter_secret_phrase_copy_btn_id";
const ECONVERTER_BINARY_INPUT_ID = "econverter_binary_input_id";
const ECONVERTER_BINARY_COPY_BTN_ID = "econverter_binary_copy_btn_id";
const ECONVERTER_LANG_SELECT_ID = "econverter_lang_select_id";
const ECONVERTER_GRID_IMG_ID = "econverter_grid_img_id";
const ECONVERTER_CLEAR_BTN_ID = "econverter_clear_btn_id";
const ECONVERTER_QUIT_BTN_ID = "econverter_quit_btn_id";
const BIP39_ALLOWED_BYTES_COUNT = [ 16, 20, 24, 28, 32 ];
const BIP39_ALLOWED_WORD_COUNT = [ 12, 15, 18, 21, 24 ];
const BIP39_ALLOWED_BIT_SIZES = [ 128, 160, 192, 224, 256 ];
const INPUT_FIELDS_IDS = [ ECONVERTER_RAWTEXT_INPUT_ID, ECONVERTER_HEXADECIMAL_INPUT_ID,
ECONVERTER_BASE64_INPUT_ID, ECONVERTER_BASE58_INPUT_ID,
ECONVERTER_SECRET_PHRASE_INPUT_ID, ECONVERTER_BINARY_INPUT_ID ];
//const BASE256U_ALPHABET = "ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğ !\"#$%&'()*+,-./0123456789:;<=>?@" +
// "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~à" +
// "âçèéêëîïôûùüÿœŒÀİıIJijĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőĨĴŔŕŖŗŘřŚśŜŝŞşŠš" +
// "αβγδεζηθικλμνξοπρςστυφχψωŶŷŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƠ";
const BASE256U_ALPHABET = "▲△▼▽▶▷◀◁♠♣♥♦€£¥¢§←↑→↓≪≫©®∀∃∈∞!\"#" +
"$%&()*+,-./0123456789:;<=>?@ABCD" +
"EFGHIJKLMNOPQRSTUVWXYZ[\]^Þabcde" +
"fghijklmnopqrstuvwxyz{|}~àâçèéêë" +
"îïôûùüÿœŒĀāĂăĆćĈĉĊċČčĎĐđĒēĔĕĖėĚě" +
"ĞĿƔƕ∫∬∂αβγδεζηθλμξπςστφχψω∮∯∤≼≽≠" +
"≶≸≡≤≥⊥⊤⊢⊣⊨⊩⊪⊗⊘⊙⊚⊞⊟⊕⊖⊜⊍◆◇◈◉○◎●◐◑∇" +
"ΓΔΘΛΞΠΣΦΨΩ√∛∢∩⊂⊃⊄⊅∧∨∅⊓⊔⊏⊐⊑⊒┼∎◤◥◣◢";
// ≈≡≤≥⊥⊤⊢⊣⊨⊩⊪⊫⊬⊭⊮⊯⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟
// ∇∑∏∫∂┌┐└┘├┤┬┴┼█▌▐▖▗▘▙▚▛▜▝▞▟◆◇◈◉○◍◎●◐◑
// "ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğ"
// "∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳"
// "≈≠≡≤≥≪≫≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝"
const BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
const HEXADECIMAL_ALPHABET = "0123456789ABCDEFabcdef";
const BINARY_ALPHABET = "01";
const convertirEnHexAvecZero = (n) => {
// Convertir en hexadécimal (en majuscules pour A-F)
let hex = n.toString(16).toUpperCase();
// Ajouter un zéro à gauche si n <= 9
if (n <= 9) {
hex = '0' + hex;
}
return hex;
}; // convertirEnHexAvecZero()
class EntropyConverterDialog {
static #Key = Symbol();
static #Singleton = new EntropyConverterDialog( this.#Key );
static #InstanceCount = 0;
static get This() {
if ( EntropyConverterDialog.#Singleton == undefined ) {
EntropyConverterDialog.#Singleton = new EntropyConverterDialog( this.#Key );
if ( Bip38EncryptDecryptDialog.#Singleton > 0 ) {
throw new TypeError("'EntropyConverterDialog' constructor called more than once");
}
EntropyConverterDialog.#InstanceCount++;
}
return EntropyConverterDialog.#Singleton;
} // EntropyConverterDialog 'This' getter
// ** Private constructor **
constructor( key ) {
// console.log(">> **************** new EntropyConverterDialog");
if ( key !== EntropyConverterDialog.#Key ) {
throw new TypeError("'EntropyConverterDialog' constructor is private");
}
this.event_handlers_attached = false;
this.displayed = false;
this.encrypt_mode = true;
this.previous_lang = 'EN';
this.word_has_been_replaced = false;
this.allow_cb = true;
} // ** Private constructor **
initialize() {
// console.log(">> EntropyConverterDialog.initialize");
$("#" + ENTROPY_CONVERTER_DIALOG_ID).dialog
( { // -------------------- JQuery Dialog options --------------------
modal: true,
resizable: false,
autoOpen: false,
dialogClass: 'DialogBox',
// https://stackoverflow.com/questions/18992081/trigger-event-on-dialog-box-open
// https://stackoverflow.com/questions/394491/passing-data-to-a-jquery-ui-dialog/3458299#3458299
width: 685, // 680
open: function( event, ui ) {
let this_obj = EntropyConverterDialog.This;
if ( ! this_obj.event_handlers_attached ) {
this_obj.addEventHandler
( ECONVERTER_RAWTEXT_COPY_BTN_ID, 'click',
() => { EntropyConverterDialog.This.onCopyField(ECONVERTER_RAWTEXT_INPUT_ID); } );
this_obj.addEventHandler
( ECONVERTER_GENERATE_ENTROPY_BTN_ID, 'click',
async () => { await EntropyConverterDialog.This.onGenerateEntropy(); } );
this_obj.addEventHandler
( ECONVERTER_HEXADECIMAL_COPY_BTN_ID, 'click',
() => { EntropyConverterDialog.This.onCopyField(ECONVERTER_HEXADECIMAL_INPUT_ID); } );
this_obj.addEventHandler
( ECONVERTER_BASE64_COPY_BTN_ID, 'click',
() => { EntropyConverterDialog.This.onCopyField(ECONVERTER_BASE64_INPUT_ID); } );
this_obj.addEventHandler
( ECONVERTER_BASE58_COPY_BTN_ID, 'click',
() => { EntropyConverterDialog.This.onCopyField(ECONVERTER_BASE58_INPUT_ID); } );
this_obj.addEventHandler
( ECONVERTER_SECRET_PHRASE_COPY_BTN_ID, 'click',
() => { EntropyConverterDialog.This.onCopyField(ECONVERTER_SECRET_PHRASE_INPUT_ID); } );
this_obj.addEventHandler
( ECONVERTER_BINARY_COPY_BTN_ID, 'click',
() => { EntropyConverterDialog.This.onCopyField(ECONVERTER_BINARY_INPUT_ID); } );
this_obj.addEventHandler
( ECONVERTER_RAWTEXT_INPUT_ID, 'input',
async ( evt ) =>
{ await EntropyConverterDialog.This.onChangeInputField( ECONVERTER_RAWTEXT_INPUT_ID ); } );
this_obj.addEventHandler
( ECONVERTER_HEXADECIMAL_INPUT_ID, 'input',
async ( evt ) =>
{ await EntropyConverterDialog.This.onChangeInputField( ECONVERTER_HEXADECIMAL_INPUT_ID ); } );
this_obj.addEventHandler
( ECONVERTER_BASE64_INPUT_ID, 'input',
async ( evt ) =>
{ await EntropyConverterDialog.This.onChangeInputField( ECONVERTER_BASE64_INPUT_ID ); } );
this_obj.addEventHandler
( ECONVERTER_BASE58_INPUT_ID, 'input',
async ( evt ) =>
{ await EntropyConverterDialog.This.onChangeInputField( ECONVERTER_BASE58_INPUT_ID ); } );
this_obj.addEventHandler
( ECONVERTER_BINARY_INPUT_ID, 'input',
async ( evt ) =>
{ await EntropyConverterDialog.This.onChangeInputField( ECONVERTER_BINARY_INPUT_ID ); } );
this_obj.addEventHandler
( ECONVERTER_SECRET_PHRASE_INPUT_ID, 'keypress',
async ( evt ) =>
{ await EntropyConverterDialog.This.onSecretPhraseKeypress( evt ); } );
this_obj.addEventHandler
( ECONVERTER_SECRET_PHRASE_INPUT_ID, 'keydown',
async ( evt ) =>
{ await EntropyConverterDialog.This.onSecretPhraseKeydown( evt ); } );
this_obj.addEventHandler
( ECONVERTER_SECRET_PHRASE_INPUT_ID, 'change',
async ( evt ) => {
if ( this_obj.allow_cb ) {
await EntropyConverterDialog.This.onChangeInputField( ECONVERTER_SECRET_PHRASE_INPUT_ID );
}
});
this_obj.addEventHandler
( ECONVERTER_SECRET_PHRASE_INPUT_ID, 'wheel',
async ( evt ) => {
if ( this_obj.allow_cb ) {
await EntropyConverterDialog.This.onSecretPhraseWheel( evt );
}
});
this_obj.addEventHandler
( ECONVERTER_LANG_SELECT_ID, 'change',
async ( evt ) =>
{ await EntropyConverterDialog.This.onChangeLang( ECONVERTER_LANG_SELECT_ID ); } );
this_obj.addEventHandler
( ECONVERTER_GRID_IMG_ID, 'mousemove',
async ( evt ) => {
if ( this_obj.allow_cb ) {
await EntropyConverterDialog.This.onImgGridHover( evt );
}
});
this_obj.addEventHandler
( ECONVERTER_GRID_IMG_ID, 'click',
async ( evt ) =>
{ await EntropyConverterDialog.This.onImgGridClick( evt ); } );
this_obj.addEventHandler
( ECONVERTER_GRID_IMG_ID, 'mouseleave',
( evt ) =>
{ EntropyConverterDialog.This.onImgGridMouseLeave( evt ); } );
this_obj.addEventHandler
( ECONVERTER_CLEAR_BTN_ID, 'click',
() => { EntropyConverterDialog.This.onClearFields(); } );
this_obj.addEventHandler
( ECONVERTER_QUIT_BTN_ID, 'click',
() => { EntropyConverterDialog.This.onQuit(); } );
this_obj.event_handlers_attached = true;
}
this_obj.clearFields();
this_obj.displayed = true;
}, // open()
close: function( event, ui ) {
let this_obj = EntropyConverterDialog.This;
this_obj.displayed = false;
} // close()
} // -------------------- JQuery Dialog options
).parent().css('z-index', 900);
} // initialize()
showDialog() {
trace2Main( pretty_func_header_format( "EntropyConverterDialog.showDialog" ) );
let dialog_id = ENTROPY_CONVERTER_DIALOG_ID;
let dialog_elt = document.getElementById( dialog_id );
// https://stackoverflow.com/questions/394491/passing-data-to-a-jquery-ui-dialog/3458299#3458299
if ( dialog_elt != undefined ) {
// https://stackoverflow.com/questions/13520139/jquery-ui-dialog-cannot-call-methods-on-dialog-prior-to-initialization
let dialog_obj = $("#" + dialog_id);
dialog_obj.dialog('open');
}
else {
console.log( ">> " + _RED_HIGH_ + "*ERROR* NOT FOUND " + dialog_id
+ " (EntropyConverterDialog.showDialog)" + _END_);
}
} // showDialog()
closeDialog() {
let dialog_obj = $("#" + ENTROPY_CONVERTER_DIALOG_ID);
this.clearFields();
dialog_obj.dialog('close');
} // closeDialog()
ascii_to_hexa( in_str ) {
// Initialize an empty array to store the hexadecimal values
let hex_str = [];
// Iterate through each character in the input string
for (let i = 0; i < in_str.length; i++) {
// Convert the ASCII value of the current character to its hexadecimal representation
// let hex = in_str.charCodeAt(i).toString(16).padStart(2, '0');
let current_char = in_str[i];
let char_code = BASE256U_ALPHABET.indexOf(current_char);
let hex_digits = convertirEnHexAvecZero(char_code);
// Push the hexadecimal value to the array
hex_str.push(hex_digits);
}
// Join the hexadecimal values in the array to form a single string
return hex_str.join('');
} // ascii_to_hexa()
hexa_to_ascii( hex_value ) {
let hex_str = hex_value.toString(); //force conversion
// console.log(" hex_str: " + hex_str);
var ascii_str = '';
for (let i = 0; i < hex_str.length; i += 2) {
let hex_byte = hex_str.substr(i, 2);
// console.log(" hex_byte(" + i + "): " + hex_byte);
let char_code = parseInt( hex_byte, 16 );
// console.log(" char_code(" + i + "): " + char_code);
// let new_char = String.fromCharCode(char_code);
let new_char = BASE256U_ALPHABET[char_code];
// console.log(" new_char(" + i + "): " + new_char);
ascii_str += new_char;
}
return ascii_str;
} // hexa_to_ascii()
getEntropyBip39ByteCount( hex_str ) {
// Initialize an empty array to store the hexadecimal values
if ( ! isHexString( hex_str ) || hex_str.length % 2 != 0) return 0;
let bytes_count = hex_str.length / 2;
if ( BIP39_ALLOWED_BYTES_COUNT.indexOf( bytes_count ) != -1 ) {
return bytes_count;
}
} // getEntropyBip39ByteCount()
async propagateNewValue( source_elt_id ) {
let hex_value = '';
let raw_value = '';
let base64_value = '';
let base58_value = '';
let secret_phrase_value = '';
let binary_value = '';
let entropy = '';
let mnemonics = '';
let lang = '';
let mnemonics_value = "";
let data = {};
let entropy_info = {};
const getHexValue = async ( field_id ) => {
let hex_value = '';
let mnemonics_value = '';
let field_value = HtmlUtils.GetElementValue( field_id );
if ( field_id == ECONVERTER_HEXADECIMAL_INPUT_ID ) {
hex_value = HtmlUtils.GetElementValue( ECONVERTER_HEXADECIMAL_INPUT_ID );
}
else if ( field_id == ECONVERTER_SECRET_PHRASE_INPUT_ID ) {
mnemonics_value = HtmlUtils.GetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID );
mnemonics = mnemonics_value;
lang = HtmlUtils.GetElementValue( ECONVERTER_LANG_SELECT_ID );
data = { mnemonics, lang };
// entropy_info = await window.ipcMain.MnemonicsToEntropyInfo( data );
entropy_info = await window.ipcMain.MnemonicsToEntropyInfoCustom( data );
hex_value = entropy_info[ENTROPY_HEX];
}
else {
let bases_data = {};
if ( field_id == ECONVERTER_RAWTEXT_INPUT_ID ) {
bases_data[FROM_RAW_TEXT] = field_value;
}
else if ( field_id == ECONVERTER_BASE64_INPUT_ID ) {
bases_data[FROM_BASE64] = field_value;
}
else if ( field_id == ECONVERTER_BASE58_INPUT_ID ) {
bases_data[FROM_BASE58] = field_value;
}
else if ( field_id == ECONVERTER_BINARY_INPUT_ID ) {
bases_data[FROM_BINARY] = field_value;
}
data = bases_data;
hex_value = await window.ipcMain.ConvertFromBasesToHex( data );
if ( field_id == ECONVERTER_RAWTEXT_INPUT_ID ) {
hex_value = '';
for ( let i=0; i < field_value.length; i++ ) {
let current_char = field_value[ i ];
let char_pos_Base256 = BASE256U_ALPHABET.indexOf(current_char);
let char_code_as_hex = convertirEnHexAvecZero(char_pos_Base256);
hex_value += char_code_as_hex;
}
}
}
return hex_value;
}; // async getHexValue()
let base_conversions = {};
const BIP39_ALLOWED_BYTES_COUNT = [ 16, 20, 24, 28, 32 ];
let bit_size = 0;
let hex_value_bit_size = 0;
let word_count = 0;
let word_label = '';
let bit_label = '';
for ( let i=0; i < INPUT_FIELDS_IDS.length; i++ ) {
let current_field_id = INPUT_FIELDS_IDS [ i ];
raw_value = '';
base64_value = '';
base58_value = '';
base_conversions = {};
secret_phrase_value = '';
binary_value = '';
bit_size = 0;
hex_value_bit_size = 0;
word_count = 0;
word_label = '';
bit_label = '';
if ( source_elt_id != current_field_id ) continue;
if ( current_field_id == ECONVERTER_HEXADECIMAL_INPUT_ID ) {
hex_value = HtmlUtils.GetElementValue( ECONVERTER_HEXADECIMAL_INPUT_ID ).trim();
bit_size = hex_value.length * 4;
// console.log(" STEP 0 HEX: bit_size: " + bit_size);
}
else if ( current_field_id == ECONVERTER_RAWTEXT_INPUT_ID ) {
raw_value = HtmlUtils.GetElementValue( ECONVERTER_RAWTEXT_INPUT_ID );
bit_size = raw_value.length * 8;
// console.log(" STEP 0 RAW: bit_size: " + bit_size);
hex_value = await getHexValue( ECONVERTER_RAWTEXT_INPUT_ID );
}
else if ( current_field_id == ECONVERTER_BASE64_INPUT_ID ) {
base64_value = HtmlUtils.GetElementValue( ECONVERTER_BASE64_INPUT_ID ).trim();
// base64_value = base64_value.replaceAll('=','');
bit_size = base64_value.replaceAll('=','').length * 6;
// console.log(" STEP 0 BASE64: bit_size: " + bit_size);
hex_value = await getHexValue( ECONVERTER_BASE64_INPUT_ID );
hex_value_bit_size = hex_value.length * 4;
bit_size = hex_value_bit_size;
}
else if ( current_field_id == ECONVERTER_BASE58_INPUT_ID ) {
base58_value = HtmlUtils.GetElementValue( ECONVERTER_BASE58_INPUT_ID ).trim();
// base64_value = base64_value.replaceAll('=','');
// bit_size = base58_value.length * 5.86;
// console.log(" STEP 0 BASE64: bit_size: " + bit_size);
hex_value = await getHexValue( ECONVERTER_BASE58_INPUT_ID );
hex_value_bit_size = hex_value.length * 4;
bit_size = hex_value_bit_size;
}
// else if ( current_field_id == ECONVERTER_BASE58_INPUT_ID ) {
// base58_value = HtmlUtils.GetElementValue( ECONVERTER_BASE58_INPUT_ID ).trim();
// base58_value = base58_value.replaceAll('=','');
// bit_size = base58_value.length * 5.86;
// // console.log(" STEP 0 BASE58: bit_size: " + bit_size);
// hex_value = await getHexValue( ECONVERTER_BASE58_INPUT_ID );
// hex_value_bit_size = hex_value.length * 4;
// bit_size = hex_value_bit_size;
// }
else if ( current_field_id == ECONVERTER_SECRET_PHRASE_INPUT_ID ) {
secret_phrase_value = HtmlUtils.GetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID ).trim();
if ( secret_phrase_value == '' ) {
bit_size = 0;
word_count = 0;
}
else {
// console.log(" STEP 0 SECRET_PHRASE: secret_phrase_value: " + secret_phrase_value);
let words = secret_phrase_value.trim().split(' ');
word_count = words.length;
// console.log(" STEP 0 SECRET_PHRASE: word_count: " + word_count);
HtmlUtils.SetElementValue( ECONVERTER_ENTROPY_WORD_COUNT_ID, word_count );
bit_size = word_count * 11;
hex_value = await getHexValue( ECONVERTER_SECRET_PHRASE_INPUT_ID );
hex_value_bit_size = hex_value.length * 4;
bit_size = hex_value_bit_size;
// console.log(" STEP 0 SECRET_PHRASE: bit_size: " + bit_size);
}
}
else if ( current_field_id == ECONVERTER_BINARY_INPUT_ID ) {
binary_value = HtmlUtils.GetElementValue( ECONVERTER_BINARY_INPUT_ID ).trim();
// console.log(" binary_value: " + binary_value + " isBinaryString: " + isBinaryString(binary_value));
if ( isBinaryString(binary_value) ) {
bit_size = binary_value.length;
// console.log(" STEP 1 BINARY: bit_size: " + bit_size);
if ( bit_size % 4 == 0 ) {
hex_value = binaryToHex( binary_value );
// console.log(" hex_value (4 binary digits): " + hex_value);
hex_value_bit_size = hex_value.length * 4;
bit_size = hex_value_bit_size;
// console.log(" STEP 1 BINARY: bit_size (hex digits): " + bit_size);
}
// console.log(" STEP 0 BINARY: bit_size: " + bit_size);
}
}
else {
hex_value = await getHexValue( current_field_id );
}
if ( bit_size == 0 ) {
HtmlUtils.SetElementValue( ECONVERTER_ENTROPY_SIZE_VALUE_ID, '0' );
}
else if ( bit_size > 0 ) {
// console.log(" STEP 2: bit_size: " + bit_size);
bit_size = Number( bit_size );
if ( ! Number.isInteger(bit_size) ) bit_size = bit_size.toFixed(2);
// console.log(" STEP 2: bit_size 2 decimales: " + bit_size);
HtmlUtils.SetElementValue( ECONVERTER_ENTROPY_SIZE_VALUE_ID, bit_size );
}
if ( word_count == 0 ) {
word_count = HtmlUtils.SetElementValue( ECONVERTER_ENTROPY_WORD_COUNT_ID, '0' );
}
else if ( word_count > 0 ) {
// console.log(" STEP 2: word_count: " + word_count);
HtmlUtils.SetElementValue( ECONVERTER_ENTROPY_WORD_COUNT_ID, word_count );
}
let bytes_count = hex_value.length / 2;
if ( BIP39_ALLOWED_BYTES_COUNT.indexOf( bytes_count ) == -1 ) {
continue;
}
if ( hex_value != '' ) {
if ( current_field_id == ECONVERTER_BASE64_INPUT_ID ) {
let current_base64_value = HtmlUtils.GetElementValue( ECONVERTER_BASE64_INPUT_ID );
console.log("current_base64_value(" + current_base64_value.length + "): " + current_base64_value);
let bip39_base64_value = hexToB64( hex_value );
console.log("bip39_base64_value(" + bip39_base64_value.length + "): " + bip39_base64_value);
let base64_value_without_padding = base64_value.replaceAll('=','');
console.log("base64_value_without_padding(" + base64_value_without_padding.length + "): " + base64_value_without_padding);
}
if ( [ 128, 160, 192, 224, 256].indexOf(hex_value.length*4) != -1 ) {
if ( current_field_id == ECONVERTER_BASE64_INPUT_ID ) {
let current_base64_value = HtmlUtils.GetElementValue( ECONVERTER_BASE64_INPUT_ID );
console.log("current_base64_value(" + current_base64_value.length + "): " + current_base64_value);
let bip39_base64_value = hexToB64( hex_value );
console.log("bip39_base64_value(" + bip39_base64_value.length + "): " + bip39_base64_value);
if ( current_base64_value.length > bip39_base64_value.length ) {
base64_value = current_base64_value;
}
else {
base64_value = bip39_base64_value;
}
}
else {
base64_value = hexToB64( hex_value );
}
HtmlUtils.SetElementValue( ECONVERTER_BASE64_INPUT_ID, base64_value );
}
lang = HtmlUtils.GetElementValue( ECONVERTER_LANG_SELECT_ID );
this.previous_lang = lang;
entropy = hex_value;
data = { entropy, lang };
mnemonics_value = await window.ipcMain.EntropyToMnemonics( data );
base_conversions = await window.ipcMain.ConvertFromHexToBases( hex_value );
}
for ( let j=0; j < INPUT_FIELDS_IDS.length; j++ ) {
let target_field_id = INPUT_FIELDS_IDS [ j ];
if ( source_elt_id != target_field_id && hex_value != '' ) {
// console.log(">> target_field_id: " + target_field_id + " hex_value(" + hex_value.length/2 + " bytes): " + hex_value);
if ( target_field_id == ECONVERTER_RAWTEXT_INPUT_ID && base_conversions[TO_RAW_TEXT] != undefined ) {
raw_value = this.hexa_to_ascii( hex_value );
HtmlUtils.SetElementValue( ECONVERTER_RAWTEXT_INPUT_ID, raw_value );
// HtmlUtils.SetElementValue( ECONVERTER_RAWTEXT_INPUT_ID, base_conversions[TO_RAW_TEXT] );
}
else if ( target_field_id == ECONVERTER_HEXADECIMAL_INPUT_ID && hex_value != '' ) {
HtmlUtils.SetElementValue( ECONVERTER_HEXADECIMAL_INPUT_ID, hex_value );
if ( [ 128, 160, 192, 224, 256].indexOf(hex_value.length*4) != -1 ) {
HtmlUtils.SetElementValue( ECONVERTER_BASE64_INPUT_ID, base64_value );
}
}
else if ( target_field_id == ECONVERTER_BASE64_INPUT_ID && base_conversions[TO_BASE64] != undefined ) {
if ( [ 128, 160, 192, 224, 256].indexOf(hex_value.length*4) != -1 ) {
HtmlUtils.SetElementValue( ECONVERTER_BASE64_INPUT_ID, base64_value );
}
else {
HtmlUtils.SetElementValue( ECONVERTER_BASE64_INPUT_ID, base_conversions[TO_BASE64] );
}
}
else if ( target_field_id == ECONVERTER_BASE58_INPUT_ID && base_conversions[TO_BASE58] != undefined ) {
HtmlUtils.SetElementValue( ECONVERTER_BASE58_INPUT_ID, base_conversions[TO_BASE58] );
}
else if ( target_field_id == ECONVERTER_BINARY_INPUT_ID && base_conversions[TO_BINARY] != undefined ) {
let binary_value = base_conversions[TO_BINARY];
// console.log(">> binary_value: " + binary_value);
HtmlUtils.SetElementValue( ECONVERTER_BINARY_INPUT_ID, base_conversions[TO_BINARY] );
}
else if ( target_field_id == ECONVERTER_SECRET_PHRASE_INPUT_ID && mnemonics_value != '' ) {
HtmlUtils.SetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID, mnemonics_value );
let words = mnemonics_value.trim().split(' ');
HtmlUtils.SetElementValue( ECONVERTER_ENTROPY_WORD_COUNT_ID, words.length );
}
}
}
if ( [ 128, 160, 192, 224, 256].indexOf(hex_value.length*4) != -1 ) {
HtmlUtils.SetElementValue( ECONVERTER_ENTROPY_SIZE_SELECT_ID, (hex_value.length*4).toString() );
}
}
} // async propagateNewValue()
async onGenerateEntropy() {
let log_msg = ">> " + _CYAN_ + "EntropyConverterDialog.onGenerateEntropy" + _END_;
window.ipcMain.logToMain(log_msg);
let entropy_size = HtmlUtils.GetElementValue( ECONVERTER_ENTROPY_SIZE_SELECT_ID );
// console.log( " entropy_size: " + entropy_size + " bits");
let random_entropy_hex = await window.ipcMain.GenerateEntropy( entropy_size );
// console.log( "random_entropy_hex: " + random_entropy_hex + " " + random_entropy_hex.length*4 + " bits" );
HtmlUtils.SetElementValue( ECONVERTER_LANG_SELECT_ID, 'EN' );
HtmlUtils.SetElementValue( ECONVERTER_HEXADECIMAL_INPUT_ID, random_entropy_hex );
await this.propagateNewValue( ECONVERTER_HEXADECIMAL_INPUT_ID );
} // async onGenerateEntropy()
async onChangeLang() {
this.allow_cb = false;
let log_msg = ">> " + _CYAN_ + "EntropyConverterDialog.onChangeLang" + _END_;
window.ipcMain.logToMain(log_msg);
let data = {};
let current_lang = this.previous_lang;
// console.log("> current_lang: " + this.previous_lang );
let secret_phrase_value = HtmlUtils.GetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID ).trim();
// console.log("> secret_phrase_value: '" + secret_phrase_value + "'" );
let translated_secret_phrase_value = '';
let mnemonics = '';
let lang = '';
let word_index = '';
let word_indexes = [];
let options = {};
let current_mnemonics = secret_phrase_value.split(' ');
let new_mnemonics = '';
let new_lang = HtmlUtils.GetElementValue( ECONVERTER_LANG_SELECT_ID );
// console.log("> new_lang: " + new_lang );
if ( current_mnemonics.length < 12 || [12,15,18,22,24].indexOf(current_mnemonics.length) == -1 ) {
// console.log("> Non Standard Word Count: " + current_mnemonics.length );
let translated_mnemonics = '';
let current_mnemonic = '';
let new_mnemonic = '';
options = {};
// console.log("++++++++++++++++++++++++");
// console.log("> secret_phrase_value: " + secret_phrase_value );
const normalizeBip39 = (str) =>{
if (!str) return '';
// Convertir TOUT en forme décomposée, puis supprimer les accents combinants
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}; // normalizeBip39()
for ( let i=0; i < current_mnemonics.length; i++ ) {
console.log("--------------- " + i);
current_mnemonic = current_mnemonics[ i ];
// current_mnemonic = normalizeBip39( current_mnemonic );
// console.log("current_mnemonic: <" + current_mnemonic + "> current_lang: " + current_lang);
if ( current_mnemonic == '' ) continue;
if ( current_lang == WORDLIST_WORD_INDEXES ) {
word_index = parseInt( current_mnemonic ).toString();
}
else {
try {
// console.log("mnemonics BEFORE normalize: '" + current_mnemonic + "'");
// mnemonics = normalizeBip39( current_mnemonic );
mnemonics = current_mnemonic;
//-------------
// console.log("mnemonics AFTER normalize: '" + mnemonics + "' LANG: " + LANG);
options = { ['Lang']: current_lang };
data = { mnemonics, options };
word_index = await window.ipcMain.MnemonicToWordIndex( data );
}
catch ( err ) {
throw new Error("**** Error **** in EntropyConverterDialog.onChangeLang Line 544");
}
}
word_index = parseInt(word_index);
// console.log("word_index: " + word_index + " From: " + current_lang + " To: " + new_lang);
if ( new_lang == WORDLIST_WORD_INDEXES ) {
new_mnemonic = word_index.toString();
}
else {
lang = new_lang;
data = { word_index, lang };
try {
new_mnemonic = await window.ipcMain.WordIndexToMnemonic( data );
}
catch ( err ) {
throw new Error("**** Error **** in EntropyConverterDialog.onChangeLang Line 556");
}
}
// console.log("new_mnemonic: " + new_mnemonic);
new_mnemonic = new_mnemonic.normalize('NFC');
console.log("[" + i + "," + current_lang + "] idx:" + word_index + ": <" + current_mnemonic + "> to " + new_lang + ": <" + new_mnemonic + ">");
translated_secret_phrase_value += new_mnemonic + ' ';
}
translated_secret_phrase_value = translated_secret_phrase_value.trim(' ');
HtmlUtils.SetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID, translated_secret_phrase_value );
this.previous_lang = new_lang;
}
else { // Standard Word Count
// console.log(" Standard Word Count: " + current_mnemonics.length);
if ( current_lang == WORDLIST_WORD_INDEXES ) {
// console.log(" current_lang = WORDLIST_WORD_INDEXES");
// console.log("> current_lang: " + current_lang );
// console.log("> new_lang: " + new_lang );
// console.log("> previous_lang: " + this.previous_lang );
// console.log(" current_mnemonics: '" + current_mnemonics + "'");
lang = 'EN';
// console.log(" word indexes of mnemonics: '" + mnemonics + "'" );
let word_indexes = current_mnemonics; //..split(' ');
// console.log(" word indexes typeof " + typeof word_indexes );
// console.log(" word indexes: " + JSON.stringify(word_indexes) );
data = { word_indexes, lang };
secret_phrase_value = await window.ipcMain.WordIndexesToMnemonics( data );
// console.log(" word indexes to mnemonics: '" + mnemonics + "'" );
}
console.log(" current mnemonics: " + secret_phrase_value);
mnemonics = secret_phrase_value;
lang = current_lang;
data = { mnemonics, lang };
let entropy_info = await window.ipcMain.MnemonicsToEntropyInfo( data );
let entropy_value = entropy_info[ENTROPY_HEX];
// console.log(" entropy_value: " + entropy_value);
let entropy = '';
if ( new_lang == WORDLIST_WORD_INDEXES ) {
mnemonics = secret_phrase_value;
options = { [LANG]: this.previous_lang };
data = { mnemonics, options };
let word_indexes = await window.ipcMain.MnemonicsToWordIndexes( data );
new_mnemonics = word_indexes.join(' ');
}
else {
entropy = entropy_value;
lang = new_lang;
data = { entropy, lang };
new_mnemonics = await window.ipcMain.EntropyToMnemonics( data );
console.log(" new_mnemonics(" + lang + "): " + new_mnemonics);
}
HtmlUtils.SetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID, new_mnemonics );
this.previous_lang = new_lang;
} // if (check if Standard Word Count)
this.allow_cb = true;
} // async onChangeLang()
async onChangeInputField( source_elt_id ) {
let log_msg = ">> " + _CYAN_ + "EntropyConverterDialog.onChangeInputField" + _END_;
window.ipcMain.logToMain(log_msg);
// console.log(" source_elt_id: " + source_elt_id);
let field_value = HtmlUtils.GetElementValue( source_elt_id );
// console.log(" Change field_value: " + field_value + " length: " + field_value.length + " bytes: " + field_value.length/2);
for ( let i=0; i < INPUT_FIELDS_IDS.length; i++ ) {
let current_field_id = INPUT_FIELDS_IDS[ i ];
if ( current_field_id != source_elt_id ) {
HtmlUtils.SetElementValue( current_field_id, '' );
}
}
const convertInputValueToValidBaseValue = ( field_value, base_alphabet, max_length ) => {
let valid_base_value = '';
// console.log("base_alphabet: " + base_alphabet);
// console.log("max_length: " + max_length);
if ( max_length === undefined ) max_length = -1;
for ( let j=0; j < field_value.length; j++ ) {
let c = field_value[ j ];
if ( base_alphabet.indexOf( c ) != -1 ) {
// console.log("max_length: " + max_length);
if ( max_length > 0 ) {
let accepted_base_length = parseInt( valid_base_value.length ) + 1;
// console.log("accepted_base_length: " + accepted_base_length );
if ( accepted_base_length <= max_length ) {
valid_base_value += c;
}
}
}
}
return valid_base_value;
}; // convertInputValueToValidBaseValue()
for ( let i=0; i < INPUT_FIELDS_IDS.length; i++ ) {
let current_field_id = INPUT_FIELDS_IDS[ i ];
if ( current_field_id == source_elt_id ) {
if ( current_field_id == ECONVERTER_RAWTEXT_INPUT_ID) {
let rawtext_value = HtmlUtils.GetElementValue( ECONVERTER_RAWTEXT_INPUT_ID );
rawtext_value = convertInputValueToValidBaseValue( field_value, BASE256U_ALPHABET, 32 );
HtmlUtils.SetElementValue( ECONVERTER_RAWTEXT_INPUT_ID, rawtext_value );
}
else if ( current_field_id == ECONVERTER_HEXADECIMAL_INPUT_ID ) {
field_value = HtmlUtils.GetElementValue( ECONVERTER_HEXADECIMAL_INPUT_ID );
field_value = convertInputValueToValidBaseValue( field_value, HEXADECIMAL_ALPHABET, 64 );
HtmlUtils.SetElementValue( ECONVERTER_HEXADECIMAL_INPUT_ID, field_value );
}
else if ( current_field_id == ECONVERTER_BASE64_INPUT_ID ) {
field_value = HtmlUtils.GetElementValue( ECONVERTER_BASE64_INPUT_ID ).trim();
// field_value = convertInputValueToValidBaseValue( field_value, BASE64_ALPHABET, 43 );
// field_value = convertInputValueToValidBaseValue( field_value, BASE64_ALPHABET, 60 );
field_value = convertInputValueToValidBaseValue( field_value, BASE64_ALPHABET, 43);
HtmlUtils.SetElementValue( ECONVERTER_BASE64_INPUT_ID, field_value );
}
else if ( current_field_id == ECONVERTER_BASE58_INPUT_ID ) {
let base58_value = convertInputValueToValidBaseValue( field_value, BASE58_ALPHABET, 43 );
HtmlUtils.SetElementValue( ECONVERTER_BASE58_INPUT_ID, base58_value );
}
else if ( current_field_id == ECONVERTER_BINARY_INPUT_ID ) {
let binary_value = convertInputValueToValidBaseValue( field_value, BINARY_ALPHABET, 256 );
HtmlUtils.SetElementValue( ECONVERTER_BINARY_INPUT_ID, binary_value );
}
field_value = HtmlUtils.GetElementValue( current_field_id );
if ( current_field_id != '' ) await this.propagateNewValue( current_field_id );
}
}
} // async onChangeInputField()
async updateTranslatedMnemonics( entropy, output_lang ) {
let log_msg = ">> " + _CYAN_ + "EntropyConverterDialog.updateTranslatedMnemonics" + _END_;
window.ipcMain.logToMain(log_msg);
let lang = output_lang;
let data = { entropy, lang };
let mnemonics = await window.ipcMain.EntropyToMnemonics( data );
let translated_secret_phrase = mnemonics;
if ( output_lang == 'JP' ) {
translated_secret_phrase = translated_secret_phrase.replaceAll(' ', '\u3000');
}
// console.log(" translated_secret_phrase: " + translated_secret_phrase);
HtmlUtils.SetElementValue( ECONVERTER_DIALOG_TRANSLATED_ID, translated_secret_phrase );
} // async updateTranslatedMnemonics()
getWordIndexFromEvent( evt ) {
let evt_X = evt.offsetX;
let evt_Y = evt.offsetY;
let X = Math.round(evt_X / 2);
let Y = Math.round(evt_Y / 2);
let word_index = Y*46 + X;
if ( word_index > 2047 ) word_index = 2047;
return word_index;
} // getWordIndexFromEvent()
async getMnemonicFromEvent( evt ) {
// console.log("EntropyConverterDialog.getMnemonicFromEvent");
let evt_X = evt.offsetX;
let evt_Y = evt.offsetY;
let X = Math.round(evt_X / 2);
let Y = Math.round(evt_Y / 2);
let word_index = Y*46 + X;
if ( word_index < 0 ) word_index = 0;
else if ( word_index > 2047 ) word_index = 2047;
// console.log(" word_index: " + word_index);
this.previous_lang = HtmlUtils.GetElementValue( ECONVERTER_LANG_SELECT_ID );
let lang = this.previous_lang;
// console.log("EntropyConverterDialog.getMnemonicFromEvent lang: " + lang);
let data = { word_index, lang };
let mnemonic = '';
if ( this.previous_lang == WORDLIST_WORD_INDEXES ) {
mnemonic = word_index.toString();
}
else {
mnemonic = await window.ipcMain.WordIndexToMnemonic( data );
}
// console.log("EntropyConverterDialog.getMnemonicFromEvent mnemonic: " + mnemonic);
return mnemonic;
} // async getMnemonicFromEvent()
getSecretPhrase() {
let secret_phrase = HtmlUtils.GetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID ).trim();
// console.log(" secret_phrase: <" + secret_phrase + ">");
return secret_phrase;
} // getSecretPhrase()
async onImgGridHover( evt ) {
let log_msg = ">> " + _CYAN_ + "EntropyConverterDialog.onImgGridHover" + _END_;
window.ipcMain.logToMain(log_msg);
let mnemonic = await this.getMnemonicFromEvent( evt );
// console.log(" mnemonic: " + mnemonic);
let secret_phrase = this.getSecretPhrase();
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).focus();
let secrete_phrase_field_elt = HtmlUtils.GetElement(ECONVERTER_SECRET_PHRASE_INPUT_ID);
let selection_start = secrete_phrase_field_elt.selectionStart;
let text_cursor_pos = secrete_phrase_field_elt.selectionStart;
let word_index_at_cursor = this.getWordIndexAtCursor( secret_phrase, text_cursor_pos );
// console.log(" word_index_at_cursor:" + word_index_at_cursor + " text_cursor_pos:" + text_cursor_pos + " total length:" + secret_phrase.length);
let words = secret_phrase.split(' ');
let selected_text = secrete_phrase_field_elt.value.substring(secrete_phrase_field_elt.selectionStart, secrete_phrase_field_elt.selectionEnd);
selected_text = selected_text.trim(' ');
let word_index = -1;
// NB: Tried to "select last word" when none selected: Regression !!
//if ( selected_text == '' ) {
// if (secret_phrase != '') {
// selected_text = words[words.length-1].trim();
//
// selection_start = secret_phrase.length - selected_text.length;
// HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionStart = selection_start;
// HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionEnd = selection_start + selected_text.length;
// }
//}
let tmp_secret_phrase = secret_phrase;
let tmp_words = JSON.parse(JSON.stringify(words));
let selected_text_pos = -1;
const OUT_OF_RANGE_WORD_INDEX = 100;
let tmp_word_index = OUT_OF_RANGE_WORD_INDEX;
console.log(" 1 selected_text: '" + selected_text + "' word_index:" + word_index + "' mnemonic: '" + mnemonic + "'");
if ( selected_text != '' ) {
selected_text_pos = tmp_secret_phrase.indexOf(selected_text);
while ( selected_text_pos != -1 && tmp_word_index != -1) {
if (selected_text_pos == selection_start) {
word_index = tmp_words.indexOf(selected_text);
break;
}
tmp_word_index = tmp_words.indexOf(selected_text);
if (tmp_word_index != -1) {
word_index = tmp_word_index;
tmp_secret_phrase.replace(selected_text, "####");
tmp_words[tmp_word_index] = "####";
selected_text_pos = tmp_secret_phrase.indexOf(selected_text);
}
else {
selected_text_pos = -1;
}
}
}
console.log(" 2 selected_text: '" + selected_text + "' word_index:" + word_index + "' mnemonic: '" + mnemonic + "'");
this.word_has_been_replaced = false;
if ( words.length < 24 ) {
if ( words.length > 0 ) {
if ( word_index == -1 ) word_index = words.length-1;
else {
words[word_index] = mnemonic;
this.word_has_been_replaced = true;
}
}
else {
words = [mnemonic];
}
secret_phrase = words.join(' ');
// console.log(" secret_phrase: '" + secret_phrase + "'");
HtmlUtils.SetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID, secret_phrase);
//let updated_cursor = this.getPositionCurseurDepuisIndexMot(secret_phrase, word_index);
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).focus();
if ( this.word_has_been_replaced ) {
selection_start = secret_phrase.indexOf(mnemonic);
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionStart = selection_start;
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionEnd = selection_start + mnemonic.length;
}
else {
selection_start = secret_phrase.length;
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionStart = selection_start;
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionEnd = selection_start;
}
await this.onChangeInputField( ECONVERTER_SECRET_PHRASE_INPUT_ID );
}
} // async onImgGridHover()
onImgGridMouseLeave( evt ) {
console.log(">> onImgGridMouseLeave");
let secret_phrase = this.getSecretPhrase();
let selection_start = secret_phrase.length;
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionStart = selection_start;
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionEnd = selection_start;
this.word_has_been_replaced = false;
} // onImgGridMouseLeave()
async onImgGridClick( evt ) {
let log_msg = ">> " + _CYAN_ + "EntropyConverterDialog.onImgGridClick" + _END_;
window.ipcMain.logToMain(log_msg);
let mnemonic = await this.getMnemonicFromEvent( evt );
// console.log(" mnemonic: " + mnemonic);
let secret_phrase = this.getSecretPhrase();
if ( ! this.word_has_been_replaced ) {
let words = secret_phrase.split(' ');
if ( words.length < 24 ) {
if (secret_phrase == '') secret_phrase = mnemonic;
else secret_phrase += ' ' + mnemonic;
HtmlUtils.SetElementValue( ECONVERTER_SECRET_PHRASE_INPUT_ID, secret_phrase);
await this.onChangeInputField( ECONVERTER_SECRET_PHRASE_INPUT_ID );
}
}
this.word_has_been_replaced = false;
let selection_start = secret_phrase.length;
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionStart = selection_start;
HtmlUtils.GetElement( ECONVERTER_SECRET_PHRASE_INPUT_ID ).selectionEnd = selection_start;
} // async onImgGridClick()
getWordIndexAtCursor(chaine, curseur) {
if (typeof chaine !== 'string' || chaine.trim() === '') return -1;
curseur = Math.min(Math.max(curseur, 0), chaine.length);
// Extraire les mots avec positions
const mots = [];
let i = 0;
const len = chaine.length;
while (i < len) {
if (chaine[i] === ' ') {
i++;
continue;
}
const debut = i;
while (i < len && chaine[i] !== ' ') i++;
const fin = i - 1;
mots.push({ debut, fin, index: mots.length });
}
if (mots.length === 0) return -1;
// Chercher selon les règles
for (const mot of mots) {
if (curseur >= mot.debut && curseur <= mot.fin) return mot.index; // à l'intérieur
if (curseur === mot.debut) return mot.index; // juste avant
if (curseur === mot.fin + 1) return mot.index; // juste après
}
// Si on est dans un espace ou avant premier mot ou après dernier, trouver le plus proche
let meilleur = 0;
let minDist = Infinity;
for (const mot of mots) {
const distDebut = Math.abs(curseur - mot.debut);
const distFin = Math.abs(curseur - (mot.fin + 1));
const dist = Math.min(distDebut, distFin);
if (dist < minDist) {
minDist = dist;
meilleur = mot.index;
} else if (dist === minDist && mot.index < meilleur) {
meilleur = mot.index;
}
}
return meilleur;
} // getWordIndexAtCursor()
getPositionCurseurDepuisIndexMot( texte, indexMot ) {
const mots = [];
const regex = /\S+/g;
let match;
while ((match = regex.exec(texte)) !== null) {
mots.push({
index: mots.length,
debut: match.index
});
}
if (indexMot < 0 || indexMot >= mots.length) {
return -1;
}
return mots[indexMot].debut;
} // getPositionCurseurDepuisIndexMot()
getNearestWordIndex( chaine, curseur ) {
// Gestion des cas extrêmes
if (typeof chaine !== 'string' || chaine.trim() === '') return -1;
// curseur peut être entre 0 et chaine.length (inclus)
if (curseur < 0) curseur = 0;
if (curseur > chaine.length) curseur = chaine.length;
// Étape 1 : découper la chaîne en mots avec leurs positions (début, fin inclus)
const mots = [];
let i = 0;
const len = chaine.length;
while (i < len) {
if (chaine[i] === ' ') {
i++;
continue;
}
const debut = i;
while (i < len && chaine[i] !== ' ') {
i++;
}
const fin = i - 1; // dernière lettre du mot
mots.push({ debut, fin, index: mots.length });
}
if (mots.length === 0) return -1;
// Étape 2 : trouver le mot le plus proche
let meilleurMot = null;
let meilleureDistance = Infinity;
for (const mot of mots) {
const { debut, fin, index: motIndex } = mot;
const apresMot = fin + 1;
// Cas exacts
if (curseur >= debut && curseur <= fin) {
return motIndex; // à l'intérieur
}
if (curseur === debut) {
return motIndex; // juste avant
}
if (curseur === apresMot) {
return motIndex; // juste après
}
// Distance minimale entre le curseur et les limites du mot
const distDebut = Math.abs(curseur - debut);
const distFin = Math.abs(curseur - apresMot);
const distance = Math.min(distDebut, distFin);
if (distance < meilleureDistance) {
meilleureDistance = distance;
meilleurMot = motIndex;
} else if (distance === meilleureDistance && meilleurMot !== null) {
// égalité : on garde l'index le plus petit (mot de gauche)
if (motIndex < meilleurMot) {
meilleurMot = motIndex;
}
}
}
return meilleurMot !== null ? meilleurMot : 0;
} // getNearestWordIndex()
isThereDuplicatesInSecrePhrase( secret_phrase ) {
const mots = secret_phrase.trim().split(/\s+/);
const motsUniques = new Set(mots);
// return {
// asDuplicates: mots.length !== motsUniques.size,
// totalMots: mots.length,
// motsUniques: motsUniques.size,
// nombreDoublons: mots.length - motsUniques.size
// };
return mots.length !== motsUniques.size;
} // isThereDuplicatesInSecrePhrase()
async onSecretPhraseWheel( evt ) {
let log_msg = ">> " + _CYAN_ + "EntropyConverterDialog.onSecretPhraseWheel" + _END_;
window.ipcMain.logToMain(log_msg);
// Empêche le défilement par défaut de la page (optionnel)
// evt.preventDefault();
let secret_phrase = this.getSecretPhrase();
if ( secret_phrase == "" ) return;
console.log( "onSecretPhraseWheel secret_phrase: '" + secret_phrase + "'");
let memonics = secret_phrase.split(' ');
console.log( "onSecretPhraseWheel memonics.length: " + memonics.length);
let secrete_phrase_field_elt = HtmlUtils.GetElement(ECONVERTER_SECRET_PHRASE_INPUT_ID);
let selection_start = secrete_phrase_field