/* SYSCMD — arbre avec sections en sous-niveaux + page d'accueil */ function t(fr, en) { return { fr: fr, en: en }; } let currentNode = null; let currentSection = null; const TREE = { id: 'root', label: t('OS', 'OS'), children: [ { id: 'linux', label: t('Linux', 'Linux'), children: [ { id: 'ubuntu', label: t('Ubuntu', 'Ubuntu'), children: [ { id: 'ubuntu-2004', label: t('20.04', '20.04'), osKey: 'ubuntu', sectionIds: ['sys','apt','users'] }, { id: 'ubuntu-2204', label: t('22.04', '22.04'), osKey: 'ubuntu', sectionIds: ['sys','apt','users'] }, { id: 'ubuntu-2404', label: t('24.04', '24.04'), osKey: 'ubuntu', sectionIds: ['sys','apt','users','systemd'] }, ]}, { id: 'debian', label: t('Debian', 'Debian'), osKey: 'debian', sectionIds: ['sys','apt','users','systemd'] }, { id: 'oracle', label: t('Oracle Linux', 'Oracle Linux'), osKey: 'oracle', sectionIds: ['oracle-dnf','oracle-spec','oracle-selinux','oracle-fw','systemd'] }, { id: 'rhel', label: t('RHEL / CentOS', 'RHEL / CentOS') }, { id: 'fedora', label: t('Fedora', 'Fedora') }, ]}, { id: 'windows', label: t('Windows', 'Windows'), children: [ { id: 'win-client', label: t('Client', 'Client'), children: [ { id: 'win-xp', label: t('XP', 'XP') }, { id: 'win-10', label: t('10', '10'), osKey: 'windows', sectionIds: ['win-sys','win-files','win-process','win-network'] }, { id: 'win-11', label: t('11', '11'), osKey: 'windows', sectionIds: ['win-sys','win-files','win-process','win-network'] }, ]}, { id: 'win-server', label: t('Server', 'Server'), children: [ { id: 'win-2016', label: t('2016', '2016'), osKey: 'windows-server', sectionIds: ['win-sys','win-files','win-process','win-network'] }, { id: 'win-2019', label: t('2019', '2019'), osKey: 'windows-server', sectionIds: ['win-sys','win-files','win-process','win-network'] }, ]}, ]}, { id: 'solaris', label: t('Solaris / illumos', 'Solaris / illumos'), osKey: 'solaris', sectionIds: ['solaris-ips','solaris-smf','solaris-zfs','solaris-zones'] }, { id: 'macos', label: t('macOS', 'macOS') }, { id: 'docker', label: t('Docker', 'Docker') }, { id: 'other', label: t('Other', 'Other') }, ] }; const SEC = {}; SEC.sys = { label: t('système', 'system'), commands: [ { d: t('Version du noyau', 'Kernel version'), c: 'uname -r' }, { d: t('Version OS', 'OS version'), c: 'lsb_release -a' }, { d: t('Mémoire dispo', 'Memory available'), c: 'free -h' }, { d: t("Nom d'hôte", 'Hostname'), c: 'hostnamectl' }, { d: t('Uptime', 'Uptime'), c: 'uptime' }, { d: t('Infos CPU', 'CPU info'), c: 'lscpu' }, { d: t('Date / heure', 'Date / time'), c: 'timedatectl' }, ]}; SEC.apt = { label: t('APT', 'APT'), commands: [ { d: t('Synchro dépôts', 'Sync repos'), c: 'sudo apt update' }, { d: t('Mise à jour', 'Full upgrade'), c: 'sudo apt full-upgrade -y' }, { d: t('Installer', 'Install'), c: 'sudo apt install [package]' }, { d: t('Purge', 'Purge'), c: 'sudo apt purge [package]' }, { d: t('Chercher', 'Search'), c: 'apt search [keyword]' }, { d: t('Paquets installés', 'Installed'), c: 'apt list --installed' }, { d: t('Fichiers fournis', 'Package files'), c: 'dpkg -L [package]' }, ]}; SEC.users = { label: t('utilisateurs', 'users'), commands: [ { d: t('Ajouter', 'Add user'), c: 'sudo adduser [name]' }, { d: t('Supprimer', 'Delete user'), c: 'sudo deluser --remove-home [name]' }, { d: t('Groupe sudo', 'Sudo group'), c: 'sudo usermod -aG sudo [name]' }, { d: t('Permissions', 'Permissions'), c: 'chmod 755 [file]' }, { d: t('Root', 'Root shell'), c: 'sudo -i' }, ]}; SEC.systemd = { label: t('systemd', 'systemd'), commands: [ { d: t('Start/Stop', 'Start/Stop'), c: 'sudo systemctl start|stop [service]' }, { d: t('Restart', 'Restart'), c: 'sudo systemctl restart [service]' }, { d: t('Enable', 'Enable'), c: 'sudo systemctl enable [service]' }, { d: t('Statut', 'Status'), c: 'systemctl status [service]' }, { d: t('Logs', 'Logs'), c: 'journalctl -u [service] -n 50' }, { d: t('Purger logs', 'Purge logs'), c: 'sudo journalctl --vacuum-time=7d' }, ]}; SEC['win-sys'] = { label: t('système', 'system'), commands: [ { d: t('(CMD) Version', '(CMD) Version'), c: 'ver' }, { d: t('(CMD) systeminfo', '(CMD) systeminfo'), c: 'systeminfo' }, { d: t('(PS) Get-ComputerInfo', '(PS) Get-ComputerInfo'), c: 'Get-ComputerInfo' }, ]}; SEC['win-files'] = { label: t('fichiers', 'files'), commands: [ { d: t('(CMD) dir', '(CMD) dir'), c: 'dir /s' }, { d: t('(CMD) rmdir', '(CMD) rmdir'), c: 'rmdir /s [folder]' }, { d: t('(PS) Get-ChildItem', '(PS) Get-ChildItem'), c: 'Get-ChildItem -Recurse -Filter *.txt' }, ]}; SEC['win-process'] = { label: t('processus', 'processes'), commands: [ { d: t('(CMD) tasklist', '(CMD) tasklist'), c: 'tasklist' }, { d: t('(CMD) taskkill', '(CMD) taskkill'), c: 'taskkill /IM notepad.exe /F' }, { d: t('(PS) Get-Process', '(PS) Get-Process'), c: 'Get-Process' }, ]}; SEC['win-network'] = { label: t('réseau', 'network'), commands: [ { d: t('(CMD) ipconfig', '(CMD) ipconfig'), c: 'ipconfig /all' }, { d: t('(CMD) netstat', '(CMD) netstat'), c: 'netstat -an | findstr LISTEN' }, { d: t('(PS) Test-NetConnection', '(PS) Test-NetConnection'), c: 'Test-NetConnection [ip] -Port [port]' }, ]}; SEC['oracle-dnf'] = { label: t('DNF', 'DNF'), commands: [ { d: t('Synchro', 'Sync'), c: 'sudo dnf check-update' }, { d: t('Upgrade', 'Upgrade'), c: 'sudo dnf upgrade -y' }, { d: t('Install', 'Install'), c: 'sudo dnf install [package]' }, { d: t('Remove', 'Remove'), c: 'sudo dnf remove [package]' }, ]}; SEC['oracle-spec'] = { label: t('Oracle spec.', 'Oracle spec.'), commands: [ { d: t('Ksplice status', 'Ksplice status'), c: 'sudo uptrack-status' }, { d: t('Ksplice upgrade', 'Ksplice upgrade'), c: 'sudo uptrack-upgrade' }, { d: t('Changer noyau', 'Switch kernel'), c: 'sudo grubby --set-default /boot/vmlinuz-[ver]' }, ]}; SEC['oracle-selinux'] = { label: t('SELinux', 'SELinux'), commands: [ { d: t('Statut', 'Status'), c: 'getenforce' }, { d: t('Permissif', 'Permissive'), c: 'sudo setenforce 0' }, { d: t('Logs AVC', 'AVC logs'), c: 'sudo ausearch -m avc -ts recent' }, ]}; SEC['oracle-fw'] = { label: t('firewalld', 'firewalld'), commands: [ { d: t('Status', 'Status'), c: 'sudo firewall-cmd --state' }, { d: t('Ouvrir port', 'Open port'), c: 'sudo firewall-cmd --permanent --add-port=22/tcp' }, ]}; SEC['solaris-ips'] = { label: t('IPS', 'IPS'), commands: [ { d: t('Refresh', 'Refresh'), c: 'sudo pkg refresh' }, { d: t('Update', 'Update'), c: 'sudo pkg update' }, { d: t('Install', 'Install'), c: 'sudo pkg install [package]' }, { d: t('Remove', 'Remove'), c: 'sudo pkg uninstall [package]' }, ]}; SEC['solaris-smf'] = { label: t('SMF', 'SMF'), commands: [ { d: t('Liste', 'List'), c: 'svcs -a' }, { d: t('Enable', 'Enable'), c: 'sudo svcadm enable [service]' }, { d: t('Disable', 'Disable'), c: 'sudo svcadm disable [service]' }, { d: t('Restart', 'Restart'), c: 'sudo svcadm restart [service]' }, ]}; SEC['solaris-zfs'] = { label: t('ZFS', 'ZFS'), commands: [ { d: t('Pool status', 'Pool status'), c: 'zpool status' }, { d: t('Scrub', 'Scrub'), c: 'sudo zpool scrub [pool]' }, { d: t('Snapshot', 'Snapshot'), c: 'sudo zfs snapshot [pool]/[ds]@[name]' }, { d: t('Send/Receive', 'Send/Receive'), c: 'zfs send [pool]/[ds]@snap | zfs receive [dest]' }, ]}; SEC['solaris-zones'] = { label: t('Zones', 'Zones'), commands: [ { d: t('Liste', 'List'), c: 'zoneadm list -cv' }, { d: t('Boot', 'Boot'), c: 'sudo zoneadm -z [zone] boot' }, { d: t('Halt', 'Halt'), c: 'sudo zoneadm -z [zone] halt' }, { d: t('Console', 'Console'), c: 'sudo zlogin -C [zone]' }, ]}; // ── COLLECT ALL COMMANDS (for global search) ── var ALL_COMMANDS = []; (function() { var seen = {}; for (var k in SEC) { if (SEC.hasOwnProperty(k)) { SEC[k].commands.forEach(function(cmd) { var key = cmd.c; if (!seen[key]) { seen[key] = true; ALL_COMMANDS.push(cmd); } }); } } })(); // ── HELPERS ── function findNode(tree, id) { if (tree.id === id) return tree; for (var i = 0; i < (tree.children || []).length; i++) { var f = findNode(tree.children[i], id); if (f) return f; } return null; } function collectLeafNodes(node, out) { if (node.children) { for (var i = 0; i < node.children.length; i++) collectLeafNodes(node.children[i], out); } else { out.push(node); } return out; } function countNodeCmds(node) { if (node.sectionIds) { var n = 0; for (var i = 0; i < node.sectionIds.length; i++) { if (SEC[node.sectionIds[i]]) n += SEC[node.sectionIds[i]].commands.length; } return n; } return 0; } // ── RENDER TREE ── function renderTree() { var el = document.getElementById('tree'); el.innerHTML = ''; renderNode(el, TREE, 0); } function renderNode(container, node, depth) { var isBranch = node.children && node.children.length > 0; var isVersion = !!node.sectionIds; var div = document.createElement('div'); if (depth === 0) { var label = document.createElement('div'); label.className = 'group-label'; label.textContent = node.label.fr; div.appendChild(label); } else { var row = document.createElement('div'); var cls = 'sidebar-link'; if (depth === 2) cls += ' sidebar-link-3'; if (depth === 3) cls += ' sidebar-link-4'; if (node === currentNode) cls += ' active'; row.className = cls; if (isBranch) { var tgl = document.createElement('span'); tgl.className = 'tree-toggle open'; tgl.innerHTML = ''; row.appendChild(tgl); } else { var sp = document.createElement('span'); sp.style.cssText = 'width:16px;flex-shrink:0;display:inline-block'; row.appendChild(sp); } var dot = document.createElement('span'); if (isVersion || node._parent) dot.className = 'dot-green'; else if (isBranch) dot.className = 'dot-orange'; else dot.className = 'dot-gray'; row.appendChild(dot); var lbl = document.createElement('span'); lbl.textContent = node.label.fr; row.appendChild(lbl); var cnt = countNodeCmds(node) || (node._parent && node._parent.sectionIds ? SEC[node._sectionId] ? SEC[node._sectionId].commands.length : 0 : 0); if (cnt > 0) { var b = document.createElement('span'); b.className = 'ml-auto text-[0.625rem] text-[#94a3b8]'; b.textContent = '' + cnt; row.appendChild(b); } row.onclick = function(e) { if (isBranch && (e.target.closest('.tree-toggle') || e.target.closest('[data-toggle]'))) { var tg = row.querySelector('.tree-toggle'); if (tg) { tg.classList.toggle('open'); row.nextElementSibling.classList.toggle('open'); e.stopPropagation(); } return; } if (isBranch) return; // only leaf nodes select selectNode(node); }; div.appendChild(row); } if (isBranch) { var kids = document.createElement('div'); kids.className = 'tree-children open'; for (var i = 0; i < node.children.length; i++) { node.children[i]._parent = node; renderNode(kids, node.children[i], depth + 1); } div.appendChild(kids); } if (isVersion && node.sectionIds) { var kids = document.createElement('div'); kids.className = 'tree-children'; if (node === currentNode || (currentNode && currentNode._parent === node)) { kids.className = 'tree-children open'; } for (var j = 0; j < node.sectionIds.length; j++) { var sid = node.sectionIds[j]; var sec = SEC[sid]; if (!sec) continue; var snode = { id: node.id + '-' + sid, label: sec.label, _sectionId: sid, _parent: node }; renderNode(kids, snode, depth + 1); } div.appendChild(kids); } container.appendChild(div); } // ── SELECT NODE ── function selectNode(node) { currentNode = node; currentSection = null; renderTree(); document.getElementById('search').value = ''; hideHome(); document.getElementById('home-btn').style.display = 'flex'; var titleEl = document.getElementById('os-title'); var subEl = document.getElementById('os-sub'); var cmdsEl = document.getElementById('cmds'); if (node._sectionId) { var sec = SEC[node._sectionId]; if (sec) { titleEl.textContent = node._parent.label.fr + ' > ' + sec.label.fr; subEl.textContent = sec.commands.length + ' commandes'; showCmds(sec.commands); } return; } if (node.sectionIds && node.sectionIds.length > 0) { var sid = node.sectionIds[0]; var sec = SEC[sid]; if (sec) { titleEl.textContent = node.label.fr; subEl.textContent = node.sectionIds.length + ' sections · ' + countNodeCmds(node) + ' commandes'; showCmds(sec.commands); } return; } titleEl.textContent = node.label.fr; subEl.textContent = 'Aucune donnée'; cmdsEl.innerHTML = '

