diff --git a/index.js b/index.js index 742b53d656c24a20921e63846117f84d8efdada8..f264a374daeeb9e8ed801cf81bcc20594fc37477 100755 --- a/index.js +++ b/index.js @@ -51,7 +51,7 @@ module.exports = { name: 'currency-monit [start|indexing] [host] [port]', desc: 'Start duniter with module currency-monit or Indexing blockchain history', preventIfRunning: true, - logs: false, + logs: true, onDatabaseExecute: (server, conf, program, params, startServices) => co(function*() { // currency-monit parameters diff --git a/lib/main.js b/lib/main.js index b35fd742b5e41378b96afcd6d44d87b0cec298ee..03eb825652f10d3c35fef77fbdcbb158ccab4e78 100755 --- a/lib/main.js +++ b/lib/main.js @@ -6,6 +6,7 @@ const fs = require('fs'); const webserver = require(__dirname + '/webserver2.js'); const timestampToDatetime = require(__dirname + '/timestampToDatetime.js'); +const {willMembers} = require("../modules/will-members"); /**************************** * Main algorithm @@ -51,6 +52,14 @@ module.exports = (duniterServer, host, port, appParente, program) => co(function let httpServer = webserver(host, port, appParente, duniterServer, monitDatasPath, offset, cache, program.resetData); yield httpServer.openConnection(); + // On déclenche immédiatement une 1ère mise à jour de willMembers + willMembers(duniterServer) + .then(() => console.log('Initialisation de willMembers terminée')) + .catch((e) => { + console.error(e) + console.error('Initialisation de willMembers terminée avec erreur : ' + e.message) + }) + }) .catch((err) => console.error(err.stack || err)); diff --git a/modules/will-members.ts b/modules/will-members.ts index b1c9abcbf0f5b47b4f77a0ca4d3459c3ec99c4ad..aa7983c56f3b3c814cb4eff8c96340c199b9c904 100644 --- a/modules/will-members.ts +++ b/modules/will-members.ts @@ -1,16 +1,9 @@ import {MonitConstants} from "../lib/constants2"; import {DBIdentity} from "duniter/app/lib/dal/sqliteDAL/IdentityDAL"; -import {DBMembership} from "duniter/app/lib/dal/sqliteDAL/MembershipDAL"; import {showExecutionTimes} from "../lib/MonitorExecutionTime"; import {DataFinder} from "../lib/DataFinder"; import {Server} from "duniter/server"; -import {WotBuilder} from "duniter/neon/lib"; -import { - DetailedDistance, - PendingCert, - WillMemberIdentity, - WillMemberIdentityWithPendingCerts -} from "./willMembers/interfaces"; +import {PendingCert, WillMemberIdentity, WillMemberIdentityWithPendingCerts} from "./willMembers/interfaces"; import {triParDateDeDisponibilite} from "./willMembers/triParDateDeDisponibilite"; import {WotbIdCache} from "./willMembers/wotbIdCache"; import {getIdentityListOrdered} from "./willMembers/getIdentityListOrdered"; @@ -18,172 +11,217 @@ import {computeMeansAndCounts} from "./willMembers/computeMeansAndCounts"; import {getMembersQualityExt} from "./willMembers/getMembersQualityExt"; import {getSorting} from "./willMembers/getSorting"; import {SentryChecker} from "./willMembers/issuerIsSentry"; +import {ConfDTO} from "duniter/app/lib/dto/ConfDTO"; // Préserver les résultats en cache -let lockWillMembers = false let willMembersLastUptime = 0 let identitiesList: WillMemberIdentity[] = [] let idtysPendingCertifsList: PendingCert[][] = [] let nbMaxCertifs = 0 let countMembersWithSigQtyValidCert = 0 +let idtysListOrdered: WillMemberIdentityWithPendingCerts[] = [] +let membersQualityExt: { [p: string]: string } = {} +let meanSentriesReachedByIdtyPerCert: number[] = [] +let meanMembersReachedByIdtyPerCert: number[] = [] +let cacheBeingUpdatedSince = 0 +let currentBlockchainTimestamp = 0 +let currentMembersCount = 0 +let currentBlockNumber = -1 +let limitTimestamp = 0 export async function willMembers(duniterServer: Server, days = 65, order = 'desc', sort_by = 'registrationPackage', showIdtyWithZeroCert = 'no', sortSig = 'Availability') { - const dataFinder = await DataFinder.getInstanceReindexedIfNecessary() - const wotbIdCache = new WotbIdCache(dataFinder) - // get blockchain timestamp - let resultQueryCurrentBlock: any = await dataFinder.getCurrentBlockOrNull(); - const currentBlockchainTimestamp = resultQueryCurrentBlock.medianTime; - const currentMembersCount = resultQueryCurrentBlock.membersCount; - const currentBlockNumber = resultQueryCurrentBlock.number; // Initaliser les constantes - const conf = duniterServer.conf; - const dSen = Math.ceil(Math.pow(currentMembersCount, 1 / conf.stepMax)); - // Calculer le timestamp limite à prendre en compte - let limitTimestamp = currentBlockchainTimestamp + (days*86400); - // Alimenter wotb avec la toile de confiance - const wotbInstance = duniterServer.dal.wotb; + const conf: ConfDTO = duniterServer.conf; + const dSen: number = Math.ceil(Math.pow(currentMembersCount, 1 / conf.stepMax)); // Vérifier si le cache doit être Réinitialiser let reinitCache = (Math.floor(Date.now() / 1000) > (willMembersLastUptime + MonitConstants.MIN_WILLMEMBERS_UPDATE_FREQ)); // Si le cache willMembers est dévérouillé, le vérouiller, sinon ne pas réinitialiser le cache - if (reinitCache && !lockWillMembers) { - lockWillMembers = true; - } else if(lockWillMembers) { + if (reinitCache && !cacheBeingUpdatedSince) { + cacheBeingUpdatedSince = new Date().getTime(); + } else if (cacheBeingUpdatedSince) { reinitCache = false; } if (reinitCache) { - // Réinitialiser le cache - dataFinder.invalidateCache() - identitiesList = []; - idtysPendingCertifsList = []; - nbMaxCertifs = 0; - countMembersWithSigQtyValidCert = 0; - willMembersLastUptime = Math.floor(Date.now() / 1000); - - // Récupérer la liste des membres référents - const sentryChecker = new SentryChecker(wotbInstance.getSentries(dSen)) - - // Récupérer la liste des identités en piscine - const pendingMembers: DBIdentity[] = await dataFinder.findPendingMembers() - - // Récupérer pour chaque identité, l'ensemble des certifications qu'elle à reçue. - for (const pendingIdty of pendingMembers) { - // Extraire le numéro de bloc d'émission de l'identité - let idtyBlockStamp = pendingIdty.buid.split("-"); - let idtyBlockNumber = idtyBlockStamp[0]; - - // récupérer le medianTime et le hash du bloc d'émission de l'identité - let idtyEmittedBlock = await dataFinder.getBlock(parseInt(idtyBlockNumber)); - - // Récupérer l'identifiant wotex de l'identité (en cas d'identité multiple) - let idties = await dataFinder.getWotexInfos(pendingIdty.uid); - let wotexId = ''; - if (idties.length > 1) { - let pos = 0; - for (const idty of idties) { - if (idty.hash == pendingIdty.hash) { wotexId = '['+pos+']'; } - pos++; - } - } + // En asynchrone + rechargeCache(duniterServer, days, dSen, conf, sortSig, sort_by, order) + .then(() => { + console.log('Cache mis à jour') + cacheBeingUpdatedSince = 0; + }) + .catch((e) => { + console.error('Exception lors de la mise à jour du cache : ' + e.message) + console.error(e) + }) + } - // vérifier la validité du blockstamp de l'identité - let validIdtyBlockStamp = false; - if (typeof(idtyEmittedBlock) == 'undefined' || idtyEmittedBlock.hash == idtyBlockStamp[1]) { - validIdtyBlockStamp = true; - } + return { + days, + order, + sort_by, + showIdtyWithZeroCert, + sortSig, + idtysListOrdered, + currentBlockNumber, + currentBlockchainTimestamp, + currentMembersCount, + limitTimestamp, + dSen, + conf, + nbMaxCertifs, + countMembersWithSigQtyValidCert, + meanSentriesReachedByIdtyPerCert, + meanMembersReachedByIdtyPerCert, + membersQualityExt, + cacheBeingUpdatedSince + } +} - // vérifier si l'identité a été révoquée ou non - let idtyRevoked = false; - if (pendingIdty.revocation_sig != null) { - idtyRevoked = true; - } +async function rechargeCache(duniterServer: Server, days: number, dSen: number, conf: ConfDTO, sortSig: string, sort_by: string, order: string) { + + const dataFinder = await DataFinder.getInstanceReindexedIfNecessary() + const wotbIdCache = new WotbIdCache(dataFinder) + // get blockchain timestamp + let resultQueryCurrentBlock: any = await dataFinder.getCurrentBlockOrNull(); + currentBlockchainTimestamp = resultQueryCurrentBlock.medianTime; + currentMembersCount = resultQueryCurrentBlock.membersCount; + currentBlockNumber = resultQueryCurrentBlock.number; + // Calculer le timestamp limite à prendre en compte + limitTimestamp = currentBlockchainTimestamp + (days*86400); + // Alimenter wotb avec la toile de confiance + const wotbInstance = duniterServer.dal.wotb; + + // Réinitialiser le cache + dataFinder.invalidateCache() + identitiesList = []; + idtysPendingCertifsList = []; + nbMaxCertifs = 0; + countMembersWithSigQtyValidCert = 0; + willMembersLastUptime = Math.floor(Date.now() / 1000); + + // Récupérer la liste des membres référents + const sentryChecker = new SentryChecker(wotbInstance.getSentries(dSen)) + + // Récupérer la liste des identités en piscine + const pendingMembers: DBIdentity[] = await dataFinder.findPendingMembers() + + // Récupérer pour chaque identité, l'ensemble des certifications qu'elle à reçue. + for (const pendingIdty of pendingMembers) { + // Extraire le numéro de bloc d'émission de l'identité + let idtyBlockStamp = pendingIdty.buid.split("-"); + let idtyBlockNumber = idtyBlockStamp[0]; + + // récupérer le medianTime et le hash du bloc d'émission de l'identité + let idtyEmittedBlock = await dataFinder.getBlock(parseInt(idtyBlockNumber)); - // Stocker les informations de l'identité - const identity = { - BlockNumber: parseInt(idtyBlockNumber), - creationTimestamp: (typeof(idtyEmittedBlock) == 'undefined' ) ? currentBlockchainTimestamp:idtyEmittedBlock.medianTime, - pubkey: pendingIdty.pubkey, - uid: pendingIdty.uid, - hash: pendingIdty.hash, - wotexId: wotexId, - expires_on: pendingIdty.expires_on || 0, - nbCert: 0, - nbValidPendingCert: 0, - registrationAvailability: 0, - validBlockStamp: validIdtyBlockStamp, - idtyRevoked: idtyRevoked + // Récupérer l'identifiant wotex de l'identité (en cas d'identité multiple) + let idties = await dataFinder.getWotexInfos(pendingIdty.uid); + let wotexId = ''; + if (idties.length > 1) { + let pos = 0; + for (const idty of idties) { + if (idty.hash == pendingIdty.hash) { wotexId = '['+pos+']'; } + pos++; } - identitiesList.push(identity); - const pendingCertifications: PendingCert[] = [] - - // récupérer l'ensemble des certifications en attente destinées à l'identité courante - let pendingCerts = await dataFinder.findPendingCertsToTarget(pendingIdty.pubkey, pendingIdty.hash); - - // Récupérer les uid des émetteurs des certifications reçus par l'utilisateur - // Et stocker les uid et dates d'expiration dans un tableau - for (const pendingCert of pendingCerts) { - // Récupérer le medianTime et le hash du bloc d'émission de la certification - let emittedBlock = await dataFinder.getBlock(pendingCert.block_number) - - // Vérifier que l'émetteur de la certification correspond à une identité inscrite en blockchain - let member = await dataFinder.getUidOfPub(pendingCert.from) - if (emittedBlock && member) { - // Récupérer la pubkey de l'émetteur - let issuerPubkey = pendingCert.from; - - // Récupérer le wotb_id - let wotb_id = await wotbIdCache.getWotbId(issuerPubkey) - - // Vérifier si l'émetteur de la certification est référent - let issuerIsSentry = sentryChecker.isIssuerSentry(issuerPubkey, wotb_id); - - // Vérifier si le blockstamp est correct - const validBlockStamp = emittedBlock.hash == pendingCert.block_hash; - // récupérer le timestamp d'enchainement de la dernière certification écrite par l'émetteur - let tmpQueryLastIssuerCert = await dataFinder.getChainableOnByIssuerPubkey(issuerPubkey) - let certTimestampWritable = 0; - if ( typeof(tmpQueryLastIssuerCert[0]) != 'undefined' && typeof(tmpQueryLastIssuerCert[0].chainable_on) != 'undefined' ) { - certTimestampWritable = tmpQueryLastIssuerCert[0].chainable_on; - } - //identity.registrationAvailability = (certTimestampWritable > identity.registrationAvailability) ? certTimestampWritable : identity.registrationAvailability; - - // Vérifier que l'identité courant n'a pas déjà reçu d'autre(s) certification(s) de la part du même membre ET dans le même état de validité du blockstamp - let doubloonPendingCertif = pendingCertifications.filter(c => c.from == member.uid && c.validBlockStamp == validBlockStamp).length > 0; - if (!doubloonPendingCertif) { - // Stoker la liste des certifications en piscine qui n'ont pas encore expirées - if (pendingCert.expires_on > currentBlockchainTimestamp) { - pendingCertifications.push({ - from: member.uid, - pubkey: issuerPubkey, - wotb_id: wotb_id, - issuerIsSentry: issuerIsSentry, - blockNumber: pendingCert.block_number, - creationTimestamp: emittedBlock.medianTime, - timestampExpire: pendingCert.expires_on, - timestampWritable: certTimestampWritable, - validBlockStamp: validBlockStamp - }); - identity.nbCert++; - if (validBlockStamp) { identity.nbValidPendingCert++; } - } + } + + // vérifier la validité du blockstamp de l'identité + let validIdtyBlockStamp = false; + if (typeof(idtyEmittedBlock) == 'undefined' || idtyEmittedBlock.hash == idtyBlockStamp[1]) { + validIdtyBlockStamp = true; + } + + // vérifier si l'identité a été révoquée ou non + let idtyRevoked = false; + if (pendingIdty.revocation_sig != null) { + idtyRevoked = true; + } + + // Stocker les informations de l'identité + const identity = { + BlockNumber: parseInt(idtyBlockNumber), + creationTimestamp: (typeof(idtyEmittedBlock) == 'undefined' ) ? currentBlockchainTimestamp:idtyEmittedBlock.medianTime, + pubkey: pendingIdty.pubkey, + uid: pendingIdty.uid, + hash: pendingIdty.hash, + wotexId: wotexId, + expires_on: pendingIdty.expires_on || 0, + nbCert: 0, + nbValidPendingCert: 0, + registrationAvailability: 0, + validBlockStamp: validIdtyBlockStamp, + idtyRevoked: idtyRevoked + } + identitiesList.push(identity); + const pendingCertifications: PendingCert[] = [] + + // récupérer l'ensemble des certifications en attente destinées à l'identité courante + let pendingCerts = await dataFinder.findPendingCertsToTarget(pendingIdty.pubkey, pendingIdty.hash); + + // Récupérer les uid des émetteurs des certifications reçus par l'utilisateur + // Et stocker les uid et dates d'expiration dans un tableau + for (const pendingCert of pendingCerts) { + // Récupérer le medianTime et le hash du bloc d'émission de la certification + let emittedBlock = await dataFinder.getBlock(pendingCert.block_number) + + // Vérifier que l'émetteur de la certification correspond à une identité inscrite en blockchain + let member = await dataFinder.getUidOfPub(pendingCert.from) + if (emittedBlock && member) { + // Récupérer la pubkey de l'émetteur + let issuerPubkey = pendingCert.from; + + // Récupérer le wotb_id + let wotb_id = await wotbIdCache.getWotbId(issuerPubkey) + + // Vérifier si l'émetteur de la certification est référent + let issuerIsSentry = sentryChecker.isIssuerSentry(issuerPubkey, wotb_id); + + // Vérifier si le blockstamp est correct + const validBlockStamp = emittedBlock.hash == pendingCert.block_hash; + // récupérer le timestamp d'enchainement de la dernière certification écrite par l'émetteur + let tmpQueryLastIssuerCert = await dataFinder.getChainableOnByIssuerPubkey(issuerPubkey) + let certTimestampWritable = 0; + if ( typeof(tmpQueryLastIssuerCert[0]) != 'undefined' && typeof(tmpQueryLastIssuerCert[0].chainable_on) != 'undefined' ) { + certTimestampWritable = tmpQueryLastIssuerCert[0].chainable_on; + } + //identity.registrationAvailability = (certTimestampWritable > identity.registrationAvailability) ? certTimestampWritable : identity.registrationAvailability; + + // Vérifier que l'identité courant n'a pas déjà reçu d'autre(s) certification(s) de la part du même membre ET dans le même état de validité du blockstamp + let doubloonPendingCertif = pendingCertifications.filter(c => c.from == member.uid && c.validBlockStamp == validBlockStamp).length > 0; + if (!doubloonPendingCertif) { + // Stoker la liste des certifications en piscine qui n'ont pas encore expirées + if (pendingCert.expires_on > currentBlockchainTimestamp) { + pendingCertifications.push({ + from: member.uid, + pubkey: issuerPubkey, + wotb_id: wotb_id, + issuerIsSentry: issuerIsSentry, + blockNumber: pendingCert.block_number, + creationTimestamp: emittedBlock.medianTime, + timestampExpire: pendingCert.expires_on, + timestampWritable: certTimestampWritable, + validBlockStamp: validBlockStamp + }); + identity.nbCert++; + if (validBlockStamp) { identity.nbValidPendingCert++; } } } } - idtysPendingCertifsList.push(pendingCertifications) + } + idtysPendingCertifsList.push(pendingCertifications) - // Calculer le nombre maximal de certifications reçues par l'identité courante - if ( identity.nbCert > nbMaxCertifs) { - nbMaxCertifs = identity.nbCert; - } + // Calculer le nombre maximal de certifications reçues par l'identité courante + if ( identity.nbCert > nbMaxCertifs) { + nbMaxCertifs = identity.nbCert; + } - // calculate countMembersWithSigQtyValidCert - if ( identity.nbValidPendingCert >= conf.sigQty) { - countMembersWithSigQtyValidCert++; - } - } // END IDENTITIES LOOP - } // END if (reinitCache) + // calculate countMembersWithSigQtyValidCert + if ( identity.nbValidPendingCert >= conf.sigQty) { + countMembersWithSigQtyValidCert++; + } + } // END IDENTITIES LOOP // Si demandé, retrier les, certifications par date de disponibilité if (sortSig == "Availability") { @@ -194,52 +232,27 @@ export async function willMembers(duniterServer: Server, days = 65, order = 'des let tabSort = getSorting(identitiesList, sort_by, currentBlockchainTimestamp, conf) // Trier les identités - let idtysListOrdered: WillMemberIdentityWithPendingCerts[] = await getIdentityListOrdered( - identitiesList, - idtysPendingCertifsList, - currentBlockchainTimestamp, - currentMembersCount, - limitTimestamp, - wotbInstance, - duniterServer, - conf, - dSen, - tabSort, - order) + idtysListOrdered = await getIdentityListOrdered( + identitiesList, + idtysPendingCertifsList, + currentBlockchainTimestamp, + currentMembersCount, + limitTimestamp, + wotbInstance, + duniterServer, + conf, + dSen, + tabSort, + order) console.log('Calcul des qualités...') - let membersQualityExt = getMembersQualityExt(wotbInstance, idtysListOrdered, conf, dSen) + membersQualityExt = getMembersQualityExt(wotbInstance, idtysListOrdered, conf, dSen) console.log('Calcul des moyennes...') - const { - meanSentriesReachedByIdtyPerCert, - meanMembersReachedByIdtyPerCert, - } = computeMeansAndCounts(idtysListOrdered, nbMaxCertifs) - - if (reinitCache) { - lockWillMembers = false; - } + const meansAndCounts = computeMeansAndCounts(idtysListOrdered, nbMaxCertifs) + meanSentriesReachedByIdtyPerCert = meansAndCounts.meanSentriesReachedByIdtyPerCert + meanMembersReachedByIdtyPerCert = meansAndCounts.meanMembersReachedByIdtyPerCert showExecutionTimes() - - return { - days, - order, - sort_by, - showIdtyWithZeroCert, - sortSig, - idtysListOrdered, - currentBlockNumber, - currentBlockchainTimestamp, - currentMembersCount, - limitTimestamp, - dSen, - conf, - nbMaxCertifs, - countMembersWithSigQtyValidCert, - meanSentriesReachedByIdtyPerCert, - meanMembersReachedByIdtyPerCert, - membersQualityExt, - } } diff --git a/routes/willMembers2.ts b/routes/willMembers2.ts index 14ddb0761938e95c35636c96b96c52ae9a91047e..06d8f4c2b2cce4921a2c49eadae5804c0a655dc4 100755 --- a/routes/willMembers2.ts +++ b/routes/willMembers2.ts @@ -33,6 +33,7 @@ module.exports = async (req: any, res: any, next: any) => { meanSentriesReachedByIdtyPerCert, meanMembersReachedByIdtyPerCert, membersQualityExt, + cacheBeingUpdatedSince, } = await willMembers(locals.duniterServer, req.query.d, req.query.d && req.query.order, req.query.sort_by, @@ -73,6 +74,7 @@ module.exports = async (req: any, res: any, next: any) => { meanSentriesReachedByIdtyPerCert, meanMembersReachedByIdtyPerCert, membersQualityExt, + cacheBeingUpdatedSince, // Template helpers timestampToDatetime, // Calculer la proportion de temps restant avant l'expiration diff --git a/views/willMembers.html b/views/willMembers.html index da3010ddbb056c3aefb9602767c6e10788ba565a..6f12bcec6428f1141b785138b3ab24c4cd4d922f 100755 --- a/views/willMembers.html +++ b/views/willMembers.html @@ -44,25 +44,34 @@ ${(host.substr(host.length-6,6) == '.onion') ? HTML_TOR_HEAD:HTML_HEAD} <!-- Afficher le menu --> ${printMenu(MENU_LANG, help, "WILL_MEMBERS")} +${(currentBlockNumber < 0) +? `<p style="padding: 8px; color: orange; background-color: lightgoldenrodyellow">Initialisation de currency-monit en cours...</p>` +: ``} +${(currentBlockNumber >= 0 && cacheBeingUpdatedSince) ? + `<p style="padding: 8px; color: darkblue; background-color: lightblue">Un recalcul est en cours, refraîchissez la page dans quelques secondes pour avoir la dernière version.</p>` +: (currentBlockNumber < 0) ? '' : ` <!-- Afficher le formulaire --> - <input type="number" name="d" value="${days}"/>${LANG["DAYS"]} - ${LANG["SORT_BY"]} - <select name="sort_by"> - <option name="sort_by" value ="creationIdty">${LANG["SORT_BY_CREATION_IDTY"]} - <option name="sort_by" value ="sigCount" ${sort_by == 'sigCount' ? 'selected' : ''}>${LANG["SORT_BY_SIG_COUNT"]} - <option name="sort_by" value ="registrationPackage" ${sort_by == 'registrationPackage' ? 'selected' : ''}>${LANG["SORT_BY_REGISTRATION_PACKAGE"]} - </select> ${LANG["ORDER"]} : <select name="order"> - <option name="order" value ="asc">${LANG["ORDER_ASC"]} - <option name="order" value ="desc" ${order == 'desc' ? 'selected' : ''}>${LANG["ORDER_DESC"]} - </select> <input type="submit" value="${LANG["SUBMIT_TXT"]}"><br> - <input type="checkbox" name="showIdtyWithZeroCert" value="yes" ${showIdtyWithZeroCert == 'yes' ? 'checked' : ''}>${LANG["CHECKBOX_SHOW_IDTY_WITH_ZERO_CERT"]}<br> - <input type="checkbox" name="sortSig" value="Availability" ${sortSig == 'Availability' ? 'checked' : ''}>${LANG["CHECKBOX_SORT_SIG"]}<br> - ${LANG["IDTY_FILTER"]} : <input type="text" name="filter" id="filter" value="" maxlength="20" onchange="filterRows(document.getElementById('table'),2,0,this.value);" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();"/> -</form> -<br> -<hr> +<!--<form>--> +<!-- <input type="number" name="d" value="${days}"/>${LANG["DAYS"]} - ${LANG["SORT_BY"]}--> +<!-- <select name="sort_by">--> +<!-- <option name="sort_by" value ="creationIdty">${LANG["SORT_BY_CREATION_IDTY"]}--> +<!-- <option name="sort_by" value ="sigCount" ${sort_by == 'sigCount' ? 'selected' : ''}>${LANG["SORT_BY_SIG_COUNT"]}--> +<!-- <option name="sort_by" value ="registrationPackage" ${sort_by == 'registrationPackage' ? 'selected' : ''}>${LANG["SORT_BY_REGISTRATION_PACKAGE"]}--> +<!-- </select> ${LANG["ORDER"]} : <select name="order">--> +<!-- <option name="order" value ="asc">${LANG["ORDER_ASC"]}--> +<!-- <option name="order" value ="desc" ${order == 'desc' ? 'selected' : ''}>${LANG["ORDER_DESC"]}--> +<!-- </select> <input type="submit" value="${LANG["SUBMIT_TXT"]}"><br>--> +<!-- <input type="checkbox" name="showIdtyWithZeroCert" value="yes" ${showIdtyWithZeroCert == 'yes' ? 'checked' : ''}>${LANG["CHECKBOX_SHOW_IDTY_WITH_ZERO_CERT"]}<br>--> +<!-- <input type="checkbox" name="sortSig" value="Availability" ${sortSig == 'Availability' ? 'checked' : ''}>${LANG["CHECKBOX_SORT_SIG"]}<br>--> +<!-- ${LANG["IDTY_FILTER"]} : <input type="text" name="filter" id="filter" value="" maxlength="20" onchange="filterRows(document.getElementById('table'),2,0,this.value);" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();"/>--> +<!--</form>--> +<!--<br>--> +<!--<hr>--> +` +} <!-- Afficher la légende et l'aide --> -${(help != 'no') ? ` +${(currentBlockNumber >= 0 && help != 'no') ? ` <div id="zone1" style="width: 100%; height: 20px; background: White; border: 1px solid DimGrey; transition: height 1s; -moz-transition: height 1s;-webkit-transition: height 1s;-o-transition: height 1s; overflow: hidden;"> <div id="bandeau1" style="height: 20px; width: 100%; font-size: medium; color: white; background-color: darkgrey;" onmouseover="deroule(1,400);" onmouseout="deroule(1,20);"><b>${LANG["LEGEND"]}</b> </div> @@ -85,6 +94,7 @@ ${(help != 'no') ? ` </div> `:''} +${(currentBlockNumber < 0) ? '' : ` <!-- Afficher l'état de tension de la toile de confiance --> <div id="zone2" style="width: 100%; height: 20px; background: White; border: 1px solid DimGrey; transition: height 1s; -moz-transition: height 1s;-webkit-transition: height 1s;-o-transition: height 1s; overflow: hidden;"> <div id="bandeau2" style="height: 20px; width: 100%; font-size: medium; color: white; background-color: darkgrey;" onmouseover="deroule(2,150);" onmouseout="deroule(2,20);"><b>${LANG["WOT_TENSION_STATE"]}</b> @@ -231,3 +241,4 @@ ${(help != 'no') ? ` </table><br> <hr> +`}