Skip to content

Commit ef336f8

Browse files
author
Glasspham
committed
version 4
1 parent 80c71e9 commit ef336f8

4 files changed

Lines changed: 179 additions & 9 deletions

File tree

index.html

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,24 @@
4646
Number Converter
4747
</a>
4848
</li>
49+
<li class="nav-item">
50+
<a class="nav-link" href="#theory-tool" data-tool="theory">
51+
<i class="fas fa-book me-1"></i>
52+
Theory
53+
</a>
54+
</li>
4955
</ul>
5056
</div>
5157
</div>
5258
</nav>
5359

5460
<!-- Main Content -->
5561
<div class="container py-4">
62+
<!-- Theory Tool -->
63+
<div id="theory-tool" class="tool-section" style="display: none;">
64+
<!-- Content will be loaded here by theoryLoader.js -->
65+
</div>
66+
5667
<!-- VLSM Tool -->
5768
<div id="vlsm-tool" class="tool-section">
5869
<div class="row">
@@ -379,21 +390,13 @@ <h5 class="mb-1 text-white">
379390
</div>
380391
</div>
381392
</div>
382-
<!-- <hr class="my-3 border-light opacity-25" />
383-
<div class="row">
384-
<div class="col-12 text-center small">
385-
<p class="mb-0 text-light opacity-75">
386-
&copy; 2025 Network Tools Suite. Built with
387-
<i class="fas fa-heart text-danger mx-1"></i>
388-
for AI and Glasspham.
389-
</p>
390-
</div> -->
391393
</div>
392394
</div>
393395
</footer>
394396

395397
<!-- Scripts -->
396398
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
397399
<script type="module" src="js/uiHandler.js"></script>
400+
<script type="module" src="js/theoryLoader.js"></script>
398401
</body>
399402
</html>

js/theoryLoader.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
document.addEventListener("DOMContentLoaded", function () {
2+
const theoryToolSection = document.getElementById("theory-tool");
3+
4+
if (theoryToolSection) {
5+
theoryToolSection.innerHTML = `
6+
<div class="row">
7+
<div class="col-12">
8+
<div class="card shadow-sm border-0">
9+
<div class="card-body">
10+
<section id="tables" class="mt-4">
11+
<!-- Bảng thông tin Prefix-length -->
12+
<div class="table-responsive mb-4">
13+
<h3>Bảng thông tin Prefix-length</h3>
14+
<div id="prefix-grid-container" class="prefix-grid">
15+
<!-- Grid content will be generated by JavaScript -->
16+
</div>
17+
</div>
18+
<!-- Bảng phân chia địa chỉ IP -->
19+
<div class="table-responsive mb-4">
20+
<h3>Bảng phân chia địa chỉ IP</h3>
21+
<div id="ip-grid-container" class="ip-grid">
22+
<!-- IP grid content will be generated by JavaScript -->
23+
</div>
24+
</div>
25+
</section>
26+
</div>
27+
</div>
28+
</div>
29+
</div>
30+
`;
31+
32+
const prefixData = {
33+
headers: ["Prefix-length", "/24", "/25", "/26", "/27", "/28", "/29", "/30"],
34+
rows: [
35+
{ label: "Number of IP", values: ["256 - 2", "128 - 2", "64 - 2", "32 - 2", "16 - 2", "8 - 2", "4 - 2"] },
36+
{ label: "Number of Subnet", values: ["1", "2", "4", "8", "16", "32", "64"] },
37+
{ label: "Number of Host", values: ["127 > 254", "63 > 126", "31 > 62", "15 > 30", "7 > 14", "3 > 6", "1 > 2"], class: "text-danger" },
38+
{ label: "Subnet mask", values: ["255.255.255.0", "255.255.255.128", "255.255.255.192", "255.255.255.224", "255.255.255.240", "255.255.255.248", "255.255.255.252"], class: "text-primary" },
39+
{ label: "Wildcard mask", values: ["0.0.0.255", "0.0.0.127", "0.0.0.63", "0.0.0.31", "0.0.0.15", "0.0.0.7", "0.0.0.3"], class: "text-success" },
40+
],
41+
};
42+
43+
const gridContainer = document.getElementById("prefix-grid-container");
44+
if (gridContainer) {
45+
let gridHTML = "";
46+
47+
// Generate headers
48+
prefixData.headers.forEach((header) => {
49+
gridHTML += `<div class="prefix-grid-header">${header}</div>`;
50+
});
51+
52+
// Generate rows
53+
prefixData.rows.forEach((row) => {
54+
gridHTML += `<div class="prefix-grid-cell"><strong>${row.label}</strong></div>`;
55+
row.values.forEach((value) => {
56+
gridHTML += `<div class="prefix-grid-cell ${row.class || ""}">${value}</div>`;
57+
});
58+
});
59+
60+
gridContainer.innerHTML = gridHTML;
61+
}
62+
63+
const ipGridContainer = document.getElementById("ip-grid-container");
64+
if (ipGridContainer) {
65+
const totalRows = 64;
66+
let ipGridHTML = [...Array(7)].map((_, i) => `<div class="ip-grid-header">${Math.pow(2, 8 - (i + 1))}</div>`).join("");
67+
68+
const columns = [
69+
{ prefix: 24, subnets: 1, step: 256 },
70+
{ prefix: 25, subnets: 2, step: 128 },
71+
{ prefix: 26, subnets: 4, step: 64 },
72+
{ prefix: 27, subnets: 8, step: 32 },
73+
{ prefix: 28, subnets: 16, step: 16 },
74+
{ prefix: 29, subnets: 32, step: 8 },
75+
{ prefix: 30, subnets: 64, step: 4 },
76+
];
77+
78+
const generateIpGridColumn = (prefix, subnets, step) => {
79+
let columnHTML = '<div class="ip-grid-col">';
80+
// Generate IP cells
81+
for (let i = 0; i < subnets; i++) {
82+
columnHTML += `<div class="ip-grid-cell">192.168.1.${i * step}/${prefix}</div>`;
83+
}
84+
// Generate empty cells
85+
const emptyCells = totalRows - subnets;
86+
for (let i = 0; i < emptyCells; i++) {
87+
columnHTML += `<div class="ip-grid-cell bg-secondary">&nbsp;</div>`;
88+
}
89+
columnHTML += "</div>";
90+
return columnHTML;
91+
};
92+
93+
columns.forEach((col) => {
94+
ipGridHTML += generateIpGridColumn(col.prefix, col.subnets, col.step);
95+
});
96+
97+
ipGridContainer.innerHTML = ipGridHTML;
98+
}
99+
}
100+
});

