@@ -140,7 +161,7 @@
Формат оконечного номера — ABC21UV
-
Для Алматы: 7271UV. Реестр пополняется, а схема пересчитывается автоматически — введите номер в поле поиска и сверьте маршрут.
+
Для Алматы: 7271UV. Введите номер в поле поиска и сверьте: его данные подставятся в цепочки и в схему маршрутизации.
Перейти к поиску
diff --git a/script.js b/script.js
index 9ba10a8..9ec679f 100644
--- a/script.js
+++ b/script.js
@@ -171,6 +171,7 @@
document.getElementById("r2src").textContent = "Станция владельца номера → SSW/NGN рег. → " + (d.entry ? d.entry.num : "оконечный номер");
renderChain("chain1", d.mobile);
renderChain("chain2", d.fixed);
+ renderScheme(d.entry ? d.entry.num : num);
}
function renderRegister() {
@@ -202,8 +203,116 @@
document.getElementById("regCounter").textContent = "Каждый номер: тип (ТДМ / GPON / SIP), станция владения, формат набора ABC21UV и резерв. В реестре: " + REG.length + ".";
}
+ function renderScheme(focusNum) {
+ const NS = "http://www.w3.org/2000/svg";
+ const svg = document.createElementNS(NS, "svg");
+ svg.setAttribute("viewBox", "0 0 1100 460");
+ svg.setAttribute("role", "img");
+ svg.setAttribute("aria-label", "Схема маршрутизации вызовов экстренных служб");
+
+ const entry = findEntry(focusNum) || REG[0] || null;
+ const endNum = entry ? entry.num : "—";
+ const hasBrw = entry ? normalize(entry.type).indexOf("BRW") === 0 : false;
+
+ function rect(x, y, w, h, rx, fill, stroke, sw) {
+ const r = document.createElementNS(NS, "rect");
+ r.setAttribute("x", x); r.setAttribute("y", y);
+ r.setAttribute("width", w); r.setAttribute("height", h);
+ r.setAttribute("rx", rx);
+ if (fill) r.setAttribute("fill", fill);
+ if (stroke) r.setAttribute("stroke", stroke);
+ r.setAttribute("stroke-width", sw || 1);
+ return r;
+ }
+ function txt(x, y, s, size, fill, weight) {
+ const t = document.createElementNS(NS, "text");
+ t.setAttribute("x", x); t.setAttribute("y", y);
+ t.setAttribute("text-anchor", "middle");
+ t.setAttribute("style", "font-size:" + size + "px; fill:" + fill + ";" + (weight ? " font-weight:" + weight + ";" : ""));
+ t.textContent = s;
+ return t;
+ }
+ function edge(x1, y1, x2, y2, dashed, label, ldy) {
+ const l = document.createElementNS(NS, "line");
+ l.setAttribute("x1", x1); l.setAttribute("y1", y1);
+ l.setAttribute("x2", x2); l.setAttribute("y2", y2);
+ l.setAttribute("stroke", dashed ? "var(--kt-ai-fg-muted)" : "var(--vibe-accent)");
+ l.setAttribute("stroke-width", "1.6");
+ if (dashed) l.setAttribute("stroke-dasharray", "5 4");
+ l.setAttribute("marker-end", "url(#arrow" + (dashed ? "M" : "A") + ")");
+ l.setAttribute("opacity", "0.85");
+ svg.appendChild(l);
+ if (label) {
+ const t = document.createElementNS(NS, "text");
+ t.setAttribute("x", (x1 + x2) / 2); t.setAttribute("y", ((y1 + y2) / 2) + (ldy || -7));
+ t.setAttribute("text-anchor", "middle");
+ t.setAttribute("style", "font-size:10px; fill:var(--kt-ai-fg-muted)");
+ t.textContent = label;
+ svg.appendChild(t);
+ }
+ }
+
+ const defs = document.createElementNS(NS, "defs");
+ defs.innerHTML = '
';
+ svg.appendChild(defs);
+
+ edge(215, 60, 390, 170);
+ edge(385, 60, 530, 170);
+ edge(560, 204, 620, 266);
+ if (hasBrw) {
+ edge(695, 300, 656, 334);
+ }
+ edge(620, 300, 350, 335, true, "резерв при недоступности SIP", -7);
+
+ const boxFill = "var(--kt-ai-card-bg)";
+ const bStroke = "var(--kt-ai-border)";
+
+ // Мобильные операторы
+ svg.appendChild(rect(50, 32, 165, 56, 10, boxFill, bStroke));
+ svg.appendChild(txt(132, 56, "Мобильные", 14, "var(--kt-ai-fg)", 600));
+ svg.appendChild(txt(132, 73, "операторы", 14, "var(--kt-ai-fg)", 600));
+ // ГТС
+ svg.appendChild(rect(220, 32, 165, 56, 10, boxFill, bStroke));
+ svg.appendChild(txt(302, 63, "ГТС", 15, "var(--kt-ai-fg)", 600));
+ // SSW/NGN транзит
+ svg.appendChild(rect(390, 170, 170, 56, 10, boxFill, bStroke));
+ svg.appendChild(txt(475, 193, "SSW/NGN транзит", 14, "var(--kt-ai-fg)", 600));
+ svg.appendChild(txt(475, 210, "транзитная шлюзовая система", 11, "var(--kt-ai-fg-muted)"));
+ // SSW/NGN рег.
+ svg.appendChild(rect(550, 266, 170, 56, 10, boxFill, bStroke));
+ svg.appendChild(txt(635, 289, "SSW/NGN рег.", 14, "var(--kt-ai-fg)", 600));
+ svg.appendChild(txt(635, 306, "региональная маршрутизация", 11, "var(--kt-ai-fg-muted)"));
+ // Резерв
+ svg.appendChild(rect(200, 335, 150, 56, 10, "var(--kt-ai-bg)", bStroke));
+ svg.appendChild(txt(275, 358, "SIP Trunk (резерв)", 12, "var(--kt-ai-fg)", 600));
+ svg.appendChild(txt(275, 375, "7272222222 · ГТС Алматы", 11, "var(--kt-ai-fg-muted)"));
+ // Оконечный номер
+ svg.appendChild(rect(700, 335, 190, 56, 10, "var(--kt-ai-bg)", hasBrw ? "var(--vibe-accent)" : bStroke, hasBrw ? 2 : 1));
+ svg.appendChild(txt(795, 358, "Оконечный номер", 13, "var(--kt-ai-fg)", 600));
+ svg.appendChild(txt(795, 375, endNum, 12, "var(--vibe-accent)", 600));
+ // BRW SIP
+ if (hasBrw) {
+ svg.appendChild(rect(450, 335, 205, 56, 10, boxFill, bStroke));
+ svg.appendChild(txt(552, 358, "BRW SIP", 14, "var(--kt-ai-fg)", 600));
+ svg.appendChild(txt(552, 375, "7273130333", 12, "var(--kt-ai-fg-muted)", 600));
+ const l1 = document.createElementNS(NS, "line");
+ l1.setAttribute("x1", 655); l1.setAttribute("y1", 363);
+ l1.setAttribute("x2", 695); l1.setAttribute("y2", 363);
+ l1.setAttribute("stroke", "var(--vibe-accent)");
+ l1.setAttribute("stroke-width", "1.6");
+ l1.setAttribute("marker-end", "url(#arrowA)");
+ l1.setAttribute("opacity", "0.85");
+ svg.appendChild(l1);
+ }
+
+ const el = document.getElementById("schemeSvg");
+ el.innerHTML = "";
+ el.appendChild(svg);
+ }
+
document.addEventListener("DOMContentLoaded", function () {
renderRegister();
+ renderScheme("727103");
const input = document.getElementById("num");
const btn = document.getElementById("findBtn");
btn.addEventListener("click", function () { show(input.value); });