' + node.label.fr + '

Pas encore de commandes pour cet OS.

'; } // ── SHOW/HIDE HOME ── function showHome() { currentSection = null; currentNode = null; renderTree(); document.getElementById('search').value = ''; document.getElementById('filter-info').textContent = 'Aucun filtre'; document.getElementById('home-content').style.display = 'block'; document.getElementById('tabs').style.display = 'none'; document.getElementById('stats-bar').style.display = 'none'; document.getElementById('cmds-container').style.display = 'none'; document.getElementById('home-btn').style.display = 'none'; document.getElementById('os-title').textContent = 'SysCmd'; document.getElementById('os-sub').textContent = ''; document.getElementById('breadcrumb').innerHTML = ''; document.getElementById('footer-hint').textContent = 'Cliquez sur un OS pour explorer ses commandes'; renderHome(); } function hideHome() { document.getElementById('home-content').style.display = 'none'; document.getElementById('tabs').style.display = 'flex'; document.getElementById('stats-bar').style.display = 'flex'; document.getElementById('cmds-container').style.display = 'block'; document.getElementById('footer-hint').textContent = 'Cliquez sur une commande pour la copier'; } // ── RENDER HOME ── function renderHome() { renderStats(); renderCards(); } function renderStats() { var totalCmds = ALL_COMMANDS.length; var totalSections = 0; for (var k in SEC) if (SEC.hasOwnProperty(k)) totalSections++; var totalOS = 0; var leaves = collectLeafNodes(TREE, []); for (var i = 0; i < leaves.length; i++) if (leaves[i].sectionIds) totalOS++; var el = document.getElementById('stats-row'); el.innerHTML = '
' + totalCmds + '
commandes
' + '
' + totalSections + '
sections
' + '
' + totalOS + '
OS renseignés
' + '
' + (leaves.length - totalOS) + '
placeholders
'; } var OS_CARDS = [ { id: 'debian', label: 'Debian', icon: 'D', color: '#0f172a', desc: t('Distribution stable de référence', 'Stable reference distribution') }, { id: 'ubuntu', label: 'Ubuntu', icon: 'U', color: '#dc2626', desc: t('Basé sur Debian avec versions LTS', 'Debian-based with LTS releases'), isGroup: true }, { id: 'oracle', label: 'Oracle Linux', icon: 'O', color: '#b9141e', desc: t('Linux Oracle avec UEK + SELinux', 'Oracle Linux with UEK + SELinux') }, { id: 'windows', label: 'Windows', icon: 'W', color: '#0078d4', desc: t('CMD + PowerShell client/server', 'CMD + PowerShell client/server'), isGroup: true }, { id: 'solaris', label: 'Solaris', icon: 'S', color: '#b46400', desc: t('Solaris / illumos avec ZFS + DTrace', 'Solaris / illumos with ZFS + DTrace') }, { id: 'rhel', label: 'RHEL / CentOS', icon: 'R', color: '#94a3b8', desc: t('Enterprise Linux (à venir)', 'Enterprise Linux (pending)'), placeholder: true }, { id: 'fedora', label: 'Fedora', icon: 'F', color: '#94a3b8', desc: t('Basé sur RHEL (à venir)', 'RHEL-based (pending)'), placeholder: true }, { id: 'freebsd', label: 'FreeBSD', icon: 'B', color: '#94a3b8', desc: t('BSD Unix (à venir)', 'BSD Unix (pending)'), placeholder: true }, { id: 'macos', label: 'macOS', icon: 'M', color: '#94a3b8', desc: t('macOS (à venir)', 'macOS (pending)'), placeholder: true }, { id: 'docker', label: 'Docker', icon: 'D', color: '#94a3b8', desc: t('Containers et orchestration (à venir)', 'Containers and orchestration (pending)'), placeholder: true }, { id: 'cisco', label: 'Cisco IOS', icon: 'C', color: '#94a3b8', desc: t('Réseau Cisco (à venir)', 'Cisco networking (pending)'), placeholder: true }, { id: 'mysql', label: 'MySQL / MariaDB', icon: 'S', color: '#94a3b8', desc: t('Bases de données SQL (à venir)', 'SQL databases (pending)'), placeholder: true }, ]; function renderCards() { var el = document.getElementById('card-grid'); el.innerHTML = ''; OS_CARDS.forEach(function(card) { var div = document.createElement('div'); var isPlaceholder = card.placeholder; var node = findNode(TREE, card.id); var cnt = node ? countNodeCmds(node) : 0; if (cnt > 0) isPlaceholder = false; div.className = 'os-card' + (isPlaceholder ? ' placeholder-card' : ''); var iconBg = isPlaceholder ? 'bg-[#e2e8f0] text-[#94a3b8]' : 'text-white'; div.innerHTML = '
' + '
' + '' + card.icon + '' + '
' + '
' + '
' + (card.isGroup ? card.label + ' →' : card.label) + '
' + '
' + card.desc.fr + '
' + '
' + '
' + '
' + (cnt > 0 ? '' + cnt + 'commandes' : '' + (isPlaceholder ? 'À venir' : 'via sidebar') + '') + '
'; div.onclick = function() { if (card.isGroup) { // Expand group in sidebar var n = findNode(TREE, card.id); if (n && n.children && n.children.length > 0) { selectNode(n.children[0]); } } else if (node) { selectNode(node); } }; el.appendChild(div); }); } // ── SHOW COMMANDS ── function showCmds(commands) { var el = document.getElementById('cmds'); var sv = document.getElementById('search').value.trim().toLowerCase(); var cmds = commands; if (sv) { cmds = cmds.filter(function(x) { return x.d.fr.toLowerCase().indexOf(sv) !== -1 || x.d.en.toLowerCase().indexOf(sv) !== -1 || x.c.toLowerCase().indexOf(sv) !== -1; }); } document.getElementById('shown').textContent = '' + cmds.length; if (cmds.length === 0) { el.innerHTML = '
Aucune commande trouvée
'; return; } el.innerHTML = ''; for (var i = 0; i < cmds.length; i++) { var x = cmds[i]; var row = document.createElement('div'); row.className = 'cmd-row' + (i % 2 === 0 ? ' bg-[#fafbfc]' : ''); row.innerHTML = '
' + x.d.fr + '
' + x.c + '
'; row.querySelector('.cmd-text').onclick = (function(cmd) { return function() { navigator.clipboard.writeText(cmd).then(function() { var icon = row.querySelector('.copy-icon'); icon.innerHTML = ''; setTimeout(function() { icon.innerHTML = ''; }, 1200); }); }; })(x.c); el.appendChild(row); } } // ── SEARCH ── function filterCommands(val) { var el = document.getElementById('filter-info'); el.textContent = val.trim() ? 'Filtre: "' + val + '"' : 'Aucun filtre'; if (currentNode && currentNode._sectionId) { showCmds(SEC[currentNode._sectionId].commands); } else if (currentNode && currentNode.sectionIds && currentNode.sectionIds.length > 0) { showCmds(SEC[currentNode.sectionIds[0]].commands); } } // ── GLOBAL SEARCH ── function globalSearch(val) { var el = document.getElementById('global-search-results'); var cmdsEl = document.getElementById('global-cmds'); var sv = val.trim().toLowerCase(); if (!sv) { el.style.display = 'none'; document.getElementById('card-grid').style.display = 'grid'; document.getElementById('stats-row').style.display = 'grid'; return; } el.style.display = 'block'; document.getElementById('card-grid').style.display = 'none'; document.getElementById('stats-row').style.display = 'none'; // Search across all commands var results = []; for (var i = 0; i < ALL_COMMANDS.length; i++) { var x = ALL_COMMANDS[i]; if (x.d.fr.toLowerCase().indexOf(sv) !== -1 || x.d.en.toLowerCase().indexOf(sv) !== -1 || x.c.toLowerCase().indexOf(sv) !== -1) { results.push(x); } } cmdsEl.innerHTML = ''; if (results.length === 0) { cmdsEl.innerHTML = '
Aucune commande trouvée
'; return; } // Header stat var header = document.createElement('div'); header.className = 'px-4 py-2 text-xs text-[#94a3b8] border-b border-[#f1f5f9]'; header.textContent = results.length + ' résultat(s) dans toutes les sections'; cmdsEl.appendChild(header); for (var j = 0; j < results.length; j++) { var x = results[j]; var row = document.createElement('div'); row.className = 'cmd-row' + (j % 2 === 0 ? ' bg-[#fafbfc]' : ''); row.innerHTML = '
' + x.d.fr + '
' + x.c + '
'; row.querySelector('.cmd-text').onclick = (function(cmd) { return function() { navigator.clipboard.writeText(cmd).then(function() { var icon = row.querySelector('.copy-icon'); icon.innerHTML = ''; setTimeout(function() { icon.innerHTML = ''; }, 1200); }); }; })(x.c); cmdsEl.appendChild(row); } } // ── INIT ── renderTree(); showHome();