js/uiHandler.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class UIHandler {
2222
this.setupDynamicSubnets();
2323
this.setupViewModeToggle();
2424
this.setupNumberConverter();
25+
this.switchTool(this.currentTool);
2526
}
2627

2728
setupNavigation() {

style.css

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,3 +346,69 @@ body {
346346
background-position: right calc(0.375em + 0.1875rem) center;
347347
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
348348
}
349+
350+
.ip-grid {
351+
display: grid;
352+
grid-template-columns: repeat(7, 1fr);
353+
border: 1px solid #000000;
354+
border-radius: 0.25rem;
355+
overflow: hidden;
356+
font-size: 20px;
357+
}
358+
.ip-grid-col {
359+
display: flex;
360+
flex-direction: column;
361+
border-right: 1px solid #dee2e6;
362+
}
363+
.ip-grid-col:last-child {
364+
border-right: none;
365+
}
366+
.ip-grid-header,
367+
.ip-grid-cell {
368+
padding: 0.5rem;
369+
text-align: center;
370+
}
371+
.ip-grid-header {
372+
background-color: #f8f9fa;
373+
font-weight: bold;
374+
border-bottom: 1px solid #dee2e6;
375+
}
376+
.ip-grid-cell {
377+
border-bottom: 1px solid #dee2e6;
378+
font-size: 0.9em;
379+
}
380+
.ip-grid-col .ip-grid-cell:last-child {
381+
border-bottom: none;
382+
}
383+
384+
/* Prefix-length grid */
385+
.prefix-grid {
386+
display: grid;
387+
grid-template-columns: repeat(8, 1fr);
388+
border: 1px solid #000000;
389+
border-radius: 0.25rem;
390+
overflow: hidden;
391+
margin-bottom: 1rem;
392+
font-size: 20px;
393+
}
394+
.prefix-grid-header,
395+
.prefix-grid-cell {
396+
padding: 0.5rem;
397+
text-align: center;
398+
display: flex;
399+
align-items: center;
400+
justify-content: center;
401+
border-right: 1px solid #dee2e6;
402+
border-bottom: 1px solid #dee2e6;
403+
}
404+
.prefix-grid-header {
405+
background-color: #f8f9fa;
406+
font-weight: bold;
407+
}
408+
.prefix-grid-header:last-child,
409+
.prefix-grid-cell:last-child {
410+
border-right: none;
411+
}
412+
.prefix-grid-cell {
413+
font-size: 0.9em;
414+
}

0 commit comments

Comments
 (0)