Dynamic Network Topology Mapper

.calc-header { margin-bottom: 30px; padding: 25px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 12px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); color: white; } .calc-header h2 { margin-top: 0; color: white; font-size: 28px; margin-bottom: 10px; } .calc-header p { margin: 10px 0 20px 0; opacity: 0.95; font-size: 15px; line-height: 1.6; } .vendor-ref-section { background: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .vendor-ref-section h3 { margin-top: 0; color: #667eea; font-size: 18px; margin-bottom: 15px; } .vendor-ref-layout { display: grid; grid-template-columns: 250px 1fr; gap: 20px; margin-top: 15px; } .vendor-tabs { display: flex; flex-direction: column; gap: 5px; } .vendor-tab { padding: 12px 16px; background: #f5f5f5; border: 2px solid transparent; border-radius: 6px; cursor: pointer; font-size: 14px; font-weight: 600; color: #666; text-align: left; transition: all 0.2s ease; } .vendor-tab:hover { background: rgba(102, 126, 234, 0.1); color: #667eea; } .vendor-tab.active { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-color: #667eea; } .vendor-commands { background: #f9f9f9; border: 1px solid #e0e0e0; border-radius: 6px; padding: 0; position: relative; } .vendor-commands-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; background: #667eea; color: white; border-radius: 6px 6px 0 0; font-weight: bold; font-size: 14px; } .vendor-commands pre { margin: 0; padding: 16px; font-family: 'Courier New', monospace; font-size: 13px; color: #333; background: white; overflow-x: auto; border-radius: 0 0 6px 6px; } .copy-btn { padding: 6px 12px; background: rgba(255, 255, 255, 0.2); color: white; border: 1px solid rgba(255, 255, 255, 0.3); border-radius: 4px; cursor: pointer; font-size: 12px; font-weight: bold; transition: all 0.2s ease; } .copy-btn:hover { background: rgba(255, 255, 255, 0.3); } .input-section { background: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .input-section h3 { margin-top: 0; color: #667eea; font-size: 18px; margin-bottom: 15px; } .cli-textarea { width: 100%; min-height: 200px; padding: 14px; font-family: 'Courier New', monospace; font-size: 13px; border: 2px solid #e0e0e0; border-radius: 6px; resize: vertical; transition: border-color 0.3s ease; box-sizing: border-box; } .cli-textarea:focus { outline: none; border-color: #667eea; box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); } .button-row { display: flex; gap: 10px; margin-top: 15px; flex-wrap: wrap; } .btn-primary { padding: 12px 24px; font-size: 14px; background: #4CAF50; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; transition: all 0.2s ease; } .btn-primary:hover { background: #45a049; transform: translateY(-1px); } .btn-secondary { padding: 12px 24px; font-size: 14px; background: #667eea; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; transition: all 0.2s ease; } .btn-secondary:hover { background: #5568d3; transform: translateY(-1px); } .btn-danger { padding: 12px 24px; font-size: 14px; background: #f44336; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; transition: all 0.2s ease; } .btn-danger:hover { background: #d32f2f; transform: translateY(-1px); } .device-chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 15px; min-height: 40px; } .device-chip { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 20px; font-size: 13px; font-weight: 500; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .device-chip-label { display: flex; flex-direction: column; } .device-chip-hostname { font-weight: bold; } .device-chip-info { font-size: 11px; opacity: 0.9; } .device-chip-remove { background: rgba(255,255,255,0.2); border: none; color: white; width: 20px; height: 20px; border-radius: 50%; cursor: pointer; font-size: 14px; display: flex; align-items: center; justify-content: center; transition: background 0.2s ease; } .device-chip-remove:hover { background: rgba(255,255,255,0.4); } .view-tabs { display: flex; gap: 5px; margin-bottom: 15px; border-bottom: 2px solid #e0e0e0; } .view-tab { padding: 12px 24px; background: transparent; border: none; cursor: pointer; font-size: 14px; font-weight: 600; color: #666; border-bottom: 3px solid transparent; transition: all 0.2s ease; } .view-tab:hover { color: #667eea; background: rgba(102, 126, 234, 0.05); } .view-tab.active { color: #667eea; border-bottom-color: #667eea; } .topology-canvas { background: white; border: 1px solid #e0e0e0; border-radius: 8px; height: 700px; position: relative; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; color: #999; font-size: 16px; } .empty-state-icon { font-size: 48px; margin-bottom: 15px; opacity: 0.5; } .details-panel { background: white; border: 1px solid #e0e0e0; border-radius: 8px; padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); display: none; } .details-panel.visible { display: block; } .details-header { font-size: 18px; font-weight: bold; color: #667eea; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 2px solid #e0e0e0; } .details-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; } .details-item { display: flex; flex-direction: column; } .details-label { font-size: 11px; color: #666; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 5px; } .details-value { font-size: 16px; font-weight: bold; color: #333; } .details-list { margin-top: 15px; } .details-list h4 { font-size: 14px; color: #667eea; margin-bottom: 10px; } .details-list-item { padding: 8px 12px; background: #f5f5f5; border-radius: 4px; margin-bottom: 6px; font-size: 13px; font-family: 'Courier New', monospace; } .notification { position: fixed; top: 20px; right: 20px; padding: 15px 20px; border-radius: 6px; box-shadow: 0 4px 12px rgba(0,0,0,0.2); font-size: 14px; z-index: 10000; min-width: 300px; animation: slideIn 0.3s ease; } @keyframes slideIn { from { transform: translateX(400px); opacity: 0; } to { transform: translateX(0); opacity: 1; } } .notification.success { background: #4CAF50; color: white; } .notification.error { background: #f44336; color: white; } .notification.warning { background: #ff9800; color: white; } .stats-bar { display: flex; gap: 20px; padding: 15px 20px; background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); border-radius: 8px; margin-bottom: 20px; } .stat-item { display: flex; flex-direction: column; } .stat-label { font-size: 11px; color: #666; text-transform: uppercase; letter-spacing: 0.5px; } .stat-value { font-size: 24px; font-weight: bold; color: #667eea; } .legend { display: flex; flex-wrap: wrap; gap: 15px; padding: 15px; background: white; border-radius: 6px; margin-top: 15px; border: 1px solid #e0e0e0; } .legend-item { display: flex; align-items: center; gap: 8px; font-size: 13px; } .legend-color { width: 20px; height: 20px; border-radius: 4px; border: 1px solid rgba(0,0,0,0.1); } .search-filter-bar { display: flex; gap: 10px; padding: 15px; background: white; border-radius: 6px; margin-bottom: 15px; border: 1px solid #e0e0e0; align-items: center; flex-wrap: wrap; } .search-input { flex: 1; min-width: 200px; padding: 10px 14px; border: 2px solid #e0e0e0; border-radius: 6px; font-size: 14px; transition: border-color 0.3s ease; } .search-input:focus { outline: none; border-color: #667eea; } .filter-select { padding: 10px 14px; border: 2px solid #e0e0e0; border-radius: 6px; font-size: 14px; cursor: pointer; background: white; } .topology-storage-section { display: flex; gap: 10px; flex-wrap: wrap; } .saved-topologies { margin-top: 15px; padding: 15px; background: #f9f9f9; border-radius: 6px; border: 1px solid #e0e0e0; } .saved-topology-item { display: flex; justify-content: space-between; align-items: center; padding: 10px; background: white; border-radius: 4px; margin-bottom: 8px; border: 1px solid #e0e0e0; } .saved-topology-info { flex: 1; } .saved-topology-name { font-weight: bold; color: #333; font-size: 14px; } .saved-topology-meta { font-size: 12px; color: #666; margin-top: 4px; } .saved-topology-actions { display: flex; gap: 8px; } .path-selection-bar { padding: 15px; background: linear-gradient(135deg, rgba(76, 175, 80, 0.1) 0%, rgba(76, 175, 80, 0.05) 100%); border-radius: 6px; margin-bottom: 15px; border: 2px solid #4CAF50; } .path-selection-bar h4 { margin: 0 0 10px 0; color: #4CAF50; font-size: 14px; } .path-info { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; } .path-node { padding: 8px 14px; background: white; border-radius: 6px; font-weight: bold; color: #333; border: 2px solid #4CAF50; } .path-details { flex: 1; font-size: 13px; color: #333; } @media (max-width: 768px) { .topology-container { padding: 10px; } .vendor-ref-layout { grid-template-columns: 1fr; } .button-row { flex-direction: column; } .btn-primary, .btn-secondary, .btn-danger { width: 100%; } .stats-bar { flex-direction: column; gap: 10px; } .topology-canvas { height: 500px; } .search-filter-bar { flex-direction: column; align-items: stretch; } .search-input { min-width: 100%; } .sample-topology-selector { flex-direction: column; } } .sample-topology-selector { display: flex; gap: 10px; align-items: center; margin-top: 10px; } .sample-topology-selector select { flex: 1; padding: 10px 14px; border: 2px solid #e0e0e0; border-radius: 6px; font-size: 14px; background: white; cursor: pointer; } .sample-topology-selector select:focus { border-color: #667eea; outline: none; } .difficulty-badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; } .difficulty-badge.beginner { background: #e8f5e9; color: #2e7d32; } .difficulty-badge.intermediate { background: #fff3e0; color: #e65100; } .difficulty-badge.advanced { background: #fce4ec; color: #c62828; } .training-note { margin: 15px 0; padding: 15px 20px; background: #e3f2fd; border-left: 4px solid #1976D2; border-radius: 0 6px 6px 0; font-size: 14px; line-height: 1.6; color: #1565C0; } .training-note strong { display: block; margin-bottom: 5px; color: #0D47A1; } .vrf-badge { display: inline-block; padding: 1px 6px; border-radius: 8px; font-size: 10px; font-weight: 600; margin-left: 4px; color: white; } .route-leak-indicator { color: #e74c3c; font-weight: 600; font-size: 12px; } .vrf-detail-section { margin-top: 10px; padding: 10px; background: #f5f5f5; border-radius: 6px; border-left: 3px solid #667eea; } .vrf-detail-section h5 { margin: 0 0 6px 0; font-size: 13px; color: #333; } .vrf-detail-item { font-size: 12px; color: #555; margin-bottom: 3px; } .vrf-legend { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; padding: 10px; background: #f9f9f9; border-radius: 6px; } .vrf-legend-item { display: flex; align-items: center; gap: 4px; font-size: 11px; } .vrf-legend-color { width: 12px; height: 12px; border-radius: 3px; } /* ========================================================= WIZARD MODAL — Phase 3 ========================================================= */ .wizard-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.55); z-index: 9000; display: flex; align-items: center; justify-content: center; padding: 20px; animation: fadeOverlay 0.2s ease; } @keyframes fadeOverlay { from { opacity: 0; } to { opacity: 1; } } .wizard-modal { background: white; border-radius: 12px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); width: 100%; max-width: 680px; max-height: 90vh; overflow-y: auto; display: flex; flex-direction: column; animation: slideUp 0.25s ease; } @keyframes slideUp { from { transform: translateY(30px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .wizard-header { display: flex; align-items: center; justify-content: space-between; padding: 20px 24px 16px; border-bottom: 2px solid #f0f0f0; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 12px 12px 0 0; color: white; } .wizard-header h3 { margin: 0; font-size: 18px; color: white; } .wizard-close-btn { background: rgba(255,255,255,0.2); border: none; color: white; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; font-size: 18px; display: flex; align-items: center; justify-content: center; transition: background 0.2s; flex-shrink: 0; } .wizard-close-btn:hover { background: rgba(255,255,255,0.35); } .wizard-progress-bar { height: 4px; background: #e0e0e0; position: relative; overflow: hidden; } .wizard-progress-fill { height: 100%; background: linear-gradient(90deg, #667eea, #764ba2); transition: width 0.35s ease; } .wizard-body { padding: 24px; flex: 1; } .wizard-step-label { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px; color: #667eea; margin-bottom: 6px; } .wizard-command-block { display: inline-block; padding: 8px 14px; background: #1e1e2e; color: #a6e3a1; font-family: 'Courier New', monospace; font-size: 14px; border-radius: 6px; margin: 10px 0 16px; word-break: break-all; } .wizard-command-copy { display: inline-block; margin-left: 10px; padding: 3px 10px; background: transparent; border: 1px solid #667eea; color: #667eea; border-radius: 4px; font-size: 11px; cursor: pointer; font-weight: 600; transition: all 0.15s; vertical-align: middle; } .wizard-command-copy:hover { background: #667eea; color: white; } .wizard-textarea { width: 100%; min-height: 220px; padding: 14px; font-family: 'Courier New', monospace; font-size: 12px; border: 2px solid #e0e0e0; border-radius: 6px; resize: vertical; box-sizing: border-box; transition: border-color 0.25s; line-height: 1.5; } .wizard-textarea:focus { outline: none; border-color: #667eea; box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); } .wizard-textarea.invalid { border-color: #f44336; } .wizard-inline-error { color: #f44336; font-size: 13px; margin-top: 6px; display: none; } .wizard-validation-warning { background: #fff8e1; border: 1px solid #f9a825; border-radius: 6px; padding: 12px 16px; font-size: 13px; color: #5d4037; margin-top: 10px; display: none; } .wizard-validation-warning strong { color: #e65100; display: block; margin-bottom: 6px; } .wizard-validation-actions { display: flex; gap: 10px; margin-top: 8px; } .wizard-footer { display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; border-top: 1px solid #f0f0f0; gap: 10px; flex-wrap: wrap; } .wizard-back-link { background: none; border: none; color: #667eea; cursor: pointer; font-size: 14px; padding: 0; text-decoration: underline; text-underline-offset: 2px; } .wizard-back-link:hover { color: #5568d3; } .wizard-btn-row { display: flex; gap: 10px; } .btn-wizard-skip { padding: 10px 20px; font-size: 14px; background: transparent; color: #888; border: 2px solid #e0e0e0; border-radius: 6px; cursor: pointer; font-weight: 600; transition: all 0.2s; } .btn-wizard-skip:hover { border-color: #999; color: #555; } .btn-wizard-next { padding: 10px 24px; font-size: 14px; background: #4CAF50; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; transition: all 0.2s; } .btn-wizard-next:hover { background: #43a047; transform: translateY(-1px); } .btn-wizard-finalize { padding: 10px 24px; font-size: 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; transition: all 0.2s; } .btn-wizard-finalize:hover { opacity: 0.9; transform: translateY(-1px); } /* Step 0 — Identity form */ .wizard-identity-form { display: flex; flex-direction: column; gap: 16px; } .wizard-field-group { display: flex; flex-direction: column; gap: 6px; } .wizard-field-group label { font-size: 13px; font-weight: 600; color: #444; } .wizard-text-input, .wizard-select { width: 100%; padding: 12px 14px; border: 2px solid #e0e0e0; border-radius: 6px; font-size: 14px; box-sizing: border-box; transition: border-color 0.25s; background: white; } .wizard-text-input:focus, .wizard-select:focus { outline: none; border-color: #667eea; box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); } /* Summary step */ .wizard-summary-list { list-style: none; padding: 0; margin: 16px 0; } .wizard-summary-list li { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 6px; font-size: 14px; margin-bottom: 4px; } .wizard-summary-list li:nth-child(odd) { background: #f9f9f9; } .wizard-summary-icon { width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: bold; flex-shrink: 0; } .wizard-summary-icon.submitted { background: #e8f5e9; color: #2e7d32; } .wizard-summary-icon.skipped { background: #f5f5f5; color: #999; } .wizard-summary-cmd { flex: 1; } .wizard-summary-status { font-size: 12px; font-weight: 600; color: #999; } .wizard-summary-status.submitted { color: #4CAF50; } .wizard-summary-identity { padding: 14px 16px; background: linear-gradient(135deg, rgba(102, 126, 234, 0.08) 0%, rgba(118, 75, 162, 0.08) 100%); border-radius: 8px; border-left: 4px solid #667eea; font-size: 14px; margin-bottom: 6px; } .wizard-summary-identity strong { font-size: 16px; display: block; margin-bottom: 4px; color: #333; } .wizard-summary-vendor-badge { display: inline-block; padding: 2px 10px; border-radius: 20px; font-size: 11px; font-weight: 700; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-transform: uppercase; letter-spacing: 0.5px; } /* Quick-add (legacy) section toggle */ .quick-add-toggle { display: flex; align-items: center; gap: 8px; padding: 10px 0 0; cursor: pointer; color: #667eea; font-size: 13px; font-weight: 600; border: none; background: none; text-decoration: none; user-select: none; } .quick-add-toggle:hover { color: #5568d3; } .quick-add-caret { display: inline-block; transition: transform 0.2s; font-style: normal; } .quick-add-caret.open { transform: rotate(90deg); } .quick-add-body { overflow: hidden; max-height: 0; transition: max-height 0.3s ease, padding 0.3s ease; } .quick-add-body.open { max-height: 600px; } /* Devices collected list */ .wizard-collected-list { margin-top: 16px; } .wizard-collected-list h4 { font-size: 13px; font-weight: 700; color: #667eea; margin: 0 0 10px; text-transform: uppercase; letter-spacing: 0.5px; } .wizard-collected-empty { color: #999; font-size: 13px; font-style: italic; } @media (max-width: 768px) { .wizard-modal { max-height: 95vh; } .wizard-textarea { min-height: 200px; } .wizard-footer { flex-direction: column; align-items: stretch; } .wizard-btn-row { width: 100%; justify-content: flex-end; } }

Trình ánh xạ cấu trúc liên kết mạng động

Công cụ trực quan hóa mạng không tin cậy xử lý các kết quả đầu ra CLI hoàn toàn phía máy khách. Dán đầu ra từ nhiều thiết bị để tự động tạo sơ đồ cấu trúc liên kết tương tác. Hỗ trợ Cisco IOS/NX-OS, Aruba AOS-CX, Juniper JunOS, VyOS, Palo Alto, Fortigate và SONiC.

Đảm bảo quyền riêng tư:Tất cả quá trình xử lý diễn ra trong trình duyệt của bạn. Không có dữ liệu được truyền đến bất kỳ máy chủ nào.

Tham chiếu lệnh của nhà cung cấp

Chọn nhà cung cấp thiết bị của bạn để xem các lệnh CLI được đề xuất để khám phá mạng:

Các lệnh Cisco IOS/IOS-XE
show lldp neighbors
show lldp neighbors detail
show mac address-table
show ip ospf neighbor
show ip bgp summary
show cdp neighbors detail
show interfaces status
show vlan brief
=========================================================== PHƯƠNG THỨC WIZARD (ẩn theo mặc định) ===========================================================

Bước 1: Thêm thiết bị

Khởi chạy trình hướng dẫn + danh sách thiết bị được thu thập
Chưa có thiết bị nào được thêm — hãy sử dụng trình hướng dẫn hoặc Thêm nhanh bên dưới.
Thêm nhanh kế thừa (đã thu gọn)

Bước 2: Quản lý cấu trúc liên kết