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;
}
}
========================================================
WIZARD MODAL (defolt olaraq gizlidir)
========================================================
Köhnə Sürətli Əlavə (yıxıldı)
Dinamik Şəbəkə Topologiyası Xəritəçəkməçisi
CLI çıxışlarını tamamilə müştəri tərəfində emal edən sıfır inamlı şəbəkə vizuallaşdırma vasitəsi. Avtomatik olaraq interaktiv topologiya diaqramlarını yaratmaq üçün bir çox cihazdan çıxışları yapışdırın. Cisco IOS/NX-OS, Aruba AOS-CX, Juniper JunOS, VyOS, Palo Alto, Fortigate və SONiC-ni dəstəkləyir.
Məxfilik Zəmanəti:Bütün emal brauzerinizdə baş verir. Heç bir serverə heç bir məlumat ötürülmür.
Satıcı Komanda Referansı
Şəbəkə kəşfi üçün tövsiyə olunan CLI əmrlərini görmək üçün cihaz satıcınızı seçin:
Cisco IOS/IOS-XE Əmrləri
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
Addım 1: Cihazlar əlavə edin
Sihirbazın işə salınması + cihazların toplanmış siyahısıHələ heç bir cihaz əlavə edilməyib — aşağıdakı sehrbazdan və ya Tez əlavədən istifadə edin.