// Section components for DataLoop landing const { useState, useEffect, useRef, useMemo } = React; // -- LOGO MARK ------------------------------------------------ function LogoMark({ size = 28 }) { return ( ); } // -- NAV ------------------------------------------------------ function Nav({ direction }) { const [open, setOpen] = useState(false); // close drawer on hash navigation or window resize past mobile breakpoint useEffect(() => { function onResize() { if (window.innerWidth > 880) setOpen(false); } window.addEventListener("resize", onResize); return () => window.removeEventListener("resize", onResize); }, []); // lock body scroll while drawer is open useEffect(() => { document.body.style.overflow = open ? "hidden" : ""; return () => { document.body.style.overflow = ""; }; }, [open]); const links = [ { href: "#suggest", label: "Подсказки" }, { href: "#api", label: "API" }, { href: "#map", label: "Геокодинг" }, { href: "#features", label: "Возможности" }, { href: "#pricing", label: "Тарифы" }, { href: "cabinet.html", label: "Кабинет" }, ]; return ( ); } // -- HERO ----------------------------------------------------- function Hero({ children, direction }) { return (
v3 · API очистки адресов

Адреса{" "} под ключ
для ваших форм{" "} и баз.

Подсказки по ФИАС, нормализация, геокодинг и обратное преобразование координат — одной строкой кода. SDK для шести языков, бесплатные 10 000 запросов в день.

