/** * Matrix Cycling Blog - Data Store & Post Scheduler * Tailored for MatrixHasYou // Ulyanovsk (Volga), Aspect Air 2025 29" MTB, Books, Gym, Tennis, Journal. */ window.MatrixStore = (function () { const STORAGE_KEY_POSTS = "matrix_cycling_posts_v6"; const STORAGE_KEY_PHOTOS = "matrix_cycling_photos_v6"; const DEFAULT_NOTES = [ { "id": "note-aspect-specs-001", "type": "note", "category": "howto", "title": "πŸš΄β€β™‚οΈ Π’Π’Π₯ ΠΌΠΎΠ΅Π³ΠΎ вСлосипСда: Aspect Air 29\" (2025) β€” ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΌΠ°Π½ΡƒΠ°Π», стандарты ΠΈ расходники", "date": "2026-08-24T00:30:00.000Z", "publishAt": "2026-08-24T00:30:00.000Z", "status": "published", "heroImage": "images/aspect_matrix_bridge.jpg", "tags": [ "aspect_air_2025", "29er", "mtb_specs", "shimano_cues", "ulyanovsk", "matrix" ], "telemetry": { "distance": "1x9 Shimano CUES", "avgSpeed": "Sunshine 11-46T 9S", "elevation": "Prowheel 34T (24mm)", "watts": "EXSHO Air 100mm (34mm)" }, "content": `Полная тСхничСская спСцификация, стандарты ΡƒΠ·Π»ΠΎΠ², Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ расходников ΠΈ гСомСтрия Π½Π°ΠΉΠ½Π΅Ρ€Π° **Aspect Air 29" (2025)**. Π­Ρ‚ΠΎΡ‚ ΠΌΠ°Π½ΡƒΠ°Π» слуТит эталонным справочником ΠΏΠΎ всСм ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌ для обслуТивания, ВО ΠΈ быстрого ΠΏΠΎΠ΄Π±ΠΎΡ€Π° запчастСй ΠΏΡ€ΠΈ Ρ€Π΅ΠΌΠΎΠ½Ρ‚Π΅. --- ### 1. βš™οΈ Врансмиссия ΠΈ ΠŸΡ€ΠΈΠ²ΠΎΠ΄ (Drivetrain) * **ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ:** \`1x9\` скоростСй * **Π—Π°Π΄Π½ΠΈΠΉ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Ρ‚Π΅Π»ΡŒ:** \`Shimano CUES RD-U4000\` (с Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠ΅ΠΉ Shadow RD, прямая ΠΏΠΎΠ΄Π²ΠΎΠ΄ΠΊΠ° троса) * **ΠœΠ°Π½Π΅Ρ‚ΠΊΠ° ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ:** \`Shimano CUES SL-U4000\` (тСхнология 2-Way Release) * **БистСма ΡˆΠ°Ρ‚ΡƒΠ½ΠΎΠ²:** \`PROWHEEL C10Y-NW 34T\` с ΠΏΠΎΠ»Ρ‹ΠΌ Π²Π°Π»ΠΎΠΌ **Ø24 ΠΌΠΌ** (Hollowtech II совмСстимый стандарт) * Π”Π»ΠΈΠ½Π° ΡˆΠ°Ρ‚ΡƒΠ½ΠΎΠ²: **175 ΠΌΠΌ** (для Ρ€Π°ΠΌ M / L / XL) / **170 ΠΌΠΌ** (для Ρ€Π°ΠΌΡ‹ S) * Π—Π²Π΅Π·Π΄Π°: **34 Π·ΡƒΠ±Π° (34T)**, ΠΏΡ€ΠΎΡ„ΠΈΠ»ΡŒ **Narrow-Wide** (Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ спадания Ρ†Π΅ΠΏΠΈ) * **ΠšΠ°Ρ€Π΅Ρ‚ΠΊΠ°:** РСзьбовая \`BSA 68/73 ΠΌΠΌ\` (B902 / внСшниС ΠΏΡ€ΠΎΠΌΡ‹ΡˆΠ»Π΅Π½Π½Ρ‹Π΅ подшипники ΠΏΠΎΠ΄ Π²Π°Π» 24 ΠΌΠΌ) * **ΠšΠ°ΡΡΠ΅Ρ‚Π°:** \`Sunshine MTB-CS-HR9-46 9S\` (Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ **11-46T**: Π·Π²Π΅Π·Π΄Ρ‹ 11-13-16-20-24-28-34-40-46) * **Π‘Π°Ρ€Π°Π±Π°Π½ Π²Ρ‚ΡƒΠ»ΠΊΠΈ:** Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ \`Shimano HG (HyperGlide)\` * **ЦСпь:** \`KMC XGLIDE\` (9 скоростСй, Π·Π°ΠΌΠΎΠΊ Π±Ρ‹ΡΡ‚Ρ€ΠΎΡΡŠΠ΅ΠΌΠ½Ρ‹ΠΉ) --- ### 2. πŸ›ž КолСса, Обода ΠΈ ΠŸΠΎΠΊΡ€Ρ‹ΡˆΠΊΠΈ (Wheelset) * **Π Π°Π·ΠΌΠ΅Ρ€ колСс:** \`29 дюймов (622 ΠΌΠΌ)\` * **Обода:** \`Code D23race\` β€” Π΄Π²ΠΎΠΉΠ½Ρ‹Π΅ Π°Π»ΡŽΠΌΠΈΠ½ΠΈΠ΅Π²Ρ‹Π΅, **Tubeless Ready** (Π³ΠΎΡ‚ΠΎΠ²Ρ‹ ΠΏΠΎΠ΄ Π±Π΅ΡΠΊΠ°ΠΌΠ΅Ρ€Π½ΡƒΡŽ установку), ETRTO \`622 x 23 ΠΌΠΌ\`, 32 спицы (32H), ниппСль **Presta (FV)** * **ΠŸΠ΅Ρ€Π΅Π΄Π½ΡΡ Π²Ρ‚ΡƒΠ»ΠΊΠ°:** \`Code H1.2\` (Π°Π»ΡŽΠΌΠΈΠ½ΠΈΠ΅Π²Ρ‹ΠΉ корпус Π½Π° 2 ΠΏΡ€ΠΎΠΌΡ‹ΡˆΠ»Π΅Π½Π½Ρ‹Ρ… ΠΏΠΎΠ΄ΡˆΠΈΠΏΠ½ΠΈΠΊΠ°Ρ…, стандарт **Boost 15x110 ΠΌΠΌ** Π½Π° сквозной оси) * **Задняя Π²Ρ‚ΡƒΠ»ΠΊΠ°:** \`Code H1.2\` (Π°Π»ΡŽΠΌΠΈΠ½ΠΈΠ΅Π²Ρ‹ΠΉ корпус Π½Π° 4 ΠΏΡ€ΠΎΠΌΡ‹ΡˆΠ»Π΅Π½Π½Ρ‹Ρ… ΠΏΠΎΠ΄ΡˆΠΈΠΏΠ½ΠΈΠΊΠ°Ρ…, стандарт **Boost 12x148 ΠΌΠΌ** Π½Π° сквозной оси, Π±Π°Ρ€Π°Π±Π°Π½ HG) * **ΠŸΠΎΠΊΡ€Ρ‹ΡˆΠΊΠΈ:** \`Kenda Booster K1227 Skinwall 29x2.25"\` (ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ накатистый XC-ΠΏΡ€ΠΎΡ‚Π΅ΠΊΡ‚ΠΎΡ€ со свСтлым Π±ΠΎΡ€Ρ‚ΠΎΠΌ) * **Π Π°Π±ΠΎΡ‡Π΅Π΅ Π΄Π°Π²Π»Π΅Π½ΠΈΠ΅ шин:** * Π“Ρ€ΡƒΠ½Ρ‚ / ΠšΠΎΡ€Π½ΠΈ / ПСсок: **1.8–1.9 Π±Π°Ρ€ (26–28 PSI)** * ΠΡΡ„Π°Π»ΡŒΡ‚ / Π’Π²Π΅Ρ€Π΄ΠΎΠ΅ ΠΏΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅: **2.0–2.2 Π±Π°Ρ€ (29–32 PSI)** --- ### 3. πŸ”± Амортизационная Π²ΠΈΠ»ΠΊΠ° (Suspension Fork) * **МодСль:** \`EXSHO FIX 15 AIR / HLO / REB\` * **Π’ΠΈΠΏ:** Π’ΠΎΠ·Π΄ΡƒΡˆΠ½ΠΎ-масляная (Air Spring) * **Π₯ΠΎΠ΄ Π²ΠΈΠ»ΠΊΠΈ:** **100 ΠΌΠΌ** * **Ось:** Бквозная **Boost 15x110 ΠΌΠΌ** * **Ноги:** Анодированный Π°Π»ΡŽΠΌΠΈΠ½ΠΈΠ΅Π²Ρ‹ΠΉ сплав, Π΄ΠΈΠ°ΠΌΠ΅Ρ‚Ρ€ **Ø34 ΠΌΠΌ** (ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½Π½Π°Ρ торсионная ΠΆΠ΅ΡΡ‚ΠΊΠΎΡΡ‚ΡŒ) * **Π‘ΡƒΡˆΠΈΠ½Π³ΠΈ:** ΠœΠ΅Ρ‚Π°Π»Π»ΠΎ-Ρ‚Π΅Ρ„Π»ΠΎΠ½ΠΎΠ²Ρ‹Π΅ ΡΠΊΠΎΠ»ΡŒΠ·ΡΡ‰ΠΈΠ΅ Π½Π°ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ * **Π Π΅Π³ΡƒΠ»ΠΈΡ€ΠΎΠ²ΠΊΠΈ:** 1. *Π’ΠΎΠ·Π΄ΡƒΡˆΠ½Π°Ρ ΠΊΠ°ΠΌΠ΅Ρ€Π° (Air Preload)* β€” Π½Π°ΠΊΠ°Ρ‡ΠΊΠ° насосом высокого давлСния ΠΏΠΎΠ΄ вСс Ρ€Π°ΠΉΠ΄Π΅Ρ€Π° 2. *Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° (HLO - Hydraulic Lockout)* β€” Ρ„Π»Π°ΠΆΠΎΠΊ Π½Π° ΠΊΠΎΡ€ΠΎΠ½Π΅ Π²ΠΈΠ»ΠΊΠΈ 3. *Π Π΅Π³ΡƒΠ»ΠΈΡ€ΠΎΠ²ΠΊΠ° отскока (Rebound)* β€” ΠΊΡ€ΡƒΡ‚ΠΈΠ»ΠΊΠ° Π² Π½ΠΈΠΆΠ½Π΅ΠΉ части ΠΏΡ€Π°Π²ΠΎΠΉ Π½ΠΎΠ³ΠΈ --- ### 4. πŸ›‘ Вормозная систСма (Braking System) * **Π’ΠΎΡ€ΠΌΠΎΠ·Π°:** \`Shimano MT200\` β€” Π΄Π²ΡƒΡ…ΠΏΠΎΡ€ΡˆΠ½Π΅Π²Π°Ρ Π³ΠΈΠ΄Ρ€Π°Π²Π»ΠΈΠΊΠ° Π½Π° ΠΌΠΈΠ½Π΅Ρ€Π°Π»ΡŒΠ½ΠΎΠΌ маслС Shimano Mineral Oil * **ΠšΡ€Π΅ΠΏΠ»Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π½Π΅Π³ΠΎ ΠΊΠ°Π»ΠΈΠΏΠ΅Ρ€Π°:** \`Post Mount (PM)\` Π²Π½ΡƒΡ‚Ρ€ΠΈ Π·Π°Π΄Π½Π΅Π³ΠΎ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ° Π½Π° Π½ΠΈΠΆΠ½Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ (Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ ΡƒΠ΄Π°Ρ€ΠΎΠ²) * **ΠŸΠ΅Ρ€Π΅Π΄Π½ΠΈΠΉ Ρ€ΠΎΡ‚ΠΎΡ€:** \`RPT-009 Ø180 ΠΌΠΌ\` (6 Π±ΠΎΠ»Ρ‚ΠΎΠ²) * **Π—Π°Π΄Π½ΠΈΠΉ Ρ€ΠΎΡ‚ΠΎΡ€:** \`RPT-009 Ø160 ΠΌΠΌ\` (6 Π±ΠΎΠ»Ρ‚ΠΎΠ²) * **Π’ΠΎΡ€ΠΌΠΎΠ·Π½Ρ‹Π΅ ΠΊΠΎΠ»ΠΎΠ΄ΠΊΠΈ:** \`B01S / B03S / B05S Resin (органичСскиС)\` --- ### 5. πŸ“ Π Π°ΠΌΠ°, Π ΡƒΠ»Π΅Π²ΠΎΠ΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΈ ΠšΠΎΠΊΠΏΠΈΡ‚ (Frame & Cockpit) * **ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» Ρ€Π°ΠΌΡ‹:** \`Alloy 6061\` (Π³ΠΈΠ΄Ρ€ΠΎΡ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Ρ‚Ρ€ΡƒΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ сСчСния, Π΄Π²ΠΎΠΉΠ½ΠΎΠΉ Π±Π°Ρ‚Ρ‚ΠΈΠ½Π³, ΠΏΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΡˆΠ²Ρ‹ *Smooth Welding*) * **Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Ρ‹ Ρ€Π°ΠΌΡ‹:** Π”Ρ€ΠΎΠΏΠ°ΡƒΡ‚Ρ‹ ΠΏΠΎΠ΄ ΡΠΊΠ²ΠΎΠ·Π½ΡƒΡŽ ось **Boost 12x148 ΠΌΠΌ**, скрытая внутрСнняя ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΊΠ° тросов ΠΈ Π³ΠΈΠ΄Ρ€ΠΎΠ»ΠΈΠ½ΠΈΠΉ (*IHR / Silent Cables*) * **РулСвая ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ°:** \`Gineyea T05 52-52/39.8\` (полуинтСгрированная Π½Π° Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… ΠΏΡ€ΠΎΠΌΠΏΠΎΠ΄ΡˆΠΈΠΏΠ½ΠΈΠΊΠ°Ρ… ΠΏΠΎΠ΄ конусный ΡˆΡ‚ΠΎΠΊ 1.5"-1.5") * **Π ΡƒΠ»ΡŒ:** \`Code-802 Alloy\` β€” Π΄ΠΈΠ°ΠΌΠ΅Ρ‚Ρ€ ΠΏΠΎΠ΄ вынос **Ø31.8 ΠΌΠΌ**, ΡˆΠΈΡ€ΠΈΠ½Π° **760 ΠΌΠΌ**, подъСм 15 ΠΌΠΌ, Π·Π°Π³ΠΈΠ± Π½Π°Π·Π°Π΄ 6Β° * **Вынос руля:** \`Code AS-002N Alloy\` (ΡƒΠ³ΠΎΠ» 0Β°, Π΄Π»ΠΈΠ½Π° 60 ΠΌΠΌ ΠΏΠΎΠ΄ Ρ€Π°ΠΌΡ‹ M/L, 50 ΠΌΠΌ ΠΏΠΎΠ΄ S, 70 ΠΌΠΌ ΠΏΠΎΠ΄ XL) * **Грипсы:** \`Code G104\` (эргономичный Ρ†Π΅ΠΏΠΊΠΈΠΉ ΠΊΠΎΠΌΠΏΠ°ΡƒΠ½Π΄ с Π°Π»ΡŽΠΌΠΈΠ½ΠΈΠ΅Π²Ρ‹ΠΌ Π·Π°ΠΌΠΊΠΎΠΌ Lock-on) * **ΠŸΠΎΠ΄ΡΠ΅Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΡˆΡ‚Ρ‹Ρ€ΡŒ:** \`Code-609 Alloy\`, Π΄ΠΈΠ°ΠΌΠ΅Ρ‚Ρ€ **Ø31.6 ΠΌΠΌ**, Π΄Π»ΠΈΠ½Π° **400 ΠΌΠΌ**, Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΉ Π΄Π²ΡƒΡ…Π±ΠΎΠ»Ρ‚ΠΎΠ²Ρ‹ΠΉ Π·Π°ΠΌΠΎΠΊ * **Π‘Π΅Π΄Π»ΠΎ:** \`Code-12231\` (Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ **245 x 155 ΠΌΠΌ**, анатомичСский Π²Ρ‹Ρ€Π΅Π· ΠΈ плотная спортивная ΠΏΠ΅Π½Π°) * **ВСс вСлосипСда:** ~**13.4 ΠΊΠ³** (Π² сборС) > [!TIP] Π—Π°ΠΌΠ΅Ρ‚ΠΊΠ° для ВО ΠΈ быстрого Π·Π°ΠΊΠ°Π·Π° расходников: > * **ΠšΠ°ΡΡΠ΅Ρ‚Π°:** 9 скоростСй, Π±Π°Ρ€Π°Π±Π°Π½ HG, Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ 11-46T. > * **ЦСпь:** 9-speed KMC / Shimano (116 звСньСв). > * **Колодки:** Shimano B05S Resin. > * **НиппСль:** Presta (FV 48 ΠΌΠΌ). > * **Оси:** ΠŸΠ΅Ρ€Π΅Π΄ 15x110 Boost, Π—Π°Π΄ 12x148 Boost.` } ]; const DEFAULT_PHOTOS = []; // --- Local Storage Management --- function getStoredNotes() { try { const raw = localStorage.getItem(STORAGE_KEY_POSTS); if (raw === null) { localStorage.setItem(STORAGE_KEY_POSTS, JSON.stringify(DEFAULT_NOTES)); return DEFAULT_NOTES; } return JSON.parse(raw); } catch (e) { console.error("Error reading notes from localStorage", e); return DEFAULT_NOTES; } } function saveStoredNotes(notes) { try { localStorage.setItem(STORAGE_KEY_POSTS, JSON.stringify(notes)); } catch (e) { console.error("Error saving notes to localStorage", e); } } function getStoredPhotos() { try { const raw = localStorage.getItem(STORAGE_KEY_PHOTOS); if (raw === null) { localStorage.setItem(STORAGE_KEY_PHOTOS, JSON.stringify(DEFAULT_PHOTOS)); return DEFAULT_PHOTOS; } return JSON.parse(raw); } catch (e) { console.error("Error reading photos from localStorage", e); return DEFAULT_PHOTOS; } } function saveStoredPhotos(photos) { try { localStorage.setItem(STORAGE_KEY_PHOTOS, JSON.stringify(photos)); } catch (e) { console.error("Error saving photos to localStorage", e); } } // --- Public Queries --- function isItemLive(item) { if (!item || item.status === "draft") return false; const pubDate = new Date(item.publishAt || item.date); return pubDate <= new Date(); } function getPublishedNotes(category = null) { const now = new Date(); let notes = getStoredNotes().filter(note => { if (note.status === "draft") return false; const pubDate = new Date(note.publishAt || note.date); return pubDate <= now; }); if (category && category !== "all") { notes = notes.filter(n => n.category === category); } return notes.sort((a, b) => new Date(b.publishAt || b.date) - new Date(a.publishAt || a.date)); } function getAllNotes() { return getStoredNotes().sort((a, b) => new Date(b.date || b.publishAt) - new Date(a.date || a.publishAt)); } function getPublishedPhotos() { const now = new Date(); return getStoredPhotos().filter(photo => { if (photo.status === "draft") return false; const pubDate = new Date(photo.publishAt || photo.date); return pubDate <= now; }).sort((a, b) => new Date(b.publishAt || b.date) - new Date(a.publishAt || a.date)); } function getAllPhotos() { return getStoredPhotos().sort((a, b) => new Date(b.date || b.publishAt) - new Date(a.date || a.publishAt)); } // --- Mutations --- function saveNote(noteData) { const notes = getStoredNotes(); const nowIso = new Date().toISOString(); if (noteData.id) { const index = notes.findIndex(n => n.id === noteData.id); if (index !== -1) { notes[index] = { ...notes[index], ...noteData, updatedAt: nowIso }; } else { notes.unshift({ ...noteData, createdAt: nowIso, updatedAt: nowIso }); } } else { const newId = "note-" + Date.now(); notes.unshift({ id: newId, ...noteData, createdAt: nowIso, updatedAt: nowIso }); } saveStoredNotes(notes); return true; } function deleteNote(id) { let notes = getStoredNotes(); notes = notes.filter(n => n.id !== id); saveStoredNotes(notes); return true; } function savePhoto(photoData) { const photos = getStoredPhotos(); const nowIso = new Date().toISOString(); if (photoData.id) { const index = photos.findIndex(p => p.id === photoData.id); if (index !== -1) { photos[index] = { ...photos[index], ...photoData, updatedAt: nowIso }; } else { photos.unshift({ ...photoData, createdAt: nowIso, updatedAt: nowIso }); } } else { const newId = "photo-" + Date.now(); photos.unshift({ id: newId, ...photoData, createdAt: nowIso, updatedAt: nowIso }); } saveStoredPhotos(photos); return true; } function deletePhoto(id) { let photos = getStoredPhotos(); photos = photos.filter(p => p.id !== id); saveStoredPhotos(photos); return true; } function exportDatabase() { return JSON.stringify({ version: "6.0", exportedAt: new Date().toISOString(), notes: getStoredNotes(), photos: getStoredPhotos() }, null, 2); } function importDatabase(jsonString) { try { const data = JSON.parse(jsonString); if (Array.isArray(data.notes)) saveStoredNotes(data.notes); if (Array.isArray(data.photos)) saveStoredPhotos(data.photos); return true; } catch (e) { console.error("Import failed", e); return false; } } return { isItemLive, getLiveNotes: getPublishedNotes, getPublishedNotes, getAllNotes, getAllNotesForAdmin: getAllNotes, getLivePhotos: getPublishedPhotos, getPublishedPhotos, getAllPhotos, getAllPhotosForAdmin: getAllPhotos, saveNote, deleteNote, savePhoto, deletePhoto, exportDatabase, importDatabase }; })();