!7 concept Log { S programID, ip; long count, last; } static ConceptFieldIndexDesc lastAccessIndex; p { dbIndexing(Log, 'ip); lastAccessIndex = new ConceptFieldIndexDesc(Log, 'last); makeSalt(); } static File saltFile() { ret secretProgramFile("salt"); } sS salt() { ret trim(loadTextFile(saltFile())); } svoid makeSalt { if (empty(salt())) saveTextFile(saltFile(), aGlobalID()); } html { if (webAuthed() && eq(uri, "/logs")) { //L l = unlistedCopies(sortedByFieldDesc(Log, 'last)); L l = unlistedCopies(takeFirst(50, lastAccessIndex.objectIterator())); S salt = salt(); for (Log log : l) log.ip = md5(log.ip + salt); ret serveText(renderConcepts(l)); //ret serveText(renderConcepts(list(Log))); } S id = fsI(params.get("id")); S ip = clientIP(); Log log = uniq(Log, +ip, programID := id); cset(log, count := log.count+1, last := now()); S md5 = getServerTranspilationMD5(id); if (isMD5(md5) && !hasServerDex(id)) md5 = "-"; if (isMD5(md5)) ret md5; else ret "-"; }