Открыть песочницу → Документация API
28 мс медиана ответа
1.7 М населённых пунктов
10 000 запросов/сутки бесплатно
{children}
); } // -- SAGGEST WIDGET ------------------------------------------- function Saggest({ onSelect }) { const { ADDRESSES } = window.__DATA; const [q, setQ] = useState("тверская 12"); const [active, setActive] = useState(0); const [focus, setFocus] = useState(false); const matches = useMemo(() => { if (!q.trim()) return ADDRESSES.slice(0, 5); const lower = q.toLowerCase(); const scored = ADDRESSES.map((a) => { const t = a.full.toLowerCase(); let score = 0; lower.split(/\s+/).forEach((tok) => { if (tok && t.includes(tok)) score += 10 + tok.length; }); if (t.startsWith(lower)) score += 30; return { a, score }; }); return scored .filter((s) => s.score > 0) .sort((x, y) => y.score - x.score) .slice(0, 5) .map((s) => s.a); }, [q]); useEffect(() => { setActive(0); }, [q]); function highlight(text) { if (!q.trim()) return text; const toks = q.toLowerCase().split(/\s+/).filter(Boolean); let parts = [{ t: text, hl: false }]; toks.forEach((tok) => { const next = []; parts.forEach((p) => { if (p.hl) { next.push(p); return; } const idx = p.t.toLowerCase().indexOf(tok); if (idx === -1) { next.push(p); return; } next.push({ t: p.t.slice(0, idx), hl: false }); next.push({ t: p.t.slice(idx, idx + tok.length), hl: true }); next.push({ t: p.t.slice(idx + tok.length), hl: false }); }); parts = next; }); return parts.map((p, i) => p.hl ? {p.t} : {p.t}); } return (
POST /v1/suggest/address
→ Введите начало адреса
setQ(e.target.value)} onFocus={() => setFocus(true)} onBlur={() => setFocus(false)} onKeyDown={(e) => { if (e.key === "ArrowDown") { e.preventDefault(); setActive((a) => Math.min(matches.length - 1, a + 1)); } if (e.key === "ArrowUp") { e.preventDefault(); setActive((a) => Math.max(0, a - 1)); } if (e.key === "Enter" && matches[active]) { setQ(matches[active].full); onSelect && onSelect(matches[active]); } }} placeholder="например: тверская 12" aria-label="Адрес" />
{matches.length === 0 && (
// нет совпадений · попробуйте другой запрос
)} {matches.map((a, i) => (
setActive(i)} onClick={() => { setQ(a.full); onSelect && onSelect(a); }} >
{String(i + 1).padStart(2, "0")}
{highlight(a.full)}
{a.postal} · {a.fias.slice(0, 18)} · {a.lat.toFixed(4)}, {a.lon.toFixed(4)}
))}
навигация {" "} выбор {matches.length} результат(ов) · 14 мс
); } // -- API CODE BLOCK (moved to api-block.jsx) -------------------- function ApiBlockLegacy_UNUSED() { const { CODE_SAMPLES } = window.__DATA; const [tab, setTab] = useState("curl"); const [copied, setCopied] = useState(false); const tabs = [ { k: "curl", l: "cURL" }, { k: "js", l: "Node.js" }, { k: "python", l: "Python" }, { k: "go", l: "Go" }, ]; const lines = CODE_SAMPLES[tab]; function copy() { setCopied(true); setTimeout(() => setCopied(false), 1400); } return (
{tabs.map((t) => ( ))}
{lines.map((ln, i) => ( {ln.c && {ln.c}} {ln.t} {ln.end && {ln.end}} ))}
Ответ · 200 OK ↘ 14 мс
{"{"} "suggestions": [ {"{"} "value": "г Москва, ул Тверская, д 12 стр 9", "unrestricted": "125009, г Москва, ул Тверская, д 12 стр 9", "data": {"{"} "postal_code": "125009", "region": "Москва", "city": "Москва", "street": "Тверская", "house": "12 стр 9", "fias_id": "8da95206-5d3a-...", "geo_lat": 55.7616, "geo_lon": 37.6062, "qc": 0 // точность: дом {"}"} {"}"} ] {"}"}
); } // -- MAP / GEO (moved to map-block.jsx) ----------------------- function MapBlockLegacy_UNUSED() { const { MAP_PINS } = window.__DATA; const [active, setActive] = useState(MAP_PINS[1]); const [mouse, setMouse] = useState({ x: 50, y: 50, lat: 55.7558, lon: 37.6173 }); const canvasRef = useRef(null); function onMove(e) { const r = canvasRef.current.getBoundingClientRect(); const x = ((e.clientX - r.left) / r.width) * 100; const y = ((e.clientY - r.top) / r.height) * 100; // synthesise lat/lon from x,y (just for display) const lat = 65 - (y / 100) * 25; const lon = 30 + (x / 100) * 110; setMouse({ x, y, lat, lon }); } const a = active.addr; return (
{/* stylised russia silhouette */} {/* a loose russia-like outline (decorative) */} {/* connecting line to selected pin */} {MAP_PINS.map((p) => ( ))} {MAP_PINS.map((p) => ( ))}
курсор: {mouse.lat.toFixed(4)}, {mouse.lon.toFixed(4)} {" "} · ↓ POST /v1/geocode/reverse
→ Точка {active.label} · обратный геокодинг
{a.full}
Регион
{a.region}
Город
{a.city}
Индекс
{a.postal}
ОКАТО
{a.okato}
Широта
{a.lat.toFixed(6)}
Долгота
{a.lon.toFixed(6)}
ФИАС
{a.fias}
); } // -- FEATURES ------------------------------------------------- function FeatureIcon({ kind }) { const props = { width: 22, height: 22, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.6 }; switch (kind) { case "suggest": return ; case "geocode": return ; case "reverse": return ; case "norm": return ; case "hier": return ; case "fuzzy": return ; case "batch": return ; case "fias": return ; case "sla": return ; default: return null; } } function FeaturesLegacy_UNUSED() { const items = [ { k: "suggest", t: "Подсказки на лету", d: "Авто-дополнение от региона до квартиры, разрезано на токены и нормализовано. До 25 подсказок за 14 мс.", tag: "/suggest" }, { k: "geocode", t: "Прямой геокодинг", d: "Адрес → координаты с точностью до подъезда. Покрытие 1.7 М населённых пунктов РФ.", tag: "/geocode" }, { k: "reverse", t: "Обратный геокодинг", d: "Координаты → структурированный адрес ФИАС. Возвращаем 32 поля включая ОКАТО, ОКТМО, индекс.", tag: "/reverse" }, { k: "norm", t: "Нормализация ФИАС", d: "Распарсенные части адреса: регион, город, улица, дом, квартира. Сокращения по ФИАС.", tag: "/parse" }, { k: "fuzzy", t: "Поиск с опечатками", d: "Fuzzy-матчинг по двойной метафонии. \"Тверска 12\" найдёт Тверскую без проблем.", tag: "/fuzzy" }, { k: "fias", t: "Актуальные базы", d: "Ежесуточная синхронизация с ФИАС, КЛАДР, ЕГРЮЛ. Гарантия свежести данных.", tag: "ФИАС/КЛАДР" }, { k: "batch", t: "Пакетная обработка", d: "До 50 000 адресов за один батч-запрос, CSV/JSONL на входе и выходе.", tag: "/batch" }, { k: "hier", t: "Дерево адресов", d: "Иерархия от субъекта РФ до квартиры. Удобно для каталогов и отчётности.", tag: "/tree" }, { k: "sla", t: "SLA 99.99%", d: "Два дата-центра в Москве и Питере, гео-резервирование, мониторинг 24/7.", tag: "SLA" }, ]; return (
{items.map((it, i) => (
{it.tag}

{it.t}

{it.d}

))}
); } // -- STATS ---------------------------------------------------- function Stats() { const items = [ { num: "28", unit: "мс", label: "медианное время ответа" }, { num: "1.7", unit: "М", label: "населённых пунктов" }, { num: "99.99", unit: "%", label: "годовая доступность" }, { num: "240", unit: "млрд", label: "запросов обработано" }, ]; return (
{items.map((s, i) => (
{s.num}{s.unit}
{s.label}
))}
); } // -- MARQUEE -------------------------------------------------- function Marquee() { const words = ["ФИАС", "КЛАДР", "ЕГРЮЛ", "Геокодинг", "Suggest", "Нормализация", "Batch", "Webhooks", "SDK"]; const items = [...words, ...words]; return (
{items.map((w, i) =>
{w}
)}
); } // -- PRICING (replaced by calculator.jsx) --------------------- function PricingLegacy_UNUSED() { const tiers = [ { name: "Старт", price: "0", per: "₽/мес", meta: "Для пет-проектов и проверки гипотез", cta: "Создать ключ", feats: [ "10 000 запросов в сутки", "Подсказки + нормализация", "Прямой и обратный геокодинг", "SDK для всех языков", "Только публичный rate-limit", ], }, { name: "Прод", price: "9 800", per: "₽/мес", meta: "Боевой продакшен · оплата помесячно", popular: true, cta: "Подключить тариф", feats: [ "500 000 запросов в сутки", "SLA 99.95%, ответ < 50 мс", "Пакетная обработка batch", "Webhooks и стриминг", "Поддержка в Telegram · 4 ч", ], }, { name: "Энтерпрайз", price: "по запросу", per: "", meta: "Свой контур, банки и госсектор", cta: "Связаться", feats: [ "On-premise установка", "Персональный SLA до 99.99%", "Юр.лицо РФ · договор · акты", "Выделенный аккаунт-менеджер", "Аудит ИБ и пентест", ], }, ]; return (
{tiers.map((t, i) => (
{t.popular &&
★ выбор большинства
}
{t.name}
{t.price === "по запросу" ? ( по запросу ) : ( <> {t.price} {t.per} )}
{t.meta}
))}
); } // -- USE CASES (removed) -------------------------------------- function UseCasesLegacy_UNUSED() { const cases = [ { n: "01", t: "E-commerce и доставка", d: "Подсказки при оформлении заказа сокращают долю неверных адресов на 78%. Меньше брошенных корзин, меньше возвратов с курьерами." }, { n: "02", t: "Финтех и КYC", d: "Нормализация под ФИАС, валидация паспортных регионов, готовая выгрузка для отчётности в ЦБ. Соответствие 115-ФЗ из коробки." }, { n: "03", t: "CRM и аналитика", d: "Геокодирование клиентской базы для тепловых карт и сегментации. Иерархия адресов для отчётов по регионам и федеральным округам." }, { n: "04", t: "Госуслуги и подряд", d: "On-premise установка, контур без интернета, выгрузка ФИАС внутри периметра. Опыт интеграций с госсектором и муниципалитетами." }, ]; return (
{cases.map((c, i) => (
{c.n} →

{c.t}

{c.d}

))}
); } // -- CTA ------------------------------------------------------ function Cta() { return (
ОТКРЫТЬ ПЕСОЧНИЦУ

API уже работает.
Подключите за 4 минуты.

Бесплатные 10 000 запросов в сутки. Карта не нужна. Откройте ключ — и начинайте парсить адреса прямо из терминала.

Создать ключ Прочитать доку
); } // -- FOOTER --------------------------------------------------- function Footer() { return ( ); } Object.assign(window, { Nav, Hero, Saggest, Stats, Marquee, Cta, Footer, LogoMark, });