[{"data":1,"prerenderedAt":25422},["ShallowReactive",2],{"navigation_docs":3,"-react-typescript-custom-hooks":5466,"-react-typescript-custom-hooks-surround":25417},[4,1707,2194,2666,2847,3015,3222,3344,3394,3451,3485,3611,3688,3702,3841,4219,4296,5029,5204,5297,5350,5462],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"C#","i-devicon-csharp","\u002Fcsharp","01.csharp",[10,13,60,90,120,202,219,253,379,404,457,650,1364,1654,1703],{"title":11,"path":7,"stem":12},"C# та .NET","01.csharp\u002Findex",{"title":14,"icon":15,"path":16,"stem":17,"children":18,"page":59},"Fundamentals","i-lucide-book-open","\u002Fcsharp\u002Ffundamentals","01.csharp\u002F01.fundamentals",[19,23,27,31,35,39,43,47,51,55],{"title":20,"path":21,"stem":22},"Вступ до екосистеми .NET","\u002Fcsharp\u002Ffundamentals\u002Fintroduction-to-ecosystem","01.csharp\u002F01.fundamentals\u002F01.introduction-to-ecosystem",{"title":24,"path":25,"stem":26},"Структура програми на C#","\u002Fcsharp\u002Ffundamentals\u002Fprogram-structure","01.csharp\u002F01.fundamentals\u002F02.program-structure",{"title":28,"path":29,"stem":30},"Змінні та Типи Даних","\u002Fcsharp\u002Ffundamentals\u002Fvariables-data-types","01.csharp\u002F01.fundamentals\u002F03.variables-data-types",{"title":32,"path":33,"stem":34},"Масиви","\u002Fcsharp\u002Ffundamentals\u002Farrays","01.csharp\u002F01.fundamentals\u002F04.arrays",{"title":36,"path":37,"stem":38},"Strings & Text Handling","\u002Fcsharp\u002Ffundamentals\u002Fstrings-text-handling","01.csharp\u002F01.fundamentals\u002F05.strings-text-handling",{"title":40,"path":41,"stem":42},"Дати і Час","\u002Fcsharp\u002Ffundamentals\u002Fdates-time-handling","01.csharp\u002F01.fundamentals\u002F06.dates-time-handling",{"title":44,"path":45,"stem":46},"Потік Керування","\u002Fcsharp\u002Ffundamentals\u002Fcontrol-flow","01.csharp\u002F01.fundamentals\u002F07.control-flow",{"title":48,"path":49,"stem":50},"Методи","\u002Fcsharp\u002Ffundamentals\u002Fmethods","01.csharp\u002F01.fundamentals\u002F08.methods",{"title":52,"path":53,"stem":54},"Основи Відлагодження","\u002Fcsharp\u002Ffundamentals\u002Fdebugging-basics","01.csharp\u002F01.fundamentals\u002F09.debugging-basics",{"title":56,"path":57,"stem":58},"Інтерактивна Консоль (Classic)","\u002Fcsharp\u002Ffundamentals\u002Finteractive-console","01.csharp\u002F01.fundamentals\u002F10.interactive-console",false,{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":59},"OOP","i-lucide-box","\u002Fcsharp\u002Foop","01.csharp\u002F02.oop",[66,70,74,78,82,86],{"title":67,"path":68,"stem":69},"Package Management (Управління Пакетами)","\u002Fcsharp\u002Foop\u002Fpackage-management","01.csharp\u002F02.oop\u002F01.package-management",{"title":71,"path":72,"stem":73},"Класи та Об'єкти","\u002Fcsharp\u002Foop\u002Fclasses-objects","01.csharp\u002F02.oop\u002F02.classes-objects",{"title":75,"path":76,"stem":77},"Властивості та Поля","\u002Fcsharp\u002Foop\u002Fproperties-fields","01.csharp\u002F02.oop\u002F03.properties-fields",{"title":79,"path":80,"stem":81},"Стовпи ООП","\u002Fcsharp\u002Foop\u002Foop-pillars","01.csharp\u002F02.oop\u002F04.oop-pillars",{"title":83,"path":84,"stem":85},"Advanced Types","\u002Fcsharp\u002Foop\u002Fadvanced-types","01.csharp\u002F02.oop\u002F05.advanced-types",{"title":87,"path":88,"stem":89},"Namespaces (Простори Імен)","\u002Fcsharp\u002Foop\u002Fnamespaces","01.csharp\u002F02.oop\u002F06.namespaces",{"title":91,"icon":92,"path":93,"stem":94,"children":95,"page":59},"Advanced Core","i-lucide-zap","\u002Fcsharp\u002Fadvanced-core","01.csharp\u002F03.advanced-core",[96,100,104,108,112,116],{"title":97,"path":98,"stem":99},"Generics (Узагальнення)","\u002Fcsharp\u002Fadvanced-core\u002Fgenerics","01.csharp\u002F03.advanced-core\u002F01.generics",{"title":101,"path":102,"stem":103},"Делегати, Події та Лямбда-вирази","\u002Fcsharp\u002Fadvanced-core\u002Fdelegates-events-lambdas","01.csharp\u002F03.advanced-core\u002F02.delegates-events-lambdas",{"title":105,"path":106,"stem":107},"Interfaces Deep Dive (Інтерфейси: Поглиблений Розгляд)","\u002Fcsharp\u002Fadvanced-core\u002Finterfaces-deep-dive","01.csharp\u002F03.advanced-core\u002F03.interfaces-deep-dive",{"title":109,"path":110,"stem":111},"Обробка Винятків","\u002Fcsharp\u002Fadvanced-core\u002Fexception-handling","01.csharp\u002F03.advanced-core\u002F04.exception-handling",{"title":113,"path":114,"stem":115},"Pattern Matching","\u002Fcsharp\u002Fadvanced-core\u002Fpattern-matching","01.csharp\u002F03.advanced-core\u002F05.pattern-matching",{"title":117,"path":118,"stem":119},"Додаткові Можливості C#","\u002Fcsharp\u002Fadvanced-core\u002Fadditional-features","01.csharp\u002F03.advanced-core\u002F06.additional-features",{"title":121,"icon":122,"path":123,"stem":124,"children":125,"page":59},"Architecture Best Practices","i-lucide-building-2","\u002Fcsharp\u002Farchitecture-best-practices","01.csharp\u002F04.architecture-best-practices",[126,130,149,153,157,161,165,169],{"title":127,"path":128,"stem":129},"Software Design Principles (Частина 1)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fsoftware-design-principles","01.csharp\u002F04.architecture-best-practices\u002F01.software-design-principles",{"title":131,"icon":132,"path":133,"stem":134,"children":135,"page":59},"Design Patterns","i-lucide-folder","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns",[136],{"title":137,"icon":132,"path":138,"stem":139,"children":140,"page":59},"Creational","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational",[141,145],{"title":142,"path":143,"stem":144},"Singleton (Одинак)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational\u002Fsingleton","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational\u002F01.singleton",{"title":146,"path":147,"stem":148},"Builder (Будівельник)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational\u002Fbuilder","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational\u002F02.builder",{"title":150,"path":151,"stem":152},"Building Professional CLIs","\u002Fcsharp\u002Farchitecture-best-practices\u002Fbuilding-professional-clis","01.csharp\u002F04.architecture-best-practices\u002F03.building-professional-clis",{"title":154,"path":155,"stem":156},"Validation & Flow Control","\u002Fcsharp\u002Farchitecture-best-practices\u002Fvalidation-flow-control","01.csharp\u002F04.architecture-best-practices\u002F04.validation-flow-control",{"title":158,"path":159,"stem":160},"The Modern .NET Host (Microsoft.Extensions)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fmodern-dotnet-host","01.csharp\u002F04.architecture-best-practices\u002F05.modern-dotnet-host",{"title":162,"path":163,"stem":164},"Data Mapper: Repository та DAO патерни (Частина 1)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdata-mapper-part1","01.csharp\u002F04.architecture-best-practices\u002F06.data-mapper-part1",{"title":166,"path":167,"stem":168},"Data Mapper: Repository та DAO патерни (Частина 2)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdata-mapper-part2","01.csharp\u002F04.architecture-best-practices\u002F07.data-mapper-part2",{"title":170,"icon":132,"path":171,"stem":172,"children":173,"page":59},"Di Ioc","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc",[174,178,182,186,190,194,198],{"title":175,"path":176,"stem":177},"Проблема залежностей та Інверсія Контролю","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fthe-dependency-problem","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F01.the-dependency-problem",{"title":179,"path":180,"stem":181},"Будуємо власний Service Container","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fbuild-your-own-container","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F02.build-your-own-container",{"title":183,"path":184,"stem":185},"Service Locator: Паттерн та Анти-паттерн","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fservice-locator-pattern","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F03.service-locator-pattern",{"title":187,"path":188,"stem":189},"Паттерни Dependency Injection","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fdependency-injection-patterns","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F04.dependency-injection-patterns",{"title":191,"path":192,"stem":193},"Microsoft DI: IServiceCollection та IServiceProvider","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fmicrosoft-di-deep-dive","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F05.microsoft-di-deep-dive",{"title":195,"path":196,"stem":197},"Service Lifetimes та Scopes","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fservice-lifetimes-and-scopes","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F06.service-lifetimes-and-scopes",{"title":199,"path":200,"stem":201},"DI Анти-паттерни та Найкращі Практики","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fdi-anti-patterns-and-best-practices","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F07.di-anti-patterns-and-best-practices",{"title":203,"icon":132,"path":204,"stem":205,"children":206,"page":59},"Standard Library","\u002Fcsharp\u002Fstandard-library","01.csharp\u002F05.standard-library",[207,211,215],{"title":208,"path":209,"stem":210},"Collections (Колекції)","\u002Fcsharp\u002Fstandard-library\u002Fcollections","01.csharp\u002F05.standard-library\u002F01.collections",{"title":212,"path":213,"stem":214},"High Performance Types (Високопродуктивні Типи)","\u002Fcsharp\u002Fstandard-library\u002Fhigh-performance-types","01.csharp\u002F05.standard-library\u002F02.high-performance-types",{"title":216,"path":217,"stem":218},"LINQ (Language Integrated Query)","\u002Fcsharp\u002Fstandard-library\u002Flinq","01.csharp\u002F05.standard-library\u002F03.linq",{"title":220,"icon":221,"path":222,"stem":223,"children":224,"page":59},"System Internals Concurrency","i-lucide-server","\u002Fcsharp\u002Fsystem-internals-concurrency","01.csharp\u002F06.system-internals-concurrency",[225,229,233,237,241,245,249],{"title":226,"path":227,"stem":228},"Memory Management","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fmemory-management","01.csharp\u002F06.system-internals-concurrency\u002F01.memory-management",{"title":230,"path":231,"stem":232},"Reflection API: System.Type та Метадані","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Freflection-fundamentals","01.csharp\u002F06.system-internals-concurrency\u002F02.reflection-fundamentals",{"title":234,"path":235,"stem":236},"Attributes та Dynamic Language Runtime","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fattributes-dynamic","01.csharp\u002F06.system-internals-concurrency\u002F03.attributes-dynamic",{"title":238,"path":239,"stem":240},"Expression Trees: Швидка Альтернатива Рефлексії","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fexpression-trees-compiled","01.csharp\u002F06.system-internals-concurrency\u002F04.expression-trees-compiled",{"title":242,"path":243,"stem":244},"Source Generators: Compile-Time Code Generation","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fsource-generators","01.csharp\u002F06.system-internals-concurrency\u002F05.source-generators",{"title":246,"path":247,"stem":248},"Multithreading Fundamentals","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fmultithreading-fundamentals","01.csharp\u002F06.system-internals-concurrency\u002F06.multithreading-fundamentals",{"title":250,"path":251,"stem":252},"Synchronization Primitives","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fsynchronization-primitives","01.csharp\u002F06.system-internals-concurrency\u002F07.synchronization-primitives",{"title":254,"icon":255,"path":256,"stem":257,"children":258,"page":59},"System Programming Windows","i-lucide-cpu","\u002Fcsharp\u002Fsystem-programming-windows","01.csharp\u002F07.system-programming-windows",[259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327,331,335,339,343,347,351,355,359,363,367,371,375],{"title":260,"path":261,"stem":262},"Як Працює Операційна Система","\u002Fcsharp\u002Fsystem-programming-windows\u002Fhow-os-works","01.csharp\u002F07.system-programming-windows\u002F01.how-os-works",{"title":264,"path":265,"stem":266},"Процеси в .NET — API та Запуск","\u002Fcsharp\u002Fsystem-programming-windows\u002Fprocesses-in-dotnet","01.csharp\u002F07.system-programming-windows\u002F02.processes-in-dotnet",{"title":268,"path":269,"stem":270},"Процеси в .NET — IPC та Міжпроцесна Комунікація","\u002Fcsharp\u002Fsystem-programming-windows\u002F02a.processes-ipc","01.csharp\u002F07.system-programming-windows\u002F02a.processes-ipc",{"title":272,"path":273,"stem":274},"Application Domains та Збірки — AppDomain і AssemblyLoadContext","\u002Fcsharp\u002Fsystem-programming-windows\u002Fappdomains-assemblies","01.csharp\u002F07.system-programming-windows\u002F03.appdomains-assemblies",{"title":276,"path":277,"stem":278},"Application Domains та Збірки — Plug-in Система з Hot-Reload","\u002Fcsharp\u002Fsystem-programming-windows\u002F03a.appdomains-plugin-system","01.csharp\u002F07.system-programming-windows\u002F03a.appdomains-plugin-system",{"title":280,"path":281,"stem":282},"Потоки — Основи та API Thread","\u002Fcsharp\u002Fsystem-programming-windows\u002Fthread-fundamentals","01.csharp\u002F07.system-programming-windows\u002F04.thread-fundamentals",{"title":284,"path":285,"stem":286},"Потоки — Lifecycle, Пріоритети та Безпечне Завершення","\u002Fcsharp\u002Fsystem-programming-windows\u002F04a.thread-lifecycle-priorities","01.csharp\u002F07.system-programming-windows\u002F04a.thread-lifecycle-priorities",{"title":288,"path":289,"stem":290},"Проблеми Спільного Стану — Race Condition та Data Race","\u002Fcsharp\u002Fsystem-programming-windows\u002Fshared-state-problems","01.csharp\u002F07.system-programming-windows\u002F05.shared-state-problems",{"title":292,"path":293,"stem":294},"Проблеми Спільного Стану — Memory Model та volatile","\u002Fcsharp\u002Fsystem-programming-windows\u002F05a.shared-state-memory-model","01.csharp\u002F07.system-programming-windows\u002F05a.shared-state-memory-model",{"title":296,"path":297,"stem":298},"Синхронізація — Monitor, lock та еволюція примітивів","\u002Fcsharp\u002Fsystem-programming-windows\u002Fsynchronization-fundamentals","01.csharp\u002F07.system-programming-windows\u002F06.synchronization-fundamentals",{"title":300,"path":301,"stem":302},"Синхронізація — Наскрізний Приклад та Deadlock Detection","\u002Fcsharp\u002Fsystem-programming-windows\u002F06a.synchronization-walkthrough","01.csharp\u002F07.system-programming-windows\u002F06a.synchronization-walkthrough",{"title":304,"path":305,"stem":306},"Синхронізація — Mutex, Semaphore та Event-Based Primitives","\u002Fcsharp\u002Fsystem-programming-windows\u002Fsynchronization-advanced","01.csharp\u002F07.system-programming-windows\u002F07.synchronization-advanced",{"title":308,"path":309,"stem":310},"Синхронізація — Interlocked, Volatile та Lock-Free Структури","\u002Fcsharp\u002Fsystem-programming-windows\u002F07a.synchronization-advanced-walkthrough","01.csharp\u002F07.system-programming-windows\u002F07a.synchronization-advanced-walkthrough",{"title":312,"path":313,"stem":314},"Interlocked, CAS та Lock-Free Структури","\u002Fcsharp\u002Fsystem-programming-windows\u002Finterlocked-cas-lockfree","01.csharp\u002F07.system-programming-windows\u002F08.interlocked-cas-lockfree",{"title":316,"path":317,"stem":318},"Volatile, Memory Model та Spinning","\u002Fcsharp\u002Fsystem-programming-windows\u002F08a.volatile-memory-model","01.csharp\u002F07.system-programming-windows\u002F08a.volatile-memory-model",{"title":320,"path":321,"stem":322},"ThreadPool — Пул Потоків для Ефективного Виконання","\u002Fcsharp\u002Fsystem-programming-windows\u002Fthread-pool","01.csharp\u002F07.system-programming-windows\u002F09.thread-pool",{"title":324,"path":325,"stem":326},"ThreadPool — Просунуті Сценарії та Внутрішня Будова","\u002Fcsharp\u002Fsystem-programming-windows\u002F09a.thread-pool-advanced","01.csharp\u002F07.system-programming-windows\u002F09a.thread-pool-advanced",{"title":328,"path":329,"stem":330},"Concurrent та Immutable Collections","\u002Fcsharp\u002Fsystem-programming-windows\u002Fconcurrent-collections","01.csharp\u002F07.system-programming-windows\u002F10.concurrent-collections",{"title":332,"path":333,"stem":334},"TPL, Task та Композиція — Від Thread до Task","\u002Fcsharp\u002Fsystem-programming-windows\u002Ftpl-parallel-plinq","01.csharp\u002F07.system-programming-windows\u002F11.tpl-parallel-plinq",{"title":336,"path":337,"stem":338},"Parallel Class та PLINQ — Data Parallelism","\u002Fcsharp\u002Fsystem-programming-windows\u002F11a.tpl-parallel-plinq-advanced","01.csharp\u002F07.system-programming-windows\u002F11a.tpl-parallel-plinq-advanced",{"title":340,"path":341,"stem":342},"Async\u002FAwait — Фундамент Асинхронного Програмування","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-fundamentals","01.csharp\u002F07.system-programming-windows\u002F12.async-fundamentals",{"title":344,"path":345,"stem":346},"SynchronizationContext та ConfigureAwait — Контекст Виконання","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-context-configureawait","01.csharp\u002F07.system-programming-windows\u002F13.async-context-configureawait",{"title":348,"path":349,"stem":350},"Async — Просунуті Паттерни","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-advanced","01.csharp\u002F07.system-programming-windows\u002F14.async-advanced",{"title":352,"path":353,"stem":354},"System.Threading.Channels — Async Producer-Consumer","\u002Fcsharp\u002Fsystem-programming-windows\u002Fchannels","01.csharp\u002F07.system-programming-windows\u002F15.channels",{"title":356,"path":357,"stem":358},"Асинхронна Синхронізація","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-synchronization","01.csharp\u002F07.system-programming-windows\u002F16.async-synchronization",{"title":360,"path":361,"stem":362},"Unsafe Code та Вказівники","\u002Fcsharp\u002Fsystem-programming-windows\u002Funsafe-code","01.csharp\u002F07.system-programming-windows\u002F17.unsafe-code",{"title":364,"path":365,"stem":366},"P\u002FInvoke та Windows API — Міст між .NET та Native Code","\u002Fcsharp\u002Fsystem-programming-windows\u002Fpinvoke-winapi","01.csharp\u002F07.system-programming-windows\u002F18.pinvoke-winapi",{"title":368,"path":369,"stem":370},"Реєстр Windows — Центральна База Конфігурації Системи","\u002Fcsharp\u002Fsystem-programming-windows\u002Fwindows-registry","01.csharp\u002F07.system-programming-windows\u002F19.windows-registry",{"title":372,"path":373,"stem":374},"Windows Hooks, Hotkeys та Services — Глибока Інтеграція з ОС","\u002Fcsharp\u002Fsystem-programming-windows\u002Fwindows-hooks-services","01.csharp\u002F07.system-programming-windows\u002F20.windows-hooks-services",{"title":376,"path":377,"stem":378},"Системне Програмування C# (Windows) — 07.system-programming-windows","\u002Fcsharp\u002Fsystem-programming-windows\u002Fimplementation_plan","01.csharp\u002F07.system-programming-windows\u002Fimplementation_plan",{"title":380,"icon":132,"path":381,"stem":382,"children":383,"page":59},"Io","\u002Fcsharp\u002Fio","01.csharp\u002F08.io",[384,388,392,396,400],{"title":385,"path":386,"stem":387},"8.1.1. Основи роботи з файловою системою","\u002Fcsharp\u002Fio\u002Ffile-system-basics","01.csharp\u002F08.io\u002F01.file-system-basics",{"title":389,"path":390,"stem":391},"8.1.2. Потоки (Streams) та Серіалізація Даних","\u002Fcsharp\u002Fio\u002Fstreams-serialization","01.csharp\u002F08.io\u002F02.streams-serialization",{"title":393,"path":394,"stem":395},"8.2.1. JSON Serialization з System.Text.Json","\u002Fcsharp\u002Fio\u002Fjson-serialization","01.csharp\u002F08.io\u002F03.json-serialization",{"title":397,"path":398,"stem":399},"8.2.2. XML Serialization та LINQ to XML","\u002Fcsharp\u002Fio\u002Fxml-serialization","01.csharp\u002F08.io\u002F04.xml-serialization",{"title":401,"path":402,"stem":403},"8.2.3. Binary Serialization: MessagePack та Protocol Buffers","\u002Fcsharp\u002Fio\u002Fbinary-serialization","01.csharp\u002F08.io\u002F05.binary-serialization",{"title":405,"icon":132,"path":406,"stem":407,"children":408,"page":59},"Ado Net","\u002Fcsharp\u002Fado-net","01.csharp\u002F09.ado-net",[409,413,417,421,425,429,433,437,441,445,449,453],{"title":410,"path":411,"stem":412},"9.1. Введення в ADO.NET","\u002Fcsharp\u002Fado-net\u002Fintroduction-to-adonet","01.csharp\u002F09.ado-net\u002F01.introduction-to-adonet",{"title":414,"path":415,"stem":416},"9.2. Клас DbConnection — з'єднання з базою даних","\u002Fcsharp\u002Fado-net\u002Fconnection","01.csharp\u002F09.ado-net\u002F02.connection",{"title":418,"path":419,"stem":420},"9.3. Клас DbCommand — виконання SQL-запитів","\u002Fcsharp\u002Fado-net\u002Fcommand-and-queries","01.csharp\u002F09.ado-net\u002F03.command-and-queries",{"title":422,"path":423,"stem":424},"9.4. Клас DbDataReader — ефективне читання даних","\u002Fcsharp\u002Fado-net\u002Fdatareader","01.csharp\u002F09.ado-net\u002F04.datareader",{"title":426,"path":427,"stem":428},"9.5. Параметризовані запити та захист від SQL Injection","\u002Fcsharp\u002Fado-net\u002Fparameters-and-sql-injection","01.csharp\u002F09.ado-net\u002F05.parameters-and-sql-injection",{"title":430,"path":431,"stem":432},"9.6. Транзакції в ADO.NET","\u002Fcsharp\u002Fado-net\u002Ftransactions","01.csharp\u002F09.ado-net\u002F06.transactions",{"title":434,"path":435,"stem":436},"9.7. DbProviderFactory — провайдер-незалежний код","\u002Fcsharp\u002Fado-net\u002Fprovider-factory","01.csharp\u002F09.ado-net\u002F07.provider-factory",{"title":438,"path":439,"stem":440},"9.8. Асинхронний доступ до даних","\u002Fcsharp\u002Fado-net\u002Fasync-data-access","01.csharp\u002F09.ado-net\u002F08.async-data-access",{"title":442,"path":443,"stem":444},"9.9. Від'єднаний режим: DataSet, DataTable, DataRow","\u002Fcsharp\u002Fado-net\u002Fdisconnected-mode-dataset","01.csharp\u002F09.ado-net\u002F09.disconnected-mode-dataset",{"title":446,"path":447,"stem":448},"9.10. DataAdapter — міст між DataSet та базою даних","\u002Fcsharp\u002Fado-net\u002Fdata-adapter","01.csharp\u002F09.ado-net\u002F10.data-adapter",{"title":450,"path":451,"stem":452},"9.11. Data Mapper та Repository: Архітектура доступу до даних","\u002Fcsharp\u002Fado-net\u002Fdata-mapper-repository","01.csharp\u002F09.ado-net\u002F11.data-mapper-repository",{"title":454,"path":455,"stem":456},"9.12. Identity Map, Unit of Work та Specification Pattern","\u002Fcsharp\u002Fado-net\u002Fadvanced-patterns","01.csharp\u002F09.ado-net\u002F12.advanced-patterns",{"title":458,"icon":255,"path":459,"stem":460,"children":461,"page":59},"Ef Core","\u002Fcsharp\u002Fef-core","01.csharp\u002F10.ef-core",[462,466,470,474,478,482,486,490,494,498,502,506,510,514,518,522,526,532,538,542,546,550,554,558,562,566,570,574,578,582,586,590,594,598,602,606,610,614,618,622,626,630,634,638,642,646],{"title":463,"path":464,"stem":465},"Що таке ORM? Від SQL до об'єктів","\u002Fcsharp\u002Fef-core\u002Fwhat-is-orm","01.csharp\u002F10.ef-core\u002F01.what-is-orm",{"title":467,"path":468,"stem":469},"Перший проєкт — від нуля до CRUD","\u002Fcsharp\u002Fef-core\u002Ffirst-project","01.csharp\u002F10.ef-core\u002F02.first-project",{"title":471,"path":472,"stem":473},"DbContext — Серце EF Core","\u002Fcsharp\u002Fef-core\u002Fdbcontext-deep-dive","01.csharp\u002F10.ef-core\u002F03.dbcontext-deep-dive",{"title":475,"path":476,"stem":477},"Провайдери баз даних — Архітектура та Вибір СУБД","\u002Fcsharp\u002Fef-core\u002Fdatabase-providers","01.csharp\u002F10.ef-core\u002F04.database-providers",{"title":479,"path":480,"stem":481},"Конвенції EF Core — Магія без конфігурації","\u002Fcsharp\u002Fef-core\u002Fconventions","01.csharp\u002F10.ef-core\u002F05.conventions",{"title":483,"path":484,"stem":485},"Fluent API та Data Annotations — Явна конфігурація моделі","\u002Fcsharp\u002Fef-core\u002Ffluent-api-vs-annotations","01.csharp\u002F10.ef-core\u002F06.fluent-api-vs-annotations",{"title":487,"path":488,"stem":489},"Зв'язки — One-to-One та One-to-Many","\u002Fcsharp\u002Fef-core\u002Frelationships-basics","01.csharp\u002F10.ef-core\u002F07.relationships-basics",{"title":491,"path":492,"stem":493},"Зв'язки Advanced — Many-to-Many та Складні Сценарії","\u002Fcsharp\u002Fef-core\u002Frelationships-advanced","01.csharp\u002F10.ef-core\u002F08.relationships-advanced",{"title":495,"path":496,"stem":497},"Властивості — Типи, Конвертери, Компаратори (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fproperty-configuration-part1","01.csharp\u002F10.ef-core\u002F09.property-configuration-part1",{"title":499,"path":500,"stem":501},"Властивості — Value Comparers, Generators, Shadow Properties (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fproperty-configuration-part2","01.csharp\u002F10.ef-core\u002F09.property-configuration-part2",{"title":503,"path":504,"stem":505},"Складні типи — Owned Types та Complex Types (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fcomplex-types-owned-part1","01.csharp\u002F10.ef-core\u002F10.complex-types-owned-part1",{"title":507,"path":508,"stem":509},"Складні типи — Complex Types, Keyless Entities, Порівняння (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fcomplex-types-owned-part2","01.csharp\u002F10.ef-core\u002F10.complex-types-owned-part2",{"title":511,"path":512,"stem":513},"JSON Columns — Складні дані у JSON (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fjson-columns-part1","01.csharp\u002F10.ef-core\u002F11.json-columns-part1",{"title":515,"path":516,"stem":517},"JSON Columns — Value Comparers, Індекси, Провайдери (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fjson-columns-part2","01.csharp\u002F10.ef-core\u002F11.json-columns-part2",{"title":519,"path":520,"stem":521},"Успадкування — Абстрактні класи та TPH (Частина 1)","\u002Fcsharp\u002Fef-core\u002Finheritance-part1","01.csharp\u002F10.ef-core\u002F12.inheritance-part1",{"title":523,"path":524,"stem":525},"Успадкування — TPT, TPC та Порівняння Стратегій (Частина 2)","\u002Fcsharp\u002Fef-core\u002Finheritance-part2","01.csharp\u002F10.ef-core\u002F12.inheritance-part2",{"title":527,"path":528,"stem":529,"children":530},"Індекси, Обмеження та Схема (Частина 1)","\u002Fcsharp\u002Fef-core\u002Findexes-constraints-part1","01.csharp\u002F10.ef-core\u002F13.indexes-constraints-part1",[531],{"title":527,"path":528,"stem":529},{"title":533,"path":534,"stem":535,"children":536},"Індекси, Обмеження та Схема (Частина 2)","\u002Fcsharp\u002Fef-core\u002Findexes-constraints-part2","01.csharp\u002F10.ef-core\u002F13.indexes-constraints-part2",[537],{"title":533,"path":534,"stem":535},{"title":539,"path":540,"stem":541},"Seed Data — Початкові Дані (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fseeding-part1","01.csharp\u002F10.ef-core\u002F14.seeding-part1",{"title":543,"path":544,"stem":545},"Seed Data — SQL-скрипти, Bogus та Стратегії (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fseeding-part2","01.csharp\u002F10.ef-core\u002F14.seeding-part2",{"title":547,"path":548,"stem":549},"Global Query Filters — Глобальні Фільтри (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fglobal-query-filters-part1","01.csharp\u002F10.ef-core\u002F15.global-query-filters-part1",{"title":551,"path":552,"stem":553},"Global Query Filters — Підводні камені та Інтеграція (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fglobal-query-filters-part2","01.csharp\u002F10.ef-core\u002F15.global-query-filters-part2",{"title":555,"path":556,"stem":557},"LINQ-запити в EF Core (Частина 1)","\u002Fcsharp\u002Fef-core\u002Flinq-queries-part1","01.csharp\u002F10.ef-core\u002F16.linq-queries-part1",{"title":559,"path":560,"stem":561},"LINQ-запити в EF Core (Частина 2)","\u002Fcsharp\u002Fef-core\u002Flinq-queries-part2","01.csharp\u002F10.ef-core\u002F16.linq-queries-part2",{"title":563,"path":564,"stem":565},"Завантаження Пов'язаних Даних (Частина 1)","\u002Fcsharp\u002Fef-core\u002Floading-related-data-part1","01.csharp\u002F10.ef-core\u002F17.loading-related-data-part1",{"title":567,"path":568,"stem":569},"Завантаження Пов'язаних Даних (Частина 2)","\u002Fcsharp\u002Fef-core\u002Floading-related-data-part2","01.csharp\u002F10.ef-core\u002F17.loading-related-data-part2",{"title":571,"path":572,"stem":573},"Raw SQL, Views та Stored Procedures (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fraw-sql-part1","01.csharp\u002F10.ef-core\u002F18.raw-sql-part1",{"title":575,"path":576,"stem":577},"Raw SQL — Stored Procedures, DbFunction та Bulk Operations (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fraw-sql-part2","01.csharp\u002F10.ef-core\u002F18.raw-sql-part2",{"title":579,"path":580,"stem":581},"Продвинуті Запити — Compiled Queries, Bulk та Оптимізація (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fadvanced-queries-part1","01.csharp\u002F10.ef-core\u002F19.advanced-queries-part1",{"title":583,"path":584,"stem":585},"Продвинуті Запити — Query Tags, Bulk та Interceptors (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fadvanced-queries-part2","01.csharp\u002F10.ef-core\u002F19.advanced-queries-part2",{"title":587,"path":588,"stem":589},"Change Tracker — Відстеження Змін (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fchange-tracking-part1","01.csharp\u002F10.ef-core\u002F20.change-tracking-part1",{"title":591,"path":592,"stem":593},"Change Tracker — Графи Об'єктів та Disconnected (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fchange-tracking-part2","01.csharp\u002F10.ef-core\u002F20.change-tracking-part2",{"title":595,"path":596,"stem":597},"Збереження Даних та Транзакції (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fsaving-data-part1","01.csharp\u002F10.ef-core\u002F21.saving-data-part1",{"title":599,"path":600,"stem":601},"Збереження Даних — Concurrency та Outbox (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fsaving-data-part2","01.csharp\u002F10.ef-core\u002F21.saving-data-part2",{"title":603,"path":604,"stem":605},"Конкурентність та Блокування (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fconcurrency-part1","01.csharp\u002F10.ef-core\u002F22.concurrency-part1",{"title":607,"path":608,"stem":609},"Конкурентність — Дедлоки та Queue Processing (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fconcurrency-part2","01.csharp\u002F10.ef-core\u002F22.concurrency-part2",{"title":611,"path":612,"stem":613},"Міграції в EF Core — Основи (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fmigrations-basics-part1","01.csharp\u002F10.ef-core\u002F23.migrations-basics-part1",{"title":615,"path":616,"stem":617},"Міграції в EF Core — Основи (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fmigrations-basics-part2","01.csharp\u002F10.ef-core\u002F23.migrations-basics-part2",{"title":619,"path":620,"stem":621},"Міграції — Просунуті Сценарії (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fmigrations-advanced-part1","01.csharp\u002F10.ef-core\u002F24.migrations-advanced-part1",{"title":623,"path":624,"stem":625},"Міграції — Просунуті Сценарії (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fmigrations-advanced-part2","01.csharp\u002F10.ef-core\u002F24.migrations-advanced-part2",{"title":627,"path":628,"stem":629},"Управління Схемою та Database-First (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fschema-management-part1","01.csharp\u002F10.ef-core\u002F25.schema-management-part1",{"title":631,"path":632,"stem":633},"Управління Схемою та Database-First (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fschema-management-part2","01.csharp\u002F10.ef-core\u002F25.schema-management-part2",{"title":635,"path":636,"stem":637},"Продуктивність EF Core — Основи (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fperformance-fundamentals-part1","01.csharp\u002F10.ef-core\u002F26.performance-fundamentals-part1",{"title":639,"path":640,"stem":641},"Interceptors в EF Core (Частина 1)","\u002Fcsharp\u002Fef-core\u002Finterceptors-part1","01.csharp\u002F10.ef-core\u002F29.interceptors-part1",{"title":643,"path":644,"stem":645},"Interceptors в EF Core — Connection, Transaction та Materialization (Частина 2)","\u002Fcsharp\u002Fef-core\u002Finterceptors-part2","01.csharp\u002F10.ef-core\u002F29.interceptors-part2",{"title":647,"path":648,"stem":649},"План вивчення Entity Framework Core — Повний курс","\u002Fcsharp\u002Fef-core\u002Fimplementation_plan","01.csharp\u002F10.ef-core\u002Fimplementation_plan",{"title":651,"icon":652,"path":653,"stem":654,"children":655,"page":59},"ASP.NET","i-devicon-dotnetcore","\u002Fcsharp\u002Faspnet","01.csharp\u002F11.aspnet",[656,730,791,869,927,941,967,1057,1111,1182,1212,1289,1346],{"title":657,"icon":658,"path":659,"stem":660,"children":661,"page":59},"Minimal API","i-lucide-network","\u002Fcsharp\u002Faspnet\u002Fminimal-api","01.csharp\u002F11.aspnet\u002F01.minimal-api",[662,666,670,674,678,682,686,690,694,698,702,706,710,714,718,722,726],{"title":663,"path":664,"stem":665},"Вступ до ASP.NET та еволюція фреймворку","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fintroduction","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F01.introduction",{"title":667,"path":668,"stem":669},"Перший додаток на ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Ffirst-application","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F02.first-application",{"title":671,"path":672,"stem":673},"WebApplication, Builder та Dependency Injection","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fwebapplication-builder","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F03.webapplication-builder",{"title":675,"path":676,"stem":677},"Конвеєр запитів та Middleware","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frequest-pipeline-middleware","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F04.request-pipeline-middleware",{"title":679,"path":680,"stem":681},"Маршрутизація в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frouting-basics","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F05.routing-basics",{"title":683,"path":684,"stem":685},"Маршрутизація в ASP.NET Core: Розширені можливості","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frouting-advanced","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F06.routing-advanced",{"title":687,"path":688,"stem":689},"Статичні файли в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstatic-files","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F07.static-files",{"title":691,"path":692,"stem":693},"Статичні Активи: MapStaticAssets (ASP.NET Core 9.0)","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstatic-assets","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F08.static-assets",{"title":695,"path":696,"stem":697},"Конфігурація в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fconfiguration-fundamentals","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F09.configuration-fundamentals",{"title":699,"path":700,"stem":701},"Конфігурація: Паттерн Options","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fconfiguration-options","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F10.configuration-options",{"title":703,"path":704,"stem":705},"Логування в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Flogging-basics","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F11.logging-basics",{"title":707,"path":708,"stem":709},"Логування: Serilog та Middleware","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Flogging-advanced","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F12.logging-advanced",{"title":711,"path":712,"stem":713},"Управління станом: HttpContext.Items та Cookies","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstate-management","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F13.state-management",{"title":715,"path":716,"stem":717},"Стан сесії: Sessions","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fsession-state","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F14.session-state",{"title":719,"path":720,"stem":721},"Структура проєкту: від хаосу до архітектури","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fproject-structure","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F15.project-structure",{"title":723,"path":724,"stem":725},"Scalar у Minimal API: повний проєкт і Fluent OpenAPI","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fscalar-openapi-fluent","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F16.scalar-openapi-fluent",{"title":727,"path":728,"stem":729},"Swagger \u002F Swashbuckle у Minimal API: окремий класичний шлях","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fswagger-swashbuckle","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F17.swagger-swashbuckle",{"title":731,"icon":658,"path":732,"stem":733,"children":734,"page":59},"API","\u002Fcsharp\u002Faspnet\u002Fapi","01.csharp\u002F11.aspnet\u002F02.api",[735,739,743,747,751,755,759,763,767,771,775,779,783,787],{"title":736,"path":737,"stem":738},"Що таке API. Клієнт-серверна архітектура","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fwhat-is-api","01.csharp\u002F11.aspnet\u002F02.api\u002F01.what-is-api",{"title":740,"path":741,"stem":742},"Формати даних: JSON, XML, TOML та бінарні формати","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fdata-formats","01.csharp\u002F11.aspnet\u002F02.api\u002F02.data-formats",{"title":744,"path":745,"stem":746},"Парадигми API та концепція REST","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-paradigms-rest","01.csharp\u002F11.aspnet\u002F02.api\u002F03.api-paradigms-rest",{"title":748,"path":749,"stem":750},"HTTP-методи, статус-коди та заголовки","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fhttp-methods-status-codes","01.csharp\u002F11.aspnet\u002F02.api\u002F04.http-methods-status-codes",{"title":752,"path":753,"stem":754},"Організація HTTP API за принципами REST","\u002Fcsharp\u002Faspnet\u002Fapi\u002Frest-organizing","01.csharp\u002F11.aspnet\u002F02.api\u002F05.rest-organizing",{"title":756,"path":757,"stem":758},"Номенклатура URL та CRUD-операції","\u002Fcsharp\u002Faspnet\u002Fapi\u002Furl-nomenclature-crud","01.csharp\u002F11.aspnet\u002F02.api\u002F06.url-nomenclature-crud",{"title":760,"path":761,"stem":762},"Правила дизайну: іменування та стандарти","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-naming","01.csharp\u002F11.aspnet\u002F02.api\u002F07.api-design-naming",{"title":764,"path":765,"stem":766},"Валідація, ліміти та обробка помилок","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-validation","01.csharp\u002F11.aspnet\u002F02.api\u002F08.api-design-validation",{"title":768,"path":769,"stem":770},"Обробка помилок у Minimal API","\u002Fcsharp\u002Faspnet\u002Fapi\u002Ferror-handling-http","01.csharp\u002F11.aspnet\u002F02.api\u002F09.error-handling-http",{"title":772,"path":773,"stem":774},"Ідемпотентність та синхронізація стану","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fidempotency-sync","01.csharp\u002F11.aspnet\u002F02.api\u002F10.idempotency-sync",{"title":776,"path":777,"stem":778},"Пагінація та організація списків","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fpagination-lists","01.csharp\u002F11.aspnet\u002F02.api\u002F11.pagination-lists",{"title":780,"path":781,"stem":782},"Безпека API, кешування та інтернаціоналізація","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fsecurity-auth","01.csharp\u002F11.aspnet\u002F02.api\u002F12.security-auth",{"title":784,"path":785,"stem":786},"Процес проєктування API та документування","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-process","01.csharp\u002F11.aspnet\u002F02.api\u002F13.api-design-process",{"title":788,"path":789,"stem":790},"OpenAPI: контракт, специфікація та документація API","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fopenapi","01.csharp\u002F11.aspnet\u002F02.api\u002F14.openapi",{"title":792,"icon":793,"path":794,"stem":795,"children":796,"page":59},"Auth","i-lucide-shield-check","\u002Fcsharp\u002Faspnet\u002Fauth","01.csharp\u002F11.aspnet\u002F03.auth",[797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865],{"title":798,"path":799,"stem":800},"Основи аутентифікації та авторизації","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fauth-fundamentals","01.csharp\u002F11.aspnet\u002F03.auth\u002F01.auth-fundamentals",{"title":802,"path":803,"stem":804},"JWT-аутентифікація","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fjwt-authentication","01.csharp\u002F11.aspnet\u002F03.auth\u002F02.jwt-authentication",{"title":806,"path":807,"stem":808},"Авторизація: ролі, політики та resource-based доступ","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fauthorization-policies","01.csharp\u002F11.aspnet\u002F03.auth\u002F03.authorization-policies",{"title":810,"path":811,"stem":812},"Cookie-аутентифікація та ASP.NET Core Identity","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fcookie-auth-identity","01.csharp\u002F11.aspnet\u002F03.auth\u002F04.cookie-auth-identity",{"title":814,"path":815,"stem":816},"JWT + Refresh Tokens (HttpOnly Cookie)","\u002Fcsharp\u002Faspnet\u002Fauth\u002F04b.identity-auth-jwt","01.csharp\u002F11.aspnet\u002F03.auth\u002F04b.identity-auth-jwt",{"title":818,"path":819,"stem":820},"Identity: Підтвердження Email та Скидання Пароля","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-email-confirmation","01.csharp\u002F11.aspnet\u002F03.auth\u002F05.identity-email-confirmation",{"title":822,"path":823,"stem":824},"Identity: Двофакторна Аутентифікація (2FA)","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-two-factor","01.csharp\u002F11.aspnet\u002F03.auth\u002F06.identity-two-factor",{"title":826,"path":827,"stem":828},"Identity: Внутрішня Архітектура та Кастомізація","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-internals","01.csharp\u002F11.aspnet\u002F03.auth\u002F07.identity-internals",{"title":830,"path":831,"stem":832},"OAuth 2.0 та зовнішні провайдери","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foauth-external-providers","01.csharp\u002F11.aspnet\u002F03.auth\u002F08.oauth-external-providers",{"title":834,"path":835,"stem":836},"Безпека на практиці: CORS, HTTPS та захист від атак","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fsecurity-hardening","01.csharp\u002F11.aspnet\u002F03.auth\u002F09.security-hardening",{"title":838,"path":839,"stem":840},"Теорія OAuth 2.0: Поняття, Аналогії та Флоу","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foauth-theory","01.csharp\u002F11.aspnet\u002F03.auth\u002F10.oauth-theory",{"title":842,"path":843,"stem":844},"OIDC, OAuth 2.0 та Keycloak в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foidc-keycloak","01.csharp\u002F11.aspnet\u002F03.auth\u002F10.oidc-keycloak",{"title":846,"path":847,"stem":848},"API Keys аутентифікація в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fapi-keys","01.csharp\u002F11.aspnet\u002F03.auth\u002F11.api-keys",{"title":850,"path":851,"stem":852},"Rate Limiting та Throttling в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frate-limiting","01.csharp\u002F11.aspnet\u002F03.auth\u002F12.rate-limiting",{"title":854,"path":855,"stem":856},"Refresh Token Rotation в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frefresh-token-rotation","01.csharp\u002F11.aspnet\u002F03.auth\u002F13.refresh-token-rotation",{"title":858,"path":859,"stem":860},"Certificate Authentication та mTLS в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fcertificate-auth","01.csharp\u002F11.aspnet\u002F03.auth\u002F14.certificate-auth",{"title":862,"path":863,"stem":864},"RBAC, ABAC та ReBAC в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frbac-abac-rebac","01.csharp\u002F11.aspnet\u002F03.auth\u002F15.rbac-abac-rebac",{"title":866,"path":867,"stem":868},"Multi-tenancy та ізоляція даних в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fmulti-tenancy","01.csharp\u002F11.aspnet\u002F03.auth\u002F16.multi-tenancy",{"title":870,"icon":871,"path":872,"stem":873,"children":874,"page":59},"Нотифікації","i-lucide-bell","\u002Fcsharp\u002Faspnet\u002Fnotifications","01.csharp\u002F11.aspnet\u002F04.notifications",[875,879,883,887,891,895,899,903,907,911,915,919,923],{"title":876,"path":877,"stem":878},"In-App нотифікації через базу даних","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fin-app-database-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F01.in-app-database-notifications",{"title":880,"path":881,"stem":882},"Polling: Регулярний запит оновлень","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fpolling","01.csharp\u002F11.aspnet\u002F04.notifications\u002F02.polling",{"title":884,"path":885,"stem":886},"Server-Sent Events: Однострімовий push від сервера","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fserver-sent-events","01.csharp\u002F11.aspnet\u002F04.notifications\u002F03.server-sent-events",{"title":888,"path":889,"stem":890},"WebSockets: Двостороннє з'єднання в реальному часі","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fwebsockets","01.csharp\u002F11.aspnet\u002F04.notifications\u002F04.websockets",{"title":892,"path":893,"stem":894},"SignalR: Абстракція над транспортами реального часу","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fsignalr","01.csharp\u002F11.aspnet\u002F04.notifications\u002F05.signalr",{"title":896,"path":897,"stem":898},"Background Services: Фонові задачі в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fbackground-services","01.csharp\u002F11.aspnet\u002F04.notifications\u002F06.background-services",{"title":900,"path":901,"stem":902},"Web Push нотифікації","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fweb-push","01.csharp\u002F11.aspnet\u002F04.notifications\u002F07.web-push",{"title":904,"path":905,"stem":906},"Email нотифікації","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Femail-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F08.email-notifications",{"title":908,"path":909,"stem":910},"Порівняння підходів: Як вибрати правильну технологію нотифікацій","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fchoosing-the-right-approach","01.csharp\u002F11.aspnet\u002F04.notifications\u002F09.choosing-the-right-approach",{"title":912,"path":913,"stem":914},"Hangfire: Надійне планування фонових задач","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire","01.csharp\u002F11.aspnet\u002F04.notifications\u002F10.hangfire",{"title":916,"path":917,"stem":918},"Практика: Конвертація зображень у WebP через Hangfire","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire-image-webp","01.csharp\u002F11.aspnet\u002F04.notifications\u002F11.hangfire-image-webp",{"title":920,"path":921,"stem":922},"Практика: Підготовка відео до HLS-стрімінгу через Hangfire","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire-video-hls","01.csharp\u002F11.aspnet\u002F04.notifications\u002F12.hangfire-video-hls",{"title":924,"path":925,"stem":926},"Telegram-нотифікації: від одного повідомлення до масових розсилок і мульти-канального підходу","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Ftelegram-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F13.telegram-notifications",{"title":928,"icon":929,"path":930,"stem":931,"children":932,"page":59},"Інтернаціоналізація","i-lucide-languages","\u002Fcsharp\u002Faspnet\u002Fi18n","01.csharp\u002F11.aspnet\u002F05.i18n",[933,937],{"title":934,"path":935,"stem":936},"Інтернаціоналізація (i18n) у Minimal API: від A до Я","\u002Fcsharp\u002Faspnet\u002Fi18n\u002Finternationalization","01.csharp\u002F11.aspnet\u002F05.i18n\u002F01.internationalization",{"title":938,"path":939,"stem":940},"Humanizer: людиномовні рядки у .NET","\u002Fcsharp\u002Faspnet\u002Fi18n\u002Fhumanizer","01.csharp\u002F11.aspnet\u002F05.i18n\u002F02.humanizer",{"title":942,"icon":943,"path":944,"stem":945,"children":946,"page":59},"Кешування","i-lucide-layers","\u002Fcsharp\u002Faspnet\u002Fcaching","01.csharp\u002F11.aspnet\u002F06.caching",[947,951,955,959,963],{"title":948,"path":949,"stem":950},"Огляд кешування: чотири рівні і коли що обирати","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fcaching","01.csharp\u002F11.aspnet\u002F06.caching\u002F01.caching",{"title":952,"path":953,"stem":954},"IMemoryCache: кеш в оперативній пам'яті","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fmemory-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F02.memory-cache",{"title":956,"path":957,"stem":958},"IDistributedCache і Redis: розподілений кеш","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fdistributed-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F03.distributed-cache",{"title":960,"path":961,"stem":962},"Response Cache: HTTP-кешування через Cache-Control","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fresponse-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F04.response-cache",{"title":964,"path":965,"stem":966},"Output Cache: серверний кеш HTTP-відповідей (.NET 7+)","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Foutput-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F05.output-cache",{"title":968,"icon":969,"path":970,"stem":971,"children":972,"page":59},"Тестування","i-lucide-test-tube","\u002Fcsharp\u002Faspnet\u002Ftesting","01.csharp\u002F11.aspnet\u002F07.testing",[973,977,981,985,989,993,997,1001,1005,1009,1013,1017,1021,1025,1029,1033,1037,1041,1045,1049,1053],{"title":974,"path":975,"stem":976},"Що таке тестування? Від інтуїції до науки","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwhat-is-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F01.what-is-testing",{"title":978,"path":979,"stem":980},"Піраміда тестування — Стратегія, а не Догма","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-pyramid","01.csharp\u002F11.aspnet\u002F07.testing\u002F02.testing-pyramid",{"title":982,"path":983,"stem":984},"Дві Школи Тестування — Лондон проти Детройту","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-schools","01.csharp\u002F11.aspnet\u002F07.testing\u002F03.testing-schools",{"title":986,"path":987,"stem":988},"TDD та BDD — Тести як Дизайн-інструмент","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftdd-and-bdd","01.csharp\u002F11.aspnet\u002F07.testing\u002F04.tdd-and-bdd",{"title":990,"path":991,"stem":992},"Що саме тестувати — Техніки аналізу та Циклomatична складність","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwhat-to-test","01.csharp\u002F11.aspnet\u002F07.testing\u002F05.what-to-test",{"title":994,"path":995,"stem":996},"Тестові Фреймворки — Навіщо вони і що всередині","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftest-frameworks","01.csharp\u002F11.aspnet\u002F07.testing\u002F06.test-frameworks",{"title":998,"path":999,"stem":1000},"xUnit — Факти, Теорії та Lifecycle тестів","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fxunit-basics","01.csharp\u002F11.aspnet\u002F07.testing\u002F07.xunit-basics",{"title":1002,"path":1003,"stem":1004},"xUnit Advanced — Fixtures, Кастомізація та Розширення","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fxunit-advanced","01.csharp\u002F11.aspnet\u002F07.testing\u002F08.xunit-advanced",{"title":1006,"path":1007,"stem":1008},"Moq — Глибоке занурення в мокування","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fmocking-with-moq","01.csharp\u002F11.aspnet\u002F07.testing\u002F09.mocking-with-moq",{"title":1010,"path":1011,"stem":1012},"Тестування Баз Даних — EF Core, SQLite та Testcontainers","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fdatabase-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F10.database-testing",{"title":1014,"path":1015,"stem":1016},"Integration Testing — Частина 1 [Теорія та WebApplicationFactory]","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fintegration-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F11.integration-testing",{"title":1018,"path":1019,"stem":1020},"Інтеграційне тестування — Практика","\u002Fcsharp\u002Faspnet\u002Ftesting\u002F11a.integration-testing-practice","01.csharp\u002F11.aspnet\u002F07.testing\u002F11a.integration-testing-practice",{"title":1022,"path":1023,"stem":1024},"Integration Testing — Частина 2 [Просунуті Сценарії та Testcontainers]","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fintegration-testing-advanced","01.csharp\u002F11.aspnet\u002F07.testing\u002F12.integration-testing-advanced",{"title":1026,"path":1027,"stem":1028},"Професійний Postman: Колекції, Змінні та GitHub Інтеграція","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fpostman-professional","01.csharp\u002F11.aspnet\u002F07.testing\u002F13.postman-professional",{"title":1030,"path":1031,"stem":1032},"HttpClient у Тестах Частина 1: Архітектура та MockHttpMessageHandler","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fhttpclient-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F14.httpclient-testing",{"title":1034,"path":1035,"stem":1036},"HttpClient у Тестах Частина 2: WireMock.Net та Resilience","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwiremock-net","01.csharp\u002F11.aspnet\u002F07.testing\u002F15.wiremock-net",{"title":1038,"path":1039,"stem":1040},"Патерни та Анти-патерни Тестування: Test Smells","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-patterns","01.csharp\u002F11.aspnet\u002F07.testing\u002F16.testing-patterns",{"title":1042,"path":1043,"stem":1044},"Просунуті інструменти: Time, Snapshots та Властивості","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fadvanced-testing-tools","01.csharp\u002F11.aspnet\u002F07.testing\u002F17.advanced-testing-tools",{"title":1046,"path":1047,"stem":1048},"Тестування Архітектури з NetArchTest","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Farchitecture-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F18.architecture-testing",{"title":1050,"path":1051,"stem":1052},"Тестування Продуктивності: BenchmarkDotNet, NBomber та k6","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fperformance-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F19.performance-testing",{"title":1054,"path":1055,"stem":1056},"Залишок плану для курсу \"Тестування ASP.NET Minimal API\"","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fremaining_plan","01.csharp\u002F11.aspnet\u002F07.testing\u002Fremaining_plan",{"title":1058,"icon":1059,"path":1060,"stem":1061,"children":1062,"page":59},"Платежі","i-lucide-credit-card","\u002Fcsharp\u002Faspnet\u002Fpayments","01.csharp\u002F11.aspnet\u002F08.payments",[1063,1067,1071,1075,1079,1083,1087,1091,1095,1099,1103,1107],{"title":1064,"path":1065,"stem":1066},"Основи платіжної інфраструктури","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-fundamentals","01.csharp\u002F11.aspnet\u002F08.payments\u002F01.payment-fundamentals",{"title":1068,"path":1069,"stem":1070},"Методи оплати в Україні","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-methods-ukraine","01.csharp\u002F11.aspnet\u002F08.payments\u002F02.payment-methods-ukraine",{"title":1072,"path":1073,"stem":1074},"PCI DSS та безпека платежів","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpci-dss-security","01.csharp\u002F11.aspnet\u002F08.payments\u002F03.pci-dss-security",{"title":1076,"path":1077,"stem":1078},"Архітектура платіжної підсистеми","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-architecture","01.csharp\u002F11.aspnet\u002F08.payments\u002F04.payment-architecture",{"title":1080,"path":1081,"stem":1082},"Інтеграція LiqPay (ПриватБанк)","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fliqpay-integration","01.csharp\u002F11.aspnet\u002F08.payments\u002F05.liqpay-integration",{"title":1084,"path":1085,"stem":1086},"Інтеграція Monobank Acquiring API","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fmonobank-acquiring","01.csharp\u002F11.aspnet\u002F08.payments\u002F06.monobank-acquiring",{"title":1088,"path":1089,"stem":1090},"Інтеграція Stripe","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fstripe-integration","01.csharp\u002F11.aspnet\u002F08.payments\u002F07.stripe-integration",{"title":1092,"path":1093,"stem":1094},"Webhooks — глибоке занурення","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fwebhooks-deep-dive","01.csharp\u002F11.aspnet\u002F08.payments\u002F08.webhooks-deep-dive",{"title":1096,"path":1097,"stem":1098},"Підписки та рекурентні платежі","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fsubscriptions-recurring","01.csharp\u002F11.aspnet\u002F08.payments\u002F09.subscriptions-recurring",{"title":1100,"path":1101,"stem":1102},"Повернення коштів та диспути","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Frefunds-disputes","01.csharp\u002F11.aspnet\u002F08.payments\u002F10.refunds-disputes",{"title":1104,"path":1105,"stem":1106},"Тестування платіжних інтеграцій","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Ftesting-payments","01.csharp\u002F11.aspnet\u002F08.payments\u002F11.testing-payments",{"title":1108,"path":1109,"stem":1110},"Чекліст виходу в Production","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fproduction-checklist","01.csharp\u002F11.aspnet\u002F08.payments\u002F12.production-checklist",{"title":1112,"icon":1113,"items":1114,"path":1127,"stem":1128,"children":1129,"page":59},"Популярні бібліотеки","lucide:box",[1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126],"01.fluent-validation","02.mapster","03.erroror-result-pattern","04.serilog","05.mediatr","06.polly","07.health-checks","08.feature-management","09.fluent-email","10.quest-pdf","11.bogus","12.humanizer-guard","\u002Fcsharp\u002Faspnet\u002Flibraries","01.csharp\u002F11.aspnet\u002F09.libraries",[1130,1134,1138,1142,1146,1150,1154,1158,1162,1166,1170,1174,1178],{"title":1131,"path":1132,"stem":1133},"Валідація з FluentValidation в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffluent-validation","01.csharp\u002F11.aspnet\u002F09.libraries\u002F01.fluent-validation",{"title":1135,"path":1136,"stem":1137},"Маппінг об","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fmapster","01.csharp\u002F11.aspnet\u002F09.libraries\u002F02.mapster",{"title":1139,"path":1140,"stem":1141},"Обробка помилок з ErrorOr та Result Pattern в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ferroror-result-pattern","01.csharp\u002F11.aspnet\u002F09.libraries\u002F03.erroror-result-pattern",{"title":1143,"path":1144,"stem":1145},"Структуроване логування з Serilog в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fserilog","01.csharp\u002F11.aspnet\u002F09.libraries\u002F04.serilog",{"title":1147,"path":1148,"stem":1149},"CQRS та Mediator з MediatR в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fmediatr","01.csharp\u002F11.aspnet\u002F09.libraries\u002F05.mediatr",{"title":1151,"path":1152,"stem":1153},"Відмовостійкість з Polly в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fpolly","01.csharp\u002F11.aspnet\u002F09.libraries\u002F06.polly",{"title":1155,"path":1156,"stem":1157},"Health Checks в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fhealth-checks","01.csharp\u002F11.aspnet\u002F09.libraries\u002F07.health-checks",{"title":1159,"path":1160,"stem":1161},"Feature Management та Feature Flags в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffeature-management","01.csharp\u002F11.aspnet\u002F09.libraries\u002F08.feature-management",{"title":1163,"path":1164,"stem":1165},"Відправка Email з FluentEmail в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffluent-email","01.csharp\u002F11.aspnet\u002F09.libraries\u002F09.fluent-email",{"title":1167,"path":1168,"stem":1169},"Генерація PDF з QuestPDF в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fquest-pdf","01.csharp\u002F11.aspnet\u002F09.libraries\u002F10.quest-pdf",{"title":1171,"path":1172,"stem":1173},"Генерація тестових даних з Bogus в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fbogus","01.csharp\u002F11.aspnet\u002F09.libraries\u002F11.bogus",{"title":1175,"path":1176,"stem":1177},"Humanizer та Guard Clauses в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fhumanizer-guard","01.csharp\u002F11.aspnet\u002F09.libraries\u002F12.humanizer-guard",{"title":1179,"path":1180,"stem":1181},"План модуля 10.libraries — Популярні бібліотеки ASP.NET","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fplan","01.csharp\u002F11.aspnet\u002F09.libraries\u002Fplan",{"title":1183,"icon":1184,"path":1185,"stem":1186,"children":1187,"page":59},"Razor Pages","i-lucide-layout-template","\u002Fcsharp\u002Faspnet\u002Frazor-pages","01.csharp\u002F11.aspnet\u002F10.razor-pages",[1188,1192,1196,1200,1204,1208],{"title":1189,"path":1190,"stem":1191},"Від Minimal API до Razor Pages: концептуальний перехід","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Ffrom-minimal-api","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F01.from-minimal-api",{"title":1193,"path":1194,"stem":1195},"PageModel: логіка сторінки Razor Pages","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fpage-model","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F02.page-model",{"title":1197,"path":1198,"stem":1199},"Razor синтаксис: шаблонізатор у .cshtml","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Frazor-syntax","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F03.razor-syntax",{"title":1201,"path":1202,"stem":1203},"Tag Helpers: типізований HTML","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Ftag-helpers","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F04.tag-helpers",{"title":1205,"path":1206,"stem":1207},"Форми і валідація: повний цикл обробки даних","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fforms-validation","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F05.forms-validation",{"title":1209,"path":1210,"stem":1211},"Практичний проєкт: TaskManager на Razor Pages","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fproject-task-manager","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F06.project-task-manager",{"title":1213,"path":1214,"stem":1215,"children":1216,"page":59},"ASP.NET Core MVC","\u002Fcsharp\u002Faspnet\u002Fmvc","01.csharp\u002F11.aspnet\u002F11.mvc",[1217,1221,1225,1229,1233,1237,1241,1245,1249,1253,1257,1261,1265,1269,1273,1277,1281,1285],{"title":1218,"path":1219,"stem":1220},"Патерн MVC: архітектура, що змінила веб","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmvc-pattern","01.csharp\u002F11.aspnet\u002F11.mvc\u002F01.mvc-pattern",{"title":1222,"path":1223,"stem":1224},"Від Razor Pages до MVC: концептуальний перехід","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffrom-razor-pages","01.csharp\u002F11.aspnet\u002F11.mvc\u002F02.from-razor-pages",{"title":1226,"path":1227,"stem":1228},"Controllers та Actions: серце MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fcontrollers-actions","01.csharp\u002F11.aspnet\u002F11.mvc\u002F03.controllers-actions",{"title":1230,"path":1231,"stem":1232},"Маршрутизація в MVC: Convention vs Attribute Routing","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Frouting-mvc","01.csharp\u002F11.aspnet\u002F11.mvc\u002F04.routing-mvc",{"title":1234,"path":1235,"stem":1236},"Model Binding: від HTTP до C#","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmodel-binding","01.csharp\u002F11.aspnet\u002F11.mvc\u002F05.model-binding",{"title":1238,"path":1239,"stem":1240},"Views, ViewData, ViewBag, TempData і ViewModel","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fviews-viewdata-tempdata","01.csharp\u002F11.aspnet\u002F11.mvc\u002F06.views-viewdata-tempdata",{"title":1242,"path":1243,"stem":1244},"Filters: аспектно-орієнтоване програмування в MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffilters","01.csharp\u002F11.aspnet\u002F11.mvc\u002F07.filters",{"title":1246,"path":1247,"stem":1248},"Areas: структурування великих застосунків","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fareas","01.csharp\u002F11.aspnet\u002F11.mvc\u002F08.areas",{"title":1250,"path":1251,"stem":1252},"View Components: повторювані незалежні блоки UI","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fview-components","01.csharp\u002F11.aspnet\u002F11.mvc\u002F09.view-components",{"title":1254,"path":1255,"stem":1256},"Display та Editor Templates","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fdisplay-editor-templates","01.csharp\u002F11.aspnet\u002F11.mvc\u002F10.display-editor-templates",{"title":1258,"path":1259,"stem":1260},"Валідація: IValidatableObject та FluentValidation","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fvalidation-advanced","01.csharp\u002F11.aspnet\u002F11.mvc\u002F11.validation-advanced",{"title":1262,"path":1263,"stem":1264},"HTMX: інтерактивність через HTML-атрибути","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fhtmx","01.csharp\u002F11.aspnet\u002F11.mvc\u002F12.htmx",{"title":1266,"path":1267,"stem":1268},"HTMX у ASP.NET Core MVC: серверна інтеграція","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fajax-htmx-mvc","01.csharp\u002F11.aspnet\u002F11.mvc\u002F13.ajax-htmx-mvc",{"title":1270,"path":1271,"stem":1272},"Практичний проєкт: Каталог товарів з HTMX","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fhtmx-project","01.csharp\u002F11.aspnet\u002F11.mvc\u002F14.htmx-project",{"title":1274,"path":1275,"stem":1276},"Завантаження та обробка файлів","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffile-upload","01.csharp\u002F11.aspnet\u002F11.mvc\u002F15.file-upload",{"title":1278,"path":1279,"stem":1280},"Глобалізація та Локалізація MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fglobalization-localization","01.csharp\u002F11.aspnet\u002F11.mvc\u002F16.globalization-localization",{"title":1282,"path":1283,"stem":1284},"Підсумковий проєкт: Блог-платформа","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmvc-project","01.csharp\u002F11.aspnet\u002F11.mvc\u002F17.mvc-project",{"title":1286,"path":1287,"stem":1288},"План курсу: ASP.NET Core MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fplan","01.csharp\u002F11.aspnet\u002F11.mvc\u002Fplan",{"title":1290,"path":1291,"stem":1292,"children":1293,"page":59},"Web Api","\u002Fcsharp\u002Faspnet\u002Fweb-api","01.csharp\u002F11.aspnet\u002F12.web-api",[1294,1298,1302,1306,1310,1314,1318,1322,1326,1330,1334,1338,1342],{"title":1295,"path":1296,"stem":1297},"Від Minimal API до Controller-based API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Ffrom-minimal-api-to-controllers","01.csharp\u002F11.aspnet\u002F12.web-api\u002F01.from-minimal-api-to-controllers",{"title":1299,"path":1300,"stem":1301},"ControllerBase, ActionResult\u003CT> та Response Types","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fcontroller-base-actionresult","01.csharp\u002F11.aspnet\u002F12.web-api\u002F02.controller-base-actionresult",{"title":1303,"path":1304,"stem":1305},"Content Negotiation - JSON, XML та власні форматери","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fcontent-negotiation","01.csharp\u002F11.aspnet\u002F12.web-api\u002F03.content-negotiation",{"title":1307,"path":1308,"stem":1309},"Версіонування API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fapi-versioning","01.csharp\u002F11.aspnet\u002F12.web-api\u002F04.api-versioning",{"title":1311,"path":1312,"stem":1313},"ProblemDetails та структурована обробка помилок","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fproblemdetails-error-handling","01.csharp\u002F11.aspnet\u002F12.web-api\u002F05.problemdetails-error-handling",{"title":1315,"path":1316,"stem":1317},"Фільтри у Web API контексті","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Ffilters-for-api","01.csharp\u002F11.aspnet\u002F12.web-api\u002F06.filters-for-api",{"title":1319,"path":1320,"stem":1321},"Пагінація, фільтрація та сортування","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fpagination-filtering-sorting","01.csharp\u002F11.aspnet\u002F12.web-api\u002F07.pagination-filtering-sorting",{"title":1323,"path":1324,"stem":1325},"HATEOAS та Resource Expansion","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fhateoas-resource-expansion","01.csharp\u002F11.aspnet\u002F12.web-api\u002F08.hateoas-resource-expansion",{"title":1327,"path":1328,"stem":1329},"Гібридна архітектура - Minimal API + Controllers","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fminimal-api-vs-controllers-hybrid","01.csharp\u002F11.aspnet\u002F12.web-api\u002F09.minimal-api-vs-controllers-hybrid",{"title":1331,"path":1332,"stem":1333},"Документація API - Swashbuckle, NSwag та генерація клієнтів","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fapi-documentation-generation","01.csharp\u002F11.aspnet\u002F12.web-api\u002F10.api-documentation-generation",{"title":1335,"path":1336,"stem":1337},"Health Checks та моніторинг API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fhealth-checks-monitoring","01.csharp\u002F11.aspnet\u002F12.web-api\u002F11.health-checks-monitoring",{"title":1339,"path":1340,"stem":1341},"Підсумковий проєкт - Production-Ready REST API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fweb-api-project","01.csharp\u002F11.aspnet\u002F12.web-api\u002F12.web-api-project",{"title":1343,"path":1344,"stem":1345},"План курсу: ASP.NET Core Web API (Controllers)","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fplan","01.csharp\u002F11.aspnet\u002F12.web-api\u002Fplan",{"title":1347,"icon":1348,"path":1349,"stem":1350,"children":1351,"page":59},"Моніторинг","i-lucide-activity","\u002Fcsharp\u002Faspnet\u002Fmonitoring","01.csharp\u002F11.aspnet\u002F13.monitoring",[1352,1356,1360],{"title":1353,"path":1354,"stem":1355},"Спостережуваність: від console.log до production-систем","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fobservability-intro","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F01.observability-intro",{"title":1357,"path":1358,"stem":1359},"Health Checks: перший рівень observability","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fhealth-checks","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F02.health-checks",{"title":1361,"path":1362,"stem":1363},"Вбудовані метрики .NET 10 та System.Diagnostics.Metrics","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fdotnet-metrics","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F03.dotnet-metrics",{"title":1365,"icon":1366,"path":1367,"stem":1368,"children":1369,"page":59},"Desktop UI","i-lucide-app-window","\u002Fcsharp\u002Fdesktop-ui","01.csharp\u002F12.desktop-ui",[1370,1374,1378,1382,1386,1390,1394,1398,1402,1406,1410,1414,1418,1422,1426,1430,1434,1438,1442,1446,1450,1454,1458,1462,1466,1470,1474,1478,1482,1486,1490,1494,1498,1502,1506,1510,1514,1518,1522,1526,1530,1534,1538,1542,1546,1550,1554,1558,1562,1566,1570,1574,1578,1582,1586,1590,1594,1598,1602,1606,1610,1614,1618,1622,1626,1630,1634,1638,1642,1646,1650],{"title":1371,"path":1372,"stem":1373},"Що таке десктопна розробка?","\u002Fcsharp\u002Fdesktop-ui\u002Fwhat-is-desktop-dev","01.csharp\u002F12.desktop-ui\u002F01.what-is-desktop-dev",{"title":1375,"path":1376,"stem":1377},"Архітектура WPF — як влаштований графічний інтерфейс","\u002Fcsharp\u002Fdesktop-ui\u002Fwpf-architecture","01.csharp\u002F12.desktop-ui\u002F02.wpf-architecture",{"title":1379,"path":1380,"stem":1381},"Перший WPF-проєкт — від нуля до вікна","\u002Fcsharp\u002Fdesktop-ui\u002Ffirst-wpf-app","01.csharp\u002F12.desktop-ui\u002F03.first-wpf-app",{"title":1383,"path":1384,"stem":1385},"Перший Avalonia-проєкт: WPF для всіх платформ","\u002Fcsharp\u002Fdesktop-ui\u002F03a.first-avalonia-app","01.csharp\u002F12.desktop-ui\u002F03a.first-avalonia-app",{"title":1387,"path":1388,"stem":1389},"XAML: декларативний інтерфейс","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-basics","01.csharp\u002F12.desktop-ui\u002F04.xaml-basics",{"title":1391,"path":1392,"stem":1393},"Fluent UI у WPF — сучасний дизайн Windows 11","\u002Fcsharp\u002Fdesktop-ui\u002F04a.wpf-fluent-ui","01.csharp\u002F12.desktop-ui\u002F04a.wpf-fluent-ui",{"title":1395,"path":1396,"stem":1397},"WPF UI — сучасна бібліотека Fluent контролів","\u002Fcsharp\u002Fdesktop-ui\u002F04b.wpf-ui-library","01.csharp\u002F12.desktop-ui\u002F04b.wpf-ui-library",{"title":1399,"path":1400,"stem":1401},"HandyControl — велика бібліотека UI контролів для WPF","\u002Fcsharp\u002Fdesktop-ui\u002F04c.handycontrol-library","01.csharp\u002F12.desktop-ui\u002F04c.handycontrol-library",{"title":1403,"path":1404,"stem":1405},"Простори імен та ресурси XAML","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-namespaces-resources","01.csharp\u002F12.desktop-ui\u002F05.xaml-namespaces-resources",{"title":1407,"path":1408,"stem":1409},"XAML в Avalonia: ключові відмінності від WPF","\u002Fcsharp\u002Fdesktop-ui\u002F05a.avalonia-xaml-differences","01.csharp\u002F12.desktop-ui\u002F05a.avalonia-xaml-differences",{"title":1411,"path":1412,"stem":1413},"Розширення розмітки XAML (Markup Extensions)","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-markup-extensions","01.csharp\u002F12.desktop-ui\u002F06.xaml-markup-extensions",{"title":1415,"path":1416,"stem":1417},"Панелі Layout: StackPanel, WrapPanel, DockPanel","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-panels-part1","01.csharp\u002F12.desktop-ui\u002F07.layout-panels-part1",{"title":1419,"path":1420,"stem":1421},"Grid, Canvas, UniformGrid","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-panels-part2","01.csharp\u002F12.desktop-ui\u002F07.layout-panels-part2",{"title":1423,"path":1424,"stem":1425},"Просунуті техніки Layout","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-advanced","01.csharp\u002F12.desktop-ui\u002F08.layout-advanced",{"title":1427,"path":1428,"stem":1429},"Адаптивний Layout та найкращі практики","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-responsive","01.csharp\u002F12.desktop-ui\u002F09.layout-responsive",{"title":1431,"path":1432,"stem":1433},"Layout в Avalonia: відмінності та нові можливості","\u002Fcsharp\u002Fdesktop-ui\u002F09a.layout-avalonia","01.csharp\u002F12.desktop-ui\u002F09a.layout-avalonia",{"title":1435,"path":1436,"stem":1437},"Button, Image, ProgressBar та інші базові контроли","\u002Fcsharp\u002Fdesktop-ui\u002Fbasic-controls","01.csharp\u002F12.desktop-ui\u002F10.basic-controls",{"title":1439,"path":1440,"stem":1441},"Контроли в Avalonia: відмінності від WPF","\u002Fcsharp\u002Fdesktop-ui\u002F10a.controls-avalonia","01.csharp\u002F12.desktop-ui\u002F10a.controls-avalonia",{"title":1443,"path":1444,"stem":1445},"Текстові контроли — TextBlock, TextBox, RichTextBox","\u002Fcsharp\u002Fdesktop-ui\u002Ftext-controls","01.csharp\u002F12.desktop-ui\u002F11.text-controls",{"title":1447,"path":1448,"stem":1449},"Контроли вибору — CheckBox, RadioButton, ComboBox, ListBox, DatePicker","\u002Fcsharp\u002Fdesktop-ui\u002Fselection-controls","01.csharp\u002F12.desktop-ui\u002F12.selection-controls",{"title":1451,"path":1452,"stem":1453},"Content Model — GroupBox, Expander, TabControl, StatusBar","\u002Fcsharp\u002Fdesktop-ui\u002Fcontent-controls","01.csharp\u002F12.desktop-ui\u002F13.content-controls",{"title":1455,"path":1456,"stem":1457},"UI\u002FUX принципи десктопних застосунків","\u002Fcsharp\u002Fdesktop-ui\u002F13a.ui-ux-principles","01.csharp\u002F12.desktop-ui\u002F13a.ui-ux-principles",{"title":1459,"path":1460,"stem":1461},"Dependency Properties — Концепція та Value Resolution","\u002Fcsharp\u002Fdesktop-ui\u002Fdependency-properties-part1","01.csharp\u002F12.desktop-ui\u002F14.dependency-properties-part1",{"title":1463,"path":1464,"stem":1465},"Avalonia Property System — StyledProperty та DirectProperty","\u002Fcsharp\u002Fdesktop-ui\u002F14a.avalonia-property-system","01.csharp\u002F12.desktop-ui\u002F14a.avalonia-property-system",{"title":1467,"path":1468,"stem":1469},"Attached Properties — Властивості без меж","\u002Fcsharp\u002Fdesktop-ui\u002Fattached-properties","01.csharp\u002F12.desktop-ui\u002F15.attached-properties",{"title":1471,"path":1472,"stem":1473},"Routed Events — Маршрутизація подій у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Frouted-events","01.csharp\u002F12.desktop-ui\u002F16.routed-events",{"title":1475,"path":1476,"stem":1477},"Data Binding — Від Code-Behind до Декларативності","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-basics-part1","01.csharp\u002F12.desktop-ui\u002F17.data-binding-basics-part1",{"title":1479,"path":1480,"stem":1481},"INotifyPropertyChanged — Живе оновлення UI","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-basics-part2","01.csharp\u002F12.desktop-ui\u002F17.data-binding-basics-part2",{"title":1483,"path":1484,"stem":1485},"Compiled Bindings в Avalonia — Безпека на етапі компіляції","\u002Fcsharp\u002Fdesktop-ui\u002F17a.avalonia-compiled-bindings","01.csharp\u002F12.desktop-ui\u002F17a.avalonia-compiled-bindings",{"title":1487,"path":1488,"stem":1489},"Просунутий Data Binding — ElementName, RelativeSource, MultiBinding","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-advanced","01.csharp\u002F12.desktop-ui\u002F18.data-binding-advanced",{"title":1491,"path":1492,"stem":1493},"Value Converters — Перетворення типів даних у Data Binding","\u002Fcsharp\u002Fdesktop-ui\u002Fvalue-converters","01.csharp\u002F12.desktop-ui\u002F19.value-converters",{"title":1495,"path":1496,"stem":1497},"Data Templates — Візуалізація об'єктів у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-templates","01.csharp\u002F12.desktop-ui\u002F20.data-templates",{"title":1499,"path":1500,"stem":1501},"Collections Binding Part 1 — ObservableCollection та ItemsControl","\u002Fcsharp\u002Fdesktop-ui\u002Fcollections-binding-part1","01.csharp\u002F12.desktop-ui\u002F21.collections-binding-part1",{"title":1503,"path":1504,"stem":1505},"Collections Binding Part 2 — ICollectionView, Filtering, Sorting та Virtualization","\u002Fcsharp\u002Fdesktop-ui\u002Fcollections-binding-part2","01.csharp\u002F12.desktop-ui\u002F21.collections-binding-part2",{"title":1507,"path":1508,"stem":1509},"MVVM Pattern — Від Spaghetti Code до архітектури","\u002Fcsharp\u002Fdesktop-ui\u002Fmvvm-pattern","01.csharp\u002F12.desktop-ui\u002F22.mvvm-pattern",{"title":1511,"path":1512,"stem":1513},"ViewModel Implementation — Від BaseViewModel до валідації","\u002Fcsharp\u002Fdesktop-ui\u002Fviewmodel-implementation","01.csharp\u002F12.desktop-ui\u002F23.viewmodel-implementation",{"title":1515,"path":1516,"stem":1517},"Commands — Від event handlers до декларативних команд","\u002Fcsharp\u002Fdesktop-ui\u002Fcommands","01.csharp\u002F12.desktop-ui\u002F24.commands",{"title":1519,"path":1520,"stem":1521},"MVVM Toolkit — MVVM без boilerplate через Source Generators","\u002Fcsharp\u002Fdesktop-ui\u002Fmvvm-toolkit","01.csharp\u002F12.desktop-ui\u002F25.mvvm-toolkit",{"title":1523,"path":1524,"stem":1525},"Messenger Pattern — Комунікація між ViewModel без прямих посилань","\u002Fcsharp\u002Fdesktop-ui\u002Fmessenger-pattern","01.csharp\u002F12.desktop-ui\u002F26.messenger-pattern",{"title":1527,"path":1528,"stem":1529},"Стилі WPF — CSS для десктопу","\u002Fcsharp\u002Fdesktop-ui\u002Fstyles-basics","01.csharp\u002F12.desktop-ui\u002F27.styles-basics",{"title":1531,"path":1532,"stem":1533},"CSS-like стилі Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002F27a.avalonia-css-styling","01.csharp\u002F12.desktop-ui\u002F27a.avalonia-css-styling",{"title":1535,"path":1536,"stem":1537},"Control Templates — Частина 1. Концепція та TemplateBinding","\u002Fcsharp\u002Fdesktop-ui\u002Fcontrol-templates-part1","01.csharp\u002F12.desktop-ui\u002F28.control-templates-part1",{"title":1539,"path":1540,"stem":1541},"Control Templates — Частина 2. Named Parts та ContentPresenter","\u002Fcsharp\u002Fdesktop-ui\u002Fcontrol-templates-part2","01.csharp\u002F12.desktop-ui\u002F28.control-templates-part2",{"title":1543,"path":1544,"stem":1545},"Control Themes в Avalonia — нова ера стилізації","\u002Fcsharp\u002Fdesktop-ui\u002F28a.avalonia-control-themes","01.csharp\u002F12.desktop-ui\u002F28a.avalonia-control-themes",{"title":1547,"path":1548,"stem":1549},"Triggers та Visual State Manager у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Ftriggers-visual-states","01.csharp\u002F12.desktop-ui\u002F29.triggers-visual-states",{"title":1551,"path":1552,"stem":1553},"Pseudo-classes в Avalonia — замість WPF Triggers","\u002Fcsharp\u002Fdesktop-ui\u002F29a.avalonia-pseudo-classes","01.csharp\u002F12.desktop-ui\u002F29a.avalonia-pseudo-classes",{"title":1555,"path":1556,"stem":1557},"Теми та ресурсні словники у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fresources-themes","01.csharp\u002F12.desktop-ui\u002F30.resources-themes",{"title":1559,"path":1560,"stem":1561},"Avalonia Themes — Fluent Design та система тематизації","\u002Fcsharp\u002Fdesktop-ui\u002F30a.avalonia-themes-fluent","01.csharp\u002F12.desktop-ui\u002F30a.avalonia-themes-fluent",{"title":1563,"path":1564,"stem":1565},"Контроли колекцій — глибоке занурення","\u002Fcsharp\u002Fdesktop-ui\u002Fcollection-controls","01.csharp\u002F12.desktop-ui\u002F31.collection-controls",{"title":1567,"path":1568,"stem":1569},"DataGrid — колонки та базове відображення","\u002Fcsharp\u002Fdesktop-ui\u002Fdatagrid-part1","01.csharp\u002F12.desktop-ui\u002F32.datagrid-part1",{"title":1571,"path":1572,"stem":1573},"DataGrid — сортування, фільтрація, редагування","\u002Fcsharp\u002Fdesktop-ui\u002Fdatagrid-part2","01.csharp\u002F12.desktop-ui\u002F32.datagrid-part2",{"title":1575,"path":1576,"stem":1577},"TreeView та GridView","\u002Fcsharp\u002Fdesktop-ui\u002Ftreeview-listview","01.csharp\u002F12.desktop-ui\u002F33.treeview-listview",{"title":1579,"path":1580,"stem":1581},"Меню, Toolbar, ContextMenu, StatusBar","\u002Fcsharp\u002Fdesktop-ui\u002Fmenus-toolbars","01.csharp\u002F12.desktop-ui\u002F34.menus-toolbars",{"title":1583,"path":1584,"stem":1585},"Навігація та керування вікнами. Частина 1: вікна та сторінки","\u002Fcsharp\u002Fdesktop-ui\u002Fnavigation-windows-part1","01.csharp\u002F12.desktop-ui\u002F35.navigation-windows-part1",{"title":1587,"path":1588,"stem":1589},"Навігація та керування вікнами. Частина 2: MVVM-навігація","\u002Fcsharp\u002Fdesktop-ui\u002Fnavigation-windows-part2","01.csharp\u002F12.desktop-ui\u002F35.navigation-windows-part2",{"title":1591,"path":1592,"stem":1593},"Avalonia — Навігація та діалоги","\u002Fcsharp\u002Fdesktop-ui\u002F35a.avalonia-navigation-dialogs","01.csharp\u002F12.desktop-ui\u002F35a.avalonia-navigation-dialogs",{"title":1595,"path":1596,"stem":1597},"Діалоги та File Pickers у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fdialogs-file-pickers","01.csharp\u002F12.desktop-ui\u002F36.dialogs-file-pickers",{"title":1599,"path":1600,"stem":1601},"UserControl: компонентний підхід у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fuser-controls","01.csharp\u002F12.desktop-ui\u002F37.user-controls",{"title":1603,"path":1604,"stem":1605},"Custom Controls: Lookless Controls у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fcustom-controls","01.csharp\u002F12.desktop-ui\u002F38.custom-controls",{"title":1607,"path":1608,"stem":1609},"Avalonia TemplatedControl — Lookless Controls","\u002Fcsharp\u002Fdesktop-ui\u002F38a.avalonia-templated-controls","01.csharp\u002F12.desktop-ui\u002F38a.avalonia-templated-controls",{"title":1611,"path":1612,"stem":1613},"Анімації у WPF: Storyboard та Easing Functions","\u002Fcsharp\u002Fdesktop-ui\u002Fanimations-transitions","01.csharp\u002F12.desktop-ui\u002F39.animations-transitions",{"title":1615,"path":1616,"stem":1617},"Анімації в Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002F39a.avalonia-animations","01.csharp\u002F12.desktop-ui\u002F39a.avalonia-animations",{"title":1619,"path":1620,"stem":1621},"2D Графіка та Мультимедіа у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fmedia-graphics","01.csharp\u002F12.desktop-ui\u002F40.media-graphics",{"title":1623,"path":1624,"stem":1625},"Dependency Injection у WPF та Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002Fdi-integration","01.csharp\u002F12.desktop-ui\u002F41.di-integration",{"title":1627,"path":1628,"stem":1629},"SQLite та EF Core у десктопних додатках","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-persistence-part1","01.csharp\u002F12.desktop-ui\u002F42.data-persistence-part1",{"title":1631,"path":1632,"stem":1633},"Repository Pattern та Unit of Work","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-persistence-part2","01.csharp\u002F12.desktop-ui\u002F43.data-persistence-part2",{"title":1635,"path":1636,"stem":1637},"Тестування ViewModels","\u002Fcsharp\u002Fdesktop-ui\u002Fviewmodel-testing","01.csharp\u002F12.desktop-ui\u002F44.viewmodel-testing",{"title":1639,"path":1640,"stem":1641},"Avalonia Headless Testing — тестування UI без вікон","\u002Fcsharp\u002Fdesktop-ui\u002F44a.avalonia-headless-testing","01.csharp\u002F12.desktop-ui\u002F44a.avalonia-headless-testing",{"title":1643,"path":1644,"stem":1645},"Кросплатформна розробка з Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002Favalonia-cross-platform","01.csharp\u002F12.desktop-ui\u002F45.avalonia-cross-platform",{"title":1647,"path":1648,"stem":1649},"Пакування та розгортання Avalonia додатків","\u002Fcsharp\u002Fdesktop-ui\u002Favalonia-packaging-deployment","01.csharp\u002F12.desktop-ui\u002F46.avalonia-packaging-deployment",{"title":1651,"path":1652,"stem":1653},"Розгортання WPF застосунків","\u002Fcsharp\u002Fdesktop-ui\u002Fwpf-packaging-deployment","01.csharp\u002F12.desktop-ui\u002F47.wpf-packaging-deployment",{"title":1655,"icon":658,"path":1656,"stem":1657,"children":1658,"page":59},"Network Programming","\u002Fcsharp\u002Fnetwork-programming","01.csharp\u002F13.network-programming",[1659,1663,1667,1671,1675,1679,1683,1687,1691,1695,1699],{"title":1660,"path":1661,"stem":1662},"Основи комп'ютерних мереж","\u002Fcsharp\u002Fnetwork-programming\u002Ffoundations","01.csharp\u002F13.network-programming\u002F01.foundations",{"title":1664,"path":1665,"stem":1666},"Модель OSI та стек TCP\u002FIP","\u002Fcsharp\u002Fnetwork-programming\u002Fosi-model","01.csharp\u002F13.network-programming\u002F02.osi-model",{"title":1668,"path":1669,"stem":1670},"IP-протокол та адресація","\u002Fcsharp\u002Fnetwork-programming\u002Fip-addressing","01.csharp\u002F13.network-programming\u002F03.ip-addressing",{"title":1672,"path":1673,"stem":1674},"UDP — протокол без з'єднання","\u002Fcsharp\u002Fnetwork-programming\u002Fudp","01.csharp\u002F13.network-programming\u002F05.udp",{"title":1676,"path":1677,"stem":1678},"UDP Broadcast та Multicast","\u002Fcsharp\u002Fnetwork-programming\u002Fudp-broadcast-multicast","01.csharp\u002F13.network-programming\u002F06.udp-broadcast-multicast",{"title":1680,"path":1681,"stem":1682},"HTTP — протокол вебу","\u002Fcsharp\u002Fnetwork-programming\u002Fhttp-fundamentals","01.csharp\u002F13.network-programming\u002F07.http-fundamentals",{"title":1684,"path":1685,"stem":1686},"HttpListener — вбудований HTTP-сервер .NET","\u002Fcsharp\u002Fnetwork-programming\u002F07a.http-listener","01.csharp\u002F13.network-programming\u002F07a.http-listener",{"title":1688,"path":1689,"stem":1690},"HTTP Advanced — cookies, аутентифікація та HTTPS","\u002Fcsharp\u002Fnetwork-programming\u002Fhttp-advanced","01.csharp\u002F13.network-programming\u002F08.http-advanced",{"title":1692,"path":1693,"stem":1694},"SMTP та протоколи електронної пошти","\u002Fcsharp\u002Fnetwork-programming\u002Fsmtp","01.csharp\u002F13.network-programming\u002F09.smtp",{"title":1696,"path":1697,"stem":1698},"WebSocket — повнодуплексний протокол реального часу","\u002Fcsharp\u002Fnetwork-programming\u002Fwebsockets","01.csharp\u002F13.network-programming\u002F10.websockets",{"title":1700,"path":1701,"stem":1702},"TLS\u002FSSL — криптографічний захист мережевих з'єднань","\u002Fcsharp\u002Fnetwork-programming\u002Ftls-ssl","01.csharp\u002F13.network-programming\u002F11.tls-ssl",{"title":1704,"path":1705,"stem":1706},"C# & .NET: The Ultimate Roadmap","\u002Fcsharp\u002Froadmap","01.csharp\u002Froadmap",{"title":1708,"icon":1709,"path":1710,"stem":1711,"children":1712,"page":59},"C++","i-devicon-cplusplus","\u002Fcpp","02.cpp",[1713,1717,1721,1725,1729,1733,1737,1741,1745,1748,1752,1756,1760,1764,1768,1772,1776,1780,1784,1788,1792,1796,1800,1804,1808,1812,1816,1820,1824,1828,1832,1836,1840,1844,1848,1852,1856,1860,1864,1868,1872,1876,1880,1884,1888,1892,1896,1900,1904,1908,1912,1916,1920,1924,1928,1932,1936,1940,1944,1948,1952,1956,1960,1964,1968,1972,1976,1980,1984,1988,1992,1996,2000,2004,2008,2012,2016,2020,2024,2028,2032,2036,2040,2044,2048,2052,2056,2060,2064,2068,2072,2076,2080,2084,2088,2092,2096,2100,2104,2108,2112,2116],{"title":1714,"path":1715,"stem":1716},"Вступ у програмування та алгоритми","\u002Fcpp\u002Fintro-algorithms","02.cpp\u002F01.intro-algorithms",{"title":1718,"path":1719,"stem":1720},"Code Style: угоди про оформлення коду","\u002Fcpp\u002Fcode-style","02.cpp\u002F02.code-style",{"title":1722,"path":1723,"stem":1724},"Середовище розробки та перший проєкт","\u002Fcpp\u002Fide-setup","02.cpp\u002F03.ide-setup",{"title":1726,"path":1727,"stem":1728},"Вивід даних на екран","\u002Fcpp\u002Fdata-output","02.cpp\u002F04.data-output",{"title":1730,"path":1731,"stem":1732},"Типи даних, змінні та константи","\u002Fcpp\u002Fdata-types-variables","02.cpp\u002F05.data-types-variables",{"title":1734,"path":1735,"stem":1736},"Ввід даних з клавіатури","\u002Fcpp\u002Fdata-input","02.cpp\u002F06.data-input",{"title":1738,"path":1739,"stem":1740},"Оператори, перетворення типів та логічні операції","\u002Fcpp\u002Foperators-type-conversion","02.cpp\u002F07.operators-type-conversion",{"title":1742,"path":1743,"stem":1744},"Цикли","\u002Fcpp\u002Floops","02.cpp\u002F08.loops",{"title":32,"path":1746,"stem":1747},"\u002Fcpp\u002Farrays","02.cpp\u002F09.arrays",{"title":1749,"path":1750,"stem":1751},"Алгоритми сортування та аналіз складності","\u002Fcpp\u002Fsorting","02.cpp\u002F10.sorting",{"title":1753,"path":1754,"stem":1755},"Революція C++20: Ranges та Views","\u002Fcpp\u002Franges-views","02.cpp\u002F100.ranges-views",{"title":1757,"path":1758,"stem":1759},"Алгоритми пошуку","\u002Fcpp\u002Fsearching","02.cpp\u002F11.searching",{"title":1761,"path":1762,"stem":1763},"Функції: основи","\u002Fcpp\u002Ffunctions-basics","02.cpp\u002F12.functions-basics",{"title":1765,"path":1766,"stem":1767},"Функції: прототипи, область видимості та додаткові можливості","\u002Fcpp\u002Ffunctions-scope","02.cpp\u002F13.functions-scope",{"title":1769,"path":1770,"stem":1771},"Функції: перевантаження та шаблони","\u002Fcpp\u002Ffunctions-overloading-templates","02.cpp\u002F14.functions-overloading-templates",{"title":1773,"path":1774,"stem":1775},"Вказівники: основи","\u002Fcpp\u002Fpointers-basics","02.cpp\u002F15.pointers-basics",{"title":1777,"path":1778,"stem":1779},"Посилання (References)","\u002Fcpp\u002Freferences","02.cpp\u002F16.references",{"title":1781,"path":1782,"stem":1783},"Вказівники, const і масиви","\u002Fcpp\u002Fpointers-const-arrays","02.cpp\u002F17.pointers-const-arrays",{"title":1785,"path":1786,"stem":1787},"Адресна арифметика","\u002Fcpp\u002Fpointer-arithmetic","02.cpp\u002F18.pointer-arithmetic",{"title":1789,"path":1790,"stem":1791},"Динамічна пам'ять","\u002Fcpp\u002Fdynamic-memory","02.cpp\u002F19.dynamic-memory",{"title":1793,"path":1794,"stem":1795},"Вказівники типу void","\u002Fcpp\u002Fvoid-pointers","02.cpp\u002F20.void-pointers",{"title":1797,"path":1798,"stem":1799},"Вказівники на вказівники","\u002Fcpp\u002Fpointers-to-pointers","02.cpp\u002F21.pointers-to-pointers",{"title":1801,"path":1802,"stem":1803},"Оператор доступу до членів через вказівник (->)","\u002Fcpp\u002Fmember-access-operator","02.cpp\u002F22.member-access-operator",{"title":1805,"path":1806,"stem":1807},"Цикл for-each (Range-based for)","\u002Fcpp\u002Fforeach-loop","02.cpp\u002F23.foreach-loop",{"title":1809,"path":1810,"stem":1811},"Вказівники на функції","\u002Fcpp\u002Ffunction-pointers","02.cpp\u002F24.function-pointers",{"title":1813,"path":1814,"stem":1815},"Лямбда-вирази","\u002Fcpp\u002Flambdas","02.cpp\u002F25.lambdas",{"title":1817,"path":1818,"stem":1819},"Лямбда-захоплення","\u002Fcpp\u002Flambda-captures","02.cpp\u002F26.lambda-captures",{"title":1821,"path":1822,"stem":1823},"Еліпсис","\u002Fcpp\u002Fellipsis","02.cpp\u002F27.ellipsis",{"title":1825,"path":1826,"stem":1827},"Безпечні альтернативи еліпсису","\u002Fcpp\u002F27a.ellipsis","02.cpp\u002F27a.ellipsis",{"title":1829,"path":1830,"stem":1831},"Аргументи командного рядка","\u002Fcpp\u002Fcommand-line-arguments","02.cpp\u002F28.command-line-arguments",{"title":1833,"path":1834,"stem":1835},"Перерахування (enum)","\u002Fcpp\u002Fenum","02.cpp\u002F29.enum",{"title":1837,"path":1838,"stem":1839},"Класи-перерахування (enum class)","\u002Fcpp\u002Fenum-class","02.cpp\u002F30.enum-class",{"title":1841,"path":1842,"stem":1843},"Псевдоніми типів (typedef і using)","\u002Fcpp\u002Ftype-aliases","02.cpp\u002F31.type-aliases",{"title":1845,"path":1846,"stem":1847},"Системи числення та двійкова арифметика","\u002Fcpp\u002Fnumber-systems","02.cpp\u002F32.number-systems",{"title":1849,"path":1850,"stem":1851},"Структури (struct): агрегування даних","\u002Fcpp\u002Fstruct","02.cpp\u002F33.struct",{"title":1853,"path":1854,"stem":1855},"Структури у функціях","\u002Fcpp\u002Fstruct-functions","02.cpp\u002F34.struct-functions",{"title":1857,"path":1858,"stem":1859},"Масиви структур і вкладені структури","\u002Fcpp\u002Fstruct-arrays","02.cpp\u002F35.struct-arrays",{"title":1861,"path":1862,"stem":1863},"Патерни struct та межі застосування","\u002Fcpp\u002Fstruct-patterns","02.cpp\u002F36.struct-patterns",{"title":1865,"path":1866,"stem":1867},"Символи та таблиця ASCII","\u002Fcpp\u002Fascii-characters","02.cpp\u002F37.ascii-characters",{"title":1869,"path":1870,"stem":1871},"Unicode та кодування UTF","\u002Fcpp\u002Funicode-utf","02.cpp\u002F38.unicode-utf",{"title":1873,"path":1874,"stem":1875},"C-style рядки","\u002Fcpp\u002Fc-strings","02.cpp\u002F39.c-strings",{"title":1877,"path":1878,"stem":1879},"Вступ до std::string","\u002Fcpp\u002Fstd-string-intro","02.cpp\u002F40.std-string-intro",{"title":1881,"path":1882,"stem":1883},"Довжина, ємність та доступ до символів std::string","\u002Fcpp\u002Fstd-string-capacity-access","02.cpp\u002F41.std-string-capacity-access",{"title":1885,"path":1886,"stem":1887},"Модифікація std::string: присвоювання, додавання, вставка, видалення та заміна","\u002Fcpp\u002Fstd-string-modification","02.cpp\u002F42.std-string-modification",{"title":1889,"path":1890,"stem":1891},"Пошук у std::string: find, npos та практичні патерни","\u002Fcpp\u002Fstd-string-search","02.cpp\u002F43.std-string-search",{"title":1893,"path":1894,"stem":1895},"std::string_view: невласницький погляд на рядок без копіювання","\u002Fcpp\u002Fstd-string-view","02.cpp\u002F44.std-string-view",{"title":1897,"path":1898,"stem":1899},"Об'єднання (union): один блок пам'яті, кілька інтерпретацій","\u002Fcpp\u002Funion","02.cpp\u002F45.union",{"title":1901,"path":1902,"stem":1903},"Організація коду: файли, препроцесор, простори імен","\u002Fcpp\u002Fmultifile-programs","02.cpp\u002F46.multifile-programs",{"title":1905,"path":1906,"stem":1907},"Робота з файлами: C-стиль (stdio.h)","\u002Fcpp\u002Fc-style-files","02.cpp\u002F47.c-style-files",{"title":1909,"path":1910,"stem":1911},"Робота з файлами: C++-стиль (fstream)","\u002Fcpp\u002Fcpp-style-files","02.cpp\u002F48.cpp-style-files",{"title":1913,"path":1914,"stem":1915},"Введення в ООП: від процедур до об'єктів","\u002Fcpp\u002Foop-intro","02.cpp\u002F49.oop-intro",{"title":1917,"path":1918,"stem":1919},"Класи, об'єкти та методи","\u002Fcpp\u002Fclasses-objects-methods","02.cpp\u002F50.classes-objects-methods",{"title":1921,"path":1922,"stem":1923},"Специфікатори доступу та інкапсуляція","\u002Fcpp\u002Faccess-specifiers-encapsulation","02.cpp\u002F51.access-specifiers-encapsulation",{"title":1925,"path":1926,"stem":1927},"Конструктори: гарантована ініціалізація об'єктів","\u002Fcpp\u002Fconstructors","02.cpp\u002F52.constructors",{"title":1929,"path":1930,"stem":1931},"Списки ініціалізації та делегуючі конструктори","\u002Fcpp\u002Finit-lists-delegating","02.cpp\u002F53.init-lists-delegating",{"title":1933,"path":1934,"stem":1935},"Деструктори та ідіома RAII","\u002Fcpp\u002Fdestructors-raii","02.cpp\u002F54.destructors-raii",{"title":1937,"path":1938,"stem":1939},"Прихований покажчик this","\u002Fcpp\u002Fthis-pointer","02.cpp\u002F55.this-pointer",{"title":1941,"path":1942,"stem":1943},"Розподіл класу на заголовковий файл та файл реалізації","\u002Fcpp\u002Fclass-header-source","02.cpp\u002F56.class-header-source",{"title":1945,"path":1946,"stem":1947},"Класи та const","\u002Fcpp\u002Fconst-classes","02.cpp\u002F57.const-classes",{"title":1949,"path":1950,"stem":1951},"Статичні члени класу","\u002Fcpp\u002Fstatic-members","02.cpp\u002F58.static-members",{"title":1953,"path":1954,"stem":1955},"Конструктор копіювання та запобігання копіюванню","\u002Fcpp\u002Fcopy-constructor","02.cpp\u002F59.copy-constructor",{"title":1957,"path":1958,"stem":1959},"Дружні функції та класи","\u002Fcpp\u002Ffriend-functions-classes","02.cpp\u002F60.friend-functions-classes",{"title":1961,"path":1962,"stem":1963},"Анонімні об'єкти та вкладені типи","\u002Fcpp\u002Fanonymous-objects-nested-types","02.cpp\u002F61.anonymous-objects-nested-types",{"title":1965,"path":1966,"stem":1967},"Вимірювання часу виконання: RAII-таймер","\u002Fcpp\u002Ftiming-raii-timer","02.cpp\u002F62.timing-raii-timer",{"title":1969,"path":1970,"stem":1971},"Перевантаження операторів: основи та арифметика","\u002Fcpp\u002Foperator-overloading-basics","02.cpp\u002F63.operator-overloading-basics",{"title":1973,"path":1974,"stem":1975},"Перевантаження операторів: методи класу та спеціальні оператори","\u002Fcpp\u002Foperator-overloading-methods","02.cpp\u002F64.operator-overloading-methods",{"title":1977,"path":1978,"stem":1979},"Приведення типів, explicit та delete","\u002Fcpp\u002Ftypecast-explicit-delete","02.cpp\u002F65.typecast-explicit-delete",{"title":1981,"path":1982,"stem":1983},"Глибоке копіювання та оператор присвоювання","\u002Fcpp\u002Fdeep-copy-assignment","02.cpp\u002F66.deep-copy-assignment",{"title":1985,"path":1986,"stem":1987},"Зв'язки між об'єктами: композиція та агрегація","\u002Fcpp\u002Fcomposition-aggregation","02.cpp\u002F67.composition-aggregation",{"title":1989,"path":1990,"stem":1991},"Асоціація та залежність між об","\u002Fcpp\u002Fassociation-dependency","02.cpp\u002F68.association-dependency",{"title":1993,"path":1994,"stem":1995},"Контейнерні класи та `std::initializer_list`","\u002Fcpp\u002Fcontainer-classes-initializer-list","02.cpp\u002F69.container-classes-initializer-list",{"title":1997,"path":1998,"stem":1999},"Вступ до наслідування: базові поняття та відношення «is-a»","\u002Fcpp\u002Finheritance-intro","02.cpp\u002F70.inheritance-intro",{"title":2001,"path":2002,"stem":2003},"Конструктори, деструктори та порядок ініціалізації в ієрархіях","\u002Fcpp\u002Finheritance-constructors-destructors","02.cpp\u002F71.inheritance-constructors-destructors",{"title":2005,"path":2006,"stem":2007},"Специфікатор `protected` та види наслідування","\u002Fcpp\u002Finheritance-access-specifiers","02.cpp\u002F72.inheritance-access-specifiers",{"title":2009,"path":2010,"stem":2011},"Перевизначення методів та приховування імен","\u002Fcpp\u002Fmethod-overriding-hiding","02.cpp\u002F73.method-overriding-hiding",{"title":2013,"path":2014,"stem":2015},"Множинне наслідування та проблема ромба","\u002Fcpp\u002Fmultiple-inheritance-diamond","02.cpp\u002F74.multiple-inheritance-diamond",{"title":2017,"path":2018,"stem":2019},"Вказівники на базовий клас та віртуальні функції","\u002Fcpp\u002Fvirtual-functions-polymorphism","02.cpp\u002F75.virtual-functions-polymorphism",{"title":2021,"path":2022,"stem":2023},"Специфікатори override, final та віртуальні деструктори","\u002Fcpp\u002Foverride-final-virtual-destructors","02.cpp\u002F76.override-final-virtual-destructors",{"title":2025,"path":2026,"stem":2027},"Внутрішні механізми поліморфізму: vtable, vptr та зв'язування","\u002Fcpp\u002Fvirtual-table-binding","02.cpp\u002F77.virtual-table-binding",{"title":2029,"path":2030,"stem":2031},"Абстрактні класи та чисті віртуальні функції","\u002Fcpp\u002Fabstract-classes-interfaces","02.cpp\u002F78.abstract-classes-interfaces",{"title":2033,"path":2034,"stem":2035},"Зрізка об'єктів, віртуальне наслідування та поліморфний вивід","\u002Fcpp\u002Fslicing-virtual-base-io","02.cpp\u002F79.slicing-virtual-base-io",{"title":2037,"path":2038,"stem":2039},"Динамічне приведення типів (`dynamic_cast`) та RTTI","\u002Fcpp\u002Fdynamic-cast-rtti","02.cpp\u002F80.dynamic-cast-rtti",{"title":2041,"path":2042,"stem":2043},"Шаблони функцій: узагальнене програмування","\u002Fcpp\u002Ffunction-templates","02.cpp\u002F81.function-templates",{"title":2045,"path":2046,"stem":2047},"Шаблони класів та NTTP-параметри","\u002Fcpp\u002Fclass-templates-nttp","02.cpp\u002F82.class-templates-nttp",{"title":2049,"path":2050,"stem":2051},"Повна (явна) спеціалізація шаблонів","\u002Fcpp\u002Ffull-template-specialization","02.cpp\u002F83.full-template-specialization",{"title":2053,"path":2054,"stem":2055},"Часткова спеціалізація шаблонів класів","\u002Fcpp\u002Fpartial-template-specialization","02.cpp\u002F84.partial-template-specialization",{"title":2057,"path":2058,"stem":2059},"Механізм винятків: try, catch, throw та розкручування стеку","\u002Fcpp\u002Fexceptions-basics","02.cpp\u002F85.exceptions-basics",{"title":2061,"path":2062,"stem":2063},"Ієрархія std::exception та власні класи винятків","\u002Fcpp\u002Fexception-hierarchy-custom","02.cpp\u002F86.exception-hierarchy-custom",{"title":2065,"path":2066,"stem":2067},"Повторне генерування винятків та функціональний try-блок","\u002Fcpp\u002Frethrow-function-try","02.cpp\u002F87.rethrow-function-try",{"title":2069,"path":2070,"stem":2071},"Безпека винятків, noexcept та деструктори","\u002Fcpp\u002Fsafety-noexcept","02.cpp\u002F88.safety-noexcept",{"title":2073,"path":2074,"stem":2075},"Власні структури даних: стек та черга","\u002Fcpp\u002Fcustom-stack-queue","02.cpp\u002F89.custom-stack-queue",{"title":2077,"path":2078,"stem":2079},"Власні структури даних: однозв'язаний список","\u002Fcpp\u002Flinked-list","02.cpp\u002F90.linked-list",{"title":2081,"path":2082,"stem":2083},"Власні структури даних: бінарне дерево пошуку","\u002Fcpp\u002Fbinary-search-tree","02.cpp\u002F91.binary-search-tree",{"title":2085,"path":2086,"stem":2087},"Власні структури даних: хеш-таблиця","\u002Fcpp\u002Fhash-table","02.cpp\u002F92.hash-table",{"title":2089,"path":2090,"stem":2091},"Готові структури даних C++: послідовні контейнери STL","\u002Fcpp\u002Fstl-sequential-containers","02.cpp\u002F93.stl-sequential-containers",{"title":2093,"path":2094,"stem":2095},"Готові структури даних C++: асоціативні контейнери та адаптери","\u002Fcpp\u002Fstl-associative-adapters","02.cpp\u002F94.stl-associative-adapters",{"title":2097,"path":2098,"stem":2099},"Готові структури даних C++: ітератори та алгоритми STL","\u002Fcpp\u002Fstl-iterators-algorithms","02.cpp\u002F95.stl-iterators-algorithms",{"title":2101,"path":2102,"stem":2103},"R-value посилання та move-семантика","\u002Fcpp\u002Frvalue-references-move-semantics","02.cpp\u002F96.rvalue-references-move-semantics",{"title":2105,"path":2106,"stem":2107},"Move-конструктор, move-присвоювання та Правило п","\u002Fcpp\u002Fmove-constructors-rule-of-five","02.cpp\u002F97.move-constructors-rule-of-five",{"title":2109,"path":2110,"stem":2111},"Розумний покажчик std::unique_ptr","\u002Fcpp\u002Funique-ptr","02.cpp\u002F98.unique-ptr",{"title":2113,"path":2114,"stem":2115},"Спільне володіння: std::shared_ptr та std::weak_ptr","\u002Fcpp\u002Fshared-ptr-weak-ptr","02.cpp\u002F99.shared-ptr-weak-ptr",{"title":2117,"icon":2118,"path":2119,"stem":2120,"children":2121,"page":59},"CMake і vcpkg","i-devicon-cmake","\u002Fcpp\u002Fcmake","02.cpp\u002F990.cmake",[2122,2126,2130,2134,2138,2142,2146,2150,2154,2158,2162,2166,2170,2174,2178,2182,2186,2190],{"title":2123,"path":2124,"stem":2125},"CMake: навіщо він потрібен і як його встановити","\u002Fcpp\u002Fcmake\u002Fwhat-is-cmake","02.cpp\u002F990.cmake\u002F01.what-is-cmake",{"title":2127,"path":2128,"stem":2129},"Перший проєкт з CMake: конфігурація, збірка, запуск","\u002Fcpp\u002Fcmake\u002Ffirst-project","02.cpp\u002F990.cmake\u002F02.first-project",{"title":2131,"path":2132,"stem":2133},"Синтаксис CMakeLists.txt: команди, змінні, списки","\u002Fcpp\u002Fcmake\u002Fcmakelists-syntax","02.cpp\u002F990.cmake\u002F03.cmakelists-syntax",{"title":2135,"path":2136,"stem":2137},"Проєкт із кількома файлами: перелік джерел і file(GLOB)","\u002Fcpp\u002Fcmake\u002Fmultiple-files","02.cpp\u002F990.cmake\u002F04.multiple-files",{"title":2139,"path":2140,"stem":2141},"Бібліотеки в CMake: STATIC, SHARED, INTERFACE та видимість PUBLIC\u002FPRIVATE","\u002Fcpp\u002Fcmake\u002Flibraries","02.cpp\u002F990.cmake\u002F05.libraries",{"title":2143,"path":2144,"stem":2145},"Підключення зовнішніх бібліотек: find_package, add_subdirectory, FetchContent, pkg-config","\u002Fcpp\u002Fcmake\u002Fexternal-libraries","02.cpp\u002F990.cmake\u002F06.external-libraries",{"title":2147,"path":2148,"stem":2149},"Умови, опції, цикли та функції в CMake","\u002Fcpp\u002Fcmake\u002Fvariables-conditions","02.cpp\u002F990.cmake\u002F07.variables-conditions",{"title":2151,"path":2152,"stem":2153},"Конфігурації збірки: Debug, Release і вирази-генератори","\u002Fcpp\u002Fcmake\u002Fbuild-configurations","02.cpp\u002F990.cmake\u002F08.build-configurations",{"title":2155,"path":2156,"stem":2157},"Структура великого проєкту: підпапки, модулі CMake, PCH та install","\u002Fcpp\u002Fcmake\u002Fproject-structure","02.cpp\u002F990.cmake\u002F09.project-structure",{"title":2159,"path":2160,"stem":2161},"Тестування з CMake: CTest, Google Test, покриття коду","\u002Fcpp\u002Fcmake\u002Ftesting-ctest","02.cpp\u002F990.cmake\u002F10.testing-ctest",{"title":2163,"path":2164,"stem":2165},"Команди CMake, пресети, скрипти збірки та кращі практики","\u002Fcpp\u002Fcmake\u002Fcommands-best-practices","02.cpp\u002F990.cmake\u002F11.commands-best-practices",{"title":2167,"path":2168,"stem":2169},"Практичні проєкти: калькулятор, Qt-застосунок і кросплатформна збірка","\u002Fcpp\u002Fcmake\u002Freal-projects","02.cpp\u002F990.cmake\u002F12.real-projects",{"title":2171,"path":2172,"stem":2173},"Пакетні менеджери для C++: vcpkg, Conan, CPM та системні пакети","\u002Fcpp\u002Fcmake\u002Fpackage-managers","02.cpp\u002F990.cmake\u002F13.package-managers",{"title":2175,"path":2176,"stem":2177},"vcpkg: встановлення, основні команди та triplets","\u002Fcpp\u002Fcmake\u002Fvcpkg-basics","02.cpp\u002F990.cmake\u002F14.vcpkg-basics",{"title":2179,"path":2180,"stem":2181},"vcpkg і CMake: toolchain-файл, manifest vcpkg.json, IDE","\u002Fcpp\u002Fcmake\u002Fvcpkg-cmake","02.cpp\u002F990.cmake\u002F15.vcpkg-cmake",{"title":2183,"path":2184,"stem":2185},"vcpkg для досвідчених: версії, features, реєстри, власні порти, кеш і діагностика","\u002Fcpp\u002Fcmake\u002Fvcpkg-advanced","02.cpp\u002F990.cmake\u002F16.vcpkg-advanced",{"title":2187,"path":2188,"stem":2189},"Бібліотеки C++: fmt, spdlog і nlohmann\u002Fjson","\u002Fcpp\u002Fcmake\u002Flibraries-format-log-json","02.cpp\u002F990.cmake\u002F17.libraries-format-log-json",{"title":2191,"path":2192,"stem":2193},"Бібліотеки C++: cpp-httplib, cxxopts, CLI11, Google Test і Catch2","\u002Fcpp\u002Fcmake\u002Flibraries-network-cli-testing","02.cpp\u002F990.cmake\u002F18.libraries-network-cli-testing",{"title":2195,"icon":2196,"path":2197,"stem":2198,"children":2199,"page":59},"JavaScript","i-devicon-javascript","\u002Fjavascript","03.javascript",[2200,2226,2280,2302,2606,2644,2662],{"title":2201,"icon":2202,"path":2203,"stem":2204,"children":2205,"page":59},"Events","i-lucide-mouse-pointer-click","\u002Fjavascript\u002Fevents","03.javascript\u002F01.events",[2206,2210,2214,2218,2222],{"title":2207,"path":2208,"stem":2209},"Вступ до подій браузера","\u002Fjavascript\u002Fevents\u002Fintro","03.javascript\u002F01.events\u002F01.intro",{"title":2211,"path":2212,"stem":2213},"Бульбашковий механізм (Bubbling) та занурення (Capturing)","\u002Fjavascript\u002Fevents\u002Fbubbling-capturing","03.javascript\u002F01.events\u002F02.bubbling-capturing",{"title":2215,"path":2216,"stem":2217},"Делегування подій (Event Delegation)","\u002Fjavascript\u002Fevents\u002Fdelegate-events","03.javascript\u002F01.events\u002F03.delegate-events",{"title":2219,"path":2220,"stem":2221},"Типові дії браузера та preventDefault()","\u002Fjavascript\u002Fevents\u002Fprevent-default","03.javascript\u002F01.events\u002F04.prevent-default",{"title":2223,"path":2224,"stem":2225},"Запуск користувацьких подій (Custom Events)","\u002Fjavascript\u002Fevents\u002Fcustom-events","03.javascript\u002F01.events\u002F05.custom-events",{"title":2227,"icon":2228,"path":2229,"stem":2230,"children":2231,"page":59},"Network","i-lucide-globe","\u002Fjavascript\u002Fnetwork","03.javascript\u002F02.network",[2232,2236,2240,2244,2248,2252,2256,2260,2264,2268,2272,2276],{"title":2233,"path":2234,"stem":2235},"Fetch API - Сучасний підхід до HTTP-запитів","\u002Fjavascript\u002Fnetwork\u002F01-fetch-api","03.javascript\u002F02.network\u002F01-fetch-api",{"title":2237,"path":2238,"stem":2239},"FormData - Робота з формами та файлами","\u002Fjavascript\u002Fnetwork\u002F02-formdata","03.javascript\u002F02.network\u002F02-formdata",{"title":2241,"path":2242,"stem":2243},"Відстеження прогресу завантаження","\u002Fjavascript\u002Fnetwork\u002F03-download-progress","03.javascript\u002F02.network\u002F03-download-progress",{"title":2245,"path":2246,"stem":2247},"Переривання fetch-запитів","\u002Fjavascript\u002Fnetwork\u002F04-abort-requests","03.javascript\u002F02.network\u002F04-abort-requests",{"title":2249,"path":2250,"stem":2251},"CORS - Запити між різними джерелами","\u002Fjavascript\u002Fnetwork\u002F05-cors","03.javascript\u002F02.network\u002F05-cors",{"title":2253,"path":2254,"stem":2255},"Fetch API - Повний довідник опцій","\u002Fjavascript\u002Fnetwork\u002F06-fetch-options","03.javascript\u002F02.network\u002F06-fetch-options",{"title":2257,"path":2258,"stem":2259},"URL Objects - Робота з посиланнями","\u002Fjavascript\u002Fnetwork\u002F07-url-objects","03.javascript\u002F02.network\u002F07-url-objects",{"title":2261,"path":2262,"stem":2263},"XMLHttpRequest - AJAX та низькорівневі запити","\u002Fjavascript\u002Fnetwork\u002F08-xmlhttprequest","03.javascript\u002F02.network\u002F08-xmlhttprequest",{"title":2265,"path":2266,"stem":2267},"Відновлюване завантаження файлів","\u002Fjavascript\u002Fnetwork\u002F09-resumable-upload","03.javascript\u002F02.network\u002F09-resumable-upload",{"title":2269,"path":2270,"stem":2271},"Cookies, document.cookie та світ після \"Cookiepocalypse\"","\u002Fjavascript\u002Fnetwork\u002F10-cookies","03.javascript\u002F02.network\u002F10-cookies",{"title":2273,"path":2274,"stem":2275},"js-cookie: Керування Cookies без Болю","\u002Fjavascript\u002Fnetwork\u002F11-js-cookie","03.javascript\u002F02.network\u002F11-js-cookie",{"title":2277,"path":2278,"stem":2279},"Axios: Потужний HTTP-клієнт для JavaScript","\u002Fjavascript\u002Fnetwork\u002F12-axios","03.javascript\u002F02.network\u002F12-axios",{"title":2281,"icon":2282,"path":2283,"stem":2284,"children":2285,"page":59},"Bom","i-lucide-monitor","\u002Fjavascript\u002Fbom","03.javascript\u002F03.bom",[2286,2290,2294,2298],{"title":2287,"path":2288,"stem":2289},"LocalStorage, SessionStorage та patterns збереження даних","\u002Fjavascript\u002Fbom\u002F01-localstorage","03.javascript\u002F03.bom\u002F01-localstorage",{"title":2291,"path":2292,"stem":2293},"Location Object - Керування адресою сторінки","\u002Fjavascript\u002Fbom\u002F02-location-object","03.javascript\u002F03.bom\u002F02-location-object",{"title":2295,"path":2296,"stem":2297},"History API - Керування історією браузера","\u002Fjavascript\u002Fbom\u002F03-history-api","03.javascript\u002F03.bom\u002F03-history-api",{"title":2299,"path":2300,"stem":2301},"Navigator Object - Ідентифікація та Можливості Пристрою","\u002Fjavascript\u002Fbom\u002F04-navigator-object","03.javascript\u002F03.bom\u002F04-navigator-object",{"title":2303,"icon":2304,"path":2305,"stem":2306,"children":2307},"React","i-devicon-react","\u002Fjavascript\u002Freact","03.javascript\u002F04.react\u002Findex",[2308,2309,2313,2317,2321,2325,2388,2423,2575],{"title":2303,"path":2305,"stem":2306},{"title":2310,"path":2311,"stem":2312},"Робота з Формами в React","\u002Fjavascript\u002Freact\u002Freact-forms","03.javascript\u002F04.react\u002F01.react-forms",{"title":2314,"path":2315,"stem":2316},"React Hook Form: Професійна Робота з Формами","\u002Fjavascript\u002Freact\u002Freact-hook-form","03.javascript\u002F04.react\u002F02.react-hook-form",{"title":2318,"path":2319,"stem":2320},"React Hook Form: Глибоке Розуміння Архітектури та Оптимізації","\u002Fjavascript\u002Freact\u002Freact-hook-form-new","03.javascript\u002F04.react\u002F02.react-hook-form-new",{"title":2322,"path":2323,"stem":2324},"Axios та React: Професійна Архітектура Запитів","\u002Fjavascript\u002Freact\u002Fdata-fetching-axios","03.javascript\u002F04.react\u002F03.data-fetching-axios",{"title":2326,"icon":132,"path":2327,"stem":2328,"children":2329},"Tanstack Query","\u002Fjavascript\u002Freact\u002Ftanstack-query","03.javascript\u002F04.react\u002F04.tanstack-query\u002Findex",[2330,2332,2336,2340,2344,2348,2352,2356,2360,2364,2368,2372,2376,2380,2384],{"title":2331,"path":2327,"stem":2328},"TanStack Query: Майстерність Керування Станом Сервера",{"title":2333,"path":2334,"stem":2335},"Парадигма Server State: Чому useEffect недостатньо","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fserver-state-paradigm","03.javascript\u002F04.react\u002F04.tanstack-query\u002F01.server-state-paradigm",{"title":2337,"path":2338,"stem":2339},"Встановлення та Налаштування: Фундамент","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Finstallation-and-devtools","03.javascript\u002F04.react\u002F04.tanstack-query\u002F02.installation-and-devtools",{"title":2341,"path":2342,"stem":2343},"Основи Запитів та Магія Ключів","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fquery-basics-and-keys","03.javascript\u002F04.react\u002F04.tanstack-query\u002F03.query-basics-and-keys",{"title":2345,"path":2346,"stem":2347},"Синхронізація Даних: Життєвий Цикл Запиту","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fdata-synchronization","03.javascript\u002F04.react\u002F04.tanstack-query\u002F04.data-synchronization",{"title":2349,"path":2350,"stem":2351},"Мутації та Інвалідація: Зміна Даних","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fmutations-and-invalidation","03.javascript\u002F04.react\u002F04.tanstack-query\u002F05.mutations-and-invalidation",{"title":2353,"path":2354,"stem":2355},"Оптимістичні Оновлення: Швидше за Світло","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Foptimistic-updates","03.javascript\u002F04.react\u002F04.tanstack-query\u002F06.optimistic-updates",{"title":2357,"path":2358,"stem":2359},"Пагінація та Infinite Scroll","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fpagination-and-load-more","03.javascript\u002F04.react\u002F04.tanstack-query\u002F07.pagination-and-load-more",{"title":2361,"path":2362,"stem":2363},"Просунуті Патерни та Оптимізація","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fadvanced-patterns","03.javascript\u002F04.react\u002F04.tanstack-query\u002F08.advanced-patterns",{"title":2365,"path":2366,"stem":2367},"Архітектура та Best Practices","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Farchitecture-and-best-practices","03.javascript\u002F04.react\u002F04.tanstack-query\u002F09.architecture-and-best-practices",{"title":2369,"path":2370,"stem":2371},"Server-Side Rendering (SSR) та Гідратація","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fserver-side-rendering","03.javascript\u002F04.react\u002F04.tanstack-query\u002F10.server-side-rendering",{"title":2373,"path":2374,"stem":2375},"Стратегії Тестування","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Ftesting-strategies","03.javascript\u002F04.react\u002F04.tanstack-query\u002F11.testing-strategies",{"title":2377,"path":2378,"stem":2379},"Аутентифікація та Обробка Помилок","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fauthentication-and-errors","03.javascript\u002F04.react\u002F04.tanstack-query\u002F12.authentication-and-errors",{"title":2381,"path":2382,"stem":2383},"React Suspense та Майбутнє","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Freact-suspense","03.javascript\u002F04.react\u002F04.tanstack-query\u002F13.react-suspense",{"title":2385,"path":2386,"stem":2387},"Глибоке Занурення в Продуктивність","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fperformance-deep-dive","03.javascript\u002F04.react\u002F04.tanstack-query\u002F14.performance-deep-dive",{"title":2389,"icon":2304,"path":2390,"stem":2391,"children":2392},"React Router","\u002Fjavascript\u002Freact\u002Freact-router","03.javascript\u002F04.react\u002F05.react-router\u002Findex",[2393,2395,2399,2403,2407,2411,2415,2419],{"title":2394,"path":2390,"stem":2391},"React Router: Навігаційна система сучасного вебу",{"title":2396,"path":2397,"stem":2398},"Налаштування та Базовий Роутинг","\u002Fjavascript\u002Freact\u002Freact-router\u002Fsetup-and-basic-routing","03.javascript\u002F04.react\u002F05.react-router\u002F01.setup-and-basic-routing",{"title":2400,"path":2401,"stem":2402},"Динамічна Навігація","\u002Fjavascript\u002Freact\u002Freact-router\u002Fnavigation-and-links","03.javascript\u002F04.react\u002F05.react-router\u002F02.navigation-and-links",{"title":2404,"path":2405,"stem":2406},"Вкладені Маршрути та Макети","\u002Fjavascript\u002Freact\u002Freact-router\u002Fnested-routes-and-layouts","03.javascript\u002F04.react\u002F05.react-router\u002F03.nested-routes-and-layouts",{"title":2408,"path":2409,"stem":2410},"Динамічні Маршрути та Параметри","\u002Fjavascript\u002Freact\u002Freact-router\u002Fdynamic-routing","03.javascript\u002F04.react\u002F05.react-router\u002F04.dynamic-routing",{"title":2412,"path":2413,"stem":2414},"Data APIs: Loaders та Actions","\u002Fjavascript\u002Freact\u002Freact-router\u002Fdata-loading","03.javascript\u002F04.react\u002F05.react-router\u002F05.data-loading",{"title":2416,"path":2417,"stem":2418},"Просунуті Патерни","\u002Fjavascript\u002Freact\u002Freact-router\u002Fadvanced-patterns","03.javascript\u002F04.react\u002F05.react-router\u002F06.advanced-patterns",{"title":2420,"path":2421,"stem":2422},"Legacy Routing: Компонентний підхід","\u002Fjavascript\u002Freact\u002Freact-router\u002Flegacy-routing","03.javascript\u002F04.react\u002F05.react-router\u002F07.legacy-routing",{"title":2424,"icon":132,"path":2425,"stem":2426,"children":2427},"Redux","\u002Fjavascript\u002Freact\u002Fredux","03.javascript\u002F04.react\u002F06.redux\u002Findex",[2428,2430,2446,2475,2484,2505,2521,2550],{"title":2429,"path":2425,"stem":2426},"Redux: Еволюція управління станом",{"title":14,"icon":15,"path":2431,"stem":2432,"children":2433,"page":59},"\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals",[2434,2438,2442],{"title":2435,"path":2436,"stem":2437},"Вступ до State Management","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fintro-state-management","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F01.intro-state-management",{"title":2439,"path":2440,"stem":2441},"Філософія Redux та Три Принципи","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fredux-philosophy","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F02.redux-philosophy",{"title":2443,"path":2444,"stem":2445},"Чисті функції та Іммутабельність","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fpure-functions-immutability","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F03.pure-functions-immutability",{"title":2447,"icon":132,"path":2448,"stem":2449,"children":2450,"page":59},"Classic Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux",[2451,2455,2459,2463,2467,2471],{"title":2452,"path":2453,"stem":2454},"Створення Store (Classic Redux)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fstore-setup","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F01.store-setup",{"title":2456,"path":2457,"stem":2458},"Actions, Constants та Action Creators","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Factions-constants","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F02.actions-constants",{"title":2460,"path":2461,"stem":2462},"Логіка Reducers","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Freducers","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F03.reducers",{"title":2464,"path":2465,"stem":2466},"Комбінування Reducers (Root Reducer)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fdata-flow","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F04.data-flow",{"title":2468,"path":2469,"stem":2470},"Підключення до React (React-Redux)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Freact-redux-connection","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F05.react-redux-connection",{"title":2472,"path":2473,"stem":2474},"Middleware та Асинхронність (Redux Thunk)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fmiddleware-thunk","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F06.middleware-thunk",{"title":2476,"icon":132,"path":2477,"stem":2478,"children":2479,"page":59},"Transition To Rtk","\u002Fjavascript\u002Freact\u002Fredux\u002Ftransition-to-rtk","03.javascript\u002F04.react\u002F06.redux\u002F03.transition-to-rtk",[2480],{"title":2481,"path":2482,"stem":2483},"Проблеми класичного Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Ftransition-to-rtk\u002Fproblems-with-classic","03.javascript\u002F04.react\u002F06.redux\u002F03.transition-to-rtk\u002F01.problems-with-classic",{"title":2485,"icon":132,"path":2486,"stem":2487,"children":2488,"page":59},"Redux Toolkit","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit",[2489,2493,2497,2501],{"title":2490,"path":2491,"stem":2492},"Налаштування Store з configureStore","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fconfigure-store","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F01.configure-store",{"title":2494,"path":2495,"stem":2496},"createSlice: Революція в Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fcreate-slice","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F02.create-slice",{"title":2498,"path":2499,"stem":2500},"Асинхронність з createAsyncThunk","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fasync-thunks","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F03.async-thunks",{"title":2502,"path":2503,"stem":2504},"04. Entity Adapter: Керування нормалізованим станом","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fentity-adapter","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F04.entity-adapter",{"title":2506,"icon":92,"path":2507,"stem":2508,"children":2509,"page":59},"Advanced","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced",[2510,2514,2518],{"title":2511,"path":2512,"stem":2513},"Мемоізація та Селектори: Повний Гайд по Reselect","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Fselectors-reselect","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F01.selectors-reselect",{"title":2515,"path":2516,"stem":2517},"RTK Query: Архітектура Серверного Кешу","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Frtk-query-intro","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F02.rtk-query-intro",{"title":2365,"path":2519,"stem":2520},"\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Farchitecture-best-practices","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F03.architecture-best-practices",{"title":2522,"icon":132,"path":2523,"stem":2524,"children":2525,"page":59},"Project Kanban","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban",[2526,2530,2534,2538,2542,2546],{"title":2527,"path":2528,"stem":2529},"Проєкт: Kanban Board (Trello Clone)","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fproject-overview","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F01.project-overview",{"title":2531,"path":2532,"stem":2533},"Налаштування та Типізація","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fsetup-and-types","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F02.setup-and-types",{"title":2535,"path":2536,"stem":2537},"Board Slice: Серце Дошки","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fboard-slice","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F03.board-slice",{"title":2539,"path":2540,"stem":2541},"Логіка Drag & Drop","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fdrag-and-drop-logic","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F04.drag-and-drop-logic",{"title":2543,"path":2544,"stem":2545},"Інтеграція з RTK Query","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Frtk-query-integration","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F05.rtk-query-integration",{"title":2547,"path":2548,"stem":2549},"Optimistic Updates","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Foptimistic-updates","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F06.optimistic-updates",{"title":2551,"icon":132,"path":2552,"stem":2553,"children":2554,"page":59},"Testing","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting","03.javascript\u002F04.react\u002F06.redux\u002F07.testing",[2555,2559,2563,2567,2571],{"title":2556,"path":2557,"stem":2558},"Тестування Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Fintro-testing","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F01.intro-testing",{"title":2560,"path":2561,"stem":2562},"Тестування Reducers","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-reducers","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F02.testing-reducers",{"title":2564,"path":2565,"stem":2566},"Тестування Селекторів","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-selectors","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F03.testing-selectors",{"title":2568,"path":2569,"stem":2570},"Тестування Компонентів (Integration)","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-components","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F04.testing-components",{"title":2572,"path":2573,"stem":2574},"Тестування Async Thunks","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-thunks","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F05.testing-thunks",{"title":2576,"icon":132,"path":2577,"stem":2578,"children":2579},"Ui Libraries","\u002Fjavascript\u002Freact\u002Fui-libraries","03.javascript\u002F04.react\u002F07.ui-libraries\u002Findex",[2580,2582,2586,2590,2594,2598,2602],{"title":2581,"path":2577,"stem":2578},"UI Бібліотеки в React",{"title":2583,"path":2584,"stem":2585},"Вступ до UI Бібліотек: Навіщо Винаходити Велосипед Двічі?","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fintroduction-to-ui-libraries","03.javascript\u002F04.react\u002F07.ui-libraries\u002F01.introduction-to-ui-libraries",{"title":2587,"path":2588,"stem":2589},"Філософія shadcn\u002Fui: \"Not a Component Library\"","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-philosophy","03.javascript\u002F04.react\u002F07.ui-libraries\u002F02.shadcn-philosophy",{"title":2591,"path":2592,"stem":2593},"Установка та Налаштування shadcn\u002Fui","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-installation","03.javascript\u002F04.react\u002F07.ui-libraries\u002F03.shadcn-installation",{"title":2595,"path":2596,"stem":2597},"Базові Компоненти shadcn\u002Fui: Фундамент Інтерфейсу","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-basics","03.javascript\u002F04.react\u002F07.ui-libraries\u002F04.shadcn-components-basics",{"title":2599,"path":2600,"stem":2601},"Компоненти Форм: Побудова Інтерактивних Form","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-forms","03.javascript\u002F04.react\u002F07.ui-libraries\u002F05.shadcn-components-forms",{"title":2603,"path":2604,"stem":2605},"Складні Компоненти: Dialog, Dropdown, Table та Command","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-advanced","03.javascript\u002F04.react\u002F07.ui-libraries\u002F06.shadcn-components-advanced",{"title":2607,"icon":2608,"path":2609,"stem":2610,"children":2611,"page":59},"TypeScript","i-devicon-typescript","\u002Fjavascript\u002Ftypescript","03.javascript\u002F05.typescript",[2612,2616,2620,2624,2628,2632,2636,2640],{"title":2613,"path":2614,"stem":2615},"TypeScript: Броня для вашого коду","\u002Fjavascript\u002Ftypescript\u002Fintro-and-basic-types","03.javascript\u002F05.typescript\u002F01.intro-and-basic-types",{"title":2617,"path":2618,"stem":2619},"Майстерність Моделювання Даних: Інтерфейси та Просунуті Типи","\u002Fjavascript\u002Ftypescript\u002Finterfaces-and-advanced-types","03.javascript\u002F05.typescript\u002F02.interfaces-and-advanced-types",{"title":2621,"path":2622,"stem":2623},"Алхімія Типів: Generics та Utility Types","\u002Fjavascript\u002Ftypescript\u002Fgenerics-and-utilities","03.javascript\u002F05.typescript\u002F03.generics-and-utilities",{"title":2625,"path":2626,"stem":2627},"Архітектура та Шаблони: Класи в TypeScript","\u002Fjavascript\u002Ftypescript\u002Fclasses-and-oop","03.javascript\u002F05.typescript\u002F04.classes-and-oop",{"title":2629,"path":2630,"stem":2631},"Продакшн та Екосистема: Advanced Config & Workflow","\u002Fjavascript\u002Ftypescript\u002Fadvanced-patterns-and-config","03.javascript\u002F05.typescript\u002F05.advanced-patterns-and-config",{"title":2633,"path":2634,"stem":2635},"TypeScript у світі React","\u002Fjavascript\u002Ftypescript\u002Freact-basics","03.javascript\u002F05.typescript\u002F06.react-basics",{"title":2637,"path":2638,"stem":2639},"React + TypeScript: Продвинуті патерни","\u002Fjavascript\u002Ftypescript\u002Freact-advanced","03.javascript\u002F05.typescript\u002F07.react-advanced",{"title":2641,"path":2642,"stem":2643},"React + TypeScript: Екосистема та бібліотеки","\u002Fjavascript\u002Ftypescript\u002Freact-ecosystem","03.javascript\u002F05.typescript\u002F08.react-ecosystem",{"title":2645,"icon":2646,"path":2647,"stem":2648,"children":2649,"page":59},"Асинхронність","i-lucide-refresh-cw","\u002Fjavascript\u002Fasync-programming","03.javascript\u002F06.async-programming",[2650,2654,2658],{"title":2651,"path":2652,"stem":2653},"Event Loop: серце асинхронності в JavaScript","\u002Fjavascript\u002Fasync-programming\u002Fevent-loop-fundamentals","03.javascript\u002F06.async-programming\u002F01.event-loop-fundamentals",{"title":2655,"path":2656,"stem":2657},"Task Queue та Microtask Queue: пріоритети виконання","\u002Fjavascript\u002Fasync-programming\u002Ftask-queues","03.javascript\u002F06.async-programming\u002F02.task-queues",{"title":2659,"path":2660,"stem":2661},"Асинхронні патерни: від Callbacks до Async\u002FAwait","\u002Fjavascript\u002Fasync-programming\u002Fasync-patterns","03.javascript\u002F06.async-programming\u002F03.async-patterns",{"title":2663,"path":2664,"stem":2665},"Atomic Design","\u002Fjavascript\u002Fatomic-design","03.javascript\u002F2.atomic-design",{"title":2667,"icon":2668,"path":2669,"stem":2670,"children":2671,"page":59},"Java","i-devicon-java","\u002Fjava","04.java",[2672,2675,2678,2682,2686,2690,2694],{"title":162,"path":2673,"stem":2674},"\u002Fjava\u002Fdata-mapper-part1","04.java\u002F01.data-mapper-part1",{"title":166,"path":2676,"stem":2677},"\u002Fjava\u002Fdata-mapper-part2","04.java\u002F02.data-mapper-part2",{"title":2679,"path":2680,"stem":2681},"Service Layer: Організація бізнес-логіки","\u002Fjava\u002Fservice-layer","04.java\u002F03.service-layer",{"title":2683,"path":2684,"stem":2685},"Rich Domain Model та State Pattern","\u002Fjava\u002Frich-domain-model","04.java\u002F04.rich-domain-model",{"title":2687,"path":2688,"stem":2689},"Патерни для складної бізнес-логіки","\u002Fjava\u002Fbusiness-logic-patterns","04.java\u002F05.business-logic-patterns",{"title":2691,"path":2692,"stem":2693},"Обробка помилок та валідація","\u002Fjava\u002Ferror-handling-validation","04.java\u002F06.error-handling-validation",{"title":2695,"path":2696,"stem":2697,"children":2698,"page":59},"Проектування баз даних","\u002Fjava\u002Fpr2","04.java\u002Fpr2",[2699,2703,2707,2711,2715,2719,2723,2727,2731,2735,2739,2743,2747,2751,2755,2759,2763,2767,2771,2775,2779,2783,2787,2791,2795,2799,2803,2807,2811,2815,2819,2823,2827,2831,2835,2839,2843],{"title":2700,"path":2701,"stem":2702},"Концептуальне моделювання: Мистецтво розуміння предметної області","\u002Fjava\u002Fpr2\u002Fconceptual-modeling","04.java\u002Fpr2\u002F01.conceptual-modeling",{"title":2704,"path":2705,"stem":2706},"Логічне моделювання: Від бізнес-ідей до структур даних","\u002Fjava\u002Fpr2\u002Flogical-modeling","04.java\u002Fpr2\u002F02.logical-modeling",{"title":2708,"path":2709,"stem":2710},"Нормалізація: Гігієна даних та боротьба з аномаліями","\u002Fjava\u002Fpr2\u002Fnormalization","04.java\u002Fpr2\u002F03.normalization",{"title":2712,"path":2713,"stem":2714},"Фізична схема: Від абстракції до DDL","\u002Fjava\u002Fpr2\u002Fphysical-schema","04.java\u002Fpr2\u002F04.physical-schema",{"title":2716,"path":2717,"stem":2718},"Архітектурна класифікація таблиць","\u002Fjava\u002Fpr2\u002Ftable-classification","04.java\u002Fpr2\u002F05.table-classification",{"title":2720,"path":2721,"stem":2722},"Database Migrations: Версіонування схеми з Flyway","\u002Fjava\u002Fpr2\u002Fdatabase-migrations","04.java\u002Fpr2\u002F06.database-migrations",{"title":2724,"path":2725,"stem":2726},"А що, якби це була не реляційна БД?","\u002Fjava\u002Fpr2\u002Fbeyond-relational","04.java\u002Fpr2\u002F07.beyond-relational",{"title":2728,"path":2729,"stem":2730},"Object-Relational Impedance Mismatch: Два світи, що не хочуть дружити","\u002Fjava\u002Fpr2\u002Fimpedance-mismatch","04.java\u002Fpr2\u002F09.impedance-mismatch",{"title":2732,"path":2733,"stem":2734},"JDBC: Перший контакт із базою даних","\u002Fjava\u002Fpr2\u002Fjdbc-fundamentals","04.java\u002Fpr2\u002F10.jdbc-fundamentals",{"title":2736,"path":2737,"stem":2738},"Якість коду: Spotless, SpotBugs та SonarQube","\u002Fjava\u002Fpr2\u002F10a.code-quality","04.java\u002Fpr2\u002F10a.code-quality",{"title":2740,"path":2741,"stem":2742},"Connection Pool: Патерн Object Pool для JDBC-з'єднань","\u002Fjava\u002Fpr2\u002Fconnection-pool","04.java\u002Fpr2\u002F11.connection-pool",{"title":2744,"path":2745,"stem":2746},"Row Data Gateway: Об'єкт як обгортка рядка таблиці","\u002Fjava\u002Fpr2\u002Frow-data-gateway","04.java\u002Fpr2\u002F12.row-data-gateway",{"title":2748,"path":2749,"stem":2750},"Table Data Gateway: Фасад таблиці як архітектурний відступ","\u002Fjava\u002Fpr2\u002Ftable-data-gateway","04.java\u002Fpr2\u002F13.table-data-gateway",{"title":2752,"path":2753,"stem":2754},"Repository + Data Mapper: Правильна шарова архітектура з JDBC","\u002Fjava\u002Fpr2\u002Frepository-data-mapper","04.java\u002Fpr2\u002F14.repository-data-mapper",{"title":2756,"path":2757,"stem":2758},"Identity Map: Кешування сутностей у рамках сесії","\u002Fjava\u002Fpr2\u002Fidentity-map","04.java\u002Fpr2\u002F15.identity-map",{"title":2760,"path":2761,"stem":2762},"Unit of Work: Відстеження змін і координація JDBC-транзакцій","\u002Fjava\u002Fpr2\u002Funit-of-work","04.java\u002Fpr2\u002F16.unit-of-work",{"title":2764,"path":2765,"stem":2766},"Strategy: Замінювані SQL-стратегії для підтримки різних СУБД","\u002Fjava\u002Fpr2\u002Fstrategy-sql","04.java\u002Fpr2\u002F17.strategy-sql",{"title":2768,"path":2769,"stem":2770},"Proxy: Lazy Loading для One-To-Many колекцій","\u002Fjava\u002Fpr2\u002Fproxy-lazy-loading","04.java\u002Fpr2\u002F18.proxy-lazy-loading",{"title":2772,"path":2773,"stem":2774},"Generic Repository через Java Reflection: анотації та динамічний SQL","\u002Fjava\u002Fpr2\u002Fgeneric-repository-reflection","04.java\u002Fpr2\u002F19.generic-repository-reflection",{"title":2776,"path":2777,"stem":2778},"Specification Pattern: Композиція бізнес-правил для складних запитів","\u002Fjava\u002Fpr2\u002Fspecification-pattern","04.java\u002Fpr2\u002F20.specification-pattern",{"title":2780,"path":2781,"stem":2782},"Розширені можливості Specification Pattern: підзапити, агрегації та гібридний підхід","\u002Fjava\u002Fpr2\u002F20a.advanced-specifications","04.java\u002Fpr2\u002F20a.advanced-specifications",{"title":2784,"path":2785,"stem":2786},"Асинхронність у JDBC: Від блокуючих викликів до CompletableFuture","\u002Fjava\u002Fpr2\u002Fasynchronous-jdbc","04.java\u002Fpr2\u002F21.asynchronous-jdbc",{"title":2788,"path":2789,"stem":2790},"Інтеграційне тестування JDBC-репозиторіїв: Embedded H2 та патерн AAA","\u002Fjava\u002Fpr2\u002Fintegration-testing-h2","04.java\u002Fpr2\u002F22.integration-testing-h2",{"title":2792,"path":2793,"stem":2794},"Testcontainers: Тестування з реальною PostgreSQL у Docker-контейнерах","\u002Fjava\u002Fpr2\u002Fintegration-testing-testcontainers","04.java\u002Fpr2\u002F23.integration-testing-testcontainers",{"title":2796,"path":2797,"stem":2798},"Google Guice: Впровадження залежностей у JavaFX-проєкті","\u002Fjava\u002Fpr2\u002Fdependency-injection-guice","04.java\u002Fpr2\u002F24.dependency-injection-guice",{"title":2800,"path":2801,"stem":2802},"JavaFX: Основи побудови графічних інтерфейсів","\u002Fjava\u002Fpr2\u002Fjavafx-fundamentals","04.java\u002Fpr2\u002F25.javafx-fundamentals",{"title":2804,"path":2805,"stem":2806},"Properties та Bindings: Реактивність у JavaFX","\u002Fjava\u002Fpr2\u002Fjavafx-properties-bindings","04.java\u002Fpr2\u002F26.javafx-properties-bindings",{"title":2808,"path":2809,"stem":2810},"MVC vs MVP vs MVVM: Еволюція архітектурних патернів UI","\u002Fjava\u002Fpr2\u002Fui-architecture-patterns","04.java\u002Fpr2\u002F27.ui-architecture-patterns",{"title":2812,"path":2813,"stem":2814},"MVVM на практиці: Побудова ViewModel","\u002Fjava\u002Fpr2\u002Fmvvm-viewmodel-implementation","04.java\u002Fpr2\u002F28.mvvm-viewmodel-implementation",{"title":2816,"path":2817,"stem":2818},"View та Controller: Зв'язування з ViewModel через FXML","\u002Fjava\u002Fpr2\u002Fmvvm-view-controller","04.java\u002Fpr2\u002F29.mvvm-view-controller",{"title":2820,"path":2821,"stem":2822},"Інтеграція MVVM з Guice: Автоматична ін'єкція залежностей","\u002Fjava\u002Fpr2\u002Fmvvm-guice-integration","04.java\u002Fpr2\u002F30.mvvm-guice-integration",{"title":2824,"path":2825,"stem":2826},"Валідація та обробка помилок у MVVM","\u002Fjava\u002Fpr2\u002Fmvvm-validation-error-handling","04.java\u002Fpr2\u002F31.mvvm-validation-error-handling",{"title":2828,"path":2829,"stem":2830},"Навігація та управління екранами у JavaFX MVVM","\u002Fjava\u002Fpr2\u002Fmvvm-navigation-screen-management","04.java\u002Fpr2\u002F32.mvvm-navigation-screen-management",{"title":2832,"path":2833,"stem":2834},"Тестування JavaFX MVVM-додатків","\u002Fjava\u002Fpr2\u002Fmvvm-testing","04.java\u002Fpr2\u002F33.mvvm-testing",{"title":2836,"path":2837,"stem":2838},"Стилізація та теми у JavaFX: CSS та User Experience","\u002Fjava\u002Fpr2\u002Fjavafx-styling-themes","04.java\u002Fpr2\u002F34.javafx-styling-themes",{"title":2840,"path":2841,"stem":2842},"AtlantaFX: Сучасні теми для JavaFX додатків","\u002Fjava\u002Fpr2\u002Fatlantafx-modern-themes","04.java\u002Fpr2\u002F35.atlantafx-modern-themes",{"title":2844,"path":2845,"stem":2846},"Пакування та розповсюдження JavaFX-додатків","\u002Fjava\u002Fpr2\u002Fjar-packaging-distribution","04.java\u002Fpr2\u002F36.jar-packaging-distribution",{"title":2848,"icon":2849,"path":2850,"stem":2851,"children":2852,"page":59},"Python","i-devicon-python","\u002Fpython","05.python",[2853,2895,2954],{"title":2854,"icon":2855,"path":2856,"stem":2857,"children":2858,"page":59},"Python Core","i-lucide-code","\u002Fpython\u002Fcore","05.python\u002F01.core",[2859,2863,2867,2871,2875,2879,2883,2887,2891],{"title":2860,"path":2861,"stem":2862},"Як комп'ютер виконує програму","\u002Fpython\u002Fcore\u002Fhow-computers-run-programs","05.python\u002F01.core\u002F00.how-computers-run-programs",{"title":2864,"path":2865,"stem":2866},"Перша програма і функція print","\u002Fpython\u002Fcore\u002Ffirst-program-print","05.python\u002F01.core\u002F01.first-program-print",{"title":2868,"path":2869,"stem":2870},"Об'єкти, значення і типи","\u002Fpython\u002Fcore\u002Fobjects-values-types","05.python\u002F01.core\u002F02.objects-values-types",{"title":2872,"path":2873,"stem":2874},"Змінні — імена, посилання, ідентичність","\u002Fpython\u002Fcore\u002Fvariables-names-references","05.python\u002F01.core\u002F03.variables-names-references",{"title":2876,"path":2877,"stem":2878},"Вирази, оператори, введення і перетворення типів","\u002Fpython\u002Fcore\u002Fexpressions-input-types","05.python\u002F01.core\u002F04.expressions-input-types",{"title":2880,"path":2881,"stem":2882},"Логіка та розгалуження","\u002Fpython\u002Fcore\u002Flogic-branching","05.python\u002F01.core\u002F05.logic-branching",{"title":2884,"path":2885,"stem":2886},"Цикли та ітерація","\u002Fpython\u002Fcore\u002Floops-iteration","05.python\u002F01.core\u002F06.loops-iteration",{"title":2888,"path":2889,"stem":2890},"Налагодження (debugging)","\u002Fpython\u002Fcore\u002Fdebugging","05.python\u002F01.core\u002F07.debugging",{"title":2892,"path":2893,"stem":2894},"Рядки і текст","\u002Fpython\u002Fcore\u002Fstrings-text","05.python\u002F01.core\u002F08.strings-text",{"title":2506,"path":2896,"stem":2897,"children":2898,"page":59},"\u002Fpython\u002Fadvanced","05.python\u002F02.advanced",[2899,2903,2906,2910,2914,2918,2922,2926,2930,2934,2938,2942,2946,2950],{"title":2900,"path":2901,"stem":2902},"Модулі, Пакети та Віртуальні Середовища","\u002Fpython\u002Fadvanced\u002Fmodules-packages-venv","05.python\u002F02.advanced\u002F00.modules-packages-venv",{"title":71,"path":2904,"stem":2905},"\u002Fpython\u002Fadvanced\u002Fclasses-objects","05.python\u002F02.advanced\u002F01.classes-objects",{"title":2907,"path":2908,"stem":2909},"Інкапсуляція, Керування Доступом та Властивості","\u002Fpython\u002Fadvanced\u002Fencapsulation","05.python\u002F02.advanced\u002F02.encapsulation",{"title":2911,"path":2912,"stem":2913},"Наслідування, MRO та суперсила super()","\u002Fpython\u002Fadvanced\u002Finheritance-mro","05.python\u002F02.advanced\u002F03.inheritance-mro",{"title":2915,"path":2916,"stem":2917},"Абстракція — ABC проти Статичних Протоколів (PEP 544)","\u002Fpython\u002Fadvanced\u002Fabstraction-protocols","05.python\u002F02.advanced\u002F04.abstraction-protocols",{"title":2919,"path":2920,"stem":2921},"Магічні методи (Dunder) та Емуляція протоколів","\u002Fpython\u002Fadvanced\u002Fdunder-methods","05.python\u002F02.advanced\u002F05.dunder-methods",{"title":2923,"path":2924,"stem":2925},"Декоратори та Керування життєвим циклом методів","\u002Fpython\u002Fadvanced\u002Fdecorators-static-class","05.python\u002F02.advanced\u002F06.decorators-static-class",{"title":2927,"path":2928,"stem":2929},"Дескриптори — Магія доступу до атрибутів","\u002Fpython\u002Fadvanced\u002Fdescriptors","05.python\u002F02.advanced\u002F07.descriptors",{"title":2931,"path":2932,"stem":2933},"Метакласи — Динамічне створення класів під капотом CPython","\u002Fpython\u002Fadvanced\u002Fmetaclasses","05.python\u002F02.advanced\u002F08.metaclasses",{"title":2935,"path":2936,"stem":2937},"Dataclasses, NamedTuple та сучасні контейнери Python","\u002Fpython\u002Fadvanced\u002Fmodern-containers","05.python\u002F02.advanced\u002F09.modern-containers",{"title":2939,"path":2940,"stem":2941},"GIL та модель конкурентності CPython — фундамент перед потоками і процесами","\u002Fpython\u002Fadvanced\u002Fgil-concurrency-intro","05.python\u002F02.advanced\u002F11.gil-concurrency-intro",{"title":2943,"path":2944,"stem":2945},"Threading — конкурентність для I\u002FO-bound задач","\u002Fpython\u002Fadvanced\u002Fthreading","05.python\u002F02.advanced\u002F12.threading",{"title":2947,"path":2948,"stem":2949},"Multiprocessing — справжній паралелізм для CPU-bound задач","\u002Fpython\u002Fadvanced\u002Fmultiprocessing","05.python\u002F02.advanced\u002F13.multiprocessing",{"title":2951,"path":2952,"stem":2953},"asyncio — кооперативна конкурентність та event loop","\u002Fpython\u002Fadvanced\u002Fasyncio","05.python\u002F02.advanced\u002F14.asyncio",{"title":2955,"icon":92,"path":2956,"stem":2957,"children":2958,"page":59},"FastAPI","\u002Fpython\u002Ffastapi","05.python\u002F03.fastapi",[2959,2963,2967,2971,2975,2979,2983,2987,2991,2995,2999,3003,3007,3011],{"title":2960,"path":2961,"stem":2962},"Глибокий Typing та Pydantic v2 — від анотацій до валідації","\u002Fpython\u002Ffastapi\u002Ftyping-pydantic","05.python\u002F03.fastapi\u002F15.typing-pydantic",{"title":2964,"path":2965,"stem":2966},"WSGI, ASGI та Python Web-екосистема","\u002Fpython\u002Ffastapi\u002Fwsgi-asgi-ecosystem","05.python\u002F03.fastapi\u002F16.wsgi-asgi-ecosystem",{"title":2968,"path":2969,"stem":2970},"FastAPI: Перший додаток, Uvicorn та OpenAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-intro","05.python\u002F03.fastapi\u002F17.fastapi-intro",{"title":2972,"path":2973,"stem":2974},"Маршрутизація, параметри запитів та APIRouter","\u002Fpython\u002Ffastapi\u002Ffastapi-routing-params","05.python\u002F03.fastapi\u002F18.fastapi-routing-params",{"title":2976,"path":2977,"stem":2978},"Pydantic v2 у FastAPI — схеми, валідація та серіалізація","\u002Fpython\u002Ffastapi\u002Ffastapi-pydantic-schemas","05.python\u002F03.fastapi\u002F19.fastapi-pydantic-schemas",{"title":2980,"path":2981,"stem":2982},"Dependency Injection — серце архітектури FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-dependency-injection","05.python\u002F03.fastapi\u002F20.fastapi-dependency-injection",{"title":2984,"path":2985,"stem":2986},"Обробка помилок, Middleware та CORS у FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-errors-middleware","05.python\u002F03.fastapi\u002F21.fastapi-errors-middleware",{"title":2988,"path":2989,"stem":2990},"SQLAlchemy 2.0 — ORM, Core та Async Engine","\u002Fpython\u002Ffastapi\u002Fsqlalchemy-orm","05.python\u002F03.fastapi\u002F22.sqlalchemy-orm",{"title":2992,"path":2993,"stem":2994},"Alembic — міграції бази даних","\u002Fpython\u002Ffastapi\u002Falembic-migrations","05.python\u002F03.fastapi\u002F23.alembic-migrations",{"title":2996,"path":2997,"stem":2998},"Repository Pattern та Clean Architecture у FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-repository-clean-arch","05.python\u002F03.fastapi\u002F24.fastapi-repository-clean-arch",{"title":3000,"path":3001,"stem":3002},"Автентифікація та авторизація — JWT, OAuth2, RBAC","\u002Fpython\u002Ffastapi\u002Ffastapi-auth-security","05.python\u002F03.fastapi\u002F25.fastapi-auth-security",{"title":3004,"path":3005,"stem":3006},"Тестування FastAPI — pytest, httpx, fixtures","\u002Fpython\u002Ffastapi\u002Ffastapi-testing","05.python\u002F03.fastapi\u002F26.fastapi-testing",{"title":3008,"path":3009,"stem":3010},"Async на повну — Background Tasks, WebSockets, SSE та Celery","\u002Fpython\u002Ffastapi\u002Ffastapi-async-advanced","05.python\u002F03.fastapi\u002F27.fastapi-async-advanced",{"title":3012,"path":3013,"stem":3014},"Deployment — Docker, CI\u002FCD, Monitoring","\u002Fpython\u002Ffastapi\u002Ffastapi-deployment","05.python\u002F03.fastapi\u002F28.fastapi-deployment",{"title":3016,"icon":3017,"path":3018,"stem":3019,"children":3020,"page":59},"Бази даних","i-lucide-database","\u002Fdatabases","06.databases",[3021,3051,3074,3111,3140,3158,3192,3204,3213],{"title":3022,"icon":3023,"path":3024,"stem":3025,"children":3026,"page":59},"Intro","i-lucide-play","\u002Fdatabases\u002Fintro","06.databases\u002F01.intro",[3027,3031,3035,3039,3043,3047],{"title":3028,"path":3029,"stem":3030},"Введення в теорію баз даних","\u002Fdatabases\u002Fintro\u002Fintroduction-to-databases","06.databases\u002F01.intro\u002F01.introduction-to-databases",{"title":3032,"path":3033,"stem":3034},"Реляційна модель даних","\u002Fdatabases\u002Fintro\u002Frelational-model-theory","06.databases\u002F01.intro\u002F02.relational-model-theory",{"title":3036,"path":3037,"stem":3038},"ER-моделювання","\u002Fdatabases\u002Fintro\u002Fer-modeling","06.databases\u002F01.intro\u002F03.er-modeling",{"title":3040,"path":3041,"stem":3042},"Логічне проектування БД","\u002Fdatabases\u002Fintro\u002Flogical-schema","06.databases\u002F01.intro\u002F04.logical-schema",{"title":3044,"path":3045,"stem":3046},"Класифікація таблиць","\u002Fdatabases\u002Fintro\u002Ftable-classification","06.databases\u002F01.intro\u002F05.table-classification",{"title":3048,"path":3049,"stem":3050},"PlantUML для баз даних","\u002Fdatabases\u002Fintro\u002Fplantuml-diagrams","06.databases\u002F01.intro\u002F06.plantuml-diagrams",{"title":3052,"icon":3017,"path":3053,"stem":3054,"children":3055,"page":59},"MS SQL Server Start","\u002Fdatabases\u002Fms-sql-server-start","06.databases\u002F02.ms-sql-server-start",[3056,3060,3066,3070],{"title":3057,"path":3058,"stem":3059},"Типи даних у MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fdata-types","06.databases\u002F02.ms-sql-server-start\u002F01.data-types",{"title":3061,"path":3062,"stem":3063,"children":3064},"Індекси у MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fsql-indexes","06.databases\u002F02.ms-sql-server-start\u002F02.sql-indexes",[3065],{"title":3061,"path":3062,"stem":3063},{"title":3067,"path":3068,"stem":3069},"Системні бази даних MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fsystem-databases","06.databases\u002F02.ms-sql-server-start\u002F03.system-databases",{"title":3071,"path":3072,"stem":3073},"Огляд мови SQL та запитів","\u002Fdatabases\u002Fms-sql-server-start\u002Fsql-queries-overview","06.databases\u002F02.ms-sql-server-start\u002F04.sql-queries-overview",{"title":3075,"icon":3017,"path":3076,"stem":3077,"children":3078,"page":59},"SQL","\u002Fdatabases\u002Fsql","06.databases\u002F03.sql",[3079,3083,3087,3091,3095,3099,3103,3107],{"title":3080,"path":3081,"stem":3082},"Налаштування демонстраційної бази даних","\u002Fdatabases\u002Fsql\u002Fsample-database-setup","06.databases\u002F03.sql\u002F00.sample-database-setup",{"title":3084,"path":3085,"stem":3086},"DDL - Створення таблиць (CREATE TABLE)","\u002Fdatabases\u002Fsql\u002Fddl-create-table","06.databases\u002F03.sql\u002F01.ddl-create-table",{"title":3088,"path":3089,"stem":3090},"DDL - Зміна та видалення таблиць (ALTER, DROP)","\u002Fdatabases\u002Fsql\u002Fddl-alter-drop-table","06.databases\u002F03.sql\u002F02.ddl-alter-drop-table",{"title":3092,"path":3093,"stem":3094},"SELECT запити - Основи","\u002Fdatabases\u002Fsql\u002Fselect-queries-fundamentals","06.databases\u002F03.sql\u002F03.select-queries-fundamentals",{"title":3096,"path":3097,"stem":3098},"SELECT запити - Розширені можливості","\u002Fdatabases\u002Fsql\u002Fselect-queries-advanced","06.databases\u002F03.sql\u002F04.select-queries-advanced",{"title":3100,"path":3101,"stem":3102},"INSERT запити - Додавання даних","\u002Fdatabases\u002Fsql\u002Finsert-queries","06.databases\u002F03.sql\u002F05.insert-queries",{"title":3104,"path":3105,"stem":3106},"UPDATE та DELETE запити","\u002Fdatabases\u002Fsql\u002Fupdate-delete-queries","06.databases\u002F03.sql\u002F06.update-delete-queries",{"title":3108,"path":3109,"stem":3110},"Транзакції в SQL","\u002Fdatabases\u002Fsql\u002Ftransactions","06.databases\u002F03.sql\u002F07.transactions",{"title":3112,"icon":3017,"path":3113,"stem":3114,"children":3115,"page":59},"Multi Table Databases","\u002Fdatabases\u002Fmulti-table-databases","06.databases\u002F04.multi-table-databases",[3116,3120,3124,3128,3132,3136],{"title":3117,"path":3118,"stem":3119},"Зв'язки та нормалізація БД","\u002Fdatabases\u002Fmulti-table-databases\u002Frelationships-and-normalization","06.databases\u002F04.multi-table-databases\u002F00.relationships-and-normalization",{"title":3121,"path":3122,"stem":3123},"INNER JOIN - З'єднання таблиць","\u002Fdatabases\u002Fmulti-table-databases\u002Finner-join","06.databases\u002F04.multi-table-databases\u002F01.inner-join",{"title":3125,"path":3126,"stem":3127},"OUTER JOINs - LEFT, RIGHT, FULL","\u002Fdatabases\u002Fmulti-table-databases\u002Fouter-joins","06.databases\u002F04.multi-table-databases\u002F02.outer-joins",{"title":3129,"path":3130,"stem":3131},"CROSS та SELF JOINs","\u002Fdatabases\u002Fmulti-table-databases\u002Fcross-self-joins","06.databases\u002F04.multi-table-databases\u002F03.cross-self-joins",{"title":3133,"path":3134,"stem":3135},"Підзапити (Subqueries)","\u002Fdatabases\u002Fmulti-table-databases\u002Fsubqueries","06.databases\u002F04.multi-table-databases\u002F04.subqueries",{"title":3137,"path":3138,"stem":3139},"Агрегації з JOIN","\u002Fdatabases\u002Fmulti-table-databases\u002Faggregations-with-joins","06.databases\u002F04.multi-table-databases\u002F05.aggregations-with-joins",{"title":3141,"icon":3142,"path":3143,"stem":3144,"children":3145,"page":59},"Aggregate Functions","i-lucide-calculator","\u002Fdatabases\u002Faggregate-functions","06.databases\u002F05.aggregate-functions",[3146,3150,3154],{"title":3147,"path":3148,"stem":3149},"Функції агрегування в MS SQL Server","\u002Fdatabases\u002Faggregate-functions\u002Fintroduction-aggregate-functions","06.databases\u002F05.aggregate-functions\u002F01.introduction-aggregate-functions",{"title":3151,"path":3152,"stem":3153},"Групування даних в MS SQL Server","\u002Fdatabases\u002Faggregate-functions\u002Fgrouping-data","06.databases\u002F05.aggregate-functions\u002F02.grouping-data",{"title":3155,"path":3156,"stem":3157},"Підзапити з агрегатними функціями","\u002Fdatabases\u002Faggregate-functions\u002Fsubqueries-aggregates","06.databases\u002F05.aggregate-functions\u002F03.subqueries-aggregates",{"title":3159,"icon":3160,"path":3161,"stem":3162,"children":3163,"page":59},"Тригери та зберігаємі процедури","i-lucide-database-zap","\u002Fdatabases\u002Ftriggers-stored-procedures","06.databases\u002F07.triggers-stored-procedures",[3164,3168,3172,3176,3180,3184,3188],{"title":3165,"path":3166,"stem":3167},"DML-тригери","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fdml-triggers","06.databases\u002F07.triggers-stored-procedures\u002F01.dml-triggers",{"title":3169,"path":3170,"stem":3171},"DDL-тригери","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fddl-triggers","06.databases\u002F07.triggers-stored-procedures\u002F02.ddl-triggers",{"title":3173,"path":3174,"stem":3175},"Transact-SQL розширення","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Ftransact-sql-extensions","06.databases\u002F07.triggers-stored-procedures\u002F03.transact-sql-extensions",{"title":3177,"path":3178,"stem":3179},"Транзакції","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Ftransactions","06.databases\u002F07.triggers-stored-procedures\u002F04.transactions",{"title":3181,"path":3182,"stem":3183},"Зберігаємі процедури","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fstored-procedures","06.databases\u002F07.triggers-stored-procedures\u002F05.stored-procedures",{"title":3185,"path":3186,"stem":3187},"Користувацькі функції","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fuser-defined-functions","06.databases\u002F07.triggers-stored-procedures\u002F06.user-defined-functions",{"title":3189,"path":3190,"stem":3191},"Безпека баз даних","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fsecurity","06.databases\u002F07.triggers-stored-procedures\u002F08.security",{"title":3189,"icon":793,"path":3193,"stem":3194,"children":3195,"page":59},"\u002Fdatabases\u002Fsecurity","06.databases\u002F08.security",[3196,3200],{"title":3197,"path":3198,"stem":3199},"Вступ до безпеки баз даних","\u002Fdatabases\u002Fsecurity\u002Fintroduction","06.databases\u002F08.security\u002F01.introduction",{"title":3201,"path":3202,"stem":3203},"Системні представлення та метадані","\u002Fdatabases\u002Fsecurity\u002Fsystem-views","06.databases\u002F08.security\u002F02.system-views",{"title":3205,"icon":3206,"path":3207,"stem":3208,"children":3209,"page":59},"Резервне копіювання та відновлення","i-lucide-database-backup","\u002Fdatabases\u002Fbackup-recovery","06.databases\u002F09.backup-recovery",[3210],{"title":3205,"path":3211,"stem":3212},"\u002Fdatabases\u002Fbackup-recovery\u002Fbackup-restore","06.databases\u002F09.backup-recovery\u002F01.backup-restore",{"title":3214,"icon":3215,"path":3216,"stem":3217,"children":3218,"page":59},"Повнотекстовий пошук","i-lucide-search","\u002Fdatabases\u002Ffull-text-search","06.databases\u002F10.full-text-search",[3219],{"title":3214,"path":3220,"stem":3221},"\u002Fdatabases\u002Ffull-text-search\u002Ffull-text-search","06.databases\u002F10.full-text-search\u002F01.full-text-search",{"title":3223,"icon":3224,"path":3225,"stem":3226,"children":3227,"page":59},"Tools","i-lucide-wrench","\u002Ftools","07.tools",[3228,3304],{"title":3229,"icon":3230,"path":3231,"stem":3232,"children":3233},"Docker","i-simple-icons-docker","\u002Ftools\u002Fdocker","07.tools\u002F01.docker\u002Findex",[3234,3236,3240,3244,3248,3252,3256,3260,3264,3268,3272,3276,3280,3284,3288,3292,3296,3300],{"title":3235,"path":3231,"stem":3232},"Docker: від нуля до production",{"title":3237,"path":3238,"stem":3239},"Контейнеризація — від проблеми до рішення","\u002Ftools\u002Fdocker\u002Fcontainerization-concept","07.tools\u002F01.docker\u002F01.containerization-concept",{"title":3241,"path":3242,"stem":3243},"Docker — що це і навіщо?","\u002Ftools\u002Fdocker\u002Fdocker-what-and-why","07.tools\u002F01.docker\u002F02.docker-what-and-why",{"title":3245,"path":3246,"stem":3247},"Архітектура Docker Engine","\u002Ftools\u002Fdocker\u002Fdocker-architecture","07.tools\u002F01.docker\u002F03.docker-architecture",{"title":3249,"path":3250,"stem":3251},"Встановлення Docker","\u002Ftools\u002Fdocker\u002Finstallation","07.tools\u002F01.docker\u002F04.installation",{"title":3253,"path":3254,"stem":3255},"Перший контейнер — docker run","\u002Ftools\u002Fdocker\u002Ffirst-container","07.tools\u002F01.docker\u002F05.first-container",{"title":3257,"path":3258,"stem":3259},"Життєвий цикл контейнера","\u002Ftools\u002Fdocker\u002Fcontainer-lifecycle","07.tools\u002F01.docker\u002F06.container-lifecycle",{"title":3261,"path":3262,"stem":3263},"Docker Images — фундаментальні концепції","\u002Ftools\u002Fdocker\u002Fdocker-images-fundamentals","07.tools\u002F01.docker\u002F07.docker-images-fundamentals",{"title":3265,"path":3266,"stem":3267},"Dockerfile — основи","\u002Ftools\u002Fdocker\u002Fdockerfile-basics","07.tools\u002F01.docker\u002F08.dockerfile-basics",{"title":3269,"path":3270,"stem":3271},"Dockerfile — просунуті техніки","\u002Ftools\u002Fdocker\u002Fdockerfile-advanced","07.tools\u002F01.docker\u002F09.dockerfile-advanced",{"title":3273,"path":3274,"stem":3275},"Build Context та кешування шарів","\u002Ftools\u002Fdocker\u002Fbuild-context-and-cache","07.tools\u002F01.docker\u002F10.build-context-and-cache",{"title":3277,"path":3278,"stem":3279},"Реєстри Docker-образів","\u002Ftools\u002Fdocker\u002Fimage-registries","07.tools\u002F01.docker\u002F11.image-registries",{"title":3281,"path":3282,"stem":3283},"Контейнеризація .NET додатків","\u002Ftools\u002Fdocker\u002Fdotnet-containerization","07.tools\u002F01.docker\u002F12.dotnet-containerization",{"title":3285,"path":3286,"stem":3287},"Томи та збереження даних","\u002Ftools\u002Fdocker\u002Fvolumes-and-data","07.tools\u002F01.docker\u002F13.volumes-and-data",{"title":3289,"path":3290,"stem":3291},"Основи мережі в Docker","\u002Ftools\u002Fdocker\u002Fnetworking-basics","07.tools\u002F01.docker\u002F14.networking-basics",{"title":3293,"path":3294,"stem":3295},"Змінні оточення та конфігурація","\u002Ftools\u002Fdocker\u002Fenvironment-and-configuration","07.tools\u002F01.docker\u002F15.environment-and-configuration",{"title":3297,"path":3298,"stem":3299},"Docker Compose — оркестрація контейнерів","\u002Ftools\u002Fdocker\u002Fdocker-compose-basics","07.tools\u002F01.docker\u002F16.docker-compose-basics",{"title":3301,"path":3302,"stem":3303},"Docker Compose — Multi-Service застосунки","\u002Ftools\u002Fdocker\u002Fcompose-multi-service","07.tools\u002F01.docker\u002F17.compose-multi-service",{"title":3305,"icon":3306,"path":3307,"stem":3308,"children":3309},"Kubernetes","simple-icons:kubernetes","\u002Ftools\u002Fkubernetes","07.tools\u002F02.kubernetes\u002Findex",[3310,3312,3316,3320,3324,3328,3332,3336,3340],{"title":3311,"path":3307,"stem":3308},"Kubernetes: від розробки до production",{"title":3313,"path":3314,"stem":3315},"Kubernetes — коли Docker Compose більше не вистачає","\u002Ftools\u002Fkubernetes\u002Fwhy-kubernetes","07.tools\u002F02.kubernetes\u002F01.why-kubernetes",{"title":3317,"path":3318,"stem":3319},"Архітектура Kubernetes — анатомія кластера","\u002Ftools\u002Fkubernetes\u002Fkubernetes-architecture","07.tools\u002F02.kubernetes\u002F02.kubernetes-architecture",{"title":3321,"path":3322,"stem":3323},"Локальне середовище — minikube, kind та k3s","\u002Ftools\u002Fkubernetes\u002Flocal-environment","07.tools\u002F02.kubernetes\u002F03.local-environment",{"title":3325,"path":3326,"stem":3327},"Pod — атомарна одиниця Kubernetes","\u002Ftools\u002Fkubernetes\u002Fpods-and-containers","07.tools\u002F02.kubernetes\u002F04.pods-and-containers",{"title":3329,"path":3330,"stem":3331},"Патерни використання Pod","\u002Ftools\u002Fkubernetes\u002Fpod-patterns","07.tools\u002F02.kubernetes\u002F05.pod-patterns",{"title":3333,"path":3334,"stem":3335},"Deployment — декларативне управління Pod","\u002Ftools\u002Fkubernetes\u002Fdeployment-basics","07.tools\u002F02.kubernetes\u002F06.deployment-basics",{"title":3337,"path":3338,"stem":3339},"Rolling Updates та управління життєвим циклом Deployment","\u002Ftools\u002Fkubernetes\u002Fdeployment-rolling-updates","07.tools\u002F02.kubernetes\u002F07.deployment-rolling-updates",{"title":3341,"path":3342,"stem":3343},"Service — мережева абстракція для Pod","\u002Ftools\u002Fkubernetes\u002Fservices-networking","07.tools\u002F02.kubernetes\u002F08.services-networking",{"title":3345,"icon":3346,"path":3347,"stem":3348,"children":3349,"page":59},"Software Engineering","i-lucide-code-2","\u002Fsoftware-engineering","09.software-engineering",[3350,3354,3358,3362,3366,3370,3374,3378,3382,3386,3390],{"title":3351,"path":3352,"stem":3353},"1. Аналіз предметної області. Експертні знання та складність","\u002Fsoftware-engineering\u002Fintro-subdomains","09.software-engineering\u002F01.intro-subdomains",{"title":3355,"path":3356,"stem":3357},"2. Обмежені контексти. Інтеграція обмежених контекстів","\u002Fsoftware-engineering\u002Fintegrating-limited-contexts","09.software-engineering\u002F02.integrating-limited-contexts",{"title":3359,"path":3360,"stem":3361},"3. Реалізація простої бізнес-логіки","\u002Fsoftware-engineering\u002Fsimple","09.software-engineering\u002F03.simple",{"title":3363,"path":3364,"stem":3365},"4. Опрацювання складної бізнес-логіки","\u002Fsoftware-engineering\u002Fcomplex-business-logic","09.software-engineering\u002F04.complex-business-logic",{"title":3367,"path":3368,"stem":3369},"5. Моделювання фактора часу. Подієво-орієнтована архітектура.","\u002Fsoftware-engineering\u002Fmodelling-the-time-factor","09.software-engineering\u002F05.modelling-the-time-factor",{"title":3371,"path":3372,"stem":3373},"6. Архітектурні патерни","\u002Fsoftware-engineering\u002Farchitectural-patterns","09.software-engineering\u002F06.architectural-patterns",{"title":3375,"path":3376,"stem":3377},"Паттерни взаємодії","\u002Fsoftware-engineering\u002Fpatterns-of-interaction","09.software-engineering\u002F07.patterns-of-interaction",{"title":3379,"path":3380,"stem":3381},"Евристика проєктування","\u002Fsoftware-engineering\u002Fdesign-heuristics","09.software-engineering\u002F08.design-heuristics",{"title":3383,"path":3384,"stem":3385},"Еволюція проєктних рішень","\u002Fsoftware-engineering\u002Fevolution-of-design-solutions","09.software-engineering\u002F09.evolution-of-design-solutions",{"title":3387,"path":3388,"stem":3389},"EventStorming","\u002Fsoftware-engineering\u002Feventstorming","09.software-engineering\u002F10.eventstorming",{"title":3391,"path":3392,"stem":3393},"DDD на практиці","\u002Fsoftware-engineering\u002Fddd-in-practice","09.software-engineering\u002F11.ddd-in-practice",{"title":3395,"icon":943,"path":3396,"stem":3397,"children":3398,"page":59},"DDD","\u002Fddd","10.ddd",[3399,3403,3407,3411,3415,3419,3423,3427,3431,3435,3439,3443,3447],{"title":3400,"path":3401,"stem":3402},"Аналіз предметної області","\u002Fddd\u002Fdomain-analysis","10.ddd\u002F01.domain-analysis",{"title":3404,"path":3405,"stem":3406},"Експертні знання про предметну область","\u002Fddd\u002Fdomain-expert-knowledge","10.ddd\u002F02.domain-expert-knowledge",{"title":3408,"path":3409,"stem":3410},"Як осмислити складність предметної області","\u002Fddd\u002Fmanaging-domain-complexity","10.ddd\u002F03.managing-domain-complexity",{"title":3412,"path":3413,"stem":3414},"Інтеграція обмежених контекстів","\u002Fddd\u002Fbounded-context-integration","10.ddd\u002F04.bounded-context-integration",{"title":3416,"path":3417,"stem":3418},"Реалізація простої бізнес-логіки","\u002Fddd\u002Fsimple-business-logic","10.ddd\u002F05.simple-business-logic",{"title":3420,"path":3421,"stem":3422},"Обробка складної бізнес-логіки","\u002Fddd\u002Fcomplex-business-logic","10.ddd\u002F06.complex-business-logic",{"title":3424,"path":3425,"stem":3426},"Моделювання фактора часу","\u002Fddd\u002Ftime-modeling","10.ddd\u002F07.time-modeling",{"title":3428,"path":3429,"stem":3430},"Глава 8. Архітектурні Патерни","\u002Fddd\u002Farchitectural-patterns","10.ddd\u002F08.architectural-patterns",{"title":3432,"path":3433,"stem":3434},"Глава 9. Патерни Взаємодії","\u002Fddd\u002Finteraction-patterns","10.ddd\u002F09.interaction-patterns",{"title":3436,"path":3437,"stem":3438},"Глава 10. Проектні Евристики","\u002Fddd\u002Fdesign-heuristics","10.ddd\u002F10.design-heuristics",{"title":3440,"path":3441,"stem":3442},"Глава 11. Еволюція Проектних Рішень","\u002Fddd\u002Fevolution-of-design-decisions","10.ddd\u002F11.evolution-of-design-decisions",{"title":3444,"path":3445,"stem":3446},"Глава 12. EventStorming","\u002Fddd\u002Fevent-storming","10.ddd\u002F12.event-storming",{"title":3448,"path":3449,"stem":3450},"Глава 13. DDD на Практиці","\u002Fddd\u002Fddd-in-practice","10.ddd\u002F13.ddd-in-practice",{"title":3452,"icon":3453,"path":3454,"stem":3455,"children":3456,"page":59},"Media Streaming","i-lucide-video","\u002Fmedia-streaming","11.media-streaming",[3457,3461,3465,3469,3473,3477,3481],{"title":3458,"path":3459,"stem":3460},"01. Магія Стрімінгу: Що відбувається, коли ви натискаєте \"Play\"","\u002Fmedia-streaming\u002Fintroduction","11.media-streaming\u002F01.introduction",{"title":3462,"path":3463,"stem":3464},"02. Анатомія Медіа: Кодеки, Контейнери та Стиснення","\u002Fmedia-streaming\u002Faudio-video-anatomy","11.media-streaming\u002F02.audio-video-anatomy",{"title":3466,"path":3467,"stem":3468},"03. The Gym: FFmpeg Deep Dive","\u002Fmedia-streaming\u002Fffmpeg-gym","11.media-streaming\u002F03.ffmpeg-gym",{"title":3470,"path":3471,"stem":3472},"04. HLS Protocol: HTTP Live Streaming у Деталях","\u002Fmedia-streaming\u002Fhls-protocol","11.media-streaming\u002F04.hls-protocol",{"title":3474,"path":3475,"stem":3476},"05. DASH Protocol: Відкритий Стандарт","\u002Fmedia-streaming\u002Fdash-protocol","11.media-streaming\u002F05.dash-protocol",{"title":3478,"path":3479,"stem":3480},"06. Масштабування: CDN та Adaptive Bitrate","\u002Fmedia-streaming\u002Fcdn-and-adaptive-bitrate","11.media-streaming\u002F06.cdn-and-adaptive-bitrate",{"title":3482,"path":3483,"stem":3484},"07. Війна із Затримкою (Latency)","\u002Fmedia-streaming\u002Frealtime-latency","11.media-streaming\u002F07.realtime-latency",{"title":3486,"icon":3487,"path":3488,"stem":3489,"children":3490,"page":59},"HTML & CSS","i-devicon-html5","\u002Fhtml-css","12.html-css",[3491,3495,3499,3503,3507,3511,3515,3519,3523,3527,3531,3535,3539,3543,3547,3551,3555,3559,3563,3567,3571,3575,3579,3583,3587,3591,3595,3599,3603,3607],{"title":3492,"path":3493,"stem":3494},"Вступ до HTML. Структура документа","\u002Fhtml-css\u002Fintro-html-structure","12.html-css\u002F01.intro-html-structure",{"title":3496,"path":3497,"stem":3498},"Форматування тексту в HTML","\u002Fhtml-css\u002Fhtml-text-formatting","12.html-css\u002F02.html-text-formatting",{"title":3500,"path":3501,"stem":3502},"Посилання та зображення в HTML","\u002Fhtml-css\u002Fhtml-links-images","12.html-css\u002F03.html-links-images",{"title":3504,"path":3505,"stem":3506},"Списки та таблиці в HTML","\u002Fhtml-css\u002Fhtml-lists-tables","12.html-css\u002F04.html-lists-tables",{"title":3508,"path":3509,"stem":3510},"Форми в HTML","\u002Fhtml-css\u002Fhtml-forms","12.html-css\u002F05.html-forms",{"title":3512,"path":3513,"stem":3514},"Семантичні елементи HTML5","\u002Fhtml-css\u002Fhtml-semantic-elements","12.html-css\u002F06.html-semantic-elements",{"title":3516,"path":3517,"stem":3518},"Мультимедіа та розширені елементи HTML","\u002Fhtml-css\u002Fhtml-multimedia-advanced","12.html-css\u002F07.html-multimedia-advanced",{"title":3520,"path":3521,"stem":3522},"Мікророзмітка та SEO в HTML","\u002Fhtml-css\u002Fhtml-microdata-seo","12.html-css\u002F08.html-microdata-seo",{"title":3524,"path":3525,"stem":3526},"Вступ до CSS. Селектори та специфічність","\u002Fhtml-css\u002Fcss-intro-selectors","12.html-css\u002F09.css-intro-selectors",{"title":3528,"path":3529,"stem":3530},"Блокова модель CSS. Відступи. Box Sizing","\u002Fhtml-css\u002Fcss-box-model","12.html-css\u002F10.css-box-model",{"title":3532,"path":3533,"stem":3534},"Розміри у CSS: повний довідник одиниць і ключових слів","\u002Fhtml-css\u002F10a.css-sizing","12.html-css\u002F10a.css-sizing",{"title":3536,"path":3537,"stem":3538},"Типографіка в CSS. Шрифти та текст","\u002Fhtml-css\u002Fcss-typography","12.html-css\u002F11.css-typography",{"title":3540,"path":3541,"stem":3542},"Кольори та фони в CSS","\u002Fhtml-css\u002Fcss-colors-backgrounds","12.html-css\u002F12.css-colors-backgrounds",{"title":3544,"path":3545,"stem":3546},"Тіні та фільтри в CSS","\u002Fhtml-css\u002F12b.css-shadows-filters","12.html-css\u002F12b.css-shadows-filters",{"title":3548,"path":3549,"stem":3550},"CSS Flexbox: Фундамент гнучких макетів","\u002Fhtml-css\u002Fcss-flexbox-fundamentals","12.html-css\u002F13.css-flexbox-fundamentals",{"title":3552,"path":3553,"stem":3554},"CSS Flexbox: Вирівнювання та Позиціонування","\u002Fhtml-css\u002Fcss-flexbox-alignment-sizing-and-patterns","12.html-css\u002F14.css-flexbox-alignment-sizing-and-patterns",{"title":3556,"path":3557,"stem":3558},"CSS Grid. Двовимірний макет. Частина 1","\u002Fhtml-css\u002Fcss-layout-grid","12.html-css\u002F15.css-layout-grid",{"title":3560,"path":3561,"stem":3562},"CSS Grid. Двовимірний макет. Частина 2","\u002Fhtml-css\u002Fcss-layout-grid-advanced","12.html-css\u002F16.css-layout-grid-advanced",{"title":3564,"path":3565,"stem":3566},"Позиціонування в CSS. Z-index. Stacking Context","\u002Fhtml-css\u002Fcss-positioning","12.html-css\u002F17.css-positioning",{"title":3568,"path":3569,"stem":3570},"CSS Анімації та Переходи","\u002Fhtml-css\u002Fcss-animations-transitions","12.html-css\u002F18.css-animations-transitions",{"title":3572,"path":3573,"stem":3574},"Адаптивний дизайн. Media Queries. Частина 1","\u002Fhtml-css\u002Fcss-responsive-media-queries","12.html-css\u002F19.css-responsive-media-queries",{"title":3576,"path":3577,"stem":3578},"Адаптивний дизайн. Частина 2: clamp(), Container Queries, @layer","\u002Fhtml-css\u002Fcss-responsive-advanced","12.html-css\u002F20.css-responsive-advanced",{"title":3580,"path":3581,"stem":3582},"CSS Custom Properties. Методології. Сучасний CSS","\u002Fhtml-css\u002Fcss-variables-methodologies","12.html-css\u002F21.css-variables-methodologies",{"title":3584,"path":3585,"stem":3586},"Сучасний CSS 2023–2025: Нові можливості","\u002Fhtml-css\u002Fcss-modern-features","12.html-css\u002F22.css-modern-features",{"title":3588,"path":3589,"stem":3590},"CSS Nesting, @layer, @scope та @property: нативний препроцесор","\u002Fhtml-css\u002F22a.css-nesting-modern-syntax","12.html-css\u002F22a.css-nesting-modern-syntax",{"title":3592,"path":3593,"stem":3594},"CSS для форм та інтерактивних станів","\u002Fhtml-css\u002Fcss-forms-interactive-states","12.html-css\u002F23.css-forms-interactive-states",{"title":3596,"path":3597,"stem":3598},"Доступність у CSS (CSS Accessibility)","\u002Fhtml-css\u002Fcss-accessibility","12.html-css\u002F24.css-accessibility",{"title":3600,"path":3601,"stem":3602},"CSS-функції та сучасні sizing primitives","\u002Fhtml-css\u002Fcss-functions-sizing","12.html-css\u002F25.css-functions-sizing",{"title":3604,"path":3605,"stem":3606},"Rendering Pipeline і CSS Performance","\u002Fhtml-css\u002Fcss-rendering-performance","12.html-css\u002F26.css-rendering-performance",{"title":3608,"path":3609,"stem":3610},"CSS Best Practices: типові ситуації та правильні рішення","\u002Fhtml-css\u002Fcss-best-practices","12.html-css\u002F27.css-best-practices",{"title":3612,"path":3613,"stem":3614,"children":3615,"page":59},"AWS","\u002Faws","13.aws",[3616,3620,3624,3628,3632,3636,3640,3644,3648,3652,3656,3660,3664,3668,3672,3676,3680,3684],{"title":3617,"path":3618,"stem":3619},"Реєстрація AWS акаунту та студентські програми","\u002Faws\u002Faccount-registration","13.aws\u002F00.account-registration",{"title":3621,"path":3622,"stem":3623},"Вступ до хмарних обчислень та AWS","\u002Faws\u002Fintroduction-to-cloud","13.aws\u002F01.introduction-to-cloud",{"title":3625,"path":3626,"stem":3627},"AWS IAM — Identity and Access Management","\u002Faws\u002Fiam","13.aws\u002F02.iam",{"title":3629,"path":3630,"stem":3631},"AWS IAM CLI — Довідник команд","\u002Faws\u002F02a.iam-doc","13.aws\u002F02a.iam-doc",{"title":3633,"path":3634,"stem":3635},"Docker та контейнеризація в AWS — ECR, ECS та Fargate","\u002Faws\u002Fdocker-ecs","13.aws\u002F03.docker-ecs",{"title":3637,"path":3638,"stem":3639},"AWS ECR \u002F ECS CLI — Довідник команд","\u002Faws\u002F03a.docker-ecs-doc","13.aws\u002F03a.docker-ecs-doc",{"title":3641,"path":3642,"stem":3643},"Amazon EC2 — Elastic Compute Cloud","\u002Faws\u002Fec2","13.aws\u002F04.ec2",{"title":3645,"path":3646,"stem":3647},"AWS EC2 CLI — Довідник команд","\u002Faws\u002F04a.ec2-doc","13.aws\u002F04a.ec2-doc",{"title":3649,"path":3650,"stem":3651},"Elastic Load Balancing та Auto Scaling","\u002Faws\u002Falb-asg","13.aws\u002F05.alb-asg",{"title":3653,"path":3654,"stem":3655},"Amazon S3 — Simple Storage Service","\u002Faws\u002Fs3","13.aws\u002F06.s3",{"title":3657,"path":3658,"stem":3659},"Amazon CloudFront — Content Delivery Network","\u002Faws\u002Fcloudfront","13.aws\u002F07.cloudfront",{"title":3661,"path":3662,"stem":3663},"Amazon RDS — Relational Database Service","\u002Faws\u002Frds","13.aws\u002F08.rds",{"title":3665,"path":3666,"stem":3667},"Amazon DynamoDB — NoSQL Database","\u002Faws\u002Fdynamodb","13.aws\u002F09.dynamodb",{"title":3669,"path":3670,"stem":3671},"AWS Lambda та Serverless Compute","\u002Faws\u002Flambda","13.aws\u002F10.lambda",{"title":3673,"path":3674,"stem":3675},"Amazon Bedrock - Foundation Models, RAG та Agents","\u002Faws\u002Fbedrock","13.aws\u002F22.bedrock",{"title":3677,"path":3678,"stem":3679},"Amazon Rekognition - Комп'ютерний зір","\u002Faws\u002Frekognition","13.aws\u002F23.rekognition",{"title":3681,"path":3682,"stem":3683},"Amazon Textract - Інтелектуальний аналіз документів","\u002Faws\u002Ftextract","13.aws\u002F24.textract",{"title":3685,"path":3686,"stem":3687},"Amazon Polly, Transcribe, Comprehend та Translate","\u002Faws\u002Faudio-nlp-services","13.aws\u002F25.audio-nlp-services",{"title":3689,"path":3690,"stem":3691,"children":3692,"page":59},"Ai Development","\u002Fai-development","14.ai-development",[3693],{"title":3694,"path":3695,"stem":3696,"children":3697,"page":59},"Foundations","\u002Fai-development\u002Ffoundations","14.ai-development\u002F00.foundations",[3698],{"title":3699,"path":3700,"stem":3701},"Модуль 0.1. Що таке Large Language Model (LLM)","\u002Fai-development\u002Ffoundations\u002Fwhat-is-llm","14.ai-development\u002F00.foundations\u002F01.what-is-llm",{"title":3703,"path":3704,"stem":3705,"children":3706,"page":59},"React Native","\u002Freact-native","15.react-native",[3707,3728],{"title":3708,"path":3709,"stem":3710,"children":3711,"page":59},"Version1","\u002Freact-native\u002Fversion1","15.react-native\u002Fversion1",[3712,3716,3720,3724],{"title":3713,"path":3714,"stem":3715},"Що таке React Native","\u002Freact-native\u002Fversion1\u002Fwhat-is-react-native","15.react-native\u002Fversion1\u002F01.what-is-react-native",{"title":3717,"path":3718,"stem":3719},"Як влаштований React Native «під капотом»","\u002Freact-native\u002Fversion1\u002Freact-native-architecture","15.react-native\u002Fversion1\u002F02.react-native-architecture",{"title":3721,"path":3722,"stem":3723},"Від React до React Native: ключові відмінності","\u002Freact-native\u002Fversion1\u002Freact-native-vs-react","15.react-native\u002Fversion1\u002F03.react-native-vs-react",{"title":3725,"path":3726,"stem":3727},"View та Text — фундаментальні будівельні блоки","\u002Freact-native\u002Fversion1\u002Fview-and-text","15.react-native\u002Fversion1\u002F04.view-and-text",{"title":3729,"path":3730,"stem":3731,"children":3732,"page":59},"Version2","\u002Freact-native\u002Fversion2","15.react-native\u002Fversion2",[3733,3737,3741,3745,3749,3753,3757,3761,3765,3769,3773,3777,3781,3785,3789,3793,3797,3801,3805,3809,3813,3817,3821,3825,3829,3833,3837],{"title":3734,"path":3735,"stem":3736},"React Native — навіщо він потрібен","\u002Freact-native\u002Fversion2\u002Fwhy-react-native","15.react-native\u002Fversion2\u002F01.why-react-native",{"title":3738,"path":3739,"stem":3740},"Налаштування середовища розробки","\u002Freact-native\u002Fversion2\u002Fenvironment-setup","15.react-native\u002Fversion2\u002F02.environment-setup",{"title":3742,"path":3743,"stem":3744},"Expo і класичний React Native — два шляхи одного фреймворку","\u002Freact-native\u002Fversion2\u002Fexpo-vs-cli-landscape","15.react-native\u002Fversion2\u002F03.expo-vs-cli-landscape",{"title":3746,"path":3747,"stem":3748},"Середовище Expo — перший запуск","\u002Freact-native\u002Fversion2\u002Fexpo-setup-and-tooling","15.react-native\u002Fversion2\u002F04.expo-setup-and-tooling",{"title":3750,"path":3751,"stem":3752},"Структура проєкту та перші UI-примітиви","\u002Freact-native\u002Fversion2\u002Fproject-structure-and-conventions","15.react-native\u002Fversion2\u002F05.project-structure-and-conventions",{"title":3754,"path":3755,"stem":3756},"Базові компоненти React Native","\u002Freact-native\u002Fversion2\u002Fcore-components","15.react-native\u002Fversion2\u002F06.core-components",{"title":3758,"path":3759,"stem":3760},"Flexbox і layout у React Native","\u002Freact-native\u002Fversion2\u002Fflexbox-and-layout","15.react-native\u002Fversion2\u002F07.flexbox-and-layout",{"title":3762,"path":3763,"stem":3764},"StyleSheet і теми (light \u002F dark)","\u002Freact-native\u002Fversion2\u002Fstylesheet-and-theming","15.react-native\u002Fversion2\u002F08.stylesheet-and-theming",{"title":3766,"path":3767,"stem":3768},"Списки та віртуалізація","\u002Freact-native\u002Fversion2\u002Flists-and-virtualization","15.react-native\u002Fversion2\u002F09.lists-and-virtualization",{"title":3770,"path":3771,"stem":3772},"Форми, ввід і валідація","\u002Freact-native\u002Fversion2\u002Fforms-input-validation","15.react-native\u002Fversion2\u002F10.forms-input-validation",{"title":3774,"path":3775,"stem":3776},"Основи Expo Router","\u002Freact-native\u002Fversion2\u002Fexpo-router-basics","15.react-native\u002Fversion2\u002F11.expo-router-basics",{"title":3778,"path":3779,"stem":3780},"Вкладені навігатори та модалки","\u002Freact-native\u002Fversion2\u002Fnested-navigators-and-modals","15.react-native\u002Fversion2\u002F12.nested-navigators-and-modals",{"title":3782,"path":3783,"stem":3784},"Deep linking і параметри маршрутів","\u002Freact-native\u002Fversion2\u002Fdeep-linking-and-params","15.react-native\u002Fversion2\u002F13.deep-linking-and-params",{"title":3786,"path":3787,"stem":3788},"Робота з мережею та життєвий цикл застосунку","\u002Freact-native\u002Fversion2\u002Fnetworking-and-app-lifecycle","15.react-native\u002Fversion2\u002F14.networking-and-app-lifecycle",{"title":3790,"path":3791,"stem":3792},"Redux Toolkit на мобільних платформах","\u002Freact-native\u002Fversion2\u002Fredux-toolkit-on-mobile","15.react-native\u002Fversion2\u002F15.redux-toolkit-on-mobile",{"title":3794,"path":3795,"stem":3796},"RTK Query на мобільних платформах","\u002Freact-native\u002Fversion2\u002Frtk-query-mobile","15.react-native\u002Fversion2\u002F16.rtk-query-mobile",{"title":3798,"path":3799,"stem":3800},"Автентифікація та Безпечне Зберігання","\u002Freact-native\u002Fversion2\u002Fauth-secure-storage","15.react-native\u002Fversion2\u002F18.auth-secure-storage",{"title":3802,"path":3803,"stem":3804},"Локальне сховище — AsyncStorage, MMKV, SQLite","\u002Freact-native\u002Fversion2\u002Flocal-storage-mmkv-sqlite","15.react-native\u002Fversion2\u002F19.local-storage-mmkv-sqlite",{"title":3806,"path":3807,"stem":3808},"Офлайн-First і синхронізація","\u002Freact-native\u002Fversion2\u002Foffline-first-sync","15.react-native\u002Fversion2\u002F20.offline-first-sync",{"title":3810,"path":3811,"stem":3812},"Камера, медіа та файлова система","\u002Freact-native\u002Fversion2\u002Fcamera-media-filesystem","15.react-native\u002Fversion2\u002F21.camera-media-filesystem",{"title":3814,"path":3815,"stem":3816},"Карти та геолокація","\u002Freact-native\u002Fversion2\u002Fmaps-and-location","15.react-native\u002Fversion2\u002F22.maps-and-location",{"title":3818,"path":3819,"stem":3820},"Жести та дотики","\u002Freact-native\u002Fversion2\u002Fgestures-and-touch","15.react-native\u002Fversion2\u002F23.gestures-and-touch",{"title":3822,"path":3823,"stem":3824},"Анімації з Reanimated","\u002Freact-native\u002Fversion2\u002Freanimated-animations","15.react-native\u002Fversion2\u002F24.reanimated-animations",{"title":3826,"path":3827,"stem":3828},"Push і локальні сповіщення","\u002Freact-native\u002Fversion2\u002Fpush-and-local-notifications","15.react-native\u002Fversion2\u002F25.push-and-local-notifications",{"title":3830,"path":3831,"stem":3832},"Інтернаціоналізація та доступність","\u002Freact-native\u002Fversion2\u002Faccessibility-and-i18n","15.react-native\u002Fversion2\u002F26.accessibility-and-i18n",{"title":3834,"path":3835,"stem":3836},"EAS Build та профілі збірки","\u002Freact-native\u002Fversion2\u002Feas-build-and-profiles","15.react-native\u002Fversion2\u002F29.eas-build-and-profiles",{"title":3838,"path":3839,"stem":3840},"Публікація в App Store та Google Play","\u002Freact-native\u002Fversion2\u002Fapp-store-play-release","15.react-native\u002Fversion2\u002F30.app-store-play-release",{"title":3842,"path":3843,"stem":3844,"children":3845,"page":59},"Ai Python","\u002Fai-python","16.ai-python",[3846,3855,3864,3873,3902,3928,3953,3986,4003,4016,4025,4038,4047,4068,4081,4150],{"title":3847,"path":3848,"stem":3849,"children":3850,"page":59},"Intro To Ai","\u002Fai-python\u002Fintro-to-ai","16.ai-python\u002F01.intro-to-ai",[3851],{"title":3852,"path":3853,"stem":3854},"Вступ до штучного інтелекту та машинного навчання","\u002Fai-python\u002Fintro-to-ai\u002Fintro-to-ai","16.ai-python\u002F01.intro-to-ai\u002F01.intro-to-ai",{"title":3856,"path":3857,"stem":3858,"children":3859,"page":59},"Jupyter Notebook","\u002Fai-python\u002Fjupyter-notebook","16.ai-python\u002F02.jupyter-notebook",[3860],{"title":3861,"path":3862,"stem":3863},"Знайомство з Jupyter Notebook та JupyterLab","\u002Fai-python\u002Fjupyter-notebook\u002Fjupyter-notebook","16.ai-python\u002F02.jupyter-notebook\u002F02.jupyter-notebook",{"title":3865,"path":3866,"stem":3867,"children":3868,"page":59},"Numpy Pandas","\u002Fai-python\u002Fnumpy-pandas","16.ai-python\u002F03.numpy-pandas",[3869],{"title":3870,"path":3871,"stem":3872},"Робота з даними з використанням NumPy і pandas","\u002Fai-python\u002Fnumpy-pandas\u002Fnumpy-pandas","16.ai-python\u002F03.numpy-pandas\u002F03.numpy-pandas",{"title":3874,"path":3875,"stem":3876,"children":3877,"page":59},"Statistics Basics","\u002Fai-python\u002Fstatistics-basics","16.ai-python\u002F04.statistics-basics",[3878,3882,3886,3890,3894,3898],{"title":3879,"path":3880,"stem":3881},"Випадкові величини та їх типи","\u002Fai-python\u002Fstatistics-basics\u002Frandom-variables","16.ai-python\u002F04.statistics-basics\u002F01.random-variables",{"title":3883,"path":3884,"stem":3885},"Міри центральної тенденції","\u002Fai-python\u002Fstatistics-basics\u002Fcentral-tendency","16.ai-python\u002F04.statistics-basics\u002F02.central-tendency",{"title":3887,"path":3888,"stem":3889},"Міри варіації (розсіювання)","\u002Fai-python\u002Fstatistics-basics\u002Fvariability","16.ai-python\u002F04.statistics-basics\u002F03.variability",{"title":3891,"path":3892,"stem":3893},"Розподіли випадкових величин","\u002Fai-python\u002Fstatistics-basics\u002Fdistributions","16.ai-python\u002F04.statistics-basics\u002F04.distributions",{"title":3895,"path":3896,"stem":3897},"Кореляція та взаємозв'язки","\u002Fai-python\u002Fstatistics-basics\u002Fcorrelation","16.ai-python\u002F04.statistics-basics\u002F05.correlation",{"title":3899,"path":3900,"stem":3901},"Викиди та аномалії","\u002Fai-python\u002Fstatistics-basics\u002Foutliers","16.ai-python\u002F04.statistics-basics\u002F06.outliers",{"title":3903,"path":3904,"stem":3905,"children":3906},"Візуалізація даних за допомогою matplotlib","\u002Fai-python\u002Fdata-visualization","16.ai-python\u002F05.data-visualization\u002Findex",[3907,3908,3912,3916,3920,3924],{"title":3903,"path":3904,"stem":3905},{"title":3909,"path":3910,"stem":3911},"Основи matplotlib — Figure, Axes та перший графік","\u002Fai-python\u002Fdata-visualization\u002Fmatplotlib-basics","16.ai-python\u002F05.data-visualization\u002F01.matplotlib-basics",{"title":3913,"path":3914,"stem":3915},"Візуалізація розподілів — гістограми та box plots","\u002Fai-python\u002Fdata-visualization\u002Fdistributions","16.ai-python\u002F05.data-visualization\u002F02.distributions",{"title":3917,"path":3918,"stem":3919},"Візуалізація залежностей — scatter plots та кореляція","\u002Fai-python\u002Fdata-visualization\u002Frelationships","16.ai-python\u002F05.data-visualization\u002F03.relationships",{"title":3921,"path":3922,"stem":3923},"Візуалізація категоріальних даних — bar charts та pie charts","\u002Fai-python\u002Fdata-visualization\u002Fcategorical","16.ai-python\u002F05.data-visualization\u002F04.categorical",{"title":3925,"path":3926,"stem":3927},"Композиції та стилізація — subplots та багатопанельні дашборди","\u002Fai-python\u002Fdata-visualization\u002Fsubplots-styling","16.ai-python\u002F05.data-visualization\u002F05.subplots-styling",{"title":3929,"path":3930,"stem":3931,"children":3932,"page":59},"Linear Regression","\u002Fai-python\u002Flinear-regression","16.ai-python\u002F06.linear-regression",[3933,3937,3941,3945,3949],{"title":3934,"path":3935,"stem":3936},"Регресійна задача та лінійна регресія з однією змінною","\u002Fai-python\u002Flinear-regression\u002Fregression-task","16.ai-python\u002F06.linear-regression\u002F01.regression-task",{"title":3938,"path":3939,"stem":3940},"Метрики якості регресії — як оцінити модель","\u002Fai-python\u002Flinear-regression\u002Fquality-metrics","16.ai-python\u002F06.linear-regression\u002F02.quality-metrics",{"title":3942,"path":3943,"stem":3944},"Градієнтний спуск — як модель навчається","\u002Fai-python\u002Flinear-regression\u002Fgradient-descent","16.ai-python\u002F06.linear-regression\u002F03.gradient-descent",{"title":3946,"path":3947,"stem":3948},"Множинна лінійна регресія — модель з багатьма ознаками","\u002Fai-python\u002Flinear-regression\u002Fmultiple-regression","16.ai-python\u002F06.linear-regression\u002F04.multiple-regression",{"title":3950,"path":3951,"stem":3952},"Практичні завдання та резюме модуля","\u002Fai-python\u002Flinear-regression\u002Fpractice","16.ai-python\u002F06.linear-regression\u002F05.practice",{"title":3954,"path":3955,"stem":3956,"children":3957,"page":59},"Practical Regression","\u002Fai-python\u002Fpractical-regression","16.ai-python\u002F07.practical-regression",[3958,3962,3966,3970,3974,3978,3982],{"title":3959,"path":3960,"stem":3961},"Знайомство з scikit-learn","\u002Fai-python\u002Fpractical-regression\u002Fintro-scikit-learn","16.ai-python\u002F07.practical-regression\u002F01.intro-scikit-learn",{"title":3963,"path":3964,"stem":3965},"Exploratory Data Analysis датасету Housing Prices","\u002Fai-python\u002Fpractical-regression\u002Fhousing-dataset-eda","16.ai-python\u002F07.practical-regression\u002F02.housing-dataset-eda",{"title":3967,"path":3968,"stem":3969},"Попередня обробка даних (Data Preprocessing)","\u002Fai-python\u002Fpractical-regression\u002Fdata-preprocessing","16.ai-python\u002F07.practical-regression\u002F03.data-preprocessing",{"title":3971,"path":3972,"stem":3973},"Train\u002FTest Split та перша повноцінна модель","\u002Fai-python\u002Fpractical-regression\u002Ftrain-test-split","16.ai-python\u002F07.practical-regression\u002F04.train-test-split",{"title":3975,"path":3976,"stem":3977},"Перенавчання та недонавчання","\u002Fai-python\u002Fpractical-regression\u002Foverfitting-underfitting","16.ai-python\u002F07.practical-regression\u002F05.overfitting-underfitting",{"title":3979,"path":3980,"stem":3981},"Крос-валідація (Cross-Validation)","\u002Fai-python\u002Fpractical-regression\u002Fcross-validation","16.ai-python\u002F07.practical-regression\u002F06.cross-validation",{"title":3983,"path":3984,"stem":3985},"Гіперпараметри та їх оптимізація","\u002Fai-python\u002Fpractical-regression\u002Fhyperparameter-tuning","16.ai-python\u002F07.practical-regression\u002F07.hyperparameter-tuning",{"title":3987,"path":3988,"stem":3989,"children":3990,"page":59},"Polynomial Regression","\u002Fai-python\u002Fpolynomial-regression","16.ai-python\u002F08.polynomial-regression",[3991,3995,3999],{"title":3992,"path":3993,"stem":3994},"Нелінійні залежності та поліноміальна регресія","\u002Fai-python\u002Fpolynomial-regression\u002Fnonlinear-patterns","16.ai-python\u002F08.polynomial-regression\u002F01.nonlinear-patterns",{"title":3996,"path":3997,"stem":3998},"Регуляризація в регресії — Ridge та Lasso","\u002Fai-python\u002Fpolynomial-regression\u002Fregularization-methods","16.ai-python\u002F08.polynomial-regression\u002F02.regularization-methods",{"title":4000,"path":4001,"stem":4002},"Практика — поліноміальна регресія та регуляризація на Housing Prices","\u002Fai-python\u002Fpolynomial-regression\u002Fhousing-prices-practice","16.ai-python\u002F08.polynomial-regression\u002F03.housing-prices-practice",{"title":4004,"path":4005,"stem":4006,"children":4007,"page":59},"Decision Trees Random Forest","\u002Fai-python\u002Fdecision-trees-random-forest","16.ai-python\u002F09.decision-trees-random-forest",[4008,4012],{"title":4009,"path":4010,"stem":4011},"Дерева рішень — моделі з прозорою та зрозумілою логікою","\u002Fai-python\u002Fdecision-trees-random-forest\u002Fdecision-trees","16.ai-python\u002F09.decision-trees-random-forest\u002F01.decision-trees",{"title":4013,"path":4014,"stem":4015},"Random Forest — ансамблі дерев рішень","\u002Fai-python\u002Fdecision-trees-random-forest\u002Frandom-forest","16.ai-python\u002F09.decision-trees-random-forest\u002F02.random-forest",{"title":4017,"path":4018,"stem":4019,"children":4020,"page":59},"Gradient Boosting","\u002Fai-python\u002Fgradient-boosting","16.ai-python\u002F10.gradient-boosting",[4021],{"title":4022,"path":4023,"stem":4024},"Градієнтний бустинг та XGBoost — послідовне виправлення помилок","\u002Fai-python\u002Fgradient-boosting\u002Fgradient-boosting-xgboost","16.ai-python\u002F10.gradient-boosting\u002F01.gradient-boosting-xgboost",{"title":4026,"path":4027,"stem":4028,"children":4029,"page":59},"Logistic Regression Classification","\u002Fai-python\u002Flogistic-regression-classification","16.ai-python\u002F11.logistic-regression-classification",[4030,4034],{"title":4031,"path":4032,"stem":4033},"Основи класифікації та логістична регресія","\u002Fai-python\u002Flogistic-regression-classification\u002Fclassification-basics","16.ai-python\u002F11.logistic-regression-classification\u002F01.classification-basics",{"title":4035,"path":4036,"stem":4037},"Метрики якості класифікації","\u002Fai-python\u002Flogistic-regression-classification\u002Fclassification-metrics","16.ai-python\u002F11.logistic-regression-classification\u002F02.classification-metrics",{"title":4039,"path":4040,"stem":4041,"children":4042,"page":59},"Neural Networks Basics","\u002Fai-python\u002Fneural-networks-basics","16.ai-python\u002F12.neural-networks-basics",[4043],{"title":4044,"path":4045,"stem":4046},"Вступ до нейронних мереж — від персептрона до багатошарових мереж","\u002Fai-python\u002Fneural-networks-basics\u002Fperceptron-to-mlp","16.ai-python\u002F12.neural-networks-basics\u002F01.perceptron-to-mlp",{"title":4048,"path":4049,"stem":4050,"children":4051,"page":59},"Pytorch Intro","\u002Fai-python\u002Fpytorch-intro","16.ai-python\u002F13.pytorch-intro",[4052,4056,4060,4064],{"title":4053,"path":4054,"stem":4055},"Тензори та автоматичне диференціювання в PyTorch","\u002Fai-python\u002Fpytorch-intro\u002Ftensors-and-autograd","16.ai-python\u002F13.pytorch-intro\u002F01.tensors-and-autograd",{"title":4057,"path":4058,"stem":4059},"Побудова та тренування нейронних мереж у PyTorch","\u002Fai-python\u002Fpytorch-intro\u002Fbuilding-and-training","16.ai-python\u002F13.pytorch-intro\u002F02.building-and-training",{"title":4061,"path":4062,"stem":4063},"Робота з даними та регуляризація в PyTorch","\u002Fai-python\u002Fpytorch-intro\u002Fdata-and-regularization","16.ai-python\u002F13.pytorch-intro\u002F03.data-and-regularization",{"title":4065,"path":4066,"stem":4067},"Просунуті теми PyTorch — GPU, оптимізація та deployment","\u002Fai-python\u002Fpytorch-intro\u002Fadvanced-topics","16.ai-python\u002F13.pytorch-intro\u002F04.advanced-topics",{"title":4069,"path":4070,"stem":4071,"children":4072,"page":59},"Activation Functions Heart Disease","\u002Fai-python\u002Factivation-functions-heart-disease","16.ai-python\u002F14.activation-functions-heart-disease",[4073,4077],{"title":4074,"path":4075,"stem":4076},"Функції активації та побудова нейронної мережі для передбачення вад серця","\u002Fai-python\u002Factivation-functions-heart-disease\u002Fheart-disease-prediction","16.ai-python\u002F14.activation-functions-heart-disease\u002F01.heart-disease-prediction",{"title":4078,"path":4079,"stem":4080},"Бонус — Повний приклад Student Performance Prediction","\u002Fai-python\u002Factivation-functions-heart-disease\u002Fstudent-performance-bonus","16.ai-python\u002F14.activation-functions-heart-disease\u002F02.student-performance-bonus",{"title":4082,"path":4083,"stem":4084,"children":4085,"page":59},"Cnn Image Classification","\u002Fai-python\u002Fcnn-image-classification","16.ai-python\u002F15.cnn-image-classification",[4086,4090,4094,4098,4102,4106,4110,4114,4118,4122,4126,4130,4134,4138,4142,4146],{"title":4087,"path":4088,"stem":4089},"Вступ до комп'ютерного зору та проблеми Dense-мереж","\u002Fai-python\u002Fcnn-image-classification\u002Fintro-computer-vision","16.ai-python\u002F15.cnn-image-classification\u002F01.intro-computer-vision",{"title":4091,"path":4092,"stem":4093},"Навіщо потрібна згортка — від нейрона-шаблону до ковзного детектора","\u002Fai-python\u002Fcnn-image-classification\u002Fwhy-convolution","16.ai-python\u002F15.cnn-image-classification\u002F02.why-convolution",{"title":4095,"path":4096,"stem":4097},"Згортка крок за кроком — ядро, карта ознак і розмір результату","\u002Fai-python\u002Fcnn-image-classification\u002Fconvolution-step-by-step","16.ai-python\u002F15.cnn-image-classification\u002F03.convolution-step-by-step",{"title":4099,"path":4100,"stem":4101},"Що «бачить» ядро — читаємо карту ознак і класичні фільтри","\u002Fai-python\u002Fcnn-image-classification\u002Ffilters-what-kernel-sees","16.ai-python\u002F15.cnn-image-classification\u002F04.filters-what-kernel-sees",{"title":4103,"path":4104,"stem":4105},"Padding і stride — що робити з краями картинки та її розміром","\u002Fai-python\u002Fcnn-image-classification\u002Fpadding-and-stride","16.ai-python\u002F15.cnn-image-classification\u002F05.padding-and-stride",{"title":4107,"path":4108,"stem":4109},"Ядро, що навчається — від випадкових чисел до детектора країв","\u002Fai-python\u002Fcnn-image-classification\u002Flearnable-kernels","16.ai-python\u002F15.cnn-image-classification\u002F06.learnable-kernels",{"title":4111,"path":4112,"stem":4113},"Пулінг і поле зору — стискаємо карту ознак і дивимося ширше","\u002Fai-python\u002Fcnn-image-classification\u002Fpooling","16.ai-python\u002F15.cnn-image-classification\u002F07.pooling",{"title":4115,"path":4116,"stem":4117},"Багатоканальна згортка — ядро-куб, кольорове фото та підрахунок параметрів","\u002Fai-python\u002Fcnn-image-classification\u002Fmultichannel-convolution","16.ai-python\u002F15.cnn-image-classification\u002F08.multichannel-convolution",{"title":4119,"path":4120,"stem":4121},"Повна CNN для MNIST — збираємо, навчаємо, перевіряємо","\u002Fai-python\u002Fcnn-image-classification\u002Fcnn-mnist","16.ai-python\u002F15.cnn-image-classification\u002F09.cnn-mnist",{"title":4123,"path":4124,"stem":4125},"CNN для CIFAR-10 — коли задача справді складна","\u002Fai-python\u002Fcnn-image-classification\u002Fcnn-cifar10","16.ai-python\u002F15.cnn-image-classification\u002F10.cnn-cifar10",{"title":4127,"path":4128,"stem":4129},"Міні-батчі, DataLoader і швидкість навчання","\u002Fai-python\u002Fcnn-image-classification\u002Fmini-batch-learning-rate","16.ai-python\u002F15.cnn-image-classification\u002F11.mini-batch-learning-rate",{"title":4131,"path":4132,"stem":4133},"Ініціалізація ваг і Batch Normalization","\u002Fai-python\u002Fcnn-image-classification\u002Fweight-init-batchnorm","16.ai-python\u002F15.cnn-image-classification\u002F12.weight-init-batchnorm",{"title":4135,"path":4136,"stem":4137},"LayerNorm і обрізання градієнтів","\u002Fai-python\u002Fcnn-image-classification\u002Flayernorm-gradient-clipping","16.ai-python\u002F15.cnn-image-classification\u002F13.layernorm-gradient-clipping",{"title":4139,"path":4140,"stem":4141},"Аугментація даних","\u002Fai-python\u002Fcnn-image-classification\u002Fdata-augmentation","16.ai-python\u002F15.cnn-image-classification\u002F14.data-augmentation",{"title":4143,"path":4144,"stem":4145},"Глибокі мережі та ResNet","\u002Fai-python\u002Fcnn-image-classification\u002Fdeep-networks-resnet","16.ai-python\u002F15.cnn-image-classification\u002F15.deep-networks-resnet",{"title":4147,"path":4148,"stem":4149},"Пневмонія на рентгені - метрики, transfer learning, Grad-CAM","\u002Fai-python\u002Fcnn-image-classification\u002Fpneumonia-transfer-learning","16.ai-python\u002F15.cnn-image-classification\u002F16.pneumonia-transfer-learning",{"title":4151,"path":4152,"stem":4153,"children":4154,"page":59},"Natural Language Processing","\u002Fai-python\u002Fnatural-language-processing","16.ai-python\u002F16.natural-language-processing",[4155,4159,4163,4167,4171,4175,4179,4183,4187,4191,4195,4199,4203,4207,4211,4215],{"title":4156,"path":4157,"stem":4158},"Текст як дані — чому мова складна для комп'ютера","\u002Fai-python\u002Fnatural-language-processing\u002Ftext-as-data","16.ai-python\u002F16.natural-language-processing\u002F01.text-as-data",{"title":4160,"path":4161,"stem":4162},"Токенізація — розбиття тексту на слова й речення","\u002Fai-python\u002Fnatural-language-processing\u002Ftokenization","16.ai-python\u002F16.natural-language-processing\u002F02.tokenization",{"title":4164,"path":4165,"stem":4166},"Стеммінг, лемматизація та стоп-слова","\u002Fai-python\u002Fnatural-language-processing\u002Fstemming-lemmatization-stopwords","16.ai-python\u002F16.natural-language-processing\u002F03.stemming-lemmatization-stopwords",{"title":4168,"path":4169,"stem":4170},"Корпус та частоти слів","\u002Fai-python\u002Fnatural-language-processing\u002Fcorpus-and-frequency","16.ai-python\u002F16.natural-language-processing\u002F04.corpus-and-frequency",{"title":4172,"path":4173,"stem":4174},"Мішок слів — перше представлення тексту числами","\u002Fai-python\u002Fnatural-language-processing\u002Fbag-of-words","16.ai-python\u002F16.natural-language-processing\u002F05.bag-of-words",{"title":4176,"path":4177,"stem":4178},"Класифікація тексту — baseline на мішку слів","\u002Fai-python\u002Fnatural-language-processing\u002Ftext-classification-baseline","16.ai-python\u002F16.natural-language-processing\u002F06.text-classification-baseline",{"title":4180,"path":4181,"stem":4182},"Від one-hot до embeddings — щільні вектори слів","\u002Fai-python\u002Fnatural-language-processing\u002Ffrom-one-hot-to-embeddings","16.ai-python\u002F16.natural-language-processing\u002F07.from-one-hot-to-embeddings",{"title":4184,"path":4185,"stem":4186},"Word2Vec — навчання векторів слів з контексту","\u002Fai-python\u002Fnatural-language-processing\u002Fword2vec","16.ai-python\u002F16.natural-language-processing\u002F08.word2vec",{"title":4188,"path":4189,"stem":4190},"GloVe — глобальні вектори слів та попередньо навчені моделі","\u002Fai-python\u002Fnatural-language-processing\u002Fglove-pretrained-embeddings","16.ai-python\u002F16.natural-language-processing\u002F09.glove-pretrained-embeddings",{"title":4192,"path":4193,"stem":4194},"Embeddings для класифікації — від мішка слів до векторів","\u002Fai-python\u002Fnatural-language-processing\u002Fembeddings-for-classification","16.ai-python\u002F16.natural-language-processing\u002F10.embeddings-for-classification",{"title":4196,"path":4197,"stem":4198},"Мовні моделі та послідовності — від біграм до батчів","\u002Fai-python\u002Fnatural-language-processing\u002Flanguage-models-and-sequences","16.ai-python\u002F16.natural-language-processing\u002F11.language-models-and-sequences",{"title":4200,"path":4201,"stem":4202},"Рекурентні нейронні мережі (RNN)","\u002Fai-python\u002Fnatural-language-processing\u002Frnn","16.ai-python\u002F16.natural-language-processing\u002F12.rnn",{"title":4204,"path":4205,"stem":4206},"LSTM і GRU — рекурентні мережі з вентилями","\u002Fai-python\u002Fnatural-language-processing\u002Flstm-gru","16.ai-python\u002F16.natural-language-processing\u002F13.lstm-gru",{"title":4208,"path":4209,"stem":4210},"Seq2seq і механізм уваги","\u002Fai-python\u002Fnatural-language-processing\u002Fseq2seq-attention","16.ai-python\u002F16.natural-language-processing\u002F14.seq2seq-attention",{"title":4212,"path":4213,"stem":4214},"Transformer — self-attention замість рекурентності","\u002Fai-python\u002Fnatural-language-processing\u002Ftransformer","16.ai-python\u002F16.natural-language-processing\u002F15.transformer",{"title":4216,"path":4217,"stem":4218},"Готові моделі та Hugging Face — transfer learning","\u002Fai-python\u002Fnatural-language-processing\u002Fpretrained-models-sentiment","16.ai-python\u002F16.natural-language-processing\u002F16.pretrained-models-sentiment",{"title":4220,"icon":658,"path":4221,"stem":4222,"children":4223,"page":59},"Клієнт-серверна архітектура","\u002Fclient-server-architecture","17.client-server-architecture",[4224,4228,4232,4236,4240,4244,4248,4252,4256,4260,4264,4268,4272,4276,4280,4284,4288,4292],{"title":4225,"path":4226,"stem":4227},"Архітектура клієнт-серверних систем та основи Go","\u002Fclient-server-architecture\u002Fclient-server-architecture-and-go","17.client-server-architecture\u002F01.client-server-architecture-and-go",{"title":4229,"path":4230,"stem":4231},"Система типів та модель пам’яті мови Go","\u002Fclient-server-architecture\u002Ftype-system-and-memory-model","17.client-server-architecture\u002F02.type-system-and-memory-model",{"title":4233,"path":4234,"stem":4235},"Інтерфейси та модель конкурентності мови Go","\u002Fclient-server-architecture\u002Finterfaces-and-concurrency-model","17.client-server-architecture\u002F03.interfaces-and-concurrency-model",{"title":4237,"path":4238,"stem":4239},"Сокетне програмування та протокол TCP у Go","\u002Fclient-server-architecture\u002Ftcp-socket-programming","17.client-server-architecture\u002F04.tcp-socket-programming",{"title":4241,"path":4242,"stem":4243},"Протокол UDP та датаграмна передача даних","\u002Fclient-server-architecture\u002Fudp-datagram-transmission","17.client-server-architecture\u002F05.udp-datagram-transmission",{"title":4245,"path":4246,"stem":4247},"Криптографічний захист каналів зв","\u002Fclient-server-architecture\u002Ftls-cryptographic-channel-protection","17.client-server-architecture\u002F06.tls-cryptographic-channel-protection",{"title":4249,"path":4250,"stem":4251},"Прикладні мережеві протоколи DNS та SMTP","\u002Fclient-server-architecture\u002Fdns-smtp-application-protocols","17.client-server-architecture\u002F07.dns-smtp-application-protocols",{"title":4253,"path":4254,"stem":4255},"Протокол HTTP та стандартний вебсервер Go","\u002Fclient-server-architecture\u002Fhttp-protocol-and-web-server","17.client-server-architecture\u002F08.http-protocol-and-web-server",{"title":4257,"path":4258,"stem":4259},"Проєктування REST API та маршрутизація засобами Chi","\u002Fclient-server-architecture\u002Frest-api-design-and-chi-routing","17.client-server-architecture\u002F09.rest-api-design-and-chi-routing",{"title":4261,"path":4262,"stem":4263},"Лекція 10. Шарувата архітектура та конвеєри обробки запитів","\u002Fclient-server-architecture\u002Flayered-architecture-and-middleware-pipelines","17.client-server-architecture\u002F10.layered-architecture-and-middleware-pipelines",{"title":4265,"path":4266,"stem":4267},"Лекція 11. Архітектура та маршрутизація фреймворку Gin","\u002Fclient-server-architecture\u002Fgin-framework-architecture-and-routing","17.client-server-architecture\u002F11.gin-framework-architecture-and-routing",{"title":4269,"path":4270,"stem":4271},"Лекція 12. Валідація даних, безпека та документування у Gin","\u002Fclient-server-architecture\u002Fdata-validation-security-and-documentation-in-gin","17.client-server-architecture\u002F12.data-validation-security-and-documentation-in-gin",{"title":4273,"path":4274,"stem":4275},"Лекція 13. Взаємодія з реляційними СУБД та технології ORM","\u002Fclient-server-architecture\u002Frelational-databases-and-orm","17.client-server-architecture\u002F13.relational-databases-and-orm",{"title":4277,"path":4278,"stem":4279},"Потокова передача даних та протокол WebSocket","\u002Fclient-server-architecture\u002Fstreaming-data-and-websockets","17.client-server-architecture\u002F14.streaming-data-and-websockets",{"title":4281,"path":4282,"stem":4283},"Міжсервісна взаємодія на основі протоколу gRPC","\u002Fclient-server-architecture\u002Fgrpc-inter-service-communication","17.client-server-architecture\u002F15.grpc-inter-service-communication",{"title":4285,"path":4286,"stem":4287},"Асинхронний обмін повідомленнями та протоколи черг","\u002Fclient-server-architecture\u002Fasynchronous-message-exchange-and-queue-protocols","17.client-server-architecture\u002F16.asynchronous-message-exchange-and-queue-protocols",{"title":4289,"path":4290,"stem":4291},"Протоколи потокового медіа та технологія WebRTC","\u002Fclient-server-architecture\u002Fstreaming-media-protocols-and-webrtc","17.client-server-architecture\u002F17.streaming-media-protocols-and-webrtc",{"title":4293,"path":4294,"stem":4295},"Моніторинг, безпека та контейнеризація застосунків","\u002Fclient-server-architecture\u002Fmonitoring-security-and-containerization","17.client-server-architecture\u002F18.monitoring-security-and-containerization",{"title":4297,"icon":2228,"path":4298,"stem":4299,"children":4300,"page":59},"Розробка WEB-застосувань","\u002Fweb-development","18.web-development",[4301,4346,4384,4413,4442,4499,4549,4643,4709,4791,4824,4852,4894,4940,4983],{"title":4302,"icon":658,"path":4303,"stem":4304,"children":4305,"page":59},"Архітектура комп'ютерних мереж та мережеві протоколи","\u002Fweb-development\u002Fnetwork-architecture-and-protocols","18.web-development\u002F01.network-architecture-and-protocols",[4306,4310,4314,4318,4322,4326,4330,4334,4338,4342],{"title":4307,"path":4308,"stem":4309},"Еволюція веброзробки та модель клієнт-сервер","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fweb-evolution-client-server","18.web-development\u002F01.network-architecture-and-protocols\u002F01.web-evolution-client-server",{"title":4311,"path":4312,"stem":4313},"Еталонна модель OSI","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fosi-model","18.web-development\u002F01.network-architecture-and-protocols\u002F02.osi-model",{"title":4315,"path":4316,"stem":4317},"Стек протоколів TCP\u002FIP","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Ftcp-ip-stack","18.web-development\u002F01.network-architecture-and-protocols\u002F03.tcp-ip-stack",{"title":4319,"path":4320,"stem":4321},"IP-адресація, порти та сокети","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fip-addressing-ports-sockets","18.web-development\u002F01.network-architecture-and-protocols\u002F04.ip-addressing-ports-sockets",{"title":4323,"path":4324,"stem":4325},"Протоколи TCP та UDP","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Ftcp-udp-protocols","18.web-development\u002F01.network-architecture-and-protocols\u002F05.tcp-udp-protocols",{"title":4327,"path":4328,"stem":4329},"Система доменних імен DNS","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fdns-system","18.web-development\u002F01.network-architecture-and-protocols\u002F06.dns-system",{"title":4331,"path":4332,"stem":4333},"Протокол SMTP та поштові протоколи","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fsmtp-email-protocols","18.web-development\u002F01.network-architecture-and-protocols\u002F07.smtp-email-protocols",{"title":4335,"path":4336,"stem":4337},"Протокол WebSocket","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fwebsocket-protocol","18.web-development\u002F01.network-architecture-and-protocols\u002F08.websocket-protocol",{"title":4339,"path":4340,"stem":4341},"Протокол SSH","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fssh-protocol","18.web-development\u002F01.network-architecture-and-protocols\u002F09.ssh-protocol",{"title":4343,"path":4344,"stem":4345},"Огляд сучасних серверних технологій","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fmodern-backend-technologies","18.web-development\u002F01.network-architecture-and-protocols\u002F10.modern-backend-technologies",{"title":4347,"icon":4348,"path":4349,"stem":4350,"children":4351,"page":59},"Протокол HTTP та захищена передача даних HTTPS","i-lucide-lock","\u002Fweb-development\u002Fhttp-and-https","18.web-development\u002F02.http-and-https",[4352,4356,4360,4364,4368,4372,4376,4380],{"title":4353,"path":4354,"stem":4355},"Вступ до протоколу HTTP та еволюція веб-технологій","\u002Fweb-development\u002Fhttp-and-https\u002Fintroduction-and-evolution","18.web-development\u002F02.http-and-https\u002F01.introduction-and-evolution",{"title":4357,"path":4358,"stem":4359},"Анатомія HTTP-запиту","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-request-structure","18.web-development\u002F02.http-and-https\u002F02.http-request-structure",{"title":4361,"path":4362,"stem":4363},"Анатомія HTTP-відповіді","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-response-structure","18.web-development\u002F02.http-and-https\u002F03.http-response-structure",{"title":4365,"path":4366,"stem":4367},"Методи HTTP та їхня семантика","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-methods","18.web-development\u002F02.http-and-https\u002F04.http-methods",{"title":4369,"path":4370,"stem":4371},"Коди статусу HTTP та їхнє призначення","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-status-codes","18.web-development\u002F02.http-and-https\u002F05.http-status-codes",{"title":4373,"path":4374,"stem":4375},"HTTP-заголовки та їхнє призначення","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-headers","18.web-development\u002F02.http-and-https\u002F06.http-headers",{"title":4377,"path":4378,"stem":4379},"CORS та механізми безпеки HTTP","\u002Fweb-development\u002Fhttp-and-https\u002Fcors-and-security","18.web-development\u002F02.http-and-https\u002F07.cors-and-security",{"title":4381,"path":4382,"stem":4383},"HTTPS та криптографічні основи TLS","\u002Fweb-development\u002Fhttp-and-https\u002Fhttps-and-tls","18.web-development\u002F02.http-and-https\u002F08.https-and-tls",{"title":4385,"icon":2608,"path":4386,"stem":4387,"children":4388,"page":59},"Система типів мови TypeScript","\u002Fweb-development\u002Ftypescript-type-system","18.web-development\u002F03.typescript-type-system",[4389,4393,4397,4401,4405,4409],{"title":4390,"path":4391,"stem":4392},"Знайомство з TypeScript Compiler","\u002Fweb-development\u002Ftypescript-type-system\u002Fintroduction-compiler-config","18.web-development\u002F03.typescript-type-system\u002F01.introduction-compiler-config",{"title":4394,"path":4395,"stem":4396},"Примітивні типи даних: string, number, boolean","\u002Fweb-development\u002Ftypescript-type-system\u002Fprimitive-special-types","18.web-development\u002F03.typescript-type-system\u002F02.primitive-special-types",{"title":4398,"path":4399,"stem":4400},"Масиви, кортежі та об","\u002Fweb-development\u002Ftypescript-type-system\u002Farrays-tuples-objects","18.web-development\u002F03.typescript-type-system\u002F03.arrays-tuples-objects",{"title":4402,"path":4403,"stem":4404},"Псевдоніми типів, Union типи, Intersection типи та літеральні типи","\u002Fweb-development\u002Ftypescript-type-system\u002Funion-intersection-literals","18.web-development\u002F03.typescript-type-system\u002F04.union-intersection-literals",{"title":4406,"path":4407,"stem":4408},"Type Narrowing (звуження типів)","\u002Fweb-development\u002Ftypescript-type-system\u002Ftype-narrowing","18.web-development\u002F03.typescript-type-system\u002F05.type-narrowing",{"title":4410,"path":4411,"stem":4412},"Типізація функцій","\u002Fweb-development\u002Ftypescript-type-system\u002Ffunctions-typing","18.web-development\u002F03.typescript-type-system\u002F06.functions-typing",{"title":4414,"icon":2608,"path":4415,"stem":4416,"children":4417,"page":59},"Розширені засоби мови TypeScript","\u002Fweb-development\u002Ftypescript-advanced","18.web-development\u002F04.typescript-advanced",[4418,4422,4426,4430,4434,4438],{"title":4419,"path":4420,"stem":4421},"Interfaces та Classes","\u002Fweb-development\u002Ftypescript-advanced\u002Finterfaces-classes","18.web-development\u002F04.typescript-advanced\u002F01.interfaces-classes",{"title":4423,"path":4424,"stem":4425},"Основи Generic типів","\u002Fweb-development\u002Ftypescript-advanced\u002Fgenerics-fundamentals","18.web-development\u002F04.typescript-advanced\u002F02.generics-fundamentals",{"title":4427,"path":4428,"stem":4429},"Enums та Decorators","\u002Fweb-development\u002Ftypescript-advanced\u002Fenums-decorators","18.web-development\u002F04.typescript-advanced\u002F03.enums-decorators",{"title":4431,"path":4432,"stem":4433},"Utility Types","\u002Fweb-development\u002Ftypescript-advanced\u002Futility-types","18.web-development\u002F04.typescript-advanced\u002F04.utility-types",{"title":4435,"path":4436,"stem":4437},"Mapped та Conditional Types","\u002Fweb-development\u002Ftypescript-advanced\u002Fmapped-conditional-types","18.web-development\u002F04.typescript-advanced\u002F05.mapped-conditional-types",{"title":4439,"path":4440,"stem":4441},"Модулі та Strict Mode","\u002Fweb-development\u002Ftypescript-advanced\u002Fmodules-strict-mode","18.web-development\u002F04.typescript-advanced\u002F06.modules-strict-mode",{"title":4443,"icon":4444,"path":4445,"stem":4446,"children":4447,"page":59},"Платформа Node.js як середовище виконання","i-devicon-nodejs","\u002Fweb-development\u002Fnodejs-platform","18.web-development\u002F05.nodejs-platform",[4448,4452,4456,4460,4464,4468,4472,4476,4480,4484,4488,4491,4495],{"title":4449,"path":4450,"stem":4451},"Що таке Node.js та його архітектура","\u002Fweb-development\u002Fnodejs-platform\u002Fwhat-is-nodejs","18.web-development\u002F05.nodejs-platform\u002F01.what-is-nodejs",{"title":4453,"path":4454,"stem":4455},"Event Loop — серце Node.js","\u002Fweb-development\u002Fnodejs-platform\u002Fevent-loop","18.web-development\u002F05.nodejs-platform\u002F02.event-loop",{"title":4457,"path":4458,"stem":4459},"Модульні системи: CommonJS vs ES Modules","\u002Fweb-development\u002Fnodejs-platform\u002Fmodule-systems","18.web-development\u002F05.nodejs-platform\u002F03.module-systems",{"title":4461,"path":4462,"stem":4463},"npm та package.json","\u002Fweb-development\u002Fnodejs-platform\u002Fnpm-package-json","18.web-development\u002F05.nodejs-platform\u002F04.npm-package-json",{"title":4465,"path":4466,"stem":4467},"Глобальні об\\","\u002Fweb-development\u002Fnodejs-platform\u002Fglobal-objects","18.web-development\u002F05.nodejs-platform\u002F05.global-objects",{"title":4469,"path":4470,"stem":4471},"Вбудований модуль fs (File System)","\u002Fweb-development\u002Fnodejs-platform\u002Fbuilt-in-modules-fs","18.web-development\u002F05.nodejs-platform\u002F06.built-in-modules-fs",{"title":4473,"path":4474,"stem":4475},"Вбудований модуль path","\u002Fweb-development\u002Fnodejs-platform\u002Fbuilt-in-modules-path","18.web-development\u002F05.nodejs-platform\u002F07.built-in-modules-path",{"title":4477,"path":4478,"stem":4479},"Вбудований модуль http","\u002Fweb-development\u002Fnodejs-platform\u002Fbuilt-in-modules-http","18.web-development\u002F05.nodejs-platform\u002F08.built-in-modules-http",{"title":4481,"path":4482,"stem":4483},"Streams — потоки даних у Node.js","\u002Fweb-development\u002Fnodejs-platform\u002Fstreams","18.web-development\u002F05.nodejs-platform\u002F09.streams",{"title":4485,"path":4486,"stem":4487},"Вбудований модуль util (Utilities)","\u002Fweb-development\u002Fnodejs-platform\u002Fbuilt-in-modules-util","18.web-development\u002F05.nodejs-platform\u002F10.built-in-modules-util",{"title":3293,"path":4489,"stem":4490},"\u002Fweb-development\u002Fnodejs-platform\u002Fenvironment-variables","18.web-development\u002F05.nodejs-platform\u002F11.environment-variables",{"title":4492,"path":4493,"stem":4494},"Інструменти налагодження та розробки","\u002Fweb-development\u002Fnodejs-platform\u002Fdebugging-tools","18.web-development\u002F05.nodejs-platform\u002F12.debugging-tools",{"title":4496,"path":4497,"stem":4498},"Продуктивність та Best Practices","\u002Fweb-development\u002Fnodejs-platform\u002Fperformance-best-practices","18.web-development\u002F05.nodejs-platform\u002F13.performance-best-practices",{"title":4500,"icon":4501,"path":4502,"stem":4503,"children":4504,"page":59},"Асинхронне програмування у Node.js","i-lucide-clock","\u002Fweb-development\u002Fasync-programming-nodejs","18.web-development\u002F06.async-programming-nodejs",[4505,4509,4513,4517,4521,4525,4529,4533,4537,4541,4545],{"title":4506,"path":4507,"stem":4508},"Синхронний vs асинхронний код","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fsync-vs-async","18.web-development\u002F06.async-programming-nodejs\u002F01.sync-vs-async",{"title":4510,"path":4511,"stem":4512},"Callbacks — перша парадигма асинхронності","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fcallbacks","18.web-development\u002F06.async-programming-nodejs\u002F02.callbacks",{"title":4514,"path":4515,"stem":4516},"Promises — стандарт асинхронності","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fpromises","18.web-development\u002F06.async-programming-nodejs\u002F03.promises",{"title":4518,"path":4519,"stem":4520},"Promise комбінатори","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fpromise-combinators","18.web-development\u002F06.async-programming-nodejs\u002F04.promise-combinators",{"title":4522,"path":4523,"stem":4524},"Async\u002FAwait — синтаксичний цукор над Promises","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fasync-await","18.web-development\u002F06.async-programming-nodejs\u002F05.async-await",{"title":4526,"path":4527,"stem":4528},"Паралельне vs послідовне виконання","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fparallel-vs-sequential","18.web-development\u002F06.async-programming-nodejs\u002F06.parallel-vs-sequential",{"title":4530,"path":4531,"stem":4532},"EventEmitter — подієва модель Node.js","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fevent-emitter","18.web-development\u002F06.async-programming-nodejs\u002F07.event-emitter",{"title":4534,"path":4535,"stem":4536},"Worker Threads — багатопотоковість у Node.js","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fworker-threads","18.web-development\u002F06.async-programming-nodejs\u002F08.worker-threads",{"title":4538,"path":4539,"stem":4540},"Child Processes — запуск зовнішніх процесів","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fchild-processes","18.web-development\u002F06.async-programming-nodejs\u002F09.child-processes",{"title":4542,"path":4543,"stem":4544},"Обробка помилок у асинхронному коді","\u002Fweb-development\u002Fasync-programming-nodejs\u002Ferror-handling","18.web-development\u002F06.async-programming-nodejs\u002F10.error-handling",{"title":4546,"path":4547,"stem":4548},"Порівняння Node.js фреймворків","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fnodejs-frameworks","18.web-development\u002F06.async-programming-nodejs\u002F11.nodejs-frameworks",{"title":4550,"icon":4551,"path":4552,"stem":4553,"children":4554,"page":59},"Тема 7. Фреймворк NestJS. Контролери та маршрутизація","i-lucide-route","\u002Fweb-development\u002Fnestjs-controllers-routing","18.web-development\u002F07.nestjs-controllers-routing",[4555,4559,4563,4567,4571,4575,4579,4583,4587,4591,4595,4599,4603,4607,4611,4615,4619,4623,4627,4631,4635,4639],{"title":4556,"path":4557,"stem":4558},"Філософія та архітектура NestJS","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fnestjs-philosophy","18.web-development\u002F07.nestjs-controllers-routing\u002F01.nestjs-philosophy",{"title":4560,"path":4561,"stem":4562},"Три стовпи архітектури: модулі, контролери, провайдери","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fthree-pillars","18.web-development\u002F07.nestjs-controllers-routing\u002F02.three-pillars",{"title":4564,"path":4565,"stem":4566},"Інверсія керування (IoC) та ін","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fioc-and-di","18.web-development\u002F07.nestjs-controllers-routing\u002F03.ioc-and-di",{"title":4568,"path":4569,"stem":4570},"Встановлення NestJS CLI та створення проєкту","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fnestjs-cli-setup","18.web-development\u002F07.nestjs-controllers-routing\u002F04.nestjs-cli-setup",{"title":4572,"path":4573,"stem":4574},"Структура проєкту NestJS та конвенції","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fproject-structure","18.web-development\u002F07.nestjs-controllers-routing\u002F05.project-structure",{"title":4576,"path":4577,"stem":4578},"Контролери: основи маршрутизації","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fcontrollers-basics","18.web-development\u002F07.nestjs-controllers-routing\u002F06.controllers-basics",{"title":4580,"path":4581,"stem":4582},"Декоратори маршрутизації HTTP-методів","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Froute-decorators","18.web-development\u002F07.nestjs-controllers-routing\u002F07.route-decorators",{"title":4584,"path":4585,"stem":4586},"Параметри маршруту та декоратор @Param","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Froute-parameters","18.web-development\u002F07.nestjs-controllers-routing\u002F08.route-parameters",{"title":4588,"path":4589,"stem":4590},"Query-параметри та декоратор @Query","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fquery-parameters","18.web-development\u002F07.nestjs-controllers-routing\u002F09.query-parameters",{"title":4592,"path":4593,"stem":4594},"Тіло запиту та декоратор @Body","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Frequest-body","18.web-development\u002F07.nestjs-controllers-routing\u002F10.request-body",{"title":4596,"path":4597,"stem":4598},"Робота з заголовками запиту та відповіді","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fheaders-decorators","18.web-development\u002F07.nestjs-controllers-routing\u002F11.headers-decorators",{"title":4600,"path":4601,"stem":4602},"Data Transfer Objects (DTO): визначення та призначення","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fdto-introduction","18.web-development\u002F07.nestjs-controllers-routing\u002F12.dto-introduction",{"title":4604,"path":4605,"stem":4606},"Об'єкти Request та Response","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Frequest-response-objects","18.web-development\u002F07.nestjs-controllers-routing\u002F13.request-response-objects",{"title":4608,"path":4609,"stem":4610},"HTTP-статус коди та декоратор @HttpCode","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fhttp-status-codes","18.web-development\u002F07.nestjs-controllers-routing\u002F14.http-status-codes",{"title":4612,"path":4613,"stem":4614},"Перенаправлення (Redirects) та декоратор @Redirect","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fredirects","18.web-development\u002F07.nestjs-controllers-routing\u002F15.redirects",{"title":4616,"path":4617,"stem":4618},"Асинхронні обробники та Observables","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fasync-handlers","18.web-development\u002F07.nestjs-controllers-routing\u002F16.async-handlers",{"title":4620,"path":4621,"stem":4622},"Маршрутизація за піддоменами та версіонування API","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fsub-domain-routing","18.web-development\u002F07.nestjs-controllers-routing\u002F17.sub-domain-routing",{"title":4624,"path":4625,"stem":4626},"Області видимості контролерів (Scopes)","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fcontroller-scopes","18.web-development\u002F07.nestjs-controllers-routing\u002F18.controller-scopes",{"title":4628,"path":4629,"stem":4630},"Основні команди NestJS CLI","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fnestjs-cli-commands","18.web-development\u002F07.nestjs-controllers-routing\u002F19.nestjs-cli-commands",{"title":4632,"path":4633,"stem":4634},"Практичний приклад: створення CRUD-контролера","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fcrud-example","18.web-development\u002F07.nestjs-controllers-routing\u002F20.crud-example",{"title":4636,"path":4637,"stem":4638},"Тестування контролерів","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Ftesting-controllers","18.web-development\u002F07.nestjs-controllers-routing\u002F21.testing-controllers",{"title":4640,"path":4641,"stem":4642},"Best Practices для контролерів та маршрутизації","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fbest-practices","18.web-development\u002F07.nestjs-controllers-routing\u002F22.best-practices",{"title":4644,"icon":4645,"path":4646,"stem":4647,"children":4648,"page":59},"Тема 8. Провайдери, сервіси та модульна система NestJS","i-lucide-package","\u002Fweb-development\u002Fnestjs-providers-modules","18.web-development\u002F08.nestjs-providers-modules",[4649,4653,4657,4661,4665,4669,4673,4677,4681,4685,4689,4693,4697,4701,4705],{"title":4650,"path":4651,"stem":4652},"Концепція провайдерів у NestJS","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fproviders-concept","18.web-development\u002F08.nestjs-providers-modules\u002F01.providers-concept",{"title":4654,"path":4655,"stem":4656},"Сервіси: інкапсуляція бізнес-логіки","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fservices-business-logic","18.web-development\u002F08.nestjs-providers-modules\u002F02.services-business-logic",{"title":4658,"path":4659,"stem":4660},"Практика ін","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fdependency-injection-practice","18.web-development\u002F08.nestjs-providers-modules\u002F03.dependency-injection-practice",{"title":4662,"path":4663,"stem":4664},"Custom Providers: useValue, useClass, useFactory, useExisting","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fcustom-providers","18.web-development\u002F08.nestjs-providers-modules\u002F04.custom-providers",{"title":4666,"path":4667,"stem":4668},"Injection Tokens: рядкові та символьні токени","\u002Fweb-development\u002Fnestjs-providers-modules\u002Finjection-tokens","18.web-development\u002F08.nestjs-providers-modules\u002F05.injection-tokens",{"title":4670,"path":4671,"stem":4672},"Опціональні провайдери та декоратор @Optional","\u002Fweb-development\u002Fnestjs-providers-modules\u002Foptional-providers","18.web-development\u002F08.nestjs-providers-modules\u002F07.optional-providers",{"title":4674,"path":4675,"stem":4676},"Структура модулів: imports, controllers, providers, exports","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fmodules-structure","18.web-development\u002F08.nestjs-providers-modules\u002F08.modules-structure",{"title":4678,"path":4679,"stem":4680},"Feature Modules: ізоляція функціональності","\u002Fweb-development\u002Fnestjs-providers-modules\u002Ffeature-modules","18.web-development\u002F08.nestjs-providers-modules\u002F09.feature-modules",{"title":4682,"path":4683,"stem":4684},"Shared Modules: перевикористання провайдерів","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fshared-modules","18.web-development\u002F08.nestjs-providers-modules\u002F10.shared-modules",{"title":4686,"path":4687,"stem":4688},"Global Modules та декоратор @Global","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fglobal-modules","18.web-development\u002F08.nestjs-providers-modules\u002F11.global-modules",{"title":4690,"path":4691,"stem":4692},"Dynamic Modules: конфігурація під час виконання","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fdynamic-modules","18.web-development\u002F08.nestjs-providers-modules\u002F12.dynamic-modules",{"title":4694,"path":4695,"stem":4696},"Циклічні залежності та forwardRef","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fcircular-dependencies","18.web-development\u002F08.nestjs-providers-modules\u002F13.circular-dependencies",{"title":4698,"path":4699,"stem":4700},"Lifecycle Hooks: хуки життєвого циклу","\u002Fweb-development\u002Fnestjs-providers-modules\u002Flifecycle-hooks","18.web-development\u002F08.nestjs-providers-modules\u002F14.lifecycle-hooks",{"title":4702,"path":4703,"stem":4704},"ModuleRef: динамічний доступ до провайдерів","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fmodule-reference","18.web-development\u002F08.nestjs-providers-modules\u002F15.module-reference",{"title":4706,"path":4707,"stem":4708},"Тестування сервісів та провайдерів","\u002Fweb-development\u002Fnestjs-providers-modules\u002Ftesting-services","18.web-development\u002F08.nestjs-providers-modules\u002F16.testing-services",{"title":4710,"icon":4711,"path":4712,"stem":4713,"children":4714,"page":59},"Тема 9. Валідація даних та конвеєр обробки запитів у NestJS","i-lucide-filter","\u002Fweb-development\u002Fnestjs-validation-pipeline","18.web-development\u002F09.nestjs-validation-pipeline",[4715,4719,4723,4727,4731,4735,4739,4743,4747,4751,4755,4759,4763,4767,4771,4775,4779,4783,4787],{"title":4716,"path":4717,"stem":4718},"Request Pipeline: конвеєр обробки запитів","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Frequest-pipeline","18.web-development\u002F09.nestjs-validation-pipeline\u002F01.request-pipeline",{"title":4720,"path":4721,"stem":4722},"Pipes: концепція трансформації та валідації","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fpipes-concept","18.web-development\u002F09.nestjs-validation-pipeline\u002F02.pipes-concept",{"title":4724,"path":4725,"stem":4726},"Вбудовані pipes: ParseIntPipe, ParseBoolPipe, ParseUUIDPipe","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fbuilt-in-pipes","18.web-development\u002F09.nestjs-validation-pipeline\u002F03.built-in-pipes",{"title":4728,"path":4729,"stem":4730},"ValidationPipe: автоматична валідація DTO","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fvalidation-pipe","18.web-development\u002F09.nestjs-validation-pipeline\u002F04.validation-pipe",{"title":4732,"path":4733,"stem":4734},"Декоратори class-validator для DTO","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fclass-validator-decorators","18.web-development\u002F09.nestjs-validation-pipeline\u002F05.class-validator-decorators",{"title":4736,"path":4737,"stem":4738},"Створення кастомних валідаторів","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-validators","18.web-development\u002F09.nestjs-validation-pipeline\u002F06.custom-validators",{"title":4740,"path":4741,"stem":4742},"Створення власних Pipes","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-pipes","18.web-development\u002F09.nestjs-validation-pipeline\u002F07.custom-pipes",{"title":4744,"path":4745,"stem":4746},"Основи Middleware","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fmiddleware-basics","18.web-development\u002F09.nestjs-validation-pipeline\u002F08.middleware-basics",{"title":4748,"path":4749,"stem":4750},"Практичні приклади Middleware","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fmiddleware-examples","18.web-development\u002F09.nestjs-validation-pipeline\u002F09.middleware-examples",{"title":4752,"path":4753,"stem":4754},"Guards: захисні перехоплювачі доступу","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fguards-concept","18.web-development\u002F09.nestjs-validation-pipeline\u002F10.guards-concept",{"title":4756,"path":4757,"stem":4758},"Створення кастомних Guards","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-guards","18.web-development\u002F09.nestjs-validation-pipeline\u002F11.custom-guards",{"title":4760,"path":4761,"stem":4762},"Interceptors: перехоплення та трансформація відповідей","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Finterceptors-concept","18.web-development\u002F09.nestjs-validation-pipeline\u002F12.interceptors-concept",{"title":4764,"path":4765,"stem":4766},"Практичні приклади Interceptors","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Finterceptor-examples","18.web-development\u002F09.nestjs-validation-pipeline\u002F13.interceptor-examples",{"title":4768,"path":4769,"stem":4770},"Exception Filters: обробка виключень","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fexception-filters","18.web-development\u002F09.nestjs-validation-pipeline\u002F14.exception-filters",{"title":4772,"path":4773,"stem":4774},"Custom Exception Filters: спеціалізовані фільтри","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-exception-filters","18.web-development\u002F09.nestjs-validation-pipeline\u002F15.custom-exception-filters",{"title":4776,"path":4777,"stem":4778},"Execution Context: контекст виконання","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fexecution-context","18.web-development\u002F09.nestjs-validation-pipeline\u002F16.execution-context",{"title":4780,"path":4781,"stem":4782},"Custom Decorators: власні декоратори","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-decorators","18.web-development\u002F09.nestjs-validation-pipeline\u002F17.custom-decorators",{"title":4784,"path":4785,"stem":4786},"Global Components: глобальні компоненти","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fglobal-components","18.web-development\u002F09.nestjs-validation-pipeline\u002F18.global-components",{"title":4788,"path":4789,"stem":4790},"Pipeline Best Practices: найкращі практики","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fpipeline-best-practices","18.web-development\u002F09.nestjs-validation-pipeline\u002F19.pipeline-best-practices",{"title":4792,"icon":3017,"path":4793,"stem":4794,"children":4795,"page":59},"Інтеграція реляційних баз даних засобами TypeORM","\u002Fweb-development\u002Ftypeorm-integration","18.web-development\u002F10.typeorm-integration",[4796,4800,4804,4808,4812,4816,4820],{"title":4797,"path":4798,"stem":4799},"Робота з базами даних у Node.js через нативні драйвери","\u002Fweb-development\u002Ftypeorm-integration\u002F01-nodejs-database-drivers","18.web-development\u002F10.typeorm-integration\u002F01-nodejs-database-drivers",{"title":4801,"path":4802,"stem":4803},"ORM та знайомство з TypeORM","\u002Fweb-development\u002Ftypeorm-integration\u002F02-orm-and-typeorm-intro","18.web-development\u002F10.typeorm-integration\u002F02-orm-and-typeorm-intro",{"title":4805,"path":4806,"stem":4807},"Налаштування TypeORM у NestJS проєкті","\u002Fweb-development\u002Ftypeorm-integration\u002F03-typeorm-setup-nestjs","18.web-development\u002F10.typeorm-integration\u002F03-typeorm-setup-nestjs",{"title":4809,"path":4810,"stem":4811},"Entity класи та декоратори TypeORM","\u002Fweb-development\u002Ftypeorm-integration\u002F04-entities-and-decorators","18.web-development\u002F10.typeorm-integration\u002F04-entities-and-decorators",{"title":4813,"path":4814,"stem":4815},"Repository Pattern та CRUD операції","\u002Fweb-development\u002Ftypeorm-integration\u002F05-repository-pattern-crud","18.web-development\u002F10.typeorm-integration\u002F05-repository-pattern-crud",{"title":4817,"path":4818,"stem":4819},"Пагінація та фільтрація даних","\u002Fweb-development\u002Ftypeorm-integration\u002F06-pagination-filtering","18.web-development\u002F10.typeorm-integration\u002F06-pagination-filtering",{"title":4821,"path":4822,"stem":4823},"QueryBuilder для складних запитів","\u002Fweb-development\u002Ftypeorm-integration\u002F07-query-builder","18.web-development\u002F10.typeorm-integration\u002F07-query-builder",{"title":4825,"icon":4826,"path":4827,"stem":4828,"children":4829,"page":59},"Зв'язки між сутностями, міграції та оптимізація запитів","i-lucide-git-branch","\u002Fweb-development\u002Fentity-relations-migrations","18.web-development\u002F11.entity-relations-migrations",[4830,4834,4838,4842,4846],{"title":4831,"path":4832,"stem":4833},"Зв'язки One-to-Many та Many-to-One","\u002Fweb-development\u002Fentity-relations-migrations\u002F01-one-to-many-many-to-one","18.web-development\u002F11.entity-relations-migrations\u002F01-one-to-many-many-to-one",{"title":4835,"path":4836,"stem":4837},"Зв'язки One-to-One та Many-to-Many","\u002Fweb-development\u002Fentity-relations-migrations\u002F02-one-to-one-many-to-many","18.web-development\u002F11.entity-relations-migrations\u002F02-one-to-one-many-to-many",{"title":4839,"path":4840,"stem":4841},"Керування міграціями бази даних","\u002Fweb-development\u002Fentity-relations-migrations\u002F03-migrations-management","18.web-development\u002F11.entity-relations-migrations\u002F03-migrations-management",{"title":4843,"path":4844,"stem":4845},"Транзакції у TypeORM","\u002Fweb-development\u002Fentity-relations-migrations\u002F04-transactions","18.web-development\u002F11.entity-relations-migrations\u002F04-transactions",{"title":4847,"path":4848,"stem":4849,"children":4850},"Індекси та оптимізація запитів","\u002Fweb-development\u002Fentity-relations-migrations\u002F05-indexes-optimization","18.web-development\u002F11.entity-relations-migrations\u002F05-indexes-optimization",[4851],{"title":4847,"path":4848,"stem":4849},{"title":4853,"icon":4854,"path":4855,"stem":4856,"children":4857,"page":59},"Механізми автентифікації у вебзастосунках","i-lucide-key","\u002Fweb-development\u002Fauthentication","18.web-development\u002F12.authentication",[4858,4862,4866,4870,4874,4878,4882,4886,4890],{"title":4859,"path":4860,"stem":4861},"Автентифікація vs Авторизація","\u002Fweb-development\u002Fauthentication\u002F01-authentication-vs-authorization","18.web-development\u002F12.authentication\u002F01-authentication-vs-authorization",{"title":4863,"path":4864,"stem":4865},"Стратегії автентифікації","\u002Fweb-development\u002Fauthentication\u002F02-authentication-strategies","18.web-development\u002F12.authentication\u002F02-authentication-strategies",{"title":4867,"path":4868,"stem":4869},"Автентифікація на основі сесій","\u002Fweb-development\u002Fauthentication\u002F03-session-based-authentication","18.web-development\u002F12.authentication\u002F03-session-based-authentication",{"title":4871,"path":4872,"stem":4873},"Структура JSON Web Token (JWT)","\u002Fweb-development\u002Fauthentication\u002F04-jwt-structure","18.web-development\u002F12.authentication\u002F04-jwt-structure",{"title":4875,"path":4876,"stem":4877},"Інтеграція JWT у NestJS","\u002Fweb-development\u002Fauthentication\u002F05-nestjs-jwt-integration","18.web-development\u002F12.authentication\u002F05-nestjs-jwt-integration",{"title":4879,"path":4880,"stem":4881},"Passport.js стратегії у NestJS","\u002Fweb-development\u002Fauthentication\u002F06-passport-strategies","18.web-development\u002F12.authentication\u002F06-passport-strategies",{"title":4883,"path":4884,"stem":4885},"Безпечне зберігання паролів: хешування та криптографічний захист","\u002Fweb-development\u002Fauthentication\u002F07-password-hashing","18.web-development\u002F12.authentication\u002F07-password-hashing",{"title":4887,"path":4888,"stem":4889},"Refresh Token та безпечне оновлення доступу","\u002Fweb-development\u002Fauthentication\u002F08-refresh-tokens","18.web-development\u002F12.authentication\u002F08-refresh-tokens",{"title":4891,"path":4892,"stem":4893},"OAuth 2.0 та OpenID Connect: делегована автентифікація","\u002Fweb-development\u002Fauthentication\u002F09-oauth2-openid","18.web-development\u002F12.authentication\u002F09-oauth2-openid",{"title":4895,"icon":4896,"path":4897,"stem":4898,"children":4899,"page":59},"Авторизація та безпека серверних застосунків","i-lucide-shield","\u002Fweb-development\u002Fauthorization-security","18.web-development\u002F13.authorization-security",[4900,4904,4908,4912,4916,4920,4924,4928,4932,4936],{"title":4901,"path":4902,"stem":4903},"Моделі авторизації","\u002Fweb-development\u002Fauthorization-security\u002F01-authorization-models","18.web-development\u002F13.authorization-security\u002F01-authorization-models",{"title":4905,"path":4906,"stem":4907},"Реалізація RBAC у NestJS","\u002Fweb-development\u002Fauthorization-security\u002F02-rbac-implementation","18.web-development\u002F13.authorization-security\u002F02-rbac-implementation",{"title":4909,"path":4910,"stem":4911},"Permission-Based Access Control","\u002Fweb-development\u002Fauthorization-security\u002F03-permission-based-access","18.web-development\u002F13.authorization-security\u002F03-permission-based-access",{"title":4913,"path":4914,"stem":4915},"ABAC та бібліотека CASL","\u002Fweb-development\u002Fauthorization-security\u002F04-abac-casl","18.web-development\u002F13.authorization-security\u002F04-abac-casl",{"title":4917,"path":4918,"stem":4919},"Кастомні декоратори та метадані","\u002Fweb-development\u002Fauthorization-security\u002F05-custom-decorators-metadata","18.web-development\u002F13.authorization-security\u002F05-custom-decorators-metadata",{"title":4921,"path":4922,"stem":4923},"Конфігурація CORS","\u002Fweb-development\u002Fauthorization-security\u002F06-cors-configuration","18.web-development\u002F13.authorization-security\u002F06-cors-configuration",{"title":4925,"path":4926,"stem":4927},"Захист через HTTP Security Headers (Helmet)","\u002Fweb-development\u002Fauthorization-security\u002F07-helmet-security-headers","18.web-development\u002F13.authorization-security\u002F07-helmet-security-headers",{"title":4929,"path":4930,"stem":4931},"Rate Limiting та Throttling","\u002Fweb-development\u002Fauthorization-security\u002F08-rate-limiting-throttling","18.web-development\u002F13.authorization-security\u002F08-rate-limiting-throttling",{"title":4933,"path":4934,"stem":4935},"Захист від поширених атак","\u002Fweb-development\u002Fauthorization-security\u002F09-common-attacks-protection","18.web-development\u002F13.authorization-security\u002F09-common-attacks-protection",{"title":4937,"path":4938,"stem":4939},"HTTPS у продакшені","\u002Fweb-development\u002Fauthorization-security\u002F10-https-production","18.web-development\u002F13.authorization-security\u002F10-https-production",{"title":4941,"icon":871,"path":4942,"stem":4943,"children":4944,"page":59},"Комунікація у реальному часі, нотифікації та фонові задачі","\u002Fweb-development\u002Frealtime-notifications-jobs","18.web-development\u002F14.realtime-notifications-jobs",[4945,4949,4953,4957,4961,4965,4968,4971,4975,4979],{"title":4946,"path":4947,"stem":4948},"Методи комунікації у реальному часі","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F01-realtime-communication-methods","18.web-development\u002F14.realtime-notifications-jobs\u002F01-realtime-communication-methods",{"title":4950,"path":4951,"stem":4952},"WebSocket Gateway у NestJS","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F02-websocket-gateway","18.web-development\u002F14.realtime-notifications-jobs\u002F02-websocket-gateway",{"title":4954,"path":4955,"stem":4956},"Lifecycle та Rooms у WebSocket","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F03-websocket-lifecycle-rooms","18.web-development\u002F14.realtime-notifications-jobs\u002F03-websocket-lifecycle-rooms",{"title":4958,"path":4959,"stem":4960},"Server-Sent Events (SSE)","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F04-server-sent-events","18.web-development\u002F14.realtime-notifications-jobs\u002F04-server-sent-events",{"title":4962,"path":4963,"stem":4964},"Архітектура системи нотифікацій","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F05-notification-system","18.web-development\u002F14.realtime-notifications-jobs\u002F05-notification-system",{"title":904,"path":4966,"stem":4967},"\u002Fweb-development\u002Frealtime-notifications-jobs\u002F06-email-notifications","18.web-development\u002F14.realtime-notifications-jobs\u002F06-email-notifications",{"title":900,"path":4969,"stem":4970},"\u002Fweb-development\u002Frealtime-notifications-jobs\u002F07-web-push-notifications","18.web-development\u002F14.realtime-notifications-jobs\u002F07-web-push-notifications",{"title":4972,"path":4973,"stem":4974},"Фонові задачі та черги","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F08-background-jobs-queues","18.web-development\u002F14.realtime-notifications-jobs\u002F08-background-jobs-queues",{"title":4976,"path":4977,"stem":4978},"Планувальники та Cron jobs","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F09-schedulers-cron","18.web-development\u002F14.realtime-notifications-jobs\u002F09-schedulers-cron",{"title":4980,"path":4981,"stem":4982},"Практичні сценарії застосування","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F10-practical-scenarios","18.web-development\u002F14.realtime-notifications-jobs\u002F10-practical-scenarios",{"title":4984,"icon":4985,"path":4986,"stem":4987,"children":4988,"page":59},"Тестування, документування та розгортання застосунків","i-lucide-rocket","\u002Fweb-development\u002Ftesting-documentation-deployment","18.web-development\u002F15.testing-documentation-deployment",[4989,4993,4997,5001,5005,5009,5013,5017,5021,5025],{"title":4990,"path":4991,"stem":4992},"Піраміда тестування та стратегія","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F01-testing-pyramid-strategy","18.web-development\u002F15.testing-documentation-deployment\u002F01-testing-pyramid-strategy",{"title":4994,"path":4995,"stem":4996},"Основи Jest у NestJS","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F02-jest-nestjs-basics","18.web-development\u002F15.testing-documentation-deployment\u002F02-jest-nestjs-basics",{"title":4998,"path":4999,"stem":5000},"Unit-тестування сервісів","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F03-unit-testing-services","18.web-development\u002F15.testing-documentation-deployment\u002F03-unit-testing-services",{"title":5002,"path":5003,"stem":5004},"E2E тестування та покриття коду","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F04-e2e-testing-coverage","18.web-development\u002F15.testing-documentation-deployment\u002F04-e2e-testing-coverage",{"title":5006,"path":5007,"stem":5008},"Swagger, OpenAPI, Scalar та Arazzo","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F05-swagger-openapi","18.web-development\u002F15.testing-documentation-deployment\u002F05-swagger-openapi",{"title":5010,"path":5011,"stem":5012},"Керування конфігурацією","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F06-configuration-management","18.web-development\u002F15.testing-documentation-deployment\u002F06-configuration-management",{"title":5014,"path":5015,"stem":5016},"Docker та контейнеризація","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F07-docker-containerization","18.web-development\u002F15.testing-documentation-deployment\u002F07-docker-containerization",{"title":5018,"path":5019,"stem":5020},"CI\u002FCD Pipelines","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F08-cicd-pipelines","18.web-development\u002F15.testing-documentation-deployment\u002F08-cicd-pipelines",{"title":5022,"path":5023,"stem":5024},"Логування та моніторинг","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F09-logging-monitoring","18.web-development\u002F15.testing-documentation-deployment\u002F09-logging-monitoring",{"title":5026,"path":5027,"stem":5028},"Серіалізація та компресія","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F10-serialization-compression","18.web-development\u002F15.testing-documentation-deployment\u002F10-serialization-compression",{"title":5030,"icon":5031,"path":5032,"stem":5033,"children":5034,"page":59},"AI Core: мислення AI","i-lucide-brain","\u002Fai-core","19.ai-core",[5035,5076,5125,5163],{"title":5036,"icon":4985,"path":5037,"stem":5038,"children":5039,"page":59},"Вхід у професію AI Native Developer","\u002Fai-core\u002Fai-native-developer","19.ai-core\u002F01.ai-native-developer",[5040,5044,5048,5052,5056,5060,5064,5068,5072],{"title":5041,"path":5042,"stem":5043},"Вступ до професії розробника цифрових продуктів","\u002Fai-core\u002Fai-native-developer\u002Fdigital-products","19.ai-core\u002F01.ai-native-developer\u002F01.digital-products",{"title":5045,"path":5046,"stem":5047},"Професія розробника програмного забезпечення","\u002Fai-core\u002Fai-native-developer\u002Fsoftware-developer","19.ai-core\u002F01.ai-native-developer\u002F02.software-developer",{"title":5049,"path":5050,"stem":5051},"Професія AI Native Developer","\u002Fai-core\u002Fai-native-developer\u002Fai-native-developer","19.ai-core\u002F01.ai-native-developer\u002F03.ai-native-developer",{"title":5053,"path":5054,"stem":5055},"Вплив AI на розробку програмного забезпечення","\u002Fai-core\u002Fai-native-developer\u002Fai-impact-on-development","19.ai-core\u002F01.ai-native-developer\u002F04.ai-impact-on-development",{"title":5057,"path":5058,"stem":5059},"Життєвий цикл цифрового продукту","\u002Fai-core\u002Fai-native-developer\u002Fproduct-lifecycle","19.ai-core\u002F01.ai-native-developer\u002F05.product-lifecycle",{"title":5061,"path":5062,"stem":5063},"Застосування AI на етапах створення цифрового продукту","\u002Fai-core\u002Fai-native-developer\u002Fai-in-product-creation","19.ai-core\u002F01.ai-native-developer\u002F06.ai-in-product-creation",{"title":5065,"path":5066,"stem":5067},"Розподіл завдань між людиною та AI","\u002Fai-core\u002Fai-native-developer\u002Fhuman-vs-ai-tasks","19.ai-core\u002F01.ai-native-developer\u002F07.human-vs-ai-tasks",{"title":5069,"path":5070,"stem":5071},"Компетенції AI Native Developer","\u002Fai-core\u002Fai-native-developer\u002Fcompetencies","19.ai-core\u002F01.ai-native-developer\u002F08.competencies",{"title":5073,"path":5074,"stem":5075},"Карта професійного розвитку AI Native Developer","\u002Fai-core\u002Fai-native-developer\u002Fcareer-roadmap","19.ai-core\u002F01.ai-native-developer\u002F09.career-roadmap",{"title":5077,"icon":255,"path":5078,"stem":5079,"children":5080,"page":59},"Штучний інтелект і машинне навчання","\u002Fai-core\u002Fai-and-machine-learning","19.ai-core\u002F02.ai-and-machine-learning",[5081,5085,5089,5093,5097,5101,5105,5109,5113,5117,5121],{"title":5082,"path":5083,"stem":5084},"Штучний інтелект","\u002Fai-core\u002Fai-and-machine-learning\u002Fwhat-is-ai","19.ai-core\u002F02.ai-and-machine-learning\u002F01.what-is-ai",{"title":5086,"path":5087,"stem":5088},"Відмінність AI від інших програмних систем","\u002Fai-core\u002Fai-and-machine-learning\u002Fai-vs-automation","19.ai-core\u002F02.ai-and-machine-learning\u002F02.ai-vs-automation",{"title":5090,"path":5091,"stem":5092},"Завдання штучного інтелекту","\u002Fai-core\u002Fai-and-machine-learning\u002Fai-tasks","19.ai-core\u002F02.ai-and-machine-learning\u002F03.ai-tasks",{"title":5094,"path":5095,"stem":5096},"Machine Learning","\u002Fai-core\u002Fai-and-machine-learning\u002Fmachine-learning","19.ai-core\u002F02.ai-and-machine-learning\u002F04.machine-learning",{"title":5098,"path":5099,"stem":5100},"Machine Learning Workflow","\u002Fai-core\u002Fai-and-machine-learning\u002Fml-workflow","19.ai-core\u002F02.ai-and-machine-learning\u002F05.ml-workflow",{"title":5102,"path":5103,"stem":5104},"Типи машинного навчання","\u002Fai-core\u002Fai-and-machine-learning\u002Fml-types","19.ai-core\u002F02.ai-and-machine-learning\u002F06.ml-types",{"title":5106,"path":5107,"stem":5108},"Generative AI","\u002Fai-core\u002Fai-and-machine-learning\u002Fgenerative-ai","19.ai-core\u002F02.ai-and-machine-learning\u002F07.generative-ai",{"title":5110,"path":5111,"stem":5112},"Типи контенту, створюваного AI","\u002Fai-core\u002Fai-and-machine-learning\u002Fai-content-types","19.ai-core\u002F02.ai-and-machine-learning\u002F08.ai-content-types",{"title":5114,"path":5115,"stem":5116},"Великі мовні моделі","\u002Fai-core\u002Fai-and-machine-learning\u002Flarge-language-models","19.ai-core\u002F02.ai-and-machine-learning\u002F09.large-language-models",{"title":5118,"path":5119,"stem":5120},"Можливості та обмеження Generative AI","\u002Fai-core\u002Fai-and-machine-learning\u002Fcapabilities-and-limitations","19.ai-core\u002F02.ai-and-machine-learning\u002F10.capabilities-and-limitations",{"title":5122,"path":5123,"stem":5124},"Сучасні AI-асистенти","\u002Fai-core\u002Fai-and-machine-learning\u002Fmodern-ai-assistants","19.ai-core\u002F02.ai-and-machine-learning\u002F11.modern-ai-assistants",{"title":5126,"icon":5127,"path":5128,"stem":5129,"children":5130,"page":59},"Постановка завдань для AI: принципи створення промптів","i-lucide-message-square-text","\u002Fai-core\u002Fprompt-engineering","19.ai-core\u002F03.prompt-engineering",[5131,5135,5139,5143,5147,5151,5155,5159],{"title":5132,"path":5133,"stem":5134},"Промпт як інструмент","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-as-tool","19.ai-core\u002F03.prompt-engineering\u002F01.prompt-as-tool",{"title":5136,"path":5137,"stem":5138},"Принципи створення промптів","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-principles","19.ai-core\u002F03.prompt-engineering\u002F02.prompt-principles",{"title":5140,"path":5141,"stem":5142},"Структура промпта","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-structure","19.ai-core\u002F03.prompt-engineering\u002F03.prompt-structure",{"title":5144,"path":5145,"stem":5146},"Види промптів за типом задачі","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-types","19.ai-core\u002F03.prompt-engineering\u002F04.prompt-types",{"title":5148,"path":5149,"stem":5150},"Прийоми посилення промпта","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-enhancement","19.ai-core\u002F03.prompt-engineering\u002F05.prompt-enhancement",{"title":5152,"path":5153,"stem":5154},"Розбір і покращення промпта","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-analysis","19.ai-core\u002F03.prompt-engineering\u002F06.prompt-analysis",{"title":5156,"path":5157,"stem":5158},"Типові помилки під час створення промптів","\u002Fai-core\u002Fprompt-engineering\u002Fcommon-mistakes","19.ai-core\u002F03.prompt-engineering\u002F07.common-mistakes",{"title":5160,"path":5161,"stem":5162},"Практикум: особиста бібліотека промптів","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-library","19.ai-core\u002F03.prompt-engineering\u002F08.prompt-library",{"title":5164,"icon":793,"path":5165,"stem":5166,"children":5167,"page":59},"Перевірка результатів, безпека та AI Native Workflow","\u002Fai-core\u002Fverification-security-workflow","19.ai-core\u002F04.verification-security-workflow",[5168,5172,5176,5180,5184,5188,5192,5196,5200],{"title":5169,"path":5170,"stem":5171},"Межі можливостей AI","\u002Fai-core\u002Fverification-security-workflow\u002Fai-limitations","19.ai-core\u002F04.verification-security-workflow\u002F01.ai-limitations",{"title":5173,"path":5174,"stem":5175},"Галюцинації AI","\u002Fai-core\u002Fverification-security-workflow\u002Fai-hallucinations","19.ai-core\u002F04.verification-security-workflow\u002F02.ai-hallucinations",{"title":5177,"path":5178,"stem":5179},"Критичне мислення під час роботи з AI","\u002Fai-core\u002Fverification-security-workflow\u002Fcritical-thinking","19.ai-core\u002F04.verification-security-workflow\u002F03.critical-thinking",{"title":5181,"path":5182,"stem":5183},"Перевірка результатів роботи AI","\u002Fai-core\u002Fverification-security-workflow\u002Fresult-verification","19.ai-core\u002F04.verification-security-workflow\u002F04.result-verification",{"title":5185,"path":5186,"stem":5187},"Захист даних під час роботи з AI","\u002Fai-core\u002Fverification-security-workflow\u002Fdata-protection","19.ai-core\u002F04.verification-security-workflow\u002F05.data-protection",{"title":5189,"path":5190,"stem":5191},"Авторське право та навчальна доброчесність","\u002Fai-core\u002Fverification-security-workflow\u002Fcopyright-integrity","19.ai-core\u002F04.verification-security-workflow\u002F06.copyright-integrity",{"title":5193,"path":5194,"stem":5195},"Відповідальне використання AI","\u002Fai-core\u002Fverification-security-workflow\u002Fresponsible-use","19.ai-core\u002F04.verification-security-workflow\u002F07.responsible-use",{"title":5197,"path":5198,"stem":5199},"AI Native Workflow","\u002Fai-core\u002Fverification-security-workflow\u002Fai-native-workflow","19.ai-core\u002F04.verification-security-workflow\u002F08.ai-native-workflow",{"title":5201,"path":5202,"stem":5203},"Застосування AI Native Workflow під час створення цифрового продукту","\u002Fai-core\u002Fverification-security-workflow\u002Fworkflow-in-practice","19.ai-core\u002F04.verification-security-workflow\u002F09.workflow-in-practice",{"title":5205,"icon":5206,"path":5207,"stem":5208,"children":5209,"page":59},"AI Developer: Vibe Coding Sprint","i-lucide-code-xml","\u002Fai-developer","20.ai-developer",[5210,5236,5258,5279],{"title":5211,"icon":5212,"path":5213,"stem":5214,"children":5215,"page":59},"Проєктування і чорнова версія","i-lucide-pencil-ruler","\u002Fai-developer\u002Fdraft-creation","20.ai-developer\u002F01.draft-creation",[5216,5220,5224,5228,5232],{"title":5217,"path":5218,"stem":5219},"Парадигма Vibe Coding Workflow","\u002Fai-developer\u002Fdraft-creation\u002Fvibe-coding-workflow","20.ai-developer\u002F01.draft-creation\u002F01.vibe-coding-workflow",{"title":5221,"path":5222,"stem":5223},"AI-середовище швидкої розробки","\u002Fai-developer\u002Fdraft-creation\u002Fai-ide-environment","20.ai-developer\u002F01.draft-creation\u002F02.ai-ide-environment",{"title":5225,"path":5226,"stem":5227},"Користувацьке завдання та межі першої версії","\u002Fai-developer\u002Fdraft-creation\u002Fproduct-scope-and-mvp","20.ai-developer\u002F01.draft-creation\u002F03.product-scope-and-mvp",{"title":5229,"path":5230,"stem":5231},"Архітектура інтерфейсу та стани застосунку","\u002Fai-developer\u002Fdraft-creation\u002Fapplication-architecture-and-states","20.ai-developer\u002F01.draft-creation\u002F04.application-architecture-and-states",{"title":5233,"path":5234,"stem":5235},"Генерація та фіксація чорнової версії","\u002Fai-developer\u002Fdraft-creation\u002Fgenerating-draft-version","20.ai-developer\u002F01.draft-creation\u002F05.generating-draft-version",{"title":5237,"icon":5238,"path":5239,"stem":5240,"children":5241,"page":59},"Перша робоча версія","i-lucide-play-circle","\u002Fai-developer\u002Ffirst-working-version","20.ai-developer\u002F02.first-working-version",[5242,5246,5250,5254],{"title":5243,"path":5244,"stem":5245},"Уточнення контексту проєкту для AI","\u002Fai-developer\u002Ffirst-working-version\u002Frefining-project-context","20.ai-developer\u002F02.first-working-version\u002F01.refining-project-context",{"title":5247,"path":5248,"stem":5249},"Стратегія завдань для AI-розробки","\u002Fai-developer\u002Ffirst-working-version\u002Fai-prompting-strategy","20.ai-developer\u002F02.first-working-version\u002F02.ai-prompting-strategy",{"title":5251,"path":5252,"stem":5253},"Доопрацювання до першої робочої версії","\u002Fai-developer\u002Ffirst-working-version\u002Frefining-to-working-version","20.ai-developer\u002F02.first-working-version\u002F03.refining-to-working-version",{"title":5255,"path":5256,"stem":5257},"Перевірка першої робочої версії","\u002Fai-developer\u002Ffirst-working-version\u002Ftesting-first-working-version","20.ai-developer\u002F02.first-working-version\u002F04.testing-first-working-version",{"title":5259,"icon":3224,"path":5260,"stem":5261,"children":5262,"page":59},"Ітерації, дебагінг та відновлення","\u002Fai-developer\u002Fiteration-debugging-recovery","20.ai-developer\u002F03.iteration-debugging-recovery",[5263,5267,5271,5275],{"title":5264,"path":5265,"stem":5266},"Управління точковими змінами продукту","\u002Fai-developer\u002Fiteration-debugging-recovery\u002Fchange-management","20.ai-developer\u002F03.iteration-debugging-recovery\u002F01.change-management",{"title":5268,"path":5269,"stem":5270},"Надійність інтерфейсу та обробка помилок","\u002Fai-developer\u002Fiteration-debugging-recovery\u002Fscenario-reliability-and-errors","20.ai-developer\u002F03.iteration-debugging-recovery\u002F02.scenario-reliability-and-errors",{"title":5272,"path":5273,"stem":5274},"Керування контекстом і збереження версій","\u002Fai-developer\u002Fiteration-debugging-recovery\u002Fproject-context-and-versions","20.ai-developer\u002F03.iteration-debugging-recovery\u002F03.project-context-and-versions",{"title":5276,"path":5277,"stem":5278},"Збої AI-розробки, ліміти та аварійне відновлення","\u002Fai-developer\u002Fiteration-debugging-recovery\u002Fai-breakdowns-and-recovery","20.ai-developer\u002F03.iteration-debugging-recovery\u002F04.ai-breakdowns-and-recovery",{"title":5280,"icon":5281,"path":5282,"stem":5283,"children":5284,"page":59},"Перевірка та завершення продукту","i-lucide-check-check","\u002Fai-developer\u002Fverification-and-completion","20.ai-developer\u002F04.verification-and-completion",[5285,5289,5293],{"title":5286,"path":5287,"stem":5288},"Комплексний аудит та підсумкове тестування","\u002Fai-developer\u002Fverification-and-completion\u002Ffinal-product-testing","20.ai-developer\u002F04.verification-and-completion\u002F01.final-product-testing",{"title":5290,"path":5291,"stem":5292},"Підготовка підсумкової версії коду","\u002Fai-developer\u002Fverification-and-completion\u002Fpreparing-release-version","20.ai-developer\u002F04.verification-and-completion\u002F02.preparing-release-version",{"title":5294,"path":5295,"stem":5296},"Демонстрація, публікація та критерії оцінювання","\u002Fai-developer\u002Fverification-and-completion\u002Fproduct-showcase-and-publishing","20.ai-developer\u002F04.verification-and-completion\u002F03.product-showcase-and-publishing",{"title":5298,"path":5299,"stem":5300,"children":5301,"page":59},"Tailwind","\u002Ftailwind","21.tailwind",[5302,5306,5310,5314,5318,5322,5326,5330,5334,5338,5342,5346],{"title":5303,"path":5304,"stem":5305},"Що таке Tailwind CSS і навіщо він потрібен","\u002Ftailwind\u002Ftailwind-intro-philosophy","21.tailwind\u002F01.tailwind-intro-philosophy",{"title":5307,"path":5308,"stem":5309},"Встановлення та налаштування Tailwind CSS v4","\u002Ftailwind\u002Ftailwind-installation-setup","21.tailwind\u002F02.tailwind-installation-setup",{"title":5311,"path":5312,"stem":5313},"Utility-класи: основи та система Tailwind","\u002Ftailwind\u002Ftailwind-utility-classes-core","21.tailwind\u002F03.tailwind-utility-classes-core",{"title":5315,"path":5316,"stem":5317},"Layout: Flexbox та Grid через Tailwind","\u002Ftailwind\u002Ftailwind-flexbox-grid","21.tailwind\u002F04.tailwind-flexbox-grid",{"title":5319,"path":5320,"stem":5321},"Кастомізація теми через @theme у Tailwind v4","\u002Ftailwind\u002Ftailwind-theme-customization","21.tailwind\u002F05.tailwind-theme-customization",{"title":5323,"path":5324,"stem":5325},"Варіанти: hover, focus, responsive, dark mode та нові v4","\u002Ftailwind\u002Ftailwind-variants-states","21.tailwind\u002F06.tailwind-variants-states",{"title":5327,"path":5328,"stem":5329},"Типографіка та система кольорів у Tailwind v4","\u002Ftailwind\u002Ftailwind-typography-colors","21.tailwind\u002F07.tailwind-typography-colors",{"title":5331,"path":5332,"stem":5333},"Компоненти та повторюваність: @apply, @utility та патерни","\u002Ftailwind\u002Ftailwind-components-patterns","21.tailwind\u002F08.tailwind-components-patterns",{"title":5335,"path":5336,"stem":5337},"Темна тема та система дизайн-токенів у Tailwind v4","\u002Ftailwind\u002Ftailwind-dark-mode-theming","21.tailwind\u002F09.tailwind-dark-mode-theming",{"title":5339,"path":5340,"stem":5341},"Довільні значення та контейнерні запити у Tailwind v4","\u002Ftailwind\u002Ftailwind-arbitrary-container-queries","21.tailwind\u002F10.tailwind-arbitrary-container-queries",{"title":5343,"path":5344,"stem":5345},"Анімації, трансформації та 3D у Tailwind v4","\u002Ftailwind\u002Ftailwind-animations-transforms","21.tailwind\u002F11.tailwind-animations-transforms",{"title":5347,"path":5348,"stem":5349},"Tailwind CLI, PostCSS та інтеграція з фреймворками","\u002Ftailwind\u002Ftailwind-cli-tooling","21.tailwind\u002F12.tailwind-cli-tooling",{"title":5351,"path":5352,"stem":5353,"children":5354,"page":59},"React Typescript","\u002Freact-typescript","22.react-typescript",[5355,5380,5384,5388,5392,5396,5400,5404,5408,5412,5442,5446,5450,5454,5458],{"title":5356,"path":5357,"stem":5358,"children":5359,"page":59},"From Html To Project","\u002Freact-typescript\u002Ffrom-html-to-project","22.react-typescript\u002F01.from-html-to-project",[5360,5364,5368,5372,5376],{"title":5361,"path":5362,"stem":5363},"Від одного HTML-файлу до повноцінного проєкту","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fevolution","22.react-typescript\u002F01.from-html-to-project\u002F01.evolution",{"title":5365,"path":5366,"stem":5367},"Що таке React","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fwhat-is-react","22.react-typescript\u002F01.from-html-to-project\u002F02.what-is-react",{"title":5369,"path":5370,"stem":5371},"JSX та TSX — синтаксичний цукор, а не магія","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fjsx-tsx-syntax","22.react-typescript\u002F01.from-html-to-project\u002F03.jsx-tsx-syntax",{"title":5373,"path":5374,"stem":5375},"Компоненти — будівельні блоки інтерфейсу","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fcomponents","22.react-typescript\u002F01.from-html-to-project\u002F04.components",{"title":5377,"path":5378,"stem":5379},"JSX — розмітка всередині TypeScript","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fjsx-expressions","22.react-typescript\u002F01.from-html-to-project\u002F05.jsx-expressions",{"title":5381,"path":5382,"stem":5383},"Хук useReducer: структуроване управління складним станом","\u002Freact-typescript\u002Fuse-reducer","22.react-typescript\u002F23.use-reducer",{"title":5385,"path":5386,"stem":5387},"Context API: передавання даних без «пропс-дрілінгу»","\u002Freact-typescript\u002Fcontext-api","22.react-typescript\u002F24.context-api",{"title":5389,"path":5390,"stem":5391},"Синхронізація з ефектами: хук useEffect та функції очищення","\u002Freact-typescript\u002Fuse-effect","22.react-typescript\u002F27.use-effect",{"title":5393,"path":5394,"stem":5395},"Можливо, вам не потрібен ефект: антипатерни та альтернативи","\u002Freact-typescript\u002Fyou-might-not-need-effect","22.react-typescript\u002F28.you-might-not-need-effect",{"title":5397,"path":5398,"stem":5399},"Життєвий цикл реактивних ефектів: мислення процесами синхронізації","\u002Freact-typescript\u002Flifecycle-of-reactive-effects","22.react-typescript\u002F29.lifecycle-of-reactive-effects",{"title":5401,"path":5402,"stem":5403},"Розділення подій та ефектів: реактивна проти нереактивної логіки","\u002Freact-typescript\u002Fseparating-events-from-effects","22.react-typescript\u002F30.separating-events-from-effects",{"title":5405,"path":5406,"stem":5407},"Видалення зайвих залежностей ефектів та оптимізація синхронізації","\u002Freact-typescript\u002Fremoving-effect-dependencies","22.react-typescript\u002F31.removing-effect-dependencies",{"title":5409,"path":5410,"stem":5411},"Кастомні хуки: повторне використання та композиція реактивної логіки","\u002Freact-typescript\u002Fcustom-hooks","22.react-typescript\u002F32.custom-hooks",{"title":5413,"path":5414,"stem":5415,"children":5416},"React Router v7: Маршрутизація в SPA","\u002Freact-typescript\u002Freact-router-v7","22.react-typescript\u002F33.react-router-v7\u002Findex",[5417,5418,5422,5426,5430,5434,5438],{"title":5413,"path":5414,"stem":5415},{"title":5419,"path":5420,"stem":5421},"Встановлення та базова конфігурація React Router v7","\u002Freact-typescript\u002Freact-router-v7\u002Finstallation-setup","22.react-typescript\u002F33.react-router-v7\u002F01.installation-setup",{"title":5423,"path":5424,"stem":5425},"Вкладені маршрути та Outlet: архітектура складних макетів","\u002Freact-typescript\u002Freact-router-v7\u002Fnested-routes-outlet","22.react-typescript\u002F33.react-router-v7\u002F02.nested-routes-outlet",{"title":5427,"path":5428,"stem":5429},"Динамічні маршрути та параметри URL","\u002Freact-typescript\u002Freact-router-v7\u002Fdynamic-routes-params","22.react-typescript\u002F33.react-router-v7\u002F03.dynamic-routes-params",{"title":5431,"path":5432,"stem":5433},"Навігація та корисні хуки React Router","\u002Freact-typescript\u002Freact-router-v7\u002Fnavigation-hooks","22.react-typescript\u002F33.react-router-v7\u002F04.navigation-hooks",{"title":5435,"path":5436,"stem":5437},"Обробка помилок та 404: ErrorBoundary і fallback-маршрути","\u002Freact-typescript\u002Freact-router-v7\u002Ferror-handling-404","22.react-typescript\u002F33.react-router-v7\u002F05.error-handling-404",{"title":5439,"path":5440,"stem":5441},"Data Router API: альтернативний синтаксис через createBrowserRouter","\u002Freact-typescript\u002Freact-router-v7\u002Fdata-router-api-examples","22.react-typescript\u002F33.react-router-v7\u002F06.data-router-api-examples",{"title":5443,"path":5444,"stem":5445},"Axios: HTTP-клієнт із розширеними можливостями","\u002Freact-typescript\u002Faxios","22.react-typescript\u002F34.axios",{"title":5447,"path":5448,"stem":5449},"Redux: класичний підхід до глобального стану","\u002Freact-typescript\u002Fredux-classic","22.react-typescript\u002F35.redux-classic",{"title":5451,"path":5452,"stem":5453},"Redux Toolkit: сучасний стандарт Redux","\u002Freact-typescript\u002Fredux-toolkit","22.react-typescript\u002F36.redux-toolkit",{"title":5455,"path":5456,"stem":5457},"RTK Query: запити до сервера без болю","\u002Freact-typescript\u002Frtk-query-tanstack-query","22.react-typescript\u002F38.rtk-query-tanstack-query",{"title":5459,"path":5460,"stem":5461},"React Hook Form + Zod: типобезпечна валідація форм","\u002Freact-typescript\u002Freact-hook-form-zod","22.react-typescript\u002F39.react-hook-form-zod",{"title":5463,"path":5464,"stem":5465},"Тестування компонентів діаграм та пісочниць","\u002Ftest-components","98.test-components",{"id":5467,"title":5409,"body":5468,"description":25411,"extension":25412,"links":25413,"meta":25414,"navigation":5794,"path":5410,"seo":25415,"stem":5411,"__hash__":25416},"docs\u002F22.react-typescript\u002F32.custom-hooks.md",{"type":5469,"value":5470,"toc":25337},"minimark",[5471,5475,5494,5566,5569,5574,5594,5601,5640,5643,5672,5674,5678,5681,6145,6181,6183,6190,6201,6205,6499,6503,6633,6675,6677,6681,6688,6856,7041,7048,7074,7076,7082,7092,7099,7799,7806,8166,8224,8226,8232,8238,8243,8960,8965,9178,9192,9194,9201,9208,9213,9425,9431,9815,10025,10030,10068,10086,10088,10092,10102,10114,10445,10449,10867,10904,10906,10913,10916,10921,11215,11219,11505,11598,11600,11604,13840,13842,13846,13849,13853,13860,13868,14096,14101,14131,14133,14137,14148,14154,14880,14882,14886,20252,20254,20258,20264,20270,21494,21498,22119,22151,22153,22160,22163,22168,23680,23685,24565,24567,24571,24575,24755,24757,24761,24967,24969,24973,25196,25231,25233,25237,25278,25280,25284,25333],[5472,5473,5409],"h1",{"id":5474},"кастомні-хуки-повторне-використання-та-композиція-реактивної-логіки",[5476,5477,5478],"blockquote",{},[5479,5480,5481,5482,5486,5487],"p",{},"🔗 ",[5483,5484,5485],"strong",{},"Офіційний референс:"," ",[5488,5489,5493],"a",{"href":5490,"rel":5491},"https:\u002F\u002Fuk.react.dev\u002Flearn\u002Freusing-logic-with-custom-hooks",[5492],"nofollow","Повторне використання логіки з кастомними хуками (Reusing Logic with Custom Hooks)",[5495,5496,5497,5518],"card-group",{},[5498,5499,5502],"card",{"icon":5500,"title":5501},"i-lucide-target","🎯 Мета лекції",[5503,5504,5505,5509,5512,5515],"ul",{},[5506,5507,5508],"li",{},"Зрозуміти філософію кастомних хуків як абстракції для повторного використання поведінки.",[5506,5510,5511],{},"Опанувати правила іменування, композиції та ізоляції стану між викликами хуків.",[5506,5513,5514],{},"Навчитися створювати типізовані кастомні хуки для типових сценаріїв (fetch, localStorage, debounce).",[5506,5516,5517],{},"Застосувати архітектурні патерни для організації хуків у великих проєктах.",[5498,5519,5521],{"icon":4854,"title":5520},"🔑 Ключові терміни",[5503,5522,5523,5539,5548,5557],{},[5506,5524,5525,5533,5534,5538],{},[5483,5526,5527,5528,5532],{},"Кастомний хук (",[5529,5530,5531],"em",{},"Custom Hook","):"," TypeScript-функція, що починається з префікса ",[5535,5536,5537],"code",{},"use"," та може викликати інші хуки React.",[5506,5540,5541,5547],{},[5483,5542,5543,5544,5532],{},"Ізоляція стану (",[5529,5545,5546],{},"State Isolation"," кожен виклик кастомного хука отримує власний незалежний екземпляр стану.",[5506,5549,5550,5556],{},[5483,5551,5552,5553,5532],{},"Композиція хуків (",[5529,5554,5555],{},"Hook Composition"," побудова складних хуків шляхом комбінування простіших хуків.",[5506,5558,5559,5565],{},[5483,5560,5561,5562,5532],{},"Інверсія контролю (",[5529,5563,5564],{},"Inversion of Control"," компонент не знає, як реалізована логіка хука — він просто отримує результат.",[5567,5568],"hr",{},[5570,5571,5573],"h2",{"id":5572},"чому-існують-кастомні-хуки","Чому існують кастомні хуки?",[5479,5575,5576,5577,5580,5581,5580,5584,5580,5587,5580,5590,5593],{},"У попередніх лекціях ми вивчили вбудовані хуки React: ",[5535,5578,5579],{},"useState",", ",[5535,5582,5583],{},"useEffect",[5535,5585,5586],{},"useRef",[5535,5588,5589],{},"useReducer",[5535,5591,5592],{},"useContext",". Вони дозволяють компонентам мати стан, синхронізуватися із зовнішніми системами та обмінюватися даними.",[5479,5595,5596,5597,5600],{},"Проте, коли проєкт росте, ви починаєте помічати ",[5483,5598,5599],{},"повторювані патерни реактивної логіки",":",[5503,5602,5603,5610,5623,5630,5637],{},[5506,5604,5605,5606,5609],{},"Відстеження статусу мережевого з'єднання (",[5535,5607,5608],{},"navigator.onLine",").",[5506,5611,5612,5613,5580,5616,5580,5619,5622],{},"Завантаження даних з API із обробкою станів ",[5535,5614,5615],{},"loading",[5535,5617,5618],{},"error",[5535,5620,5621],{},"data",".",[5506,5624,5625,5626,5629],{},"Збереження стану у ",[5535,5627,5628],{},"localStorage"," із автоматичною синхронізацією.",[5506,5631,5632,5633,5636],{},"Відкладений (",[5529,5634,5635],{},"debounced",") виклик функції при введенні тексту.",[5506,5638,5639],{},"Анімації, таймери, підписки на браузерні події.",[5479,5641,5642],{},"Якщо копіювати цю логіку у кожен компонент, де вона потрібна, код стане громіздким, важко тестованим та схильним до помилок.",[5644,5645,5646,5651,5669],"note",{},[5479,5647,5648],{},[5483,5649,5650],{},"Фундаментальна ідея кастомних хуків:",[5479,5652,5653,5654,5657,5658,5661,5662,5657,5665,5668],{},"Якщо ",[5483,5655,5656],{},"компоненти"," відповідають за повторне використання ",[5483,5659,5660],{},"UI-структури"," (JSX-розмітки), то ",[5483,5663,5664],{},"кастомні хуки",[5483,5666,5667],{},"поведінки"," (стану + ефектів + обчислень).",[5479,5670,5671],{},"Кастомний хук інкапсулює складну реактивну логіку та надає простий API для компонентів, які його використовують.",[5567,5673],{},[5570,5675,5677],{"id":5676},"правила-створення-кастомних-хуків","Правила створення кастомних хуків",[5479,5679,5680],{},"React накладає лише дві суворі вимоги на кастомні хуки:",[5682,5683,5684,5695,5837,5850,5854,5857,5889],"steps",{},[5685,5686,5688,5689,5692,5693],"h3",{"id":5687},"правило-1-імя-функції-завжди-починається-з-префікса-use","Правило 1: Ім'я функції ",[5483,5690,5691],{},"завжди"," починається з префікса ",[5535,5694,5537],{},[5696,5697,5702],"pre",{"className":5698,"code":5699,"language":5700,"meta":5701,"style":5701},"language-tsx shiki shiki-themes light-plus dark-plus dark-plus","\u002F\u002F ✅ ПРАВИЛЬНО\nfunction useOnlineStatus() { ... }\nfunction useFetch(url: string) { ... }\nfunction useDebounce\u003CT>(value: T, delay: number) { ... }\n\n\u002F\u002F ❌ НЕПРАВИЛЬНО\nfunction getOnlineStatus() { ... } \u002F\u002F Не починається з use\nfunction fetchData(url: string) { ... } \u002F\u002F Не починається з use\n","tsx","",[5535,5703,5704,5713,5728,5753,5789,5796,5802,5816],{"__ignoreMap":5701},[5705,5706,5709],"span",{"class":5707,"line":5708},"line",1,[5705,5710,5712],{"class":5711},"spJ8K","\u002F\u002F ✅ ПРАВИЛЬНО\n",[5705,5714,5716,5720,5724],{"class":5707,"line":5715},2,[5705,5717,5719],{"class":5718},"su1O8","function",[5705,5721,5723],{"class":5722},"s8Opu"," useOnlineStatus",[5705,5725,5727],{"class":5726},"sHH4Y","() { ... }\n",[5705,5729,5731,5733,5736,5739,5743,5746,5750],{"class":5707,"line":5730},3,[5705,5732,5719],{"class":5718},[5705,5734,5735],{"class":5722}," useFetch",[5705,5737,5738],{"class":5726},"(",[5705,5740,5742],{"class":5741},"siwwj","url",[5705,5744,5745],{"class":5726},": ",[5705,5747,5749],{"class":5748},"sN1BT","string",[5705,5751,5752],{"class":5726},") { ... }\n",[5705,5754,5756,5758,5761,5764,5767,5770,5773,5775,5777,5779,5782,5784,5787],{"class":5707,"line":5755},4,[5705,5757,5719],{"class":5718},[5705,5759,5760],{"class":5722}," useDebounce",[5705,5762,5763],{"class":5726},"\u003C",[5705,5765,5766],{"class":5748},"T",[5705,5768,5769],{"class":5726},">(",[5705,5771,5772],{"class":5741},"value",[5705,5774,5745],{"class":5726},[5705,5776,5766],{"class":5748},[5705,5778,5580],{"class":5726},[5705,5780,5781],{"class":5741},"delay",[5705,5783,5745],{"class":5726},[5705,5785,5786],{"class":5748},"number",[5705,5788,5752],{"class":5726},[5705,5790,5792],{"class":5707,"line":5791},5,[5705,5793,5795],{"emptyLinePlaceholder":5794},true,"\n",[5705,5797,5799],{"class":5707,"line":5798},6,[5705,5800,5801],{"class":5711},"\u002F\u002F ❌ НЕПРАВИЛЬНО\n",[5705,5803,5805,5807,5810,5813],{"class":5707,"line":5804},7,[5705,5806,5719],{"class":5718},[5705,5808,5809],{"class":5722}," getOnlineStatus",[5705,5811,5812],{"class":5726},"() { ... } ",[5705,5814,5815],{"class":5711},"\u002F\u002F Не починається з use\n",[5705,5817,5819,5821,5824,5826,5828,5830,5832,5835],{"class":5707,"line":5818},8,[5705,5820,5719],{"class":5718},[5705,5822,5823],{"class":5722}," fetchData",[5705,5825,5738],{"class":5726},[5705,5827,5742],{"class":5741},[5705,5829,5745],{"class":5726},[5705,5831,5749],{"class":5748},[5705,5833,5834],{"class":5726},") { ... } ",[5705,5836,5815],{"class":5711},[5479,5838,5839,5840,5842,5843,5846,5847,5849],{},"Префікс ",[5535,5841,5537],{}," — це ",[5483,5844,5845],{},"не конвенція, а технічна вимога",". Лінтер React Hooks перевіряє, що функції, які починаються з ",[5535,5848,5537],{},", дотримуються правил хуків (виклик лише на верхньому рівні, не всередині умов\u002Fциклів). Без цього префікса лінтер не зможе валідувати ваш код.",[5685,5851,5853],{"id":5852},"правило-2-хук-може-викликати-інші-хуки-react","Правило 2: Хук може викликати інші хуки React",[5479,5855,5856],{},"Всередині кастомного хука можна вільно використовувати:",[5503,5858,5859,5877],{},[5506,5860,5861,5862,5580,5864,5580,5866,5580,5868,5580,5871,5580,5874,5876],{},"Вбудовані хуки: ",[5535,5863,5579],{},[5535,5865,5583],{},[5535,5867,5586],{},[5535,5869,5870],{},"useMemo",[5535,5872,5873],{},"useCallback",[5535,5875,5592],{},", тощо.",[5506,5878,5879,5880,5580,5883,5580,5886,5622],{},"Інші кастомні хуки: ",[5535,5881,5882],{},"useOnlineStatus",[5535,5884,5885],{},"useFetch",[5535,5887,5888],{},"useLocalStorage",[5696,5890,5892],{"className":5698,"code":5891,"language":5700,"meta":5701,"style":5701},"function useOnlineStatus() {\n  const [isOnline, setIsOnline] = useState(navigator.onLine); \u002F\u002F ✅ useState\n\n  useEffect(() => { \u002F\u002F ✅ useEffect\n    function handleOnline() { setIsOnline(true); }\n    function handleOffline() { setIsOnline(false); }\n\n    window.addEventListener(\"online\", handleOnline);\n    window.addEventListener(\"offline\", handleOffline);\n\n    return () => {\n      window.removeEventListener(\"online\", handleOnline);\n      window.removeEventListener(\"offline\", handleOffline);\n    };\n  }, []);\n\n  return isOnline;\n}\n",[5535,5893,5894,5903,5941,5945,5962,5983,6001,6005,6029,6050,6055,6070,6091,6110,6116,6122,6127,6139],{"__ignoreMap":5701},[5705,5895,5896,5898,5900],{"class":5707,"line":5708},[5705,5897,5719],{"class":5718},[5705,5899,5723],{"class":5722},[5705,5901,5902],{"class":5726},"() {\n",[5705,5904,5905,5908,5911,5915,5917,5920,5923,5925,5927,5930,5932,5935,5938],{"class":5707,"line":5715},[5705,5906,5907],{"class":5718},"  const",[5705,5909,5910],{"class":5726}," [",[5705,5912,5914],{"class":5913},"s-QsJ","isOnline",[5705,5916,5580],{"class":5726},[5705,5918,5919],{"class":5913},"setIsOnline",[5705,5921,5922],{"class":5726},"] = ",[5705,5924,5579],{"class":5722},[5705,5926,5738],{"class":5726},[5705,5928,5929],{"class":5741},"navigator",[5705,5931,5622],{"class":5726},[5705,5933,5934],{"class":5741},"onLine",[5705,5936,5937],{"class":5726},"); ",[5705,5939,5940],{"class":5711},"\u002F\u002F ✅ useState\n",[5705,5942,5943],{"class":5707,"line":5730},[5705,5944,5795],{"emptyLinePlaceholder":5794},[5705,5946,5947,5950,5953,5956,5959],{"class":5707,"line":5755},[5705,5948,5949],{"class":5722},"  useEffect",[5705,5951,5952],{"class":5726},"(() ",[5705,5954,5955],{"class":5718},"=>",[5705,5957,5958],{"class":5726}," { ",[5705,5960,5961],{"class":5711},"\u002F\u002F ✅ useEffect\n",[5705,5963,5964,5967,5970,5973,5975,5977,5980],{"class":5707,"line":5791},[5705,5965,5966],{"class":5718},"    function",[5705,5968,5969],{"class":5722}," handleOnline",[5705,5971,5972],{"class":5726},"() { ",[5705,5974,5919],{"class":5722},[5705,5976,5738],{"class":5726},[5705,5978,5979],{"class":5718},"true",[5705,5981,5982],{"class":5726},"); }\n",[5705,5984,5985,5987,5990,5992,5994,5996,5999],{"class":5707,"line":5798},[5705,5986,5966],{"class":5718},[5705,5988,5989],{"class":5722}," handleOffline",[5705,5991,5972],{"class":5726},[5705,5993,5919],{"class":5722},[5705,5995,5738],{"class":5726},[5705,5997,5998],{"class":5718},"false",[5705,6000,5982],{"class":5726},[5705,6002,6003],{"class":5707,"line":5804},[5705,6004,5795],{"emptyLinePlaceholder":5794},[5705,6006,6007,6010,6012,6015,6017,6021,6023,6026],{"class":5707,"line":5818},[5705,6008,6009],{"class":5741},"    window",[5705,6011,5622],{"class":5726},[5705,6013,6014],{"class":5722},"addEventListener",[5705,6016,5738],{"class":5726},[5705,6018,6020],{"class":6019},"sbdoH","\"online\"",[5705,6022,5580],{"class":5726},[5705,6024,6025],{"class":5741},"handleOnline",[5705,6027,6028],{"class":5726},");\n",[5705,6030,6032,6034,6036,6038,6040,6043,6045,6048],{"class":5707,"line":6031},9,[5705,6033,6009],{"class":5741},[5705,6035,5622],{"class":5726},[5705,6037,6014],{"class":5722},[5705,6039,5738],{"class":5726},[5705,6041,6042],{"class":6019},"\"offline\"",[5705,6044,5580],{"class":5726},[5705,6046,6047],{"class":5741},"handleOffline",[5705,6049,6028],{"class":5726},[5705,6051,6053],{"class":5707,"line":6052},10,[5705,6054,5795],{"emptyLinePlaceholder":5794},[5705,6056,6058,6062,6065,6067],{"class":5707,"line":6057},11,[5705,6059,6061],{"class":6060},"s8xlr","    return",[5705,6063,6064],{"class":5726}," () ",[5705,6066,5955],{"class":5718},[5705,6068,6069],{"class":5726}," {\n",[5705,6071,6073,6076,6078,6081,6083,6085,6087,6089],{"class":5707,"line":6072},12,[5705,6074,6075],{"class":5741},"      window",[5705,6077,5622],{"class":5726},[5705,6079,6080],{"class":5722},"removeEventListener",[5705,6082,5738],{"class":5726},[5705,6084,6020],{"class":6019},[5705,6086,5580],{"class":5726},[5705,6088,6025],{"class":5741},[5705,6090,6028],{"class":5726},[5705,6092,6094,6096,6098,6100,6102,6104,6106,6108],{"class":5707,"line":6093},13,[5705,6095,6075],{"class":5741},[5705,6097,5622],{"class":5726},[5705,6099,6080],{"class":5722},[5705,6101,5738],{"class":5726},[5705,6103,6042],{"class":6019},[5705,6105,5580],{"class":5726},[5705,6107,6047],{"class":5741},[5705,6109,6028],{"class":5726},[5705,6111,6113],{"class":5707,"line":6112},14,[5705,6114,6115],{"class":5726},"    };\n",[5705,6117,6119],{"class":5707,"line":6118},15,[5705,6120,6121],{"class":5726},"  }, []);\n",[5705,6123,6125],{"class":5707,"line":6124},16,[5705,6126,5795],{"emptyLinePlaceholder":5794},[5705,6128,6130,6133,6136],{"class":5707,"line":6129},17,[5705,6131,6132],{"class":6060},"  return",[5705,6134,6135],{"class":5741}," isOnline",[5705,6137,6138],{"class":5726},";\n",[5705,6140,6142],{"class":5707,"line":6141},18,[5705,6143,6144],{"class":5726},"}\n",[6146,6147,6148,6153,6160,6178],"warning",{},[5479,6149,6150],{},[5483,6151,6152],{},"Обмеження:",[5479,6154,6155,6156,6159],{},"Кастомні хуки підкоряються ",[5483,6157,6158],{},"тим самим правилам",", що й вбудовані хуки:",[5503,6161,6162,6165,6171],{},[5506,6163,6164],{},"❌ Не можна викликати хуки всередині умов, циклів або вкладених функцій.",[5506,6166,6167,6168,5609],{},"❌ Не можна викликати хуки після раннього повернення (",[5535,6169,6170],{},"return",[5506,6172,6173,6174,6177],{},"✅ Хуки завжди мають викликатися у ",[5483,6175,6176],{},"фіксованому порядку"," при кожному рендері.",[5479,6179,6180],{},"React покладається на порядок викликів хуків, щоб зв'язати стан із конкретним хуком. Порушення порядку призведе до непередбачуваних багів.",[5567,6182],{},[5570,6184,6186,6187,6189],{"id":6185},"базовий-приклад-useonlinestatus-відстеження-мережевого-зєднання","Базовий приклад: ",[5535,6188,5882],{}," — відстеження мережевого з'єднання",[5479,6191,6192,6193,6196,6197,6200],{},"Почнемо з найпростішого прикладу — хука, що підписується на браузерні події ",[5535,6194,6195],{},"online"," та ",[5535,6198,6199],{},"offline"," для відстеження статусу з'єднання.",[5685,6202,6204],{"id":6203},"реалізація-хука","Реалізація хука",[5696,6206,6208],{"className":5698,"code":6207,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from \"react\";\n\nexport function useOnlineStatus(): boolean {\n  \u002F\u002F Початковий стан — поточний статус з'єднання\n  const [isOnline, setIsOnline] = useState\u003Cboolean>(navigator.onLine);\n\n  useEffect(() => {\n    \u002F\u002F Обробники подій\n    function handleOnline() {\n      setIsOnline(true);\n    }\n\n    function handleOffline() {\n      setIsOnline(false);\n    }\n\n    \u002F\u002F Підписка на події window\n    window.addEventListener(\"online\", handleOnline);\n    window.addEventListener(\"offline\", handleOffline);\n\n    \u002F\u002F Очищення підписок\n    return () => {\n      window.removeEventListener(\"online\", handleOnline);\n      window.removeEventListener(\"offline\", handleOffline);\n    };\n  }, []); \u002F\u002F Порожній масив — підписка створюється один раз\n\n  return isOnline;\n}\n",[5535,6209,6210,6234,6238,6256,6261,6291,6295,6305,6310,6318,6329,6334,6338,6346,6356,6360,6364,6369,6387,6406,6411,6417,6428,6447,6466,6471,6480,6485,6494],{"__ignoreMap":5701},[5705,6211,6212,6215,6217,6219,6221,6223,6226,6229,6232],{"class":5707,"line":5708},[5705,6213,6214],{"class":6060},"import",[5705,6216,5958],{"class":5726},[5705,6218,5579],{"class":5741},[5705,6220,5580],{"class":5726},[5705,6222,5583],{"class":5741},[5705,6224,6225],{"class":5726}," } ",[5705,6227,6228],{"class":6060},"from",[5705,6230,6231],{"class":6019}," \"react\"",[5705,6233,6138],{"class":5726},[5705,6235,6236],{"class":5707,"line":5715},[5705,6237,5795],{"emptyLinePlaceholder":5794},[5705,6239,6240,6243,6246,6248,6251,6254],{"class":5707,"line":5730},[5705,6241,6242],{"class":6060},"export",[5705,6244,6245],{"class":5718}," function",[5705,6247,5723],{"class":5722},[5705,6249,6250],{"class":5726},"(): ",[5705,6252,6253],{"class":5748},"boolean",[5705,6255,6069],{"class":5726},[5705,6257,6258],{"class":5707,"line":5755},[5705,6259,6260],{"class":5711},"  \u002F\u002F Початковий стан — поточний статус з'єднання\n",[5705,6262,6263,6265,6267,6269,6271,6273,6275,6277,6279,6281,6283,6285,6287,6289],{"class":5707,"line":5791},[5705,6264,5907],{"class":5718},[5705,6266,5910],{"class":5726},[5705,6268,5914],{"class":5913},[5705,6270,5580],{"class":5726},[5705,6272,5919],{"class":5913},[5705,6274,5922],{"class":5726},[5705,6276,5579],{"class":5722},[5705,6278,5763],{"class":5726},[5705,6280,6253],{"class":5748},[5705,6282,5769],{"class":5726},[5705,6284,5929],{"class":5741},[5705,6286,5622],{"class":5726},[5705,6288,5934],{"class":5741},[5705,6290,6028],{"class":5726},[5705,6292,6293],{"class":5707,"line":5798},[5705,6294,5795],{"emptyLinePlaceholder":5794},[5705,6296,6297,6299,6301,6303],{"class":5707,"line":5804},[5705,6298,5949],{"class":5722},[5705,6300,5952],{"class":5726},[5705,6302,5955],{"class":5718},[5705,6304,6069],{"class":5726},[5705,6306,6307],{"class":5707,"line":5818},[5705,6308,6309],{"class":5711},"    \u002F\u002F Обробники подій\n",[5705,6311,6312,6314,6316],{"class":5707,"line":6031},[5705,6313,5966],{"class":5718},[5705,6315,5969],{"class":5722},[5705,6317,5902],{"class":5726},[5705,6319,6320,6323,6325,6327],{"class":5707,"line":6052},[5705,6321,6322],{"class":5722},"      setIsOnline",[5705,6324,5738],{"class":5726},[5705,6326,5979],{"class":5718},[5705,6328,6028],{"class":5726},[5705,6330,6331],{"class":5707,"line":6057},[5705,6332,6333],{"class":5726},"    }\n",[5705,6335,6336],{"class":5707,"line":6072},[5705,6337,5795],{"emptyLinePlaceholder":5794},[5705,6339,6340,6342,6344],{"class":5707,"line":6093},[5705,6341,5966],{"class":5718},[5705,6343,5989],{"class":5722},[5705,6345,5902],{"class":5726},[5705,6347,6348,6350,6352,6354],{"class":5707,"line":6112},[5705,6349,6322],{"class":5722},[5705,6351,5738],{"class":5726},[5705,6353,5998],{"class":5718},[5705,6355,6028],{"class":5726},[5705,6357,6358],{"class":5707,"line":6118},[5705,6359,6333],{"class":5726},[5705,6361,6362],{"class":5707,"line":6124},[5705,6363,5795],{"emptyLinePlaceholder":5794},[5705,6365,6366],{"class":5707,"line":6129},[5705,6367,6368],{"class":5711},"    \u002F\u002F Підписка на події window\n",[5705,6370,6371,6373,6375,6377,6379,6381,6383,6385],{"class":5707,"line":6141},[5705,6372,6009],{"class":5741},[5705,6374,5622],{"class":5726},[5705,6376,6014],{"class":5722},[5705,6378,5738],{"class":5726},[5705,6380,6020],{"class":6019},[5705,6382,5580],{"class":5726},[5705,6384,6025],{"class":5741},[5705,6386,6028],{"class":5726},[5705,6388,6390,6392,6394,6396,6398,6400,6402,6404],{"class":5707,"line":6389},19,[5705,6391,6009],{"class":5741},[5705,6393,5622],{"class":5726},[5705,6395,6014],{"class":5722},[5705,6397,5738],{"class":5726},[5705,6399,6042],{"class":6019},[5705,6401,5580],{"class":5726},[5705,6403,6047],{"class":5741},[5705,6405,6028],{"class":5726},[5705,6407,6409],{"class":5707,"line":6408},20,[5705,6410,5795],{"emptyLinePlaceholder":5794},[5705,6412,6414],{"class":5707,"line":6413},21,[5705,6415,6416],{"class":5711},"    \u002F\u002F Очищення підписок\n",[5705,6418,6420,6422,6424,6426],{"class":5707,"line":6419},22,[5705,6421,6061],{"class":6060},[5705,6423,6064],{"class":5726},[5705,6425,5955],{"class":5718},[5705,6427,6069],{"class":5726},[5705,6429,6431,6433,6435,6437,6439,6441,6443,6445],{"class":5707,"line":6430},23,[5705,6432,6075],{"class":5741},[5705,6434,5622],{"class":5726},[5705,6436,6080],{"class":5722},[5705,6438,5738],{"class":5726},[5705,6440,6020],{"class":6019},[5705,6442,5580],{"class":5726},[5705,6444,6025],{"class":5741},[5705,6446,6028],{"class":5726},[5705,6448,6450,6452,6454,6456,6458,6460,6462,6464],{"class":5707,"line":6449},24,[5705,6451,6075],{"class":5741},[5705,6453,5622],{"class":5726},[5705,6455,6080],{"class":5722},[5705,6457,5738],{"class":5726},[5705,6459,6042],{"class":6019},[5705,6461,5580],{"class":5726},[5705,6463,6047],{"class":5741},[5705,6465,6028],{"class":5726},[5705,6467,6469],{"class":5707,"line":6468},25,[5705,6470,6115],{"class":5726},[5705,6472,6474,6477],{"class":5707,"line":6473},26,[5705,6475,6476],{"class":5726},"  }, []); ",[5705,6478,6479],{"class":5711},"\u002F\u002F Порожній масив — підписка створюється один раз\n",[5705,6481,6483],{"class":5707,"line":6482},27,[5705,6484,5795],{"emptyLinePlaceholder":5794},[5705,6486,6488,6490,6492],{"class":5707,"line":6487},28,[5705,6489,6132],{"class":6060},[5705,6491,6135],{"class":5741},[5705,6493,6138],{"class":5726},[5705,6495,6497],{"class":5707,"line":6496},29,[5705,6498,6144],{"class":5726},[5685,6500,6502],{"id":6501},"використання-у-компоненті","Використання у компоненті",[5696,6504,6506],{"className":5698,"code":6505,"language":5700,"meta":5701,"style":5701},"function StatusIndicator() {\n  const isOnline = useOnlineStatus(); \u002F\u002F Простий виклик хука\n\n  return (\n    \u003Cdiv className={`status ${isOnline ? \"online\" : \"offline\"}`}>\n      {isOnline ? \"🟢 Онлайн\" : \"🔴 Офлайн\"}\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,6507,6508,6517,6534,6538,6545,6596,6615,6624,6629],{"__ignoreMap":5701},[5705,6509,6510,6512,6515],{"class":5707,"line":5708},[5705,6511,5719],{"class":5718},[5705,6513,6514],{"class":5722}," StatusIndicator",[5705,6516,5902],{"class":5726},[5705,6518,6519,6521,6523,6526,6528,6531],{"class":5707,"line":5715},[5705,6520,5907],{"class":5718},[5705,6522,6135],{"class":5913},[5705,6524,6525],{"class":5726}," = ",[5705,6527,5882],{"class":5722},[5705,6529,6530],{"class":5726},"(); ",[5705,6532,6533],{"class":5711},"\u002F\u002F Простий виклик хука\n",[5705,6535,6536],{"class":5707,"line":5730},[5705,6537,5795],{"emptyLinePlaceholder":5794},[5705,6539,6540,6542],{"class":5707,"line":5755},[5705,6541,6132],{"class":6060},[5705,6543,6544],{"class":5726}," (\n",[5705,6546,6547,6551,6555,6559,6562,6565,6568,6571,6573,6576,6579,6582,6585,6588,6591,6593],{"class":5707,"line":5791},[5705,6548,6550],{"class":6549},"s0P7L","    \u003C",[5705,6552,6554],{"class":6553},"sKtos","div",[5705,6556,6558],{"class":6557},"sa4r_"," className",[5705,6560,6561],{"class":5726},"=",[5705,6563,6564],{"class":5718},"{",[5705,6566,6567],{"class":6019},"`status ",[5705,6569,6570],{"class":5718},"${",[5705,6572,5914],{"class":5741},[5705,6574,6575],{"class":5726}," ?",[5705,6577,6578],{"class":6019}," \"online\"",[5705,6580,6581],{"class":5726}," :",[5705,6583,6584],{"class":6019}," \"offline\"",[5705,6586,6587],{"class":5718},"}",[5705,6589,6590],{"class":6019},"`",[5705,6592,6587],{"class":5718},[5705,6594,6595],{"class":6549},">\n",[5705,6597,6598,6601,6603,6605,6608,6610,6613],{"class":5707,"line":5798},[5705,6599,6600],{"class":5718},"      {",[5705,6602,5914],{"class":5741},[5705,6604,6575],{"class":5726},[5705,6606,6607],{"class":6019}," \"🟢 Онлайн\"",[5705,6609,6581],{"class":5726},[5705,6611,6612],{"class":6019}," \"🔴 Офлайн\"",[5705,6614,6144],{"class":5718},[5705,6616,6617,6620,6622],{"class":5707,"line":5804},[5705,6618,6619],{"class":6549},"    \u003C\u002F",[5705,6621,6554],{"class":6553},[5705,6623,6595],{"class":6549},[5705,6625,6626],{"class":5707,"line":5818},[5705,6627,6628],{"class":5726},"  );\n",[5705,6630,6631],{"class":5707,"line":6031},[5705,6632,6144],{"class":5726},[6634,6635,6636,6641],"tip",{},[5479,6637,6638],{},[5483,6639,6640],{},"Переваги кастомного хука:",[6642,6643,6644,6653,6663,6669],"ol",{},[5506,6645,6646,6649,6650,6652],{},[5483,6647,6648],{},"Інкапсуляція:"," Логіка роботи з ",[5535,6651,5608],{}," та браузерними подіями прихована всередині хука. Компонент не знає деталей реалізації.",[5506,6654,6655,6658,6659,6662],{},[5483,6656,6657],{},"Повторне використання:"," Будь-який компонент може викликати ",[5535,6660,6661],{},"useOnlineStatus()"," — не потрібно копіювати код підписок.",[5506,6664,6665,6668],{},[5483,6666,6667],{},"Тестованість:"," Хук можна протестувати ізольовано, не рендерячи компонент.",[5506,6670,6671,6674],{},[5483,6672,6673],{},"Читабельність:"," Компонент виражає намір на високому рівні абстракції: «покажи статус з'єднання», а не «підпишись на події, оновлюй стан, не забудь відписатися».",[5567,6676],{},[5570,6678,6680],{"id":6679},"ізоляція-стану-кожен-виклик-хука-має-власний-стан","Ізоляція стану: кожен виклик хука має власний стан",[5479,6682,6683,6684,6687],{},"Критично важливо зрозуміти: ",[5483,6685,6686],{},"кастомні хуки ділять логіку, але не ділять стан",". Кожен виклик хука отримує повністю незалежний екземпляр стану.",[5696,6689,6691],{"className":5698,"code":6690,"language":5700,"meta":5701,"style":5701},"function Dashboard() {\n  const isOnline1 = useOnlineStatus(); \u002F\u002F Власний стан isOnline\n  const isOnline2 = useOnlineStatus(); \u002F\u002F Інший незалежний стан isOnline\n\n  \u002F\u002F isOnline1 та isOnline2 — це дві різні змінні стану\n  \u002F\u002F Вони будуть мати однакове значення (true\u002Ffalse), бо обидві\n  \u002F\u002F читають navigator.onLine, але це окремі виклики useState всередині\n\n  return (\n    \u003Cdiv>\n      \u003Cp>Індикатор 1: {isOnline1 ? \"Онлайн\" : \"Офлайн\"}\u003C\u002Fp>\n      \u003Cp>Індикатор 2: {isOnline2 ? \"Онлайн\" : \"Офлайн\"}\u003C\u002Fp>\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,6692,6693,6702,6718,6734,6738,6743,6748,6753,6757,6763,6771,6808,6840,6848,6852],{"__ignoreMap":5701},[5705,6694,6695,6697,6700],{"class":5707,"line":5708},[5705,6696,5719],{"class":5718},[5705,6698,6699],{"class":5722}," Dashboard",[5705,6701,5902],{"class":5726},[5705,6703,6704,6706,6709,6711,6713,6715],{"class":5707,"line":5715},[5705,6705,5907],{"class":5718},[5705,6707,6708],{"class":5913}," isOnline1",[5705,6710,6525],{"class":5726},[5705,6712,5882],{"class":5722},[5705,6714,6530],{"class":5726},[5705,6716,6717],{"class":5711},"\u002F\u002F Власний стан isOnline\n",[5705,6719,6720,6722,6725,6727,6729,6731],{"class":5707,"line":5730},[5705,6721,5907],{"class":5718},[5705,6723,6724],{"class":5913}," isOnline2",[5705,6726,6525],{"class":5726},[5705,6728,5882],{"class":5722},[5705,6730,6530],{"class":5726},[5705,6732,6733],{"class":5711},"\u002F\u002F Інший незалежний стан isOnline\n",[5705,6735,6736],{"class":5707,"line":5755},[5705,6737,5795],{"emptyLinePlaceholder":5794},[5705,6739,6740],{"class":5707,"line":5791},[5705,6741,6742],{"class":5711},"  \u002F\u002F isOnline1 та isOnline2 — це дві різні змінні стану\n",[5705,6744,6745],{"class":5707,"line":5798},[5705,6746,6747],{"class":5711},"  \u002F\u002F Вони будуть мати однакове значення (true\u002Ffalse), бо обидві\n",[5705,6749,6750],{"class":5707,"line":5804},[5705,6751,6752],{"class":5711},"  \u002F\u002F читають navigator.onLine, але це окремі виклики useState всередині\n",[5705,6754,6755],{"class":5707,"line":5818},[5705,6756,5795],{"emptyLinePlaceholder":5794},[5705,6758,6759,6761],{"class":5707,"line":6031},[5705,6760,6132],{"class":6060},[5705,6762,6544],{"class":5726},[5705,6764,6765,6767,6769],{"class":5707,"line":6052},[5705,6766,6550],{"class":6549},[5705,6768,6554],{"class":6553},[5705,6770,6595],{"class":6549},[5705,6772,6773,6776,6778,6781,6784,6786,6789,6791,6794,6796,6799,6801,6804,6806],{"class":5707,"line":6057},[5705,6774,6775],{"class":6549},"      \u003C",[5705,6777,5479],{"class":6553},[5705,6779,6780],{"class":6549},">",[5705,6782,6783],{"class":5726},"Індикатор 1: ",[5705,6785,6564],{"class":5718},[5705,6787,6788],{"class":5741},"isOnline1",[5705,6790,6575],{"class":5726},[5705,6792,6793],{"class":6019}," \"Онлайн\"",[5705,6795,6581],{"class":5726},[5705,6797,6798],{"class":6019}," \"Офлайн\"",[5705,6800,6587],{"class":5718},[5705,6802,6803],{"class":6549},"\u003C\u002F",[5705,6805,5479],{"class":6553},[5705,6807,6595],{"class":6549},[5705,6809,6810,6812,6814,6816,6819,6821,6824,6826,6828,6830,6832,6834,6836,6838],{"class":5707,"line":6072},[5705,6811,6775],{"class":6549},[5705,6813,5479],{"class":6553},[5705,6815,6780],{"class":6549},[5705,6817,6818],{"class":5726},"Індикатор 2: ",[5705,6820,6564],{"class":5718},[5705,6822,6823],{"class":5741},"isOnline2",[5705,6825,6575],{"class":5726},[5705,6827,6793],{"class":6019},[5705,6829,6581],{"class":5726},[5705,6831,6798],{"class":6019},[5705,6833,6587],{"class":5718},[5705,6835,6803],{"class":6549},[5705,6837,5479],{"class":6553},[5705,6839,6595],{"class":6549},[5705,6841,6842,6844,6846],{"class":5707,"line":6093},[5705,6843,6619],{"class":6549},[5705,6845,6554],{"class":6553},[5705,6847,6595],{"class":6549},[5705,6849,6850],{"class":5707,"line":6112},[5705,6851,6628],{"class":5726},[5705,6853,6854],{"class":5707,"line":6118},[5705,6855,6144],{"class":5726},[6857,6858,6860],"plant-uml",{"alt":6859},"Ізоляція стану між викликами хука",[5696,6861,6865],{"className":6862,"code":6863,"language":6864,"meta":5701,"style":5701},"language-plantuml shiki shiki-themes light-plus dark-plus dark-plus","@startuml\nskinparam style plain\nskinparam backgroundColor #FFFFFF\n\npackage \"Компонент Dashboard\" #F1F5F9 {\n  \n  rectangle \"Виклик 1: useOnlineStatus()\" #DBEAFE {\n    rectangle \"useState(navigator.onLine)\" as State1 #DCFCE7\n    rectangle \"useEffect(...)\" as Effect1 #FEF3C7\n    State1 --> Effect1\n    note right of State1\n      Власний стан: isOnline1\n      Незалежна підписка на події\n    end note\n  }\n  \n  rectangle \"Виклик 2: useOnlineStatus()\" #DBEAFE {\n    rectangle \"useState(navigator.onLine)\" as State2 #DCFCE7\n    rectangle \"useEffect(...)\" as Effect2 #FEF3C7\n    State2 --> Effect2\n    note right of State2\n      Власний стан: isOnline2\n      Окрема незалежна підписка на події\n    end note\n  }\n}\n\nnote bottom of \"Компонент Dashboard\"\n  React розрізняє виклики хуків за **порядком виклику**.\n  Перший useState всередині useOnlineStatus\n  прив'язаний до першого слота стану компонента,\n  другий useState — до другого слота.\nend note\n\n@enduml\n","plantuml",[5535,6866,6867,6872,6877,6882,6886,6891,6896,6901,6906,6911,6916,6921,6926,6931,6936,6941,6945,6950,6955,6960,6965,6970,6975,6980,6984,6988,6992,6996,7001,7006,7012,7018,7024,7030,7035],{"__ignoreMap":5701},[5705,6868,6869],{"class":5707,"line":5708},[5705,6870,6871],{},"@startuml\n",[5705,6873,6874],{"class":5707,"line":5715},[5705,6875,6876],{},"skinparam style plain\n",[5705,6878,6879],{"class":5707,"line":5730},[5705,6880,6881],{},"skinparam backgroundColor #FFFFFF\n",[5705,6883,6884],{"class":5707,"line":5755},[5705,6885,5795],{"emptyLinePlaceholder":5794},[5705,6887,6888],{"class":5707,"line":5791},[5705,6889,6890],{},"package \"Компонент Dashboard\" #F1F5F9 {\n",[5705,6892,6893],{"class":5707,"line":5798},[5705,6894,6895],{},"  \n",[5705,6897,6898],{"class":5707,"line":5804},[5705,6899,6900],{},"  rectangle \"Виклик 1: useOnlineStatus()\" #DBEAFE {\n",[5705,6902,6903],{"class":5707,"line":5818},[5705,6904,6905],{},"    rectangle \"useState(navigator.onLine)\" as State1 #DCFCE7\n",[5705,6907,6908],{"class":5707,"line":6031},[5705,6909,6910],{},"    rectangle \"useEffect(...)\" as Effect1 #FEF3C7\n",[5705,6912,6913],{"class":5707,"line":6052},[5705,6914,6915],{},"    State1 --> Effect1\n",[5705,6917,6918],{"class":5707,"line":6057},[5705,6919,6920],{},"    note right of State1\n",[5705,6922,6923],{"class":5707,"line":6072},[5705,6924,6925],{},"      Власний стан: isOnline1\n",[5705,6927,6928],{"class":5707,"line":6093},[5705,6929,6930],{},"      Незалежна підписка на події\n",[5705,6932,6933],{"class":5707,"line":6112},[5705,6934,6935],{},"    end note\n",[5705,6937,6938],{"class":5707,"line":6118},[5705,6939,6940],{},"  }\n",[5705,6942,6943],{"class":5707,"line":6124},[5705,6944,6895],{},[5705,6946,6947],{"class":5707,"line":6129},[5705,6948,6949],{},"  rectangle \"Виклик 2: useOnlineStatus()\" #DBEAFE {\n",[5705,6951,6952],{"class":5707,"line":6141},[5705,6953,6954],{},"    rectangle \"useState(navigator.onLine)\" as State2 #DCFCE7\n",[5705,6956,6957],{"class":5707,"line":6389},[5705,6958,6959],{},"    rectangle \"useEffect(...)\" as Effect2 #FEF3C7\n",[5705,6961,6962],{"class":5707,"line":6408},[5705,6963,6964],{},"    State2 --> Effect2\n",[5705,6966,6967],{"class":5707,"line":6413},[5705,6968,6969],{},"    note right of State2\n",[5705,6971,6972],{"class":5707,"line":6419},[5705,6973,6974],{},"      Власний стан: isOnline2\n",[5705,6976,6977],{"class":5707,"line":6430},[5705,6978,6979],{},"      Окрема незалежна підписка на події\n",[5705,6981,6982],{"class":5707,"line":6449},[5705,6983,6935],{},[5705,6985,6986],{"class":5707,"line":6468},[5705,6987,6940],{},[5705,6989,6990],{"class":5707,"line":6473},[5705,6991,6144],{},[5705,6993,6994],{"class":5707,"line":6482},[5705,6995,5795],{"emptyLinePlaceholder":5794},[5705,6997,6998],{"class":5707,"line":6487},[5705,6999,7000],{},"note bottom of \"Компонент Dashboard\"\n",[5705,7002,7003],{"class":5707,"line":6496},[5705,7004,7005],{},"  React розрізняє виклики хуків за **порядком виклику**.\n",[5705,7007,7009],{"class":5707,"line":7008},30,[5705,7010,7011],{},"  Перший useState всередині useOnlineStatus\n",[5705,7013,7015],{"class":5707,"line":7014},31,[5705,7016,7017],{},"  прив'язаний до першого слота стану компонента,\n",[5705,7019,7021],{"class":5707,"line":7020},32,[5705,7022,7023],{},"  другий useState — до другого слота.\n",[5705,7025,7027],{"class":5707,"line":7026},33,[5705,7028,7029],{},"end note\n",[5705,7031,7033],{"class":5707,"line":7032},34,[5705,7034,5795],{"emptyLinePlaceholder":5794},[5705,7036,7038],{"class":5707,"line":7037},35,[5705,7039,7040],{},"@enduml\n",[5479,7042,7043,7044,7047],{},"Якщо потрібно ",[5483,7045,7046],{},"ділитися станом"," між компонентами, використовуйте:",[5503,7049,7050,7059,7068],{},[5506,7051,7052,7055,7056,7058],{},[5483,7053,7054],{},"Context API"," (",[5535,7057,5592],{},") для глобального стану.",[5506,7060,7061,7055,7064,7067],{},[5483,7062,7063],{},"Підйом стану",[5529,7065,7066],{},"lifting state up",") до спільного батьківського компонента.",[5506,7069,7070,7073],{},[5483,7071,7072],{},"Зовнішні стор-менеджери"," (Redux, Zustand), які ми вивчимо у наступних лекціях.",[5567,7075],{},[5570,7077,7079,7080],{"id":7078},"типізований-хук-завантаження-даних-usefetch","Типізований хук завантаження даних: ",[5535,7081,5885],{},[5479,7083,7084,7085,7088,7089,5622],{},"Один із найпоширеніших сценаріїв — завантаження даних з API. Створимо узагальнений (",[5529,7086,7087],{},"generic",") хук із підтримкою TypeScript та скасування запитів через ",[5535,7090,7091],{},"AbortController",[5685,7093,7095,7096,7098],{"id":7094},"реалізація-usefetch-з-повною-типізацією","Реалізація ",[5535,7097,5885],{}," з повною типізацією",[5696,7100,7102],{"className":5698,"code":7101,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from \"react\";\n\ninterface UseFetchResult\u003CT> {\n  data: T | null;\n  isLoading: boolean;\n  error: string | null;\n}\n\nexport function useFetch\u003CT>(url: string): UseFetchResult\u003CT> {\n  const [data, setData] = useState\u003CT | null>(null);\n  const [isLoading, setIsLoading] = useState\u003Cboolean>(true);\n  const [error, setError] = useState\u003Cstring | null>(null);\n\n  useEffect(() => {\n    \u002F\u002F Створюємо AbortController для скасування запиту\n    const controller = new AbortController();\n    const { signal } = controller;\n\n    async function fetchData(): Promise\u003Cvoid> {\n      try {\n        setIsLoading(true);\n        setError(null);\n\n        const response = await fetch(url, { signal });\n\n        if (!response.ok) {\n          throw new Error(`HTTP помилка ${response.status}: ${response.statusText}`);\n        }\n\n        const result: T = await response.json();\n        setData(result);\n      } catch (err) {\n        \u002F\u002F Ігноруємо AbortError — це нормальне скасування\n        if (err instanceof Error && err.name !== \"AbortError\") {\n          setError(err.message);\n        }\n      } finally {\n        \u002F\u002F Оновлюємо isLoading лише якщо запит не було скасовано\n        if (!signal.aborted) {\n          setIsLoading(false);\n        }\n      }\n    }\n\n    fetchData();\n\n    \u002F\u002F Функція очищення: скасовує запит при розмонтуванні або зміні URL\n    return () => {\n      controller.abort();\n    };\n  }, [url]); \u002F\u002F Ефект перезапускається при зміні URL\n\n  return { data, isLoading, error };\n}\n",[5535,7103,7104,7124,7128,7143,7160,7171,7186,7190,7194,7226,7257,7285,7316,7320,7330,7335,7354,7371,7375,7396,7403,7414,7425,7429,7457,7461,7480,7525,7530,7534,7558,7570,7585,7590,7621,7637,7642,7652,7658,7674,7686,7691,7697,7702,7707,7715,7720,7726,7737,7750,7755,7769,7774,7794],{"__ignoreMap":5701},[5705,7105,7106,7108,7110,7112,7114,7116,7118,7120,7122],{"class":5707,"line":5708},[5705,7107,6214],{"class":6060},[5705,7109,5958],{"class":5726},[5705,7111,5579],{"class":5741},[5705,7113,5580],{"class":5726},[5705,7115,5583],{"class":5741},[5705,7117,6225],{"class":5726},[5705,7119,6228],{"class":6060},[5705,7121,6231],{"class":6019},[5705,7123,6138],{"class":5726},[5705,7125,7126],{"class":5707,"line":5715},[5705,7127,5795],{"emptyLinePlaceholder":5794},[5705,7129,7130,7133,7136,7138,7140],{"class":5707,"line":5730},[5705,7131,7132],{"class":5718},"interface",[5705,7134,7135],{"class":5748}," UseFetchResult",[5705,7137,5763],{"class":5726},[5705,7139,5766],{"class":5748},[5705,7141,7142],{"class":5726},"> {\n",[5705,7144,7145,7148,7150,7152,7155,7158],{"class":5707,"line":5755},[5705,7146,7147],{"class":5741},"  data",[5705,7149,5745],{"class":5726},[5705,7151,5766],{"class":5748},[5705,7153,7154],{"class":5726}," | ",[5705,7156,7157],{"class":5748},"null",[5705,7159,6138],{"class":5726},[5705,7161,7162,7165,7167,7169],{"class":5707,"line":5791},[5705,7163,7164],{"class":5741},"  isLoading",[5705,7166,5745],{"class":5726},[5705,7168,6253],{"class":5748},[5705,7170,6138],{"class":5726},[5705,7172,7173,7176,7178,7180,7182,7184],{"class":5707,"line":5798},[5705,7174,7175],{"class":5741},"  error",[5705,7177,5745],{"class":5726},[5705,7179,5749],{"class":5748},[5705,7181,7154],{"class":5726},[5705,7183,7157],{"class":5748},[5705,7185,6138],{"class":5726},[5705,7187,7188],{"class":5707,"line":5804},[5705,7189,6144],{"class":5726},[5705,7191,7192],{"class":5707,"line":5818},[5705,7193,5795],{"emptyLinePlaceholder":5794},[5705,7195,7196,7198,7200,7202,7204,7206,7208,7210,7212,7214,7217,7220,7222,7224],{"class":5707,"line":6031},[5705,7197,6242],{"class":6060},[5705,7199,6245],{"class":5718},[5705,7201,5735],{"class":5722},[5705,7203,5763],{"class":5726},[5705,7205,5766],{"class":5748},[5705,7207,5769],{"class":5726},[5705,7209,5742],{"class":5741},[5705,7211,5745],{"class":5726},[5705,7213,5749],{"class":5748},[5705,7215,7216],{"class":5726},"): ",[5705,7218,7219],{"class":5748},"UseFetchResult",[5705,7221,5763],{"class":5726},[5705,7223,5766],{"class":5748},[5705,7225,7142],{"class":5726},[5705,7227,7228,7230,7232,7234,7236,7239,7241,7243,7245,7247,7249,7251,7253,7255],{"class":5707,"line":6052},[5705,7229,5907],{"class":5718},[5705,7231,5910],{"class":5726},[5705,7233,5621],{"class":5913},[5705,7235,5580],{"class":5726},[5705,7237,7238],{"class":5913},"setData",[5705,7240,5922],{"class":5726},[5705,7242,5579],{"class":5722},[5705,7244,5763],{"class":5726},[5705,7246,5766],{"class":5748},[5705,7248,7154],{"class":5726},[5705,7250,7157],{"class":5748},[5705,7252,5769],{"class":5726},[5705,7254,7157],{"class":5718},[5705,7256,6028],{"class":5726},[5705,7258,7259,7261,7263,7266,7268,7271,7273,7275,7277,7279,7281,7283],{"class":5707,"line":6057},[5705,7260,5907],{"class":5718},[5705,7262,5910],{"class":5726},[5705,7264,7265],{"class":5913},"isLoading",[5705,7267,5580],{"class":5726},[5705,7269,7270],{"class":5913},"setIsLoading",[5705,7272,5922],{"class":5726},[5705,7274,5579],{"class":5722},[5705,7276,5763],{"class":5726},[5705,7278,6253],{"class":5748},[5705,7280,5769],{"class":5726},[5705,7282,5979],{"class":5718},[5705,7284,6028],{"class":5726},[5705,7286,7287,7289,7291,7293,7295,7298,7300,7302,7304,7306,7308,7310,7312,7314],{"class":5707,"line":6072},[5705,7288,5907],{"class":5718},[5705,7290,5910],{"class":5726},[5705,7292,5618],{"class":5913},[5705,7294,5580],{"class":5726},[5705,7296,7297],{"class":5913},"setError",[5705,7299,5922],{"class":5726},[5705,7301,5579],{"class":5722},[5705,7303,5763],{"class":5726},[5705,7305,5749],{"class":5748},[5705,7307,7154],{"class":5726},[5705,7309,7157],{"class":5748},[5705,7311,5769],{"class":5726},[5705,7313,7157],{"class":5718},[5705,7315,6028],{"class":5726},[5705,7317,7318],{"class":5707,"line":6093},[5705,7319,5795],{"emptyLinePlaceholder":5794},[5705,7321,7322,7324,7326,7328],{"class":5707,"line":6112},[5705,7323,5949],{"class":5722},[5705,7325,5952],{"class":5726},[5705,7327,5955],{"class":5718},[5705,7329,6069],{"class":5726},[5705,7331,7332],{"class":5707,"line":6118},[5705,7333,7334],{"class":5711},"    \u002F\u002F Створюємо AbortController для скасування запиту\n",[5705,7336,7337,7340,7343,7345,7348,7351],{"class":5707,"line":6124},[5705,7338,7339],{"class":5718},"    const",[5705,7341,7342],{"class":5913}," controller",[5705,7344,6525],{"class":5726},[5705,7346,7347],{"class":5718},"new",[5705,7349,7350],{"class":5722}," AbortController",[5705,7352,7353],{"class":5726},"();\n",[5705,7355,7356,7358,7360,7363,7366,7369],{"class":5707,"line":6129},[5705,7357,7339],{"class":5718},[5705,7359,5958],{"class":5726},[5705,7361,7362],{"class":5913},"signal",[5705,7364,7365],{"class":5726}," } = ",[5705,7367,7368],{"class":5741},"controller",[5705,7370,6138],{"class":5726},[5705,7372,7373],{"class":5707,"line":6141},[5705,7374,5795],{"emptyLinePlaceholder":5794},[5705,7376,7377,7380,7382,7384,7386,7389,7391,7394],{"class":5707,"line":6389},[5705,7378,7379],{"class":5718},"    async",[5705,7381,6245],{"class":5718},[5705,7383,5823],{"class":5722},[5705,7385,6250],{"class":5726},[5705,7387,7388],{"class":5748},"Promise",[5705,7390,5763],{"class":5726},[5705,7392,7393],{"class":5748},"void",[5705,7395,7142],{"class":5726},[5705,7397,7398,7401],{"class":5707,"line":6408},[5705,7399,7400],{"class":6060},"      try",[5705,7402,6069],{"class":5726},[5705,7404,7405,7408,7410,7412],{"class":5707,"line":6413},[5705,7406,7407],{"class":5722},"        setIsLoading",[5705,7409,5738],{"class":5726},[5705,7411,5979],{"class":5718},[5705,7413,6028],{"class":5726},[5705,7415,7416,7419,7421,7423],{"class":5707,"line":6419},[5705,7417,7418],{"class":5722},"        setError",[5705,7420,5738],{"class":5726},[5705,7422,7157],{"class":5718},[5705,7424,6028],{"class":5726},[5705,7426,7427],{"class":5707,"line":6430},[5705,7428,5795],{"emptyLinePlaceholder":5794},[5705,7430,7431,7434,7437,7439,7442,7445,7447,7449,7452,7454],{"class":5707,"line":6449},[5705,7432,7433],{"class":5718},"        const",[5705,7435,7436],{"class":5913}," response",[5705,7438,6525],{"class":5726},[5705,7440,7441],{"class":6060},"await",[5705,7443,7444],{"class":5722}," fetch",[5705,7446,5738],{"class":5726},[5705,7448,5742],{"class":5741},[5705,7450,7451],{"class":5726},", { ",[5705,7453,7362],{"class":5741},[5705,7455,7456],{"class":5726}," });\n",[5705,7458,7459],{"class":5707,"line":6468},[5705,7460,5795],{"emptyLinePlaceholder":5794},[5705,7462,7463,7466,7469,7472,7474,7477],{"class":5707,"line":6473},[5705,7464,7465],{"class":6060},"        if",[5705,7467,7468],{"class":5726}," (!",[5705,7470,7471],{"class":5741},"response",[5705,7473,5622],{"class":5726},[5705,7475,7476],{"class":5741},"ok",[5705,7478,7479],{"class":5726},") {\n",[5705,7481,7482,7485,7488,7491,7493,7496,7498,7500,7503,7506,7508,7510,7512,7514,7516,7519,7521,7523],{"class":5707,"line":6482},[5705,7483,7484],{"class":6060},"          throw",[5705,7486,7487],{"class":5718}," new",[5705,7489,7490],{"class":5722}," Error",[5705,7492,5738],{"class":5726},[5705,7494,7495],{"class":6019},"`HTTP помилка ",[5705,7497,6570],{"class":5718},[5705,7499,7471],{"class":5741},[5705,7501,5622],{"class":7502},"sD7JJ",[5705,7504,7505],{"class":5741},"status",[5705,7507,6587],{"class":5718},[5705,7509,5745],{"class":6019},[5705,7511,6570],{"class":5718},[5705,7513,7471],{"class":5741},[5705,7515,5622],{"class":7502},[5705,7517,7518],{"class":5741},"statusText",[5705,7520,6587],{"class":5718},[5705,7522,6590],{"class":6019},[5705,7524,6028],{"class":5726},[5705,7526,7527],{"class":5707,"line":6487},[5705,7528,7529],{"class":5726},"        }\n",[5705,7531,7532],{"class":5707,"line":6496},[5705,7533,5795],{"emptyLinePlaceholder":5794},[5705,7535,7536,7538,7541,7543,7545,7547,7549,7551,7553,7556],{"class":5707,"line":7008},[5705,7537,7433],{"class":5718},[5705,7539,7540],{"class":5913}," result",[5705,7542,5745],{"class":5726},[5705,7544,5766],{"class":5748},[5705,7546,6525],{"class":5726},[5705,7548,7441],{"class":6060},[5705,7550,7436],{"class":5741},[5705,7552,5622],{"class":5726},[5705,7554,7555],{"class":5722},"json",[5705,7557,7353],{"class":5726},[5705,7559,7560,7563,7565,7568],{"class":5707,"line":7014},[5705,7561,7562],{"class":5722},"        setData",[5705,7564,5738],{"class":5726},[5705,7566,7567],{"class":5741},"result",[5705,7569,6028],{"class":5726},[5705,7571,7572,7575,7578,7580,7583],{"class":5707,"line":7020},[5705,7573,7574],{"class":5726},"      } ",[5705,7576,7577],{"class":6060},"catch",[5705,7579,7055],{"class":5726},[5705,7581,7582],{"class":5741},"err",[5705,7584,7479],{"class":5726},[5705,7586,7587],{"class":5707,"line":7026},[5705,7588,7589],{"class":5711},"        \u002F\u002F Ігноруємо AbortError — це нормальне скасування\n",[5705,7591,7592,7594,7596,7598,7601,7603,7606,7608,7610,7613,7616,7619],{"class":5707,"line":7032},[5705,7593,7465],{"class":6060},[5705,7595,7055],{"class":5726},[5705,7597,7582],{"class":5741},[5705,7599,7600],{"class":5718}," instanceof",[5705,7602,7490],{"class":5748},[5705,7604,7605],{"class":5726}," && ",[5705,7607,7582],{"class":5741},[5705,7609,5622],{"class":5726},[5705,7611,7612],{"class":5741},"name",[5705,7614,7615],{"class":5726}," !== ",[5705,7617,7618],{"class":6019},"\"AbortError\"",[5705,7620,7479],{"class":5726},[5705,7622,7623,7626,7628,7630,7632,7635],{"class":5707,"line":7037},[5705,7624,7625],{"class":5722},"          setError",[5705,7627,5738],{"class":5726},[5705,7629,7582],{"class":5741},[5705,7631,5622],{"class":5726},[5705,7633,7634],{"class":5741},"message",[5705,7636,6028],{"class":5726},[5705,7638,7640],{"class":5707,"line":7639},36,[5705,7641,7529],{"class":5726},[5705,7643,7645,7647,7650],{"class":5707,"line":7644},37,[5705,7646,7574],{"class":5726},[5705,7648,7649],{"class":6060},"finally",[5705,7651,6069],{"class":5726},[5705,7653,7655],{"class":5707,"line":7654},38,[5705,7656,7657],{"class":5711},"        \u002F\u002F Оновлюємо isLoading лише якщо запит не було скасовано\n",[5705,7659,7661,7663,7665,7667,7669,7672],{"class":5707,"line":7660},39,[5705,7662,7465],{"class":6060},[5705,7664,7468],{"class":5726},[5705,7666,7362],{"class":5741},[5705,7668,5622],{"class":5726},[5705,7670,7671],{"class":5741},"aborted",[5705,7673,7479],{"class":5726},[5705,7675,7677,7680,7682,7684],{"class":5707,"line":7676},40,[5705,7678,7679],{"class":5722},"          setIsLoading",[5705,7681,5738],{"class":5726},[5705,7683,5998],{"class":5718},[5705,7685,6028],{"class":5726},[5705,7687,7689],{"class":5707,"line":7688},41,[5705,7690,7529],{"class":5726},[5705,7692,7694],{"class":5707,"line":7693},42,[5705,7695,7696],{"class":5726},"      }\n",[5705,7698,7700],{"class":5707,"line":7699},43,[5705,7701,6333],{"class":5726},[5705,7703,7705],{"class":5707,"line":7704},44,[5705,7706,5795],{"emptyLinePlaceholder":5794},[5705,7708,7710,7713],{"class":5707,"line":7709},45,[5705,7711,7712],{"class":5722},"    fetchData",[5705,7714,7353],{"class":5726},[5705,7716,7718],{"class":5707,"line":7717},46,[5705,7719,5795],{"emptyLinePlaceholder":5794},[5705,7721,7723],{"class":5707,"line":7722},47,[5705,7724,7725],{"class":5711},"    \u002F\u002F Функція очищення: скасовує запит при розмонтуванні або зміні URL\n",[5705,7727,7729,7731,7733,7735],{"class":5707,"line":7728},48,[5705,7730,6061],{"class":6060},[5705,7732,6064],{"class":5726},[5705,7734,5955],{"class":5718},[5705,7736,6069],{"class":5726},[5705,7738,7740,7743,7745,7748],{"class":5707,"line":7739},49,[5705,7741,7742],{"class":5741},"      controller",[5705,7744,5622],{"class":5726},[5705,7746,7747],{"class":5722},"abort",[5705,7749,7353],{"class":5726},[5705,7751,7753],{"class":5707,"line":7752},50,[5705,7754,6115],{"class":5726},[5705,7756,7758,7761,7763,7766],{"class":5707,"line":7757},51,[5705,7759,7760],{"class":5726},"  }, [",[5705,7762,5742],{"class":5741},[5705,7764,7765],{"class":5726},"]); ",[5705,7767,7768],{"class":5711},"\u002F\u002F Ефект перезапускається при зміні URL\n",[5705,7770,7772],{"class":5707,"line":7771},52,[5705,7773,5795],{"emptyLinePlaceholder":5794},[5705,7775,7777,7779,7781,7783,7785,7787,7789,7791],{"class":5707,"line":7776},53,[5705,7778,6132],{"class":6060},[5705,7780,5958],{"class":5726},[5705,7782,5621],{"class":5741},[5705,7784,5580],{"class":5726},[5705,7786,7265],{"class":5741},[5705,7788,5580],{"class":5726},[5705,7790,5618],{"class":5741},[5705,7792,7793],{"class":5726}," };\n",[5705,7795,7797],{"class":5707,"line":7796},54,[5705,7798,6144],{"class":5726},[5685,7800,7802,7803,7805],{"id":7801},"використання-usefetch-у-компоненті","Використання ",[5535,7804,5885],{}," у компоненті",[5696,7807,7809],{"className":5698,"code":7808,"language":5700,"meta":5701,"style":5701},"interface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nfunction UserProfile({ userId }: { userId: number }) {\n  const { data: user, isLoading, error } = useFetch\u003CUser>(\n    `https:\u002F\u002Fapi.example.com\u002Fusers\u002F${userId}`\n  );\n\n  if (isLoading) {\n    return \u003Cdiv className=\"spinner\">Завантаження...\u003C\u002Fdiv>;\n  }\n\n  if (error) {\n    return \u003Cdiv className=\"error\">Помилка: {error}\u003C\u002Fdiv>;\n  }\n\n  if (!user) {\n    return \u003Cdiv>Користувача не знайдено\u003C\u002Fdiv>;\n  }\n\n  return (\n    \u003Cdiv className=\"user-card\">\n      \u003Ch2>{user.name}\u003C\u002Fh2>\n      \u003Cp>{user.email}\u003C\u002Fp>\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,7810,7811,7820,7831,7842,7853,7857,7861,7886,7919,7933,7937,7941,7952,7981,7985,7989,7999,8033,8037,8041,8051,8072,8076,8080,8086,8101,8125,8150,8158,8162],{"__ignoreMap":5701},[5705,7812,7813,7815,7818],{"class":5707,"line":5708},[5705,7814,7132],{"class":5718},[5705,7816,7817],{"class":5748}," User",[5705,7819,6069],{"class":5726},[5705,7821,7822,7825,7827,7829],{"class":5707,"line":5715},[5705,7823,7824],{"class":5741},"  id",[5705,7826,5745],{"class":5726},[5705,7828,5786],{"class":5748},[5705,7830,6138],{"class":5726},[5705,7832,7833,7836,7838,7840],{"class":5707,"line":5730},[5705,7834,7835],{"class":5741},"  name",[5705,7837,5745],{"class":5726},[5705,7839,5749],{"class":5748},[5705,7841,6138],{"class":5726},[5705,7843,7844,7847,7849,7851],{"class":5707,"line":5755},[5705,7845,7846],{"class":5741},"  email",[5705,7848,5745],{"class":5726},[5705,7850,5749],{"class":5748},[5705,7852,6138],{"class":5726},[5705,7854,7855],{"class":5707,"line":5791},[5705,7856,6144],{"class":5726},[5705,7858,7859],{"class":5707,"line":5798},[5705,7860,5795],{"emptyLinePlaceholder":5794},[5705,7862,7863,7865,7868,7871,7874,7877,7879,7881,7883],{"class":5707,"line":5804},[5705,7864,5719],{"class":5718},[5705,7866,7867],{"class":5722}," UserProfile",[5705,7869,7870],{"class":5726},"({ ",[5705,7872,7873],{"class":5741},"userId",[5705,7875,7876],{"class":5726}," }: { ",[5705,7878,7873],{"class":5741},[5705,7880,5745],{"class":5726},[5705,7882,5786],{"class":5748},[5705,7884,7885],{"class":5726}," }) {\n",[5705,7887,7888,7890,7892,7894,7896,7899,7901,7903,7905,7907,7909,7911,7913,7916],{"class":5707,"line":5818},[5705,7889,5907],{"class":5718},[5705,7891,5958],{"class":5726},[5705,7893,5621],{"class":5741},[5705,7895,5745],{"class":5726},[5705,7897,7898],{"class":5913},"user",[5705,7900,5580],{"class":5726},[5705,7902,7265],{"class":5913},[5705,7904,5580],{"class":5726},[5705,7906,5618],{"class":5913},[5705,7908,7365],{"class":5726},[5705,7910,5885],{"class":5722},[5705,7912,5763],{"class":5726},[5705,7914,7915],{"class":5748},"User",[5705,7917,7918],{"class":5726},">(\n",[5705,7920,7921,7924,7926,7928,7930],{"class":5707,"line":6031},[5705,7922,7923],{"class":6019},"    `https:\u002F\u002Fapi.example.com\u002Fusers\u002F",[5705,7925,6570],{"class":5718},[5705,7927,7873],{"class":5741},[5705,7929,6587],{"class":5718},[5705,7931,7932],{"class":6019},"`\n",[5705,7934,7935],{"class":5707,"line":6052},[5705,7936,6628],{"class":5726},[5705,7938,7939],{"class":5707,"line":6057},[5705,7940,5795],{"emptyLinePlaceholder":5794},[5705,7942,7943,7946,7948,7950],{"class":5707,"line":6072},[5705,7944,7945],{"class":6060},"  if",[5705,7947,7055],{"class":5726},[5705,7949,7265],{"class":5741},[5705,7951,7479],{"class":5726},[5705,7953,7954,7956,7959,7961,7963,7965,7968,7970,7973,7975,7977,7979],{"class":5707,"line":6093},[5705,7955,6061],{"class":6060},[5705,7957,7958],{"class":6549}," \u003C",[5705,7960,6554],{"class":6553},[5705,7962,6558],{"class":6557},[5705,7964,6561],{"class":5726},[5705,7966,7967],{"class":6019},"\"spinner\"",[5705,7969,6780],{"class":6549},[5705,7971,7972],{"class":5726},"Завантаження...",[5705,7974,6803],{"class":6549},[5705,7976,6554],{"class":6553},[5705,7978,6780],{"class":6549},[5705,7980,6138],{"class":5726},[5705,7982,7983],{"class":5707,"line":6112},[5705,7984,6940],{"class":5726},[5705,7986,7987],{"class":5707,"line":6118},[5705,7988,5795],{"emptyLinePlaceholder":5794},[5705,7990,7991,7993,7995,7997],{"class":5707,"line":6124},[5705,7992,7945],{"class":6060},[5705,7994,7055],{"class":5726},[5705,7996,5618],{"class":5741},[5705,7998,7479],{"class":5726},[5705,8000,8001,8003,8005,8007,8009,8011,8014,8016,8019,8021,8023,8025,8027,8029,8031],{"class":5707,"line":6129},[5705,8002,6061],{"class":6060},[5705,8004,7958],{"class":6549},[5705,8006,6554],{"class":6553},[5705,8008,6558],{"class":6557},[5705,8010,6561],{"class":5726},[5705,8012,8013],{"class":6019},"\"error\"",[5705,8015,6780],{"class":6549},[5705,8017,8018],{"class":5726},"Помилка: ",[5705,8020,6564],{"class":5718},[5705,8022,5618],{"class":5741},[5705,8024,6587],{"class":5718},[5705,8026,6803],{"class":6549},[5705,8028,6554],{"class":6553},[5705,8030,6780],{"class":6549},[5705,8032,6138],{"class":5726},[5705,8034,8035],{"class":5707,"line":6141},[5705,8036,6940],{"class":5726},[5705,8038,8039],{"class":5707,"line":6389},[5705,8040,5795],{"emptyLinePlaceholder":5794},[5705,8042,8043,8045,8047,8049],{"class":5707,"line":6408},[5705,8044,7945],{"class":6060},[5705,8046,7468],{"class":5726},[5705,8048,7898],{"class":5741},[5705,8050,7479],{"class":5726},[5705,8052,8053,8055,8057,8059,8061,8064,8066,8068,8070],{"class":5707,"line":6413},[5705,8054,6061],{"class":6060},[5705,8056,7958],{"class":6549},[5705,8058,6554],{"class":6553},[5705,8060,6780],{"class":6549},[5705,8062,8063],{"class":5726},"Користувача не знайдено",[5705,8065,6803],{"class":6549},[5705,8067,6554],{"class":6553},[5705,8069,6780],{"class":6549},[5705,8071,6138],{"class":5726},[5705,8073,8074],{"class":5707,"line":6419},[5705,8075,6940],{"class":5726},[5705,8077,8078],{"class":5707,"line":6430},[5705,8079,5795],{"emptyLinePlaceholder":5794},[5705,8081,8082,8084],{"class":5707,"line":6449},[5705,8083,6132],{"class":6060},[5705,8085,6544],{"class":5726},[5705,8087,8088,8090,8092,8094,8096,8099],{"class":5707,"line":6468},[5705,8089,6550],{"class":6549},[5705,8091,6554],{"class":6553},[5705,8093,6558],{"class":6557},[5705,8095,6561],{"class":5726},[5705,8097,8098],{"class":6019},"\"user-card\"",[5705,8100,6595],{"class":6549},[5705,8102,8103,8105,8107,8109,8111,8113,8115,8117,8119,8121,8123],{"class":5707,"line":6473},[5705,8104,6775],{"class":6549},[5705,8106,5570],{"class":6553},[5705,8108,6780],{"class":6549},[5705,8110,6564],{"class":5718},[5705,8112,7898],{"class":5741},[5705,8114,5622],{"class":7502},[5705,8116,7612],{"class":5741},[5705,8118,6587],{"class":5718},[5705,8120,6803],{"class":6549},[5705,8122,5570],{"class":6553},[5705,8124,6595],{"class":6549},[5705,8126,8127,8129,8131,8133,8135,8137,8139,8142,8144,8146,8148],{"class":5707,"line":6482},[5705,8128,6775],{"class":6549},[5705,8130,5479],{"class":6553},[5705,8132,6780],{"class":6549},[5705,8134,6564],{"class":5718},[5705,8136,7898],{"class":5741},[5705,8138,5622],{"class":7502},[5705,8140,8141],{"class":5741},"email",[5705,8143,6587],{"class":5718},[5705,8145,6803],{"class":6549},[5705,8147,5479],{"class":6553},[5705,8149,6595],{"class":6549},[5705,8151,8152,8154,8156],{"class":5707,"line":6487},[5705,8153,6619],{"class":6549},[5705,8155,6554],{"class":6553},[5705,8157,6595],{"class":6549},[5705,8159,8160],{"class":5707,"line":6496},[5705,8161,6628],{"class":5726},[5705,8163,8164],{"class":5707,"line":7008},[5705,8165,6144],{"class":5726},[5644,8167,8168,8179],{},[5479,8169,8170],{},[5483,8171,8172,8173,8175,8176,8178],{},"Чому ",[5535,8174,5885],{}," краще за звичайний ",[5535,8177,5583],{}," у компоненті:",[6642,8180,8181,8191,8199,8211],{},[5506,8182,8183,8186,8187,8190],{},[5483,8184,8185],{},"DRY-принцип:"," Логіка ",[5535,8188,8189],{},"fetch"," не дублюється у кожному компоненті.",[5506,8192,8193,5486,8196,8198],{},[5483,8194,8195],{},"Безпека:",[5535,8197,7091],{}," автоматично скасовує застарілі запити — запобігає race conditions.",[5506,8200,8201,8204,8205,8207,8208,5622],{},[5483,8202,8203],{},"Типізація:"," TypeScript знає структуру ",[5535,8206,5621],{}," завдяки дженерику ",[5535,8209,8210],{},"\u003CUser>",[5506,8212,8213,8216,8217,5580,8219,5580,8221,8223],{},[5483,8214,8215],{},"Стандартизація:"," Усі компоненти обробляють стани ",[5535,8218,5615],{},[5535,8220,5618],{},[5535,8222,5621],{}," однаково.",[5567,8225],{},[5570,8227,8229,8230],{"id":8228},"хук-синхронізації-з-localstorage-uselocalstorage","Хук синхронізації з localStorage: ",[5535,8231,5888],{},[5479,8233,8234,8235,8237],{},"Створимо хук, що зберігає стан у ",[5535,8236,5628],{}," та автоматично синхронізує його між вкладками браузера.",[5685,8239,7095,8241],{"id":8240},"реалізація-uselocalstorage",[5535,8242,5888],{},[5696,8244,8246],{"className":5698,"code":8245,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from \"react\";\n\nexport function useLocalStorage\u003CT>(\n  key: string,\n  initialValue: T\n): [T, (value: T | ((prev: T) => T)) => void] {\n  \u002F\u002F Ініціалізація стану: спочатку читаємо з localStorage\n  const [storedValue, setStoredValue] = useState\u003CT>(() => {\n    try {\n      const item = window.localStorage.getItem(key);\n      return item ? (JSON.parse(item) as T) : initialValue;\n    } catch (error) {\n      console.error(`Помилка читання з localStorage (ключ: ${key}):`, error);\n      return initialValue;\n    }\n  });\n\n  \u002F\u002F Функція оновлення стану з записом у localStorage\n  const setValue = (value: T | ((prev: T) => T)) => {\n    try {\n      \u002F\u002F Підтримка функціонального оновлення\n      const valueToStore = value instanceof Function ? value(storedValue) : value;\n\n      setStoredValue(valueToStore);\n\n      \u002F\u002F Записуємо у localStorage\n      window.localStorage.setItem(key, JSON.stringify(valueToStore));\n    } catch (error) {\n      console.error(`Помилка запису у localStorage (ключ: ${key}):`, error);\n    }\n  };\n\n  \u002F\u002F Синхронізація між вкладками браузера\n  useEffect(() => {\n    function handleStorageChange(event: StorageEvent) {\n      if (event.key === key && event.newValue !== null) {\n        try {\n          setStoredValue(JSON.parse(event.newValue) as T);\n        } catch (error) {\n          console.error(\"Помилка парсингу події storage:\", error);\n        }\n      }\n    }\n\n    window.addEventListener(\"storage\", handleStorageChange);\n\n    return () => {\n      window.removeEventListener(\"storage\", handleStorageChange);\n    };\n  }, [key]);\n\n  return [storedValue, setValue];\n}\n",[5535,8247,8248,8268,8272,8287,8299,8309,8354,8359,8388,8395,8424,8462,8475,8504,8513,8517,8522,8526,8531,8567,8573,8578,8609,8613,8625,8629,8634,8667,8679,8706,8710,8715,8719,8724,8734,8753,8786,8793,8822,8835,8855,8859,8863,8867,8871,8891,8895,8905,8923,8927,8936,8940,8956],{"__ignoreMap":5701},[5705,8249,8250,8252,8254,8256,8258,8260,8262,8264,8266],{"class":5707,"line":5708},[5705,8251,6214],{"class":6060},[5705,8253,5958],{"class":5726},[5705,8255,5579],{"class":5741},[5705,8257,5580],{"class":5726},[5705,8259,5583],{"class":5741},[5705,8261,6225],{"class":5726},[5705,8263,6228],{"class":6060},[5705,8265,6231],{"class":6019},[5705,8267,6138],{"class":5726},[5705,8269,8270],{"class":5707,"line":5715},[5705,8271,5795],{"emptyLinePlaceholder":5794},[5705,8273,8274,8276,8278,8281,8283,8285],{"class":5707,"line":5730},[5705,8275,6242],{"class":6060},[5705,8277,6245],{"class":5718},[5705,8279,8280],{"class":5722}," useLocalStorage",[5705,8282,5763],{"class":5726},[5705,8284,5766],{"class":5748},[5705,8286,7918],{"class":5726},[5705,8288,8289,8292,8294,8296],{"class":5707,"line":5755},[5705,8290,8291],{"class":5741},"  key",[5705,8293,5745],{"class":5726},[5705,8295,5749],{"class":5748},[5705,8297,8298],{"class":5726},",\n",[5705,8300,8301,8304,8306],{"class":5707,"line":5791},[5705,8302,8303],{"class":5741},"  initialValue",[5705,8305,5745],{"class":5726},[5705,8307,8308],{"class":5748},"T\n",[5705,8310,8311,8314,8316,8319,8321,8323,8325,8328,8331,8333,8335,8338,8340,8343,8346,8348,8351],{"class":5707,"line":5798},[5705,8312,8313],{"class":5726},"): [",[5705,8315,5766],{"class":5748},[5705,8317,8318],{"class":5726},", (",[5705,8320,5772],{"class":5741},[5705,8322,5745],{"class":5726},[5705,8324,5766],{"class":5748},[5705,8326,8327],{"class":5726}," | ((",[5705,8329,8330],{"class":5741},"prev",[5705,8332,5745],{"class":5726},[5705,8334,5766],{"class":5748},[5705,8336,8337],{"class":5726},") ",[5705,8339,5955],{"class":5718},[5705,8341,8342],{"class":5748}," T",[5705,8344,8345],{"class":5726},")) ",[5705,8347,5955],{"class":5718},[5705,8349,8350],{"class":5748}," void",[5705,8352,8353],{"class":5726},"] {\n",[5705,8355,8356],{"class":5707,"line":5804},[5705,8357,8358],{"class":5711},"  \u002F\u002F Ініціалізація стану: спочатку читаємо з localStorage\n",[5705,8360,8361,8363,8365,8368,8370,8373,8375,8377,8379,8381,8384,8386],{"class":5707,"line":5818},[5705,8362,5907],{"class":5718},[5705,8364,5910],{"class":5726},[5705,8366,8367],{"class":5913},"storedValue",[5705,8369,5580],{"class":5726},[5705,8371,8372],{"class":5913},"setStoredValue",[5705,8374,5922],{"class":5726},[5705,8376,5579],{"class":5722},[5705,8378,5763],{"class":5726},[5705,8380,5766],{"class":5748},[5705,8382,8383],{"class":5726},">(() ",[5705,8385,5955],{"class":5718},[5705,8387,6069],{"class":5726},[5705,8389,8390,8393],{"class":5707,"line":6031},[5705,8391,8392],{"class":6060},"    try",[5705,8394,6069],{"class":5726},[5705,8396,8397,8400,8403,8405,8408,8410,8412,8414,8417,8419,8422],{"class":5707,"line":6052},[5705,8398,8399],{"class":5718},"      const",[5705,8401,8402],{"class":5913}," item",[5705,8404,6525],{"class":5726},[5705,8406,8407],{"class":5741},"window",[5705,8409,5622],{"class":5726},[5705,8411,5628],{"class":5741},[5705,8413,5622],{"class":5726},[5705,8415,8416],{"class":5722},"getItem",[5705,8418,5738],{"class":5726},[5705,8420,8421],{"class":5741},"key",[5705,8423,6028],{"class":5726},[5705,8425,8426,8429,8431,8434,8437,8439,8442,8444,8447,8449,8452,8454,8457,8460],{"class":5707,"line":6057},[5705,8427,8428],{"class":6060},"      return",[5705,8430,8402],{"class":5741},[5705,8432,8433],{"class":5726}," ? (",[5705,8435,8436],{"class":5913},"JSON",[5705,8438,5622],{"class":5726},[5705,8440,8441],{"class":5722},"parse",[5705,8443,5738],{"class":5726},[5705,8445,8446],{"class":5741},"item",[5705,8448,8337],{"class":5726},[5705,8450,8451],{"class":6060},"as",[5705,8453,8342],{"class":5748},[5705,8455,8456],{"class":5726},") : ",[5705,8458,8459],{"class":5741},"initialValue",[5705,8461,6138],{"class":5726},[5705,8463,8464,8467,8469,8471,8473],{"class":5707,"line":6072},[5705,8465,8466],{"class":5726},"    } ",[5705,8468,7577],{"class":6060},[5705,8470,7055],{"class":5726},[5705,8472,5618],{"class":5741},[5705,8474,7479],{"class":5726},[5705,8476,8477,8480,8482,8484,8486,8489,8491,8493,8495,8498,8500,8502],{"class":5707,"line":6093},[5705,8478,8479],{"class":5741},"      console",[5705,8481,5622],{"class":5726},[5705,8483,5618],{"class":5722},[5705,8485,5738],{"class":5726},[5705,8487,8488],{"class":6019},"`Помилка читання з localStorage (ключ: ",[5705,8490,6570],{"class":5718},[5705,8492,8421],{"class":5741},[5705,8494,6587],{"class":5718},[5705,8496,8497],{"class":6019},"):`",[5705,8499,5580],{"class":5726},[5705,8501,5618],{"class":5741},[5705,8503,6028],{"class":5726},[5705,8505,8506,8508,8511],{"class":5707,"line":6112},[5705,8507,8428],{"class":6060},[5705,8509,8510],{"class":5741}," initialValue",[5705,8512,6138],{"class":5726},[5705,8514,8515],{"class":5707,"line":6118},[5705,8516,6333],{"class":5726},[5705,8518,8519],{"class":5707,"line":6124},[5705,8520,8521],{"class":5726},"  });\n",[5705,8523,8524],{"class":5707,"line":6129},[5705,8525,5795],{"emptyLinePlaceholder":5794},[5705,8527,8528],{"class":5707,"line":6141},[5705,8529,8530],{"class":5711},"  \u002F\u002F Функція оновлення стану з записом у localStorage\n",[5705,8532,8533,8535,8538,8541,8543,8545,8547,8549,8551,8553,8555,8557,8559,8561,8563,8565],{"class":5707,"line":6389},[5705,8534,5907],{"class":5718},[5705,8536,8537],{"class":5722}," setValue",[5705,8539,8540],{"class":5726}," = (",[5705,8542,5772],{"class":5741},[5705,8544,5745],{"class":5726},[5705,8546,5766],{"class":5748},[5705,8548,8327],{"class":5726},[5705,8550,8330],{"class":5741},[5705,8552,5745],{"class":5726},[5705,8554,5766],{"class":5748},[5705,8556,8337],{"class":5726},[5705,8558,5955],{"class":5718},[5705,8560,8342],{"class":5748},[5705,8562,8345],{"class":5726},[5705,8564,5955],{"class":5718},[5705,8566,6069],{"class":5726},[5705,8568,8569,8571],{"class":5707,"line":6408},[5705,8570,8392],{"class":6060},[5705,8572,6069],{"class":5726},[5705,8574,8575],{"class":5707,"line":6413},[5705,8576,8577],{"class":5711},"      \u002F\u002F Підтримка функціонального оновлення\n",[5705,8579,8580,8582,8585,8587,8589,8591,8594,8597,8599,8601,8603,8605,8607],{"class":5707,"line":6419},[5705,8581,8399],{"class":5718},[5705,8583,8584],{"class":5913}," valueToStore",[5705,8586,6525],{"class":5726},[5705,8588,5772],{"class":5741},[5705,8590,7600],{"class":5718},[5705,8592,8593],{"class":5748}," Function",[5705,8595,8596],{"class":5726}," ? ",[5705,8598,5772],{"class":5722},[5705,8600,5738],{"class":5726},[5705,8602,8367],{"class":5741},[5705,8604,8456],{"class":5726},[5705,8606,5772],{"class":5741},[5705,8608,6138],{"class":5726},[5705,8610,8611],{"class":5707,"line":6430},[5705,8612,5795],{"emptyLinePlaceholder":5794},[5705,8614,8615,8618,8620,8623],{"class":5707,"line":6449},[5705,8616,8617],{"class":5722},"      setStoredValue",[5705,8619,5738],{"class":5726},[5705,8621,8622],{"class":5741},"valueToStore",[5705,8624,6028],{"class":5726},[5705,8626,8627],{"class":5707,"line":6468},[5705,8628,5795],{"emptyLinePlaceholder":5794},[5705,8630,8631],{"class":5707,"line":6473},[5705,8632,8633],{"class":5711},"      \u002F\u002F Записуємо у localStorage\n",[5705,8635,8636,8638,8640,8642,8644,8647,8649,8651,8653,8655,8657,8660,8662,8664],{"class":5707,"line":6482},[5705,8637,6075],{"class":5741},[5705,8639,5622],{"class":5726},[5705,8641,5628],{"class":5741},[5705,8643,5622],{"class":5726},[5705,8645,8646],{"class":5722},"setItem",[5705,8648,5738],{"class":5726},[5705,8650,8421],{"class":5741},[5705,8652,5580],{"class":5726},[5705,8654,8436],{"class":5913},[5705,8656,5622],{"class":5726},[5705,8658,8659],{"class":5722},"stringify",[5705,8661,5738],{"class":5726},[5705,8663,8622],{"class":5741},[5705,8665,8666],{"class":5726},"));\n",[5705,8668,8669,8671,8673,8675,8677],{"class":5707,"line":6487},[5705,8670,8466],{"class":5726},[5705,8672,7577],{"class":6060},[5705,8674,7055],{"class":5726},[5705,8676,5618],{"class":5741},[5705,8678,7479],{"class":5726},[5705,8680,8681,8683,8685,8687,8689,8692,8694,8696,8698,8700,8702,8704],{"class":5707,"line":6496},[5705,8682,8479],{"class":5741},[5705,8684,5622],{"class":5726},[5705,8686,5618],{"class":5722},[5705,8688,5738],{"class":5726},[5705,8690,8691],{"class":6019},"`Помилка запису у localStorage (ключ: ",[5705,8693,6570],{"class":5718},[5705,8695,8421],{"class":5741},[5705,8697,6587],{"class":5718},[5705,8699,8497],{"class":6019},[5705,8701,5580],{"class":5726},[5705,8703,5618],{"class":5741},[5705,8705,6028],{"class":5726},[5705,8707,8708],{"class":5707,"line":7008},[5705,8709,6333],{"class":5726},[5705,8711,8712],{"class":5707,"line":7014},[5705,8713,8714],{"class":5726},"  };\n",[5705,8716,8717],{"class":5707,"line":7020},[5705,8718,5795],{"emptyLinePlaceholder":5794},[5705,8720,8721],{"class":5707,"line":7026},[5705,8722,8723],{"class":5711},"  \u002F\u002F Синхронізація між вкладками браузера\n",[5705,8725,8726,8728,8730,8732],{"class":5707,"line":7032},[5705,8727,5949],{"class":5722},[5705,8729,5952],{"class":5726},[5705,8731,5955],{"class":5718},[5705,8733,6069],{"class":5726},[5705,8735,8736,8738,8741,8743,8746,8748,8751],{"class":5707,"line":7037},[5705,8737,5966],{"class":5718},[5705,8739,8740],{"class":5722}," handleStorageChange",[5705,8742,5738],{"class":5726},[5705,8744,8745],{"class":5741},"event",[5705,8747,5745],{"class":5726},[5705,8749,8750],{"class":5748},"StorageEvent",[5705,8752,7479],{"class":5726},[5705,8754,8755,8758,8760,8762,8764,8766,8769,8771,8773,8775,8777,8780,8782,8784],{"class":5707,"line":7639},[5705,8756,8757],{"class":6060},"      if",[5705,8759,7055],{"class":5726},[5705,8761,8745],{"class":5741},[5705,8763,5622],{"class":5726},[5705,8765,8421],{"class":5741},[5705,8767,8768],{"class":5726}," === ",[5705,8770,8421],{"class":5741},[5705,8772,7605],{"class":5726},[5705,8774,8745],{"class":5741},[5705,8776,5622],{"class":5726},[5705,8778,8779],{"class":5741},"newValue",[5705,8781,7615],{"class":5726},[5705,8783,7157],{"class":5718},[5705,8785,7479],{"class":5726},[5705,8787,8788,8791],{"class":5707,"line":7644},[5705,8789,8790],{"class":6060},"        try",[5705,8792,6069],{"class":5726},[5705,8794,8795,8798,8800,8802,8804,8806,8808,8810,8812,8814,8816,8818,8820],{"class":5707,"line":7654},[5705,8796,8797],{"class":5722},"          setStoredValue",[5705,8799,5738],{"class":5726},[5705,8801,8436],{"class":5913},[5705,8803,5622],{"class":5726},[5705,8805,8441],{"class":5722},[5705,8807,5738],{"class":5726},[5705,8809,8745],{"class":5741},[5705,8811,5622],{"class":5726},[5705,8813,8779],{"class":5741},[5705,8815,8337],{"class":5726},[5705,8817,8451],{"class":6060},[5705,8819,8342],{"class":5748},[5705,8821,6028],{"class":5726},[5705,8823,8824,8827,8829,8831,8833],{"class":5707,"line":7660},[5705,8825,8826],{"class":5726},"        } ",[5705,8828,7577],{"class":6060},[5705,8830,7055],{"class":5726},[5705,8832,5618],{"class":5741},[5705,8834,7479],{"class":5726},[5705,8836,8837,8840,8842,8844,8846,8849,8851,8853],{"class":5707,"line":7676},[5705,8838,8839],{"class":5741},"          console",[5705,8841,5622],{"class":5726},[5705,8843,5618],{"class":5722},[5705,8845,5738],{"class":5726},[5705,8847,8848],{"class":6019},"\"Помилка парсингу події storage:\"",[5705,8850,5580],{"class":5726},[5705,8852,5618],{"class":5741},[5705,8854,6028],{"class":5726},[5705,8856,8857],{"class":5707,"line":7688},[5705,8858,7529],{"class":5726},[5705,8860,8861],{"class":5707,"line":7693},[5705,8862,7696],{"class":5726},[5705,8864,8865],{"class":5707,"line":7699},[5705,8866,6333],{"class":5726},[5705,8868,8869],{"class":5707,"line":7704},[5705,8870,5795],{"emptyLinePlaceholder":5794},[5705,8872,8873,8875,8877,8879,8881,8884,8886,8889],{"class":5707,"line":7709},[5705,8874,6009],{"class":5741},[5705,8876,5622],{"class":5726},[5705,8878,6014],{"class":5722},[5705,8880,5738],{"class":5726},[5705,8882,8883],{"class":6019},"\"storage\"",[5705,8885,5580],{"class":5726},[5705,8887,8888],{"class":5741},"handleStorageChange",[5705,8890,6028],{"class":5726},[5705,8892,8893],{"class":5707,"line":7717},[5705,8894,5795],{"emptyLinePlaceholder":5794},[5705,8896,8897,8899,8901,8903],{"class":5707,"line":7722},[5705,8898,6061],{"class":6060},[5705,8900,6064],{"class":5726},[5705,8902,5955],{"class":5718},[5705,8904,6069],{"class":5726},[5705,8906,8907,8909,8911,8913,8915,8917,8919,8921],{"class":5707,"line":7728},[5705,8908,6075],{"class":5741},[5705,8910,5622],{"class":5726},[5705,8912,6080],{"class":5722},[5705,8914,5738],{"class":5726},[5705,8916,8883],{"class":6019},[5705,8918,5580],{"class":5726},[5705,8920,8888],{"class":5741},[5705,8922,6028],{"class":5726},[5705,8924,8925],{"class":5707,"line":7739},[5705,8926,6115],{"class":5726},[5705,8928,8929,8931,8933],{"class":5707,"line":7752},[5705,8930,7760],{"class":5726},[5705,8932,8421],{"class":5741},[5705,8934,8935],{"class":5726},"]);\n",[5705,8937,8938],{"class":5707,"line":7757},[5705,8939,5795],{"emptyLinePlaceholder":5794},[5705,8941,8942,8944,8946,8948,8950,8953],{"class":5707,"line":7771},[5705,8943,6132],{"class":6060},[5705,8945,5910],{"class":5726},[5705,8947,8367],{"class":5741},[5705,8949,5580],{"class":5726},[5705,8951,8952],{"class":5741},"setValue",[5705,8954,8955],{"class":5726},"];\n",[5705,8957,8958],{"class":5707,"line":7776},[5705,8959,6144],{"class":5726},[5685,8961,7802,8963],{"id":8962},"використання-uselocalstorage",[5535,8964,5888],{},[5696,8966,8968],{"className":5698,"code":8967,"language":5700,"meta":5701,"style":5701},"function ThemeSelector() {\n  const [theme, setTheme] = useLocalStorage\u003C\"light\" | \"dark\">(\"theme\", \"light\");\n\n  function toggleTheme() {\n    setTheme((prevTheme) => (prevTheme === \"light\" ? \"dark\" : \"light\"));\n  }\n\n  return (\n    \u003Cdiv className={`app ${theme}`}>\n      \u003Cbutton onClick={toggleTheme}>\n        {theme === \"light\" ? \"🌙 Темна тема\" : \"☀️ Світла тема\"}\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,8969,8970,8979,9018,9022,9032,9066,9070,9074,9080,9107,9128,9153,9162,9170,9174],{"__ignoreMap":5701},[5705,8971,8972,8974,8977],{"class":5707,"line":5708},[5705,8973,5719],{"class":5718},[5705,8975,8976],{"class":5722}," ThemeSelector",[5705,8978,5902],{"class":5726},[5705,8980,8981,8983,8985,8988,8990,8993,8995,8997,8999,9002,9004,9007,9009,9012,9014,9016],{"class":5707,"line":5715},[5705,8982,5907],{"class":5718},[5705,8984,5910],{"class":5726},[5705,8986,8987],{"class":5913},"theme",[5705,8989,5580],{"class":5726},[5705,8991,8992],{"class":5913},"setTheme",[5705,8994,5922],{"class":5726},[5705,8996,5888],{"class":5722},[5705,8998,5763],{"class":5726},[5705,9000,9001],{"class":6019},"\"light\"",[5705,9003,7154],{"class":5726},[5705,9005,9006],{"class":6019},"\"dark\"",[5705,9008,5769],{"class":5726},[5705,9010,9011],{"class":6019},"\"theme\"",[5705,9013,5580],{"class":5726},[5705,9015,9001],{"class":6019},[5705,9017,6028],{"class":5726},[5705,9019,9020],{"class":5707,"line":5730},[5705,9021,5795],{"emptyLinePlaceholder":5794},[5705,9023,9024,9027,9030],{"class":5707,"line":5755},[5705,9025,9026],{"class":5718},"  function",[5705,9028,9029],{"class":5722}," toggleTheme",[5705,9031,5902],{"class":5726},[5705,9033,9034,9037,9040,9043,9045,9047,9049,9051,9053,9055,9057,9059,9062,9064],{"class":5707,"line":5791},[5705,9035,9036],{"class":5722},"    setTheme",[5705,9038,9039],{"class":5726},"((",[5705,9041,9042],{"class":5741},"prevTheme",[5705,9044,8337],{"class":5726},[5705,9046,5955],{"class":5718},[5705,9048,7055],{"class":5726},[5705,9050,9042],{"class":5741},[5705,9052,8768],{"class":5726},[5705,9054,9001],{"class":6019},[5705,9056,8596],{"class":5726},[5705,9058,9006],{"class":6019},[5705,9060,9061],{"class":5726}," : ",[5705,9063,9001],{"class":6019},[5705,9065,8666],{"class":5726},[5705,9067,9068],{"class":5707,"line":5798},[5705,9069,6940],{"class":5726},[5705,9071,9072],{"class":5707,"line":5804},[5705,9073,5795],{"emptyLinePlaceholder":5794},[5705,9075,9076,9078],{"class":5707,"line":5818},[5705,9077,6132],{"class":6060},[5705,9079,6544],{"class":5726},[5705,9081,9082,9084,9086,9088,9090,9092,9095,9097,9099,9101,9103,9105],{"class":5707,"line":6031},[5705,9083,6550],{"class":6549},[5705,9085,6554],{"class":6553},[5705,9087,6558],{"class":6557},[5705,9089,6561],{"class":5726},[5705,9091,6564],{"class":5718},[5705,9093,9094],{"class":6019},"`app ",[5705,9096,6570],{"class":5718},[5705,9098,8987],{"class":5741},[5705,9100,6587],{"class":5718},[5705,9102,6590],{"class":6019},[5705,9104,6587],{"class":5718},[5705,9106,6595],{"class":6549},[5705,9108,9109,9111,9114,9117,9119,9121,9124,9126],{"class":5707,"line":6052},[5705,9110,6775],{"class":6549},[5705,9112,9113],{"class":6553},"button",[5705,9115,9116],{"class":6557}," onClick",[5705,9118,6561],{"class":5726},[5705,9120,6564],{"class":5718},[5705,9122,9123],{"class":5741},"toggleTheme",[5705,9125,6587],{"class":5718},[5705,9127,6595],{"class":6549},[5705,9129,9130,9133,9135,9138,9141,9143,9146,9148,9151],{"class":5707,"line":6057},[5705,9131,9132],{"class":5718},"        {",[5705,9134,8987],{"class":5741},[5705,9136,9137],{"class":5726}," ===",[5705,9139,9140],{"class":6019}," \"light\"",[5705,9142,6575],{"class":5726},[5705,9144,9145],{"class":6019}," \"🌙 Темна тема\"",[5705,9147,6581],{"class":5726},[5705,9149,9150],{"class":6019}," \"☀️ Світла тема\"",[5705,9152,6144],{"class":5718},[5705,9154,9155,9158,9160],{"class":5707,"line":6072},[5705,9156,9157],{"class":6549},"      \u003C\u002F",[5705,9159,9113],{"class":6553},[5705,9161,6595],{"class":6549},[5705,9163,9164,9166,9168],{"class":5707,"line":6093},[5705,9165,6619],{"class":6549},[5705,9167,6554],{"class":6553},[5705,9169,6595],{"class":6549},[5705,9171,9172],{"class":5707,"line":6112},[5705,9173,6628],{"class":5726},[5705,9175,9176],{"class":5707,"line":6118},[5705,9177,6144],{"class":5726},[6634,9179,9180,9185],{},[5479,9181,9182],{},[5483,9183,9184],{},"Магія синхронізації між вкладками:",[5479,9186,9187,9188,9191],{},"Коли користувач змінює тему в одній вкладці, подія ",[5535,9189,9190],{},"storage"," автоматично спрацьовує в усіх інших відкритих вкладках того самого домену. Хук підписується на цю подію і оновлює стан — тема змінюється у всіх вкладках миттєво, без запитів до сервера.",[5567,9193],{},[5570,9195,9197,9198],{"id":9196},"хук-відкладеного-виклику-usedebounce","Хук відкладеного виклику: ",[5535,9199,9200],{},"useDebounce",[5479,9202,9203,9204,9207],{},"При введенні тексту у пошукове поле не варто викликати API після кожного натискання клавіші — це створить сотні зайвих запитів. ",[5483,9205,9206],{},"Debounce"," відкладає виконання функції до моменту, коли користувач припинить вводити текст на певний час.",[5685,9209,7095,9211],{"id":9210},"реалізація-usedebounce",[5535,9212,9200],{},[5696,9214,9216],{"className":5698,"code":9215,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from \"react\";\n\nexport function useDebounce\u003CT>(value: T, delay: number): T {\n  const [debouncedValue, setDebouncedValue] = useState\u003CT>(value);\n\n  useEffect(() => {\n    \u002F\u002F Створюємо таймер, що оновить debouncedValue через delay мілісекунд\n    const timerId = setTimeout(() => {\n      setDebouncedValue(value);\n    }, delay);\n\n    \u002F\u002F Очищаємо таймер при кожній зміні value (користувач продовжує вводити)\n    return () => {\n      clearTimeout(timerId);\n    };\n  }, [value, delay]);\n\n  return debouncedValue;\n}\n",[5535,9217,9218,9238,9242,9276,9304,9308,9318,9323,9341,9352,9361,9365,9370,9380,9392,9396,9408,9412,9421],{"__ignoreMap":5701},[5705,9219,9220,9222,9224,9226,9228,9230,9232,9234,9236],{"class":5707,"line":5708},[5705,9221,6214],{"class":6060},[5705,9223,5958],{"class":5726},[5705,9225,5579],{"class":5741},[5705,9227,5580],{"class":5726},[5705,9229,5583],{"class":5741},[5705,9231,6225],{"class":5726},[5705,9233,6228],{"class":6060},[5705,9235,6231],{"class":6019},[5705,9237,6138],{"class":5726},[5705,9239,9240],{"class":5707,"line":5715},[5705,9241,5795],{"emptyLinePlaceholder":5794},[5705,9243,9244,9246,9248,9250,9252,9254,9256,9258,9260,9262,9264,9266,9268,9270,9272,9274],{"class":5707,"line":5730},[5705,9245,6242],{"class":6060},[5705,9247,6245],{"class":5718},[5705,9249,5760],{"class":5722},[5705,9251,5763],{"class":5726},[5705,9253,5766],{"class":5748},[5705,9255,5769],{"class":5726},[5705,9257,5772],{"class":5741},[5705,9259,5745],{"class":5726},[5705,9261,5766],{"class":5748},[5705,9263,5580],{"class":5726},[5705,9265,5781],{"class":5741},[5705,9267,5745],{"class":5726},[5705,9269,5786],{"class":5748},[5705,9271,7216],{"class":5726},[5705,9273,5766],{"class":5748},[5705,9275,6069],{"class":5726},[5705,9277,9278,9280,9282,9285,9287,9290,9292,9294,9296,9298,9300,9302],{"class":5707,"line":5755},[5705,9279,5907],{"class":5718},[5705,9281,5910],{"class":5726},[5705,9283,9284],{"class":5913},"debouncedValue",[5705,9286,5580],{"class":5726},[5705,9288,9289],{"class":5913},"setDebouncedValue",[5705,9291,5922],{"class":5726},[5705,9293,5579],{"class":5722},[5705,9295,5763],{"class":5726},[5705,9297,5766],{"class":5748},[5705,9299,5769],{"class":5726},[5705,9301,5772],{"class":5741},[5705,9303,6028],{"class":5726},[5705,9305,9306],{"class":5707,"line":5791},[5705,9307,5795],{"emptyLinePlaceholder":5794},[5705,9309,9310,9312,9314,9316],{"class":5707,"line":5798},[5705,9311,5949],{"class":5722},[5705,9313,5952],{"class":5726},[5705,9315,5955],{"class":5718},[5705,9317,6069],{"class":5726},[5705,9319,9320],{"class":5707,"line":5804},[5705,9321,9322],{"class":5711},"    \u002F\u002F Створюємо таймер, що оновить debouncedValue через delay мілісекунд\n",[5705,9324,9325,9327,9330,9332,9335,9337,9339],{"class":5707,"line":5818},[5705,9326,7339],{"class":5718},[5705,9328,9329],{"class":5913}," timerId",[5705,9331,6525],{"class":5726},[5705,9333,9334],{"class":5722},"setTimeout",[5705,9336,5952],{"class":5726},[5705,9338,5955],{"class":5718},[5705,9340,6069],{"class":5726},[5705,9342,9343,9346,9348,9350],{"class":5707,"line":6031},[5705,9344,9345],{"class":5722},"      setDebouncedValue",[5705,9347,5738],{"class":5726},[5705,9349,5772],{"class":5741},[5705,9351,6028],{"class":5726},[5705,9353,9354,9357,9359],{"class":5707,"line":6052},[5705,9355,9356],{"class":5726},"    }, ",[5705,9358,5781],{"class":5741},[5705,9360,6028],{"class":5726},[5705,9362,9363],{"class":5707,"line":6057},[5705,9364,5795],{"emptyLinePlaceholder":5794},[5705,9366,9367],{"class":5707,"line":6072},[5705,9368,9369],{"class":5711},"    \u002F\u002F Очищаємо таймер при кожній зміні value (користувач продовжує вводити)\n",[5705,9371,9372,9374,9376,9378],{"class":5707,"line":6093},[5705,9373,6061],{"class":6060},[5705,9375,6064],{"class":5726},[5705,9377,5955],{"class":5718},[5705,9379,6069],{"class":5726},[5705,9381,9382,9385,9387,9390],{"class":5707,"line":6112},[5705,9383,9384],{"class":5722},"      clearTimeout",[5705,9386,5738],{"class":5726},[5705,9388,9389],{"class":5741},"timerId",[5705,9391,6028],{"class":5726},[5705,9393,9394],{"class":5707,"line":6118},[5705,9395,6115],{"class":5726},[5705,9397,9398,9400,9402,9404,9406],{"class":5707,"line":6124},[5705,9399,7760],{"class":5726},[5705,9401,5772],{"class":5741},[5705,9403,5580],{"class":5726},[5705,9405,5781],{"class":5741},[5705,9407,8935],{"class":5726},[5705,9409,9410],{"class":5707,"line":6129},[5705,9411,5795],{"emptyLinePlaceholder":5794},[5705,9413,9414,9416,9419],{"class":5707,"line":6141},[5705,9415,6132],{"class":6060},[5705,9417,9418],{"class":5741}," debouncedValue",[5705,9420,6138],{"class":5726},[5705,9422,9423],{"class":5707,"line":6389},[5705,9424,6144],{"class":5726},[5685,9426,7802,9428,9430],{"id":9427},"використання-usedebounce-для-пошуку",[5535,9429,9200],{}," для пошуку",[5696,9432,9434],{"className":5698,"code":9433,"language":5700,"meta":5701,"style":5701},"function SearchBar() {\n  const [searchQuery, setSearchQuery] = useState(\"\");\n  const debouncedQuery = useDebounce(searchQuery, 500); \u002F\u002F 500мс затримка\n\n  const { data: results, isLoading } = useFetch\u003Cstring[]>(\n    debouncedQuery\n      ? `https:\u002F\u002Fapi.example.com\u002Fsearch?q=${debouncedQuery}`\n      : \"\"\n  );\n\n  return (\n    \u003Cdiv>\n      \u003Cinput\n        type=\"text\"\n        value={searchQuery}\n        onChange={(e) => setSearchQuery(e.target.value)}\n        placeholder=\"Введіть запит...\"\n      \u002F>\n\n      {isLoading && \u003Cp>Пошук...\u003C\u002Fp>}\n\n      {results && (\n        \u003Cul>\n          {results.map((item, i) => (\n            \u003Cli key={i}>{item}\u003C\u002Fli>\n          ))}\n        \u003C\u002Ful>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,9435,9436,9445,9470,9496,9500,9528,9533,9550,9558,9562,9566,9572,9580,9587,9597,9610,9649,9659,9664,9668,9694,9698,9708,9717,9744,9776,9783,9792,9799,9807,9811],{"__ignoreMap":5701},[5705,9437,9438,9440,9443],{"class":5707,"line":5708},[5705,9439,5719],{"class":5718},[5705,9441,9442],{"class":5722}," SearchBar",[5705,9444,5902],{"class":5726},[5705,9446,9447,9449,9451,9454,9456,9459,9461,9463,9465,9468],{"class":5707,"line":5715},[5705,9448,5907],{"class":5718},[5705,9450,5910],{"class":5726},[5705,9452,9453],{"class":5913},"searchQuery",[5705,9455,5580],{"class":5726},[5705,9457,9458],{"class":5913},"setSearchQuery",[5705,9460,5922],{"class":5726},[5705,9462,5579],{"class":5722},[5705,9464,5738],{"class":5726},[5705,9466,9467],{"class":6019},"\"\"",[5705,9469,6028],{"class":5726},[5705,9471,9472,9474,9477,9479,9481,9483,9485,9487,9491,9493],{"class":5707,"line":5730},[5705,9473,5907],{"class":5718},[5705,9475,9476],{"class":5913}," debouncedQuery",[5705,9478,6525],{"class":5726},[5705,9480,9200],{"class":5722},[5705,9482,5738],{"class":5726},[5705,9484,9453],{"class":5741},[5705,9486,5580],{"class":5726},[5705,9488,9490],{"class":9489},"sJj4R","500",[5705,9492,5937],{"class":5726},[5705,9494,9495],{"class":5711},"\u002F\u002F 500мс затримка\n",[5705,9497,9498],{"class":5707,"line":5755},[5705,9499,5795],{"emptyLinePlaceholder":5794},[5705,9501,9502,9504,9506,9508,9510,9513,9515,9517,9519,9521,9523,9525],{"class":5707,"line":5791},[5705,9503,5907],{"class":5718},[5705,9505,5958],{"class":5726},[5705,9507,5621],{"class":5741},[5705,9509,5745],{"class":5726},[5705,9511,9512],{"class":5913},"results",[5705,9514,5580],{"class":5726},[5705,9516,7265],{"class":5913},[5705,9518,7365],{"class":5726},[5705,9520,5885],{"class":5722},[5705,9522,5763],{"class":5726},[5705,9524,5749],{"class":5748},[5705,9526,9527],{"class":5726},"[]>(\n",[5705,9529,9530],{"class":5707,"line":5798},[5705,9531,9532],{"class":5741},"    debouncedQuery\n",[5705,9534,9535,9538,9541,9543,9546,9548],{"class":5707,"line":5804},[5705,9536,9537],{"class":5726},"      ? ",[5705,9539,9540],{"class":6019},"`https:\u002F\u002Fapi.example.com\u002Fsearch?q=",[5705,9542,6570],{"class":5718},[5705,9544,9545],{"class":5741},"debouncedQuery",[5705,9547,6587],{"class":5718},[5705,9549,7932],{"class":6019},[5705,9551,9552,9555],{"class":5707,"line":5818},[5705,9553,9554],{"class":5726},"      : ",[5705,9556,9557],{"class":6019},"\"\"\n",[5705,9559,9560],{"class":5707,"line":6031},[5705,9561,6628],{"class":5726},[5705,9563,9564],{"class":5707,"line":6052},[5705,9565,5795],{"emptyLinePlaceholder":5794},[5705,9567,9568,9570],{"class":5707,"line":6057},[5705,9569,6132],{"class":6060},[5705,9571,6544],{"class":5726},[5705,9573,9574,9576,9578],{"class":5707,"line":6072},[5705,9575,6550],{"class":6549},[5705,9577,6554],{"class":6553},[5705,9579,6595],{"class":6549},[5705,9581,9582,9584],{"class":5707,"line":6093},[5705,9583,6775],{"class":6549},[5705,9585,9586],{"class":6553},"input\n",[5705,9588,9589,9592,9594],{"class":5707,"line":6112},[5705,9590,9591],{"class":6557},"        type",[5705,9593,6561],{"class":5726},[5705,9595,9596],{"class":6019},"\"text\"\n",[5705,9598,9599,9602,9604,9606,9608],{"class":5707,"line":6118},[5705,9600,9601],{"class":6557},"        value",[5705,9603,6561],{"class":5726},[5705,9605,6564],{"class":5718},[5705,9607,9453],{"class":5741},[5705,9609,6144],{"class":5718},[5705,9611,9612,9615,9617,9619,9621,9624,9626,9628,9631,9633,9635,9637,9640,9642,9644,9647],{"class":5707,"line":6124},[5705,9613,9614],{"class":6557},"        onChange",[5705,9616,6561],{"class":5726},[5705,9618,6564],{"class":5718},[5705,9620,5738],{"class":7502},[5705,9622,9623],{"class":5741},"e",[5705,9625,8337],{"class":7502},[5705,9627,5955],{"class":5718},[5705,9629,9630],{"class":5722}," setSearchQuery",[5705,9632,5738],{"class":7502},[5705,9634,9623],{"class":5741},[5705,9636,5622],{"class":7502},[5705,9638,9639],{"class":5741},"target",[5705,9641,5622],{"class":7502},[5705,9643,5772],{"class":5741},[5705,9645,9646],{"class":7502},")",[5705,9648,6144],{"class":5718},[5705,9650,9651,9654,9656],{"class":5707,"line":6129},[5705,9652,9653],{"class":6557},"        placeholder",[5705,9655,6561],{"class":5726},[5705,9657,9658],{"class":6019},"\"Введіть запит...\"\n",[5705,9660,9661],{"class":5707,"line":6141},[5705,9662,9663],{"class":6549},"      \u002F>\n",[5705,9665,9666],{"class":5707,"line":6389},[5705,9667,5795],{"emptyLinePlaceholder":5794},[5705,9669,9670,9672,9674,9677,9679,9681,9683,9686,9688,9690,9692],{"class":5707,"line":6408},[5705,9671,6600],{"class":5718},[5705,9673,7265],{"class":5741},[5705,9675,9676],{"class":5726}," &&",[5705,9678,7958],{"class":6549},[5705,9680,5479],{"class":6553},[5705,9682,6780],{"class":6549},[5705,9684,9685],{"class":7502},"Пошук...",[5705,9687,6803],{"class":6549},[5705,9689,5479],{"class":6553},[5705,9691,6780],{"class":6549},[5705,9693,6144],{"class":5718},[5705,9695,9696],{"class":5707,"line":6413},[5705,9697,5795],{"emptyLinePlaceholder":5794},[5705,9699,9700,9702,9704,9706],{"class":5707,"line":6419},[5705,9701,6600],{"class":5718},[5705,9703,9512],{"class":5741},[5705,9705,9676],{"class":5726},[5705,9707,6544],{"class":7502},[5705,9709,9710,9713,9715],{"class":5707,"line":6430},[5705,9711,9712],{"class":6549},"        \u003C",[5705,9714,5503],{"class":6553},[5705,9716,6595],{"class":6549},[5705,9718,9719,9722,9724,9726,9729,9731,9733,9735,9738,9740,9742],{"class":5707,"line":6449},[5705,9720,9721],{"class":5718},"          {",[5705,9723,9512],{"class":5741},[5705,9725,5622],{"class":7502},[5705,9727,9728],{"class":5722},"map",[5705,9730,9039],{"class":7502},[5705,9732,8446],{"class":5741},[5705,9734,5580],{"class":7502},[5705,9736,9737],{"class":5741},"i",[5705,9739,8337],{"class":7502},[5705,9741,5955],{"class":5718},[5705,9743,6544],{"class":7502},[5705,9745,9746,9749,9751,9754,9756,9758,9760,9762,9764,9766,9768,9770,9772,9774],{"class":5707,"line":6468},[5705,9747,9748],{"class":6549},"            \u003C",[5705,9750,5506],{"class":6553},[5705,9752,9753],{"class":6557}," key",[5705,9755,6561],{"class":5726},[5705,9757,6564],{"class":5718},[5705,9759,9737],{"class":5741},[5705,9761,6587],{"class":5718},[5705,9763,6780],{"class":6549},[5705,9765,6564],{"class":5718},[5705,9767,8446],{"class":5741},[5705,9769,6587],{"class":5718},[5705,9771,6803],{"class":6549},[5705,9773,5506],{"class":6553},[5705,9775,6595],{"class":6549},[5705,9777,9778,9781],{"class":5707,"line":6473},[5705,9779,9780],{"class":7502},"          ))",[5705,9782,6144],{"class":5718},[5705,9784,9785,9788,9790],{"class":5707,"line":6482},[5705,9786,9787],{"class":6549},"        \u003C\u002F",[5705,9789,5503],{"class":6553},[5705,9791,6595],{"class":6549},[5705,9793,9794,9797],{"class":5707,"line":6487},[5705,9795,9796],{"class":7502},"      )",[5705,9798,6144],{"class":5718},[5705,9800,9801,9803,9805],{"class":5707,"line":6496},[5705,9802,6619],{"class":6549},[5705,9804,6554],{"class":6553},[5705,9806,6595],{"class":6549},[5705,9808,9809],{"class":5707,"line":7008},[5705,9810,6628],{"class":5726},[5705,9812,9813],{"class":5707,"line":7014},[5705,9814,6144],{"class":5726},[6857,9816,9818],{"alt":9817},"Діаграма роботи useDebounce",[5696,9819,9821],{"className":6862,"code":9820,"language":6864,"meta":5701,"style":5701},"@startuml\nskinparam style plain\nskinparam backgroundColor #FFFFFF\n\nparticipant \"Користувач\" as User\nparticipant \"searchQuery (стан)\" as Query\nparticipant \"useDebounce\" as Debounce\nparticipant \"debouncedQuery (стан)\" as Debounced\nparticipant \"useFetch (API)\" as API\n\nUser -> Query : Введення \"r\"\nactivate Query\nQuery -> Debounce : value = \"r\"\nactivate Debounce\nDebounce -> Debounce : setTimeout(500ms)\nnote right: Таймер запущено\n\nUser -> Query : Введення \"re\" (через 100мс)\nQuery -> Debounce : value = \"re\"\nDebounce -> Debounce : clearTimeout()\\nsetTimeout(500ms)\nnote right: Старий таймер скасовано,\\nновий таймер запущено\n\nUser -> Query : Введення \"rea\" (через 150мс)\nQuery -> Debounce : value = \"rea\"\nDebounce -> Debounce : clearTimeout()\\nsetTimeout(500ms)\nnote right: Знову скасовано та перезапущено\n\nnote over User\n  Користувач припинив вводити\n  (минуло 500мс без змін)\nend note\n\nDebounce -> Debounced : setDebouncedValue(\"rea\")\nactivate Debounced\nDebounced -> API : fetch(\"\u002Fsearch?q=rea\")\nactivate API\nAPI --> Debounced : Результати пошуку\ndeactivate API\ndeactivate Debounced\ndeactivate Debounce\ndeactivate Query\n\n@enduml\n",[5535,9822,9823,9827,9831,9835,9839,9844,9849,9854,9859,9864,9868,9873,9878,9883,9888,9893,9898,9902,9907,9912,9917,9922,9926,9931,9936,9940,9945,9949,9954,9959,9964,9968,9972,9977,9982,9987,9992,9997,10002,10007,10012,10017,10021],{"__ignoreMap":5701},[5705,9824,9825],{"class":5707,"line":5708},[5705,9826,6871],{},[5705,9828,9829],{"class":5707,"line":5715},[5705,9830,6876],{},[5705,9832,9833],{"class":5707,"line":5730},[5705,9834,6881],{},[5705,9836,9837],{"class":5707,"line":5755},[5705,9838,5795],{"emptyLinePlaceholder":5794},[5705,9840,9841],{"class":5707,"line":5791},[5705,9842,9843],{},"participant \"Користувач\" as User\n",[5705,9845,9846],{"class":5707,"line":5798},[5705,9847,9848],{},"participant \"searchQuery (стан)\" as Query\n",[5705,9850,9851],{"class":5707,"line":5804},[5705,9852,9853],{},"participant \"useDebounce\" as Debounce\n",[5705,9855,9856],{"class":5707,"line":5818},[5705,9857,9858],{},"participant \"debouncedQuery (стан)\" as Debounced\n",[5705,9860,9861],{"class":5707,"line":6031},[5705,9862,9863],{},"participant \"useFetch (API)\" as API\n",[5705,9865,9866],{"class":5707,"line":6052},[5705,9867,5795],{"emptyLinePlaceholder":5794},[5705,9869,9870],{"class":5707,"line":6057},[5705,9871,9872],{},"User -> Query : Введення \"r\"\n",[5705,9874,9875],{"class":5707,"line":6072},[5705,9876,9877],{},"activate Query\n",[5705,9879,9880],{"class":5707,"line":6093},[5705,9881,9882],{},"Query -> Debounce : value = \"r\"\n",[5705,9884,9885],{"class":5707,"line":6112},[5705,9886,9887],{},"activate Debounce\n",[5705,9889,9890],{"class":5707,"line":6118},[5705,9891,9892],{},"Debounce -> Debounce : setTimeout(500ms)\n",[5705,9894,9895],{"class":5707,"line":6124},[5705,9896,9897],{},"note right: Таймер запущено\n",[5705,9899,9900],{"class":5707,"line":6129},[5705,9901,5795],{"emptyLinePlaceholder":5794},[5705,9903,9904],{"class":5707,"line":6141},[5705,9905,9906],{},"User -> Query : Введення \"re\" (через 100мс)\n",[5705,9908,9909],{"class":5707,"line":6389},[5705,9910,9911],{},"Query -> Debounce : value = \"re\"\n",[5705,9913,9914],{"class":5707,"line":6408},[5705,9915,9916],{},"Debounce -> Debounce : clearTimeout()\\nsetTimeout(500ms)\n",[5705,9918,9919],{"class":5707,"line":6413},[5705,9920,9921],{},"note right: Старий таймер скасовано,\\nновий таймер запущено\n",[5705,9923,9924],{"class":5707,"line":6419},[5705,9925,5795],{"emptyLinePlaceholder":5794},[5705,9927,9928],{"class":5707,"line":6430},[5705,9929,9930],{},"User -> Query : Введення \"rea\" (через 150мс)\n",[5705,9932,9933],{"class":5707,"line":6449},[5705,9934,9935],{},"Query -> Debounce : value = \"rea\"\n",[5705,9937,9938],{"class":5707,"line":6468},[5705,9939,9916],{},[5705,9941,9942],{"class":5707,"line":6473},[5705,9943,9944],{},"note right: Знову скасовано та перезапущено\n",[5705,9946,9947],{"class":5707,"line":6482},[5705,9948,5795],{"emptyLinePlaceholder":5794},[5705,9950,9951],{"class":5707,"line":6487},[5705,9952,9953],{},"note over User\n",[5705,9955,9956],{"class":5707,"line":6496},[5705,9957,9958],{},"  Користувач припинив вводити\n",[5705,9960,9961],{"class":5707,"line":7008},[5705,9962,9963],{},"  (минуло 500мс без змін)\n",[5705,9965,9966],{"class":5707,"line":7014},[5705,9967,7029],{},[5705,9969,9970],{"class":5707,"line":7020},[5705,9971,5795],{"emptyLinePlaceholder":5794},[5705,9973,9974],{"class":5707,"line":7026},[5705,9975,9976],{},"Debounce -> Debounced : setDebouncedValue(\"rea\")\n",[5705,9978,9979],{"class":5707,"line":7032},[5705,9980,9981],{},"activate Debounced\n",[5705,9983,9984],{"class":5707,"line":7037},[5705,9985,9986],{},"Debounced -> API : fetch(\"\u002Fsearch?q=rea\")\n",[5705,9988,9989],{"class":5707,"line":7639},[5705,9990,9991],{},"activate API\n",[5705,9993,9994],{"class":5707,"line":7644},[5705,9995,9996],{},"API --> Debounced : Результати пошуку\n",[5705,9998,9999],{"class":5707,"line":7654},[5705,10000,10001],{},"deactivate API\n",[5705,10003,10004],{"class":5707,"line":7660},[5705,10005,10006],{},"deactivate Debounced\n",[5705,10008,10009],{"class":5707,"line":7676},[5705,10010,10011],{},"deactivate Debounce\n",[5705,10013,10014],{"class":5707,"line":7688},[5705,10015,10016],{},"deactivate Query\n",[5705,10018,10019],{"class":5707,"line":7693},[5705,10020,5795],{"emptyLinePlaceholder":5794},[5705,10022,10023],{"class":5707,"line":7699},[5705,10024,7040],{},[5479,10026,10027],{},[5483,10028,10029],{},"Що відбувається:",[6642,10031,10032,10045,10051,10056],{},[5506,10033,10034,10035,5580,10038,5580,10041,10044],{},"Користувач вводить ",[5535,10036,10037],{},"\"r\"",[5535,10039,10040],{},"\"re\"",[5535,10042,10043],{},"\"rea\""," швидко (менше 500мс між натисканнями).",[5506,10046,10047,10048,5622],{},"Кожне введення скидає таймер через ",[5535,10049,10050],{},"clearTimeout",[5506,10052,10053,10054,5622],{},"Коли користувач припиняє вводити на 500мс, таймер спрацьовує і оновлює ",[5535,10055,9545],{},[5506,10057,10058,10060,10061,10063,10064,10067],{},[5535,10059,5885],{}," бачить зміну ",[5535,10062,9545],{}," і виконує ",[5483,10065,10066],{},"один"," запит до API.",[5479,10069,10070,10073,10074,5580,10077,5580,10080,10083,10084,5609],{},[5483,10071,10072],{},"Результат:"," Замість 3 запитів (",[5535,10075,10076],{},"r",[5535,10078,10079],{},"re",[5535,10081,10082],{},"rea",") — лише 1 запит (",[5535,10085,10082],{},[5567,10087],{},[5570,10089,10091],{"id":10090},"композиція-хуків-побудова-складних-хуків-із-простих","Композиція хуків: побудова складних хуків із простих",[5479,10093,10094,10095,7055,10098,10101],{},"Одна з найпотужніших властивостей кастомних хуків — їхня ",[5483,10096,10097],{},"композиційність",[5529,10099,10100],{},"composability","). Складні хуки можна будувати, комбінуючи простіші хуки.",[5685,10103,10105,10106,10109,10110,6196,10112],{"id":10104},"приклад-usesearchwithdebounce-композиція-usedebounce-та-usefetch","Приклад: ",[5535,10107,10108],{},"useSearchWithDebounce"," — композиція ",[5535,10111,9200],{},[5535,10113,5885],{},[5696,10115,10117],{"className":5698,"code":10116,"language":5700,"meta":5701,"style":5701},"interface UseSearchResult\u003CT> {\n  query: string;\n  setQuery: (value: string) => void;\n  results: T | null;\n  isLoading: boolean;\n  error: string | null;\n}\n\nexport function useSearchWithDebounce\u003CT>(\n  baseUrl: string,\n  delay: number = 500\n): UseSearchResult\u003CT> {\n  const [query, setQuery] = useState(\"\");\n  \n  \u002F\u002F Композиція хука useDebounce\n  const debouncedQuery = useDebounce(query, delay);\n  \n  \u002F\u002F Композиція хука useFetch\n  const { data: results, isLoading, error } = useFetch\u003CT>(\n    debouncedQuery ? `${baseUrl}?q=${debouncedQuery}` : \"\"\n  );\n\n  return {\n    query,\n    setQuery,\n    results,\n    isLoading,\n    error,\n  };\n}\n",[5535,10118,10119,10132,10143,10165,10180,10190,10204,10208,10212,10227,10238,10252,10265,10289,10293,10298,10318,10322,10327,10357,10388,10392,10396,10402,10409,10416,10423,10430,10437,10441],{"__ignoreMap":5701},[5705,10120,10121,10123,10126,10128,10130],{"class":5707,"line":5708},[5705,10122,7132],{"class":5718},[5705,10124,10125],{"class":5748}," UseSearchResult",[5705,10127,5763],{"class":5726},[5705,10129,5766],{"class":5748},[5705,10131,7142],{"class":5726},[5705,10133,10134,10137,10139,10141],{"class":5707,"line":5715},[5705,10135,10136],{"class":5741},"  query",[5705,10138,5745],{"class":5726},[5705,10140,5749],{"class":5748},[5705,10142,6138],{"class":5726},[5705,10144,10145,10148,10151,10153,10155,10157,10159,10161,10163],{"class":5707,"line":5730},[5705,10146,10147],{"class":5722},"  setQuery",[5705,10149,10150],{"class":5726},": (",[5705,10152,5772],{"class":5741},[5705,10154,5745],{"class":5726},[5705,10156,5749],{"class":5748},[5705,10158,8337],{"class":5726},[5705,10160,5955],{"class":5718},[5705,10162,8350],{"class":5748},[5705,10164,6138],{"class":5726},[5705,10166,10167,10170,10172,10174,10176,10178],{"class":5707,"line":5755},[5705,10168,10169],{"class":5741},"  results",[5705,10171,5745],{"class":5726},[5705,10173,5766],{"class":5748},[5705,10175,7154],{"class":5726},[5705,10177,7157],{"class":5748},[5705,10179,6138],{"class":5726},[5705,10181,10182,10184,10186,10188],{"class":5707,"line":5791},[5705,10183,7164],{"class":5741},[5705,10185,5745],{"class":5726},[5705,10187,6253],{"class":5748},[5705,10189,6138],{"class":5726},[5705,10191,10192,10194,10196,10198,10200,10202],{"class":5707,"line":5798},[5705,10193,7175],{"class":5741},[5705,10195,5745],{"class":5726},[5705,10197,5749],{"class":5748},[5705,10199,7154],{"class":5726},[5705,10201,7157],{"class":5748},[5705,10203,6138],{"class":5726},[5705,10205,10206],{"class":5707,"line":5804},[5705,10207,6144],{"class":5726},[5705,10209,10210],{"class":5707,"line":5818},[5705,10211,5795],{"emptyLinePlaceholder":5794},[5705,10213,10214,10216,10218,10221,10223,10225],{"class":5707,"line":6031},[5705,10215,6242],{"class":6060},[5705,10217,6245],{"class":5718},[5705,10219,10220],{"class":5722}," useSearchWithDebounce",[5705,10222,5763],{"class":5726},[5705,10224,5766],{"class":5748},[5705,10226,7918],{"class":5726},[5705,10228,10229,10232,10234,10236],{"class":5707,"line":6052},[5705,10230,10231],{"class":5741},"  baseUrl",[5705,10233,5745],{"class":5726},[5705,10235,5749],{"class":5748},[5705,10237,8298],{"class":5726},[5705,10239,10240,10243,10245,10247,10249],{"class":5707,"line":6057},[5705,10241,10242],{"class":5741},"  delay",[5705,10244,5745],{"class":5726},[5705,10246,5786],{"class":5748},[5705,10248,6525],{"class":5726},[5705,10250,10251],{"class":9489},"500\n",[5705,10253,10254,10256,10259,10261,10263],{"class":5707,"line":6072},[5705,10255,7216],{"class":5726},[5705,10257,10258],{"class":5748},"UseSearchResult",[5705,10260,5763],{"class":5726},[5705,10262,5766],{"class":5748},[5705,10264,7142],{"class":5726},[5705,10266,10267,10269,10271,10274,10276,10279,10281,10283,10285,10287],{"class":5707,"line":6093},[5705,10268,5907],{"class":5718},[5705,10270,5910],{"class":5726},[5705,10272,10273],{"class":5913},"query",[5705,10275,5580],{"class":5726},[5705,10277,10278],{"class":5913},"setQuery",[5705,10280,5922],{"class":5726},[5705,10282,5579],{"class":5722},[5705,10284,5738],{"class":5726},[5705,10286,9467],{"class":6019},[5705,10288,6028],{"class":5726},[5705,10290,10291],{"class":5707,"line":6112},[5705,10292,6895],{"class":5726},[5705,10294,10295],{"class":5707,"line":6118},[5705,10296,10297],{"class":5711},"  \u002F\u002F Композиція хука useDebounce\n",[5705,10299,10300,10302,10304,10306,10308,10310,10312,10314,10316],{"class":5707,"line":6124},[5705,10301,5907],{"class":5718},[5705,10303,9476],{"class":5913},[5705,10305,6525],{"class":5726},[5705,10307,9200],{"class":5722},[5705,10309,5738],{"class":5726},[5705,10311,10273],{"class":5741},[5705,10313,5580],{"class":5726},[5705,10315,5781],{"class":5741},[5705,10317,6028],{"class":5726},[5705,10319,10320],{"class":5707,"line":6129},[5705,10321,6895],{"class":5726},[5705,10323,10324],{"class":5707,"line":6141},[5705,10325,10326],{"class":5711},"  \u002F\u002F Композиція хука useFetch\n",[5705,10328,10329,10331,10333,10335,10337,10339,10341,10343,10345,10347,10349,10351,10353,10355],{"class":5707,"line":6389},[5705,10330,5907],{"class":5718},[5705,10332,5958],{"class":5726},[5705,10334,5621],{"class":5741},[5705,10336,5745],{"class":5726},[5705,10338,9512],{"class":5913},[5705,10340,5580],{"class":5726},[5705,10342,7265],{"class":5913},[5705,10344,5580],{"class":5726},[5705,10346,5618],{"class":5913},[5705,10348,7365],{"class":5726},[5705,10350,5885],{"class":5722},[5705,10352,5763],{"class":5726},[5705,10354,5766],{"class":5748},[5705,10356,7918],{"class":5726},[5705,10358,10359,10362,10364,10366,10368,10371,10373,10376,10378,10380,10382,10384,10386],{"class":5707,"line":6408},[5705,10360,10361],{"class":5741},"    debouncedQuery",[5705,10363,8596],{"class":5726},[5705,10365,6590],{"class":6019},[5705,10367,6570],{"class":5718},[5705,10369,10370],{"class":5741},"baseUrl",[5705,10372,6587],{"class":5718},[5705,10374,10375],{"class":6019},"?q=",[5705,10377,6570],{"class":5718},[5705,10379,9545],{"class":5741},[5705,10381,6587],{"class":5718},[5705,10383,6590],{"class":6019},[5705,10385,9061],{"class":5726},[5705,10387,9557],{"class":6019},[5705,10389,10390],{"class":5707,"line":6413},[5705,10391,6628],{"class":5726},[5705,10393,10394],{"class":5707,"line":6419},[5705,10395,5795],{"emptyLinePlaceholder":5794},[5705,10397,10398,10400],{"class":5707,"line":6430},[5705,10399,6132],{"class":6060},[5705,10401,6069],{"class":5726},[5705,10403,10404,10407],{"class":5707,"line":6449},[5705,10405,10406],{"class":5741},"    query",[5705,10408,8298],{"class":5726},[5705,10410,10411,10414],{"class":5707,"line":6468},[5705,10412,10413],{"class":5741},"    setQuery",[5705,10415,8298],{"class":5726},[5705,10417,10418,10421],{"class":5707,"line":6473},[5705,10419,10420],{"class":5741},"    results",[5705,10422,8298],{"class":5726},[5705,10424,10425,10428],{"class":5707,"line":6482},[5705,10426,10427],{"class":5741},"    isLoading",[5705,10429,8298],{"class":5726},[5705,10431,10432,10435],{"class":5707,"line":6487},[5705,10433,10434],{"class":5741},"    error",[5705,10436,8298],{"class":5726},[5705,10438,10439],{"class":5707,"line":6496},[5705,10440,8714],{"class":5726},[5705,10442,10443],{"class":5707,"line":7008},[5705,10444,6144],{"class":5726},[5685,10446,10448],{"id":10447},"використання-композитного-хука","Використання композитного хука",[5696,10450,10452],{"className":5698,"code":10451,"language":5700,"meta":5701,"style":5701},"interface SearchResult {\n  items: string[];\n  total: number;\n}\n\nfunction SearchComponent() {\n  const { query, setQuery, results, isLoading, error } =\n    useSearchWithDebounce\u003CSearchResult>(\"https:\u002F\u002Fapi.example.com\u002Fsearch\");\n\n  return (\n    \u003Cdiv>\n      \u003Cinput\n        type=\"text\"\n        value={query}\n        onChange={(e) => setQuery(e.target.value)}\n        placeholder=\"Пошук...\"\n      \u002F>\n\n      {isLoading && \u003Cp>Пошук...\u003C\u002Fp>}\n      {error && \u003Cp className=\"error\">{error}\u003C\u002Fp>}\n\n      {results && (\n        \u003Cdiv>\n          \u003Cp>Знайдено: {results.total}\u003C\u002Fp>\n          \u003Cul>\n            {results.items.map((item, i) => (\n              \u003Cli key={i}>{item}\u003C\u002Fli>\n            ))}\n          \u003C\u002Ful>\n        \u003C\u002Fdiv>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,10453,10454,10463,10475,10486,10490,10494,10503,10530,10547,10551,10557,10565,10571,10579,10591,10626,10635,10639,10643,10667,10701,10705,10715,10723,10752,10760,10790,10821,10828,10837,10845,10851,10859,10863],{"__ignoreMap":5701},[5705,10455,10456,10458,10461],{"class":5707,"line":5708},[5705,10457,7132],{"class":5718},[5705,10459,10460],{"class":5748}," SearchResult",[5705,10462,6069],{"class":5726},[5705,10464,10465,10468,10470,10472],{"class":5707,"line":5715},[5705,10466,10467],{"class":5741},"  items",[5705,10469,5745],{"class":5726},[5705,10471,5749],{"class":5748},[5705,10473,10474],{"class":5726},"[];\n",[5705,10476,10477,10480,10482,10484],{"class":5707,"line":5730},[5705,10478,10479],{"class":5741},"  total",[5705,10481,5745],{"class":5726},[5705,10483,5786],{"class":5748},[5705,10485,6138],{"class":5726},[5705,10487,10488],{"class":5707,"line":5755},[5705,10489,6144],{"class":5726},[5705,10491,10492],{"class":5707,"line":5791},[5705,10493,5795],{"emptyLinePlaceholder":5794},[5705,10495,10496,10498,10501],{"class":5707,"line":5798},[5705,10497,5719],{"class":5718},[5705,10499,10500],{"class":5722}," SearchComponent",[5705,10502,5902],{"class":5726},[5705,10504,10505,10507,10509,10511,10513,10515,10517,10519,10521,10523,10525,10527],{"class":5707,"line":5804},[5705,10506,5907],{"class":5718},[5705,10508,5958],{"class":5726},[5705,10510,10273],{"class":5913},[5705,10512,5580],{"class":5726},[5705,10514,10278],{"class":5913},[5705,10516,5580],{"class":5726},[5705,10518,9512],{"class":5913},[5705,10520,5580],{"class":5726},[5705,10522,7265],{"class":5913},[5705,10524,5580],{"class":5726},[5705,10526,5618],{"class":5913},[5705,10528,10529],{"class":5726}," } =\n",[5705,10531,10532,10535,10537,10540,10542,10545],{"class":5707,"line":5818},[5705,10533,10534],{"class":5722},"    useSearchWithDebounce",[5705,10536,5763],{"class":5726},[5705,10538,10539],{"class":5748},"SearchResult",[5705,10541,5769],{"class":5726},[5705,10543,10544],{"class":6019},"\"https:\u002F\u002Fapi.example.com\u002Fsearch\"",[5705,10546,6028],{"class":5726},[5705,10548,10549],{"class":5707,"line":6031},[5705,10550,5795],{"emptyLinePlaceholder":5794},[5705,10552,10553,10555],{"class":5707,"line":6052},[5705,10554,6132],{"class":6060},[5705,10556,6544],{"class":5726},[5705,10558,10559,10561,10563],{"class":5707,"line":6057},[5705,10560,6550],{"class":6549},[5705,10562,6554],{"class":6553},[5705,10564,6595],{"class":6549},[5705,10566,10567,10569],{"class":5707,"line":6072},[5705,10568,6775],{"class":6549},[5705,10570,9586],{"class":6553},[5705,10572,10573,10575,10577],{"class":5707,"line":6093},[5705,10574,9591],{"class":6557},[5705,10576,6561],{"class":5726},[5705,10578,9596],{"class":6019},[5705,10580,10581,10583,10585,10587,10589],{"class":5707,"line":6112},[5705,10582,9601],{"class":6557},[5705,10584,6561],{"class":5726},[5705,10586,6564],{"class":5718},[5705,10588,10273],{"class":5741},[5705,10590,6144],{"class":5718},[5705,10592,10593,10595,10597,10599,10601,10603,10605,10607,10610,10612,10614,10616,10618,10620,10622,10624],{"class":5707,"line":6118},[5705,10594,9614],{"class":6557},[5705,10596,6561],{"class":5726},[5705,10598,6564],{"class":5718},[5705,10600,5738],{"class":7502},[5705,10602,9623],{"class":5741},[5705,10604,8337],{"class":7502},[5705,10606,5955],{"class":5718},[5705,10608,10609],{"class":5722}," setQuery",[5705,10611,5738],{"class":7502},[5705,10613,9623],{"class":5741},[5705,10615,5622],{"class":7502},[5705,10617,9639],{"class":5741},[5705,10619,5622],{"class":7502},[5705,10621,5772],{"class":5741},[5705,10623,9646],{"class":7502},[5705,10625,6144],{"class":5718},[5705,10627,10628,10630,10632],{"class":5707,"line":6124},[5705,10629,9653],{"class":6557},[5705,10631,6561],{"class":5726},[5705,10633,10634],{"class":6019},"\"Пошук...\"\n",[5705,10636,10637],{"class":5707,"line":6129},[5705,10638,9663],{"class":6549},[5705,10640,10641],{"class":5707,"line":6141},[5705,10642,5795],{"emptyLinePlaceholder":5794},[5705,10644,10645,10647,10649,10651,10653,10655,10657,10659,10661,10663,10665],{"class":5707,"line":6389},[5705,10646,6600],{"class":5718},[5705,10648,7265],{"class":5741},[5705,10650,9676],{"class":5726},[5705,10652,7958],{"class":6549},[5705,10654,5479],{"class":6553},[5705,10656,6780],{"class":6549},[5705,10658,9685],{"class":7502},[5705,10660,6803],{"class":6549},[5705,10662,5479],{"class":6553},[5705,10664,6780],{"class":6549},[5705,10666,6144],{"class":5718},[5705,10668,10669,10671,10673,10675,10677,10679,10681,10683,10685,10687,10689,10691,10693,10695,10697,10699],{"class":5707,"line":6408},[5705,10670,6600],{"class":5718},[5705,10672,5618],{"class":5741},[5705,10674,9676],{"class":5726},[5705,10676,7958],{"class":6549},[5705,10678,5479],{"class":6553},[5705,10680,6558],{"class":6557},[5705,10682,6561],{"class":5726},[5705,10684,8013],{"class":6019},[5705,10686,6780],{"class":6549},[5705,10688,6564],{"class":5718},[5705,10690,5618],{"class":5741},[5705,10692,6587],{"class":5718},[5705,10694,6803],{"class":6549},[5705,10696,5479],{"class":6553},[5705,10698,6780],{"class":6549},[5705,10700,6144],{"class":5718},[5705,10702,10703],{"class":5707,"line":6413},[5705,10704,5795],{"emptyLinePlaceholder":5794},[5705,10706,10707,10709,10711,10713],{"class":5707,"line":6419},[5705,10708,6600],{"class":5718},[5705,10710,9512],{"class":5741},[5705,10712,9676],{"class":5726},[5705,10714,6544],{"class":7502},[5705,10716,10717,10719,10721],{"class":5707,"line":6430},[5705,10718,9712],{"class":6549},[5705,10720,6554],{"class":6553},[5705,10722,6595],{"class":6549},[5705,10724,10725,10728,10730,10732,10735,10737,10739,10741,10744,10746,10748,10750],{"class":5707,"line":6449},[5705,10726,10727],{"class":6549},"          \u003C",[5705,10729,5479],{"class":6553},[5705,10731,6780],{"class":6549},[5705,10733,10734],{"class":7502},"Знайдено: ",[5705,10736,6564],{"class":5718},[5705,10738,9512],{"class":5741},[5705,10740,5622],{"class":7502},[5705,10742,10743],{"class":5741},"total",[5705,10745,6587],{"class":5718},[5705,10747,6803],{"class":6549},[5705,10749,5479],{"class":6553},[5705,10751,6595],{"class":6549},[5705,10753,10754,10756,10758],{"class":5707,"line":6468},[5705,10755,10727],{"class":6549},[5705,10757,5503],{"class":6553},[5705,10759,6595],{"class":6549},[5705,10761,10762,10765,10767,10769,10772,10774,10776,10778,10780,10782,10784,10786,10788],{"class":5707,"line":6473},[5705,10763,10764],{"class":5718},"            {",[5705,10766,9512],{"class":5741},[5705,10768,5622],{"class":7502},[5705,10770,10771],{"class":5741},"items",[5705,10773,5622],{"class":7502},[5705,10775,9728],{"class":5722},[5705,10777,9039],{"class":7502},[5705,10779,8446],{"class":5741},[5705,10781,5580],{"class":7502},[5705,10783,9737],{"class":5741},[5705,10785,8337],{"class":7502},[5705,10787,5955],{"class":5718},[5705,10789,6544],{"class":7502},[5705,10791,10792,10795,10797,10799,10801,10803,10805,10807,10809,10811,10813,10815,10817,10819],{"class":5707,"line":6482},[5705,10793,10794],{"class":6549},"              \u003C",[5705,10796,5506],{"class":6553},[5705,10798,9753],{"class":6557},[5705,10800,6561],{"class":5726},[5705,10802,6564],{"class":5718},[5705,10804,9737],{"class":5741},[5705,10806,6587],{"class":5718},[5705,10808,6780],{"class":6549},[5705,10810,6564],{"class":5718},[5705,10812,8446],{"class":5741},[5705,10814,6587],{"class":5718},[5705,10816,6803],{"class":6549},[5705,10818,5506],{"class":6553},[5705,10820,6595],{"class":6549},[5705,10822,10823,10826],{"class":5707,"line":6487},[5705,10824,10825],{"class":7502},"            ))",[5705,10827,6144],{"class":5718},[5705,10829,10830,10833,10835],{"class":5707,"line":6496},[5705,10831,10832],{"class":6549},"          \u003C\u002F",[5705,10834,5503],{"class":6553},[5705,10836,6595],{"class":6549},[5705,10838,10839,10841,10843],{"class":5707,"line":7008},[5705,10840,9787],{"class":6549},[5705,10842,6554],{"class":6553},[5705,10844,6595],{"class":6549},[5705,10846,10847,10849],{"class":5707,"line":7014},[5705,10848,9796],{"class":7502},[5705,10850,6144],{"class":5718},[5705,10852,10853,10855,10857],{"class":5707,"line":7020},[5705,10854,6619],{"class":6549},[5705,10856,6554],{"class":6553},[5705,10858,6595],{"class":6549},[5705,10860,10861],{"class":5707,"line":7026},[5705,10862,6628],{"class":5726},[5705,10864,10865],{"class":5707,"line":7032},[5705,10866,6144],{"class":5726},[6634,10868,10869,10874],{},[5479,10870,10871],{},[5483,10872,10873],{},"Переваги композиції:",[6642,10875,10876,10890,10895],{},[5506,10877,10878,5486,10881,10883,10884,10886,10887,10889],{},[5483,10879,10880],{},"Модульність:",[5535,10882,10108],{}," побудовано з двох незалежних хуків (",[5535,10885,9200],{}," + ",[5535,10888,5885],{},"), які можна використовувати окремо.",[5506,10891,10892,10894],{},[5483,10893,6667],{}," Кожен простий хук можна протестувати ізольовано. Тест складного хука може покладатися на перевірені прості хуки.",[5506,10896,10897,10900,10901,10903],{},[5483,10898,10899],{},"Підтримуваність:"," Якщо логіка ",[5535,10902,5885],{}," змінюється (наприклад, додаємо кешування), усі композитні хуки автоматично отримають це покращення.",[5567,10905],{},[5570,10907,10909,10910],{"id":10908},"хук-відстеження-розміру-вікна-usewindowsize","Хук відстеження розміру вікна: ",[5535,10911,10912],{},"useWindowSize",[5479,10914,10915],{},"Ще один корисний приклад — хук для responsive-дизайну, що відстежує ширину та висоту вікна браузера.",[5685,10917,7095,10919],{"id":10918},"реалізація-usewindowsize",[5535,10920,10912],{},[5696,10922,10924],{"className":5698,"code":10923,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from \"react\";\n\ninterface WindowSize {\n  width: number;\n  height: number;\n}\n\nexport function useWindowSize(): WindowSize {\n  const [windowSize, setWindowSize] = useState\u003CWindowSize>({\n    width: window.innerWidth,\n    height: window.innerHeight,\n  });\n\n  useEffect(() => {\n    function handleResize() {\n      setWindowSize({\n        width: window.innerWidth,\n        height: window.innerHeight,\n      });\n    }\n\n    \u002F\u002F Підписка на зміну розміру вікна\n    window.addEventListener(\"resize\", handleResize);\n\n    return () => {\n      window.removeEventListener(\"resize\", handleResize);\n    };\n  }, []);\n\n  return windowSize;\n}\n",[5535,10925,10926,10946,10950,10959,10970,10981,10985,10989,11005,11030,11045,11059,11063,11067,11077,11086,11094,11107,11120,11125,11129,11133,11138,11158,11162,11172,11190,11194,11198,11202,11211],{"__ignoreMap":5701},[5705,10927,10928,10930,10932,10934,10936,10938,10940,10942,10944],{"class":5707,"line":5708},[5705,10929,6214],{"class":6060},[5705,10931,5958],{"class":5726},[5705,10933,5579],{"class":5741},[5705,10935,5580],{"class":5726},[5705,10937,5583],{"class":5741},[5705,10939,6225],{"class":5726},[5705,10941,6228],{"class":6060},[5705,10943,6231],{"class":6019},[5705,10945,6138],{"class":5726},[5705,10947,10948],{"class":5707,"line":5715},[5705,10949,5795],{"emptyLinePlaceholder":5794},[5705,10951,10952,10954,10957],{"class":5707,"line":5730},[5705,10953,7132],{"class":5718},[5705,10955,10956],{"class":5748}," WindowSize",[5705,10958,6069],{"class":5726},[5705,10960,10961,10964,10966,10968],{"class":5707,"line":5755},[5705,10962,10963],{"class":5741},"  width",[5705,10965,5745],{"class":5726},[5705,10967,5786],{"class":5748},[5705,10969,6138],{"class":5726},[5705,10971,10972,10975,10977,10979],{"class":5707,"line":5791},[5705,10973,10974],{"class":5741},"  height",[5705,10976,5745],{"class":5726},[5705,10978,5786],{"class":5748},[5705,10980,6138],{"class":5726},[5705,10982,10983],{"class":5707,"line":5798},[5705,10984,6144],{"class":5726},[5705,10986,10987],{"class":5707,"line":5804},[5705,10988,5795],{"emptyLinePlaceholder":5794},[5705,10990,10991,10993,10995,10998,11000,11003],{"class":5707,"line":5818},[5705,10992,6242],{"class":6060},[5705,10994,6245],{"class":5718},[5705,10996,10997],{"class":5722}," useWindowSize",[5705,10999,6250],{"class":5726},[5705,11001,11002],{"class":5748},"WindowSize",[5705,11004,6069],{"class":5726},[5705,11006,11007,11009,11011,11014,11016,11019,11021,11023,11025,11027],{"class":5707,"line":6031},[5705,11008,5907],{"class":5718},[5705,11010,5910],{"class":5726},[5705,11012,11013],{"class":5913},"windowSize",[5705,11015,5580],{"class":5726},[5705,11017,11018],{"class":5913},"setWindowSize",[5705,11020,5922],{"class":5726},[5705,11022,5579],{"class":5722},[5705,11024,5763],{"class":5726},[5705,11026,11002],{"class":5748},[5705,11028,11029],{"class":5726},">({\n",[5705,11031,11032,11035,11038,11040,11043],{"class":5707,"line":6052},[5705,11033,11034],{"class":5741},"    width:",[5705,11036,11037],{"class":5741}," window",[5705,11039,5622],{"class":5726},[5705,11041,11042],{"class":5741},"innerWidth",[5705,11044,8298],{"class":5726},[5705,11046,11047,11050,11052,11054,11057],{"class":5707,"line":6057},[5705,11048,11049],{"class":5741},"    height:",[5705,11051,11037],{"class":5741},[5705,11053,5622],{"class":5726},[5705,11055,11056],{"class":5741},"innerHeight",[5705,11058,8298],{"class":5726},[5705,11060,11061],{"class":5707,"line":6072},[5705,11062,8521],{"class":5726},[5705,11064,11065],{"class":5707,"line":6093},[5705,11066,5795],{"emptyLinePlaceholder":5794},[5705,11068,11069,11071,11073,11075],{"class":5707,"line":6112},[5705,11070,5949],{"class":5722},[5705,11072,5952],{"class":5726},[5705,11074,5955],{"class":5718},[5705,11076,6069],{"class":5726},[5705,11078,11079,11081,11084],{"class":5707,"line":6118},[5705,11080,5966],{"class":5718},[5705,11082,11083],{"class":5722}," handleResize",[5705,11085,5902],{"class":5726},[5705,11087,11088,11091],{"class":5707,"line":6124},[5705,11089,11090],{"class":5722},"      setWindowSize",[5705,11092,11093],{"class":5726},"({\n",[5705,11095,11096,11099,11101,11103,11105],{"class":5707,"line":6129},[5705,11097,11098],{"class":5741},"        width:",[5705,11100,11037],{"class":5741},[5705,11102,5622],{"class":5726},[5705,11104,11042],{"class":5741},[5705,11106,8298],{"class":5726},[5705,11108,11109,11112,11114,11116,11118],{"class":5707,"line":6141},[5705,11110,11111],{"class":5741},"        height:",[5705,11113,11037],{"class":5741},[5705,11115,5622],{"class":5726},[5705,11117,11056],{"class":5741},[5705,11119,8298],{"class":5726},[5705,11121,11122],{"class":5707,"line":6389},[5705,11123,11124],{"class":5726},"      });\n",[5705,11126,11127],{"class":5707,"line":6408},[5705,11128,6333],{"class":5726},[5705,11130,11131],{"class":5707,"line":6413},[5705,11132,5795],{"emptyLinePlaceholder":5794},[5705,11134,11135],{"class":5707,"line":6419},[5705,11136,11137],{"class":5711},"    \u002F\u002F Підписка на зміну розміру вікна\n",[5705,11139,11140,11142,11144,11146,11148,11151,11153,11156],{"class":5707,"line":6430},[5705,11141,6009],{"class":5741},[5705,11143,5622],{"class":5726},[5705,11145,6014],{"class":5722},[5705,11147,5738],{"class":5726},[5705,11149,11150],{"class":6019},"\"resize\"",[5705,11152,5580],{"class":5726},[5705,11154,11155],{"class":5741},"handleResize",[5705,11157,6028],{"class":5726},[5705,11159,11160],{"class":5707,"line":6449},[5705,11161,5795],{"emptyLinePlaceholder":5794},[5705,11163,11164,11166,11168,11170],{"class":5707,"line":6468},[5705,11165,6061],{"class":6060},[5705,11167,6064],{"class":5726},[5705,11169,5955],{"class":5718},[5705,11171,6069],{"class":5726},[5705,11173,11174,11176,11178,11180,11182,11184,11186,11188],{"class":5707,"line":6473},[5705,11175,6075],{"class":5741},[5705,11177,5622],{"class":5726},[5705,11179,6080],{"class":5722},[5705,11181,5738],{"class":5726},[5705,11183,11150],{"class":6019},[5705,11185,5580],{"class":5726},[5705,11187,11155],{"class":5741},[5705,11189,6028],{"class":5726},[5705,11191,11192],{"class":5707,"line":6482},[5705,11193,6115],{"class":5726},[5705,11195,11196],{"class":5707,"line":6487},[5705,11197,6121],{"class":5726},[5705,11199,11200],{"class":5707,"line":6496},[5705,11201,5795],{"emptyLinePlaceholder":5794},[5705,11203,11204,11206,11209],{"class":5707,"line":7008},[5705,11205,6132],{"class":6060},[5705,11207,11208],{"class":5741}," windowSize",[5705,11210,6138],{"class":5726},[5705,11212,11213],{"class":5707,"line":7014},[5705,11214,6144],{"class":5726},[5685,11216,11218],{"id":11217},"використання-для-адаптивного-ui","Використання для адаптивного UI",[5696,11220,11222],{"className":5698,"code":11221,"language":5700,"meta":5701,"style":5701},"function ResponsiveLayout() {\n  const { width } = useWindowSize();\n\n  \u002F\u002F Визначаємо breakpoints\n  const isMobile = width \u003C 768;\n  const isTablet = width >= 768 && width \u003C 1024;\n  const isDesktop = width >= 1024;\n\n  return (\n    \u003Cdiv className=\"layout\">\n      {isMobile && \u003CMobileNavigation \u002F>}\n      {isTablet && \u003CTabletNavigation \u002F>}\n      {isDesktop && \u003CDesktopNavigation \u002F>}\n\n      \u003Cmain>\n        \u003Cp>Ширина вікна: {width}px\u003C\u002Fp>\n        \u003Cp>Пристрій: {isMobile ? \"Мобільний\" : isTablet ? \"Планшет\" : \"Десктоп\"}\u003C\u002Fp>\n      \u003C\u002Fmain>\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,11223,11224,11233,11248,11252,11257,11276,11303,11320,11324,11330,11345,11364,11382,11400,11404,11413,11439,11481,11489,11497,11501],{"__ignoreMap":5701},[5705,11225,11226,11228,11231],{"class":5707,"line":5708},[5705,11227,5719],{"class":5718},[5705,11229,11230],{"class":5722}," ResponsiveLayout",[5705,11232,5902],{"class":5726},[5705,11234,11235,11237,11239,11242,11244,11246],{"class":5707,"line":5715},[5705,11236,5907],{"class":5718},[5705,11238,5958],{"class":5726},[5705,11240,11241],{"class":5913},"width",[5705,11243,7365],{"class":5726},[5705,11245,10912],{"class":5722},[5705,11247,7353],{"class":5726},[5705,11249,11250],{"class":5707,"line":5730},[5705,11251,5795],{"emptyLinePlaceholder":5794},[5705,11253,11254],{"class":5707,"line":5755},[5705,11255,11256],{"class":5711},"  \u002F\u002F Визначаємо breakpoints\n",[5705,11258,11259,11261,11264,11266,11268,11271,11274],{"class":5707,"line":5791},[5705,11260,5907],{"class":5718},[5705,11262,11263],{"class":5913}," isMobile",[5705,11265,6525],{"class":5726},[5705,11267,11241],{"class":5741},[5705,11269,11270],{"class":5726}," \u003C ",[5705,11272,11273],{"class":9489},"768",[5705,11275,6138],{"class":5726},[5705,11277,11278,11280,11283,11285,11287,11290,11292,11294,11296,11298,11301],{"class":5707,"line":5798},[5705,11279,5907],{"class":5718},[5705,11281,11282],{"class":5913}," isTablet",[5705,11284,6525],{"class":5726},[5705,11286,11241],{"class":5741},[5705,11288,11289],{"class":5726}," >= ",[5705,11291,11273],{"class":9489},[5705,11293,7605],{"class":5726},[5705,11295,11241],{"class":5741},[5705,11297,11270],{"class":5726},[5705,11299,11300],{"class":9489},"1024",[5705,11302,6138],{"class":5726},[5705,11304,11305,11307,11310,11312,11314,11316,11318],{"class":5707,"line":5804},[5705,11306,5907],{"class":5718},[5705,11308,11309],{"class":5913}," isDesktop",[5705,11311,6525],{"class":5726},[5705,11313,11241],{"class":5741},[5705,11315,11289],{"class":5726},[5705,11317,11300],{"class":9489},[5705,11319,6138],{"class":5726},[5705,11321,11322],{"class":5707,"line":5818},[5705,11323,5795],{"emptyLinePlaceholder":5794},[5705,11325,11326,11328],{"class":5707,"line":6031},[5705,11327,6132],{"class":6060},[5705,11329,6544],{"class":5726},[5705,11331,11332,11334,11336,11338,11340,11343],{"class":5707,"line":6052},[5705,11333,6550],{"class":6549},[5705,11335,6554],{"class":6553},[5705,11337,6558],{"class":6557},[5705,11339,6561],{"class":5726},[5705,11341,11342],{"class":6019},"\"layout\"",[5705,11344,6595],{"class":6549},[5705,11346,11347,11349,11352,11354,11356,11359,11362],{"class":5707,"line":6057},[5705,11348,6600],{"class":5718},[5705,11350,11351],{"class":5741},"isMobile",[5705,11353,9676],{"class":5726},[5705,11355,7958],{"class":6549},[5705,11357,11358],{"class":5748},"MobileNavigation",[5705,11360,11361],{"class":6549}," \u002F>",[5705,11363,6144],{"class":5718},[5705,11365,11366,11368,11371,11373,11375,11378,11380],{"class":5707,"line":6072},[5705,11367,6600],{"class":5718},[5705,11369,11370],{"class":5741},"isTablet",[5705,11372,9676],{"class":5726},[5705,11374,7958],{"class":6549},[5705,11376,11377],{"class":5748},"TabletNavigation",[5705,11379,11361],{"class":6549},[5705,11381,6144],{"class":5718},[5705,11383,11384,11386,11389,11391,11393,11396,11398],{"class":5707,"line":6093},[5705,11385,6600],{"class":5718},[5705,11387,11388],{"class":5741},"isDesktop",[5705,11390,9676],{"class":5726},[5705,11392,7958],{"class":6549},[5705,11394,11395],{"class":5748},"DesktopNavigation",[5705,11397,11361],{"class":6549},[5705,11399,6144],{"class":5718},[5705,11401,11402],{"class":5707,"line":6112},[5705,11403,5795],{"emptyLinePlaceholder":5794},[5705,11405,11406,11408,11411],{"class":5707,"line":6118},[5705,11407,6775],{"class":6549},[5705,11409,11410],{"class":6553},"main",[5705,11412,6595],{"class":6549},[5705,11414,11415,11417,11419,11421,11424,11426,11428,11430,11433,11435,11437],{"class":5707,"line":6124},[5705,11416,9712],{"class":6549},[5705,11418,5479],{"class":6553},[5705,11420,6780],{"class":6549},[5705,11422,11423],{"class":5726},"Ширина вікна: ",[5705,11425,6564],{"class":5718},[5705,11427,11241],{"class":5741},[5705,11429,6587],{"class":5718},[5705,11431,11432],{"class":5726},"px",[5705,11434,6803],{"class":6549},[5705,11436,5479],{"class":6553},[5705,11438,6595],{"class":6549},[5705,11440,11441,11443,11445,11447,11450,11452,11454,11456,11459,11461,11463,11465,11468,11470,11473,11475,11477,11479],{"class":5707,"line":6129},[5705,11442,9712],{"class":6549},[5705,11444,5479],{"class":6553},[5705,11446,6780],{"class":6549},[5705,11448,11449],{"class":5726},"Пристрій: ",[5705,11451,6564],{"class":5718},[5705,11453,11351],{"class":5741},[5705,11455,6575],{"class":5726},[5705,11457,11458],{"class":6019}," \"Мобільний\"",[5705,11460,6581],{"class":5726},[5705,11462,11282],{"class":5741},[5705,11464,6575],{"class":5726},[5705,11466,11467],{"class":6019}," \"Планшет\"",[5705,11469,6581],{"class":5726},[5705,11471,11472],{"class":6019}," \"Десктоп\"",[5705,11474,6587],{"class":5718},[5705,11476,6803],{"class":6549},[5705,11478,5479],{"class":6553},[5705,11480,6595],{"class":6549},[5705,11482,11483,11485,11487],{"class":5707,"line":6141},[5705,11484,9157],{"class":6549},[5705,11486,11410],{"class":6553},[5705,11488,6595],{"class":6549},[5705,11490,11491,11493,11495],{"class":5707,"line":6389},[5705,11492,6619],{"class":6549},[5705,11494,6554],{"class":6553},[5705,11496,6595],{"class":6549},[5705,11498,11499],{"class":5707,"line":6408},[5705,11500,6628],{"class":5726},[5705,11502,11503],{"class":5707,"line":6413},[5705,11504,6144],{"class":5726},[5644,11506,11507,11512,11529],{},[5479,11508,11509],{},[5483,11510,11511],{},"Оптимізація продуктивності:",[5479,11513,11514,11515,11518,11519,11521,11522,11524,11525,11528],{},"Подія ",[5535,11516,11517],{},"resize"," може спрацьовувати десятки разів за секунду при перетягуванні вікна. Для продакшн-застосунків рекомендується комбінувати ",[5535,11520,10912],{}," із ",[5535,11523,9200],{}," або використовувати ",[5535,11526,11527],{},"throttle"," (обмеження частоти викликів).",[5696,11530,11532],{"className":5698,"code":11531,"language":5700,"meta":5701,"style":5701},"function useWindowSizeOptimized(): WindowSize {\n  const rawSize = useWindowSize();\n  const debouncedSize = useDebounce(rawSize, 200); \u002F\u002F Затримка 200мс\n  return debouncedSize;\n}\n",[5535,11533,11534,11547,11560,11586,11594],{"__ignoreMap":5701},[5705,11535,11536,11538,11541,11543,11545],{"class":5707,"line":5708},[5705,11537,5719],{"class":5718},[5705,11539,11540],{"class":5722}," useWindowSizeOptimized",[5705,11542,6250],{"class":5726},[5705,11544,11002],{"class":5748},[5705,11546,6069],{"class":5726},[5705,11548,11549,11551,11554,11556,11558],{"class":5707,"line":5715},[5705,11550,5907],{"class":5718},[5705,11552,11553],{"class":5913}," rawSize",[5705,11555,6525],{"class":5726},[5705,11557,10912],{"class":5722},[5705,11559,7353],{"class":5726},[5705,11561,11562,11564,11567,11569,11571,11573,11576,11578,11581,11583],{"class":5707,"line":5730},[5705,11563,5907],{"class":5718},[5705,11565,11566],{"class":5913}," debouncedSize",[5705,11568,6525],{"class":5726},[5705,11570,9200],{"class":5722},[5705,11572,5738],{"class":5726},[5705,11574,11575],{"class":5741},"rawSize",[5705,11577,5580],{"class":5726},[5705,11579,11580],{"class":9489},"200",[5705,11582,5937],{"class":5726},[5705,11584,11585],{"class":5711},"\u002F\u002F Затримка 200мс\n",[5705,11587,11588,11590,11592],{"class":5707,"line":5755},[5705,11589,6132],{"class":6060},[5705,11591,11566],{"class":5741},[5705,11593,6138],{"class":5726},[5705,11595,11596],{"class":5707,"line":5791},[5705,11597,6144],{"class":5726},[5567,11599],{},[5570,11601,11603],{"id":11602},"практичні-завдання-для-закріплення","Практичні завдання для закріплення",[11605,11606,11607,11731,12610,12742],"accordion",{},[11608,11609,11612,11622,11627,11657,11662],"accordion-item",{"icon":11610,"label":11611},"i-lucide-clipboard-list","📋 Завдання 1: Хук автозбереження форми",[5479,11613,11614,11615,11618,11619,11621],{},"Створіть хук ",[5535,11616,11617],{},"useAutoSave",", що автоматично зберігає значення поля форми у ",[5535,11620,5628],{}," через 2 секунди після останнього введення (debounce).",[5479,11623,11624],{},[5483,11625,11626],{},"Вимоги:",[5503,11628,11629,11639,11650],{},[5506,11630,11631,11632,11635,11636,5622],{},"Хук приймає ",[5535,11633,11634],{},"key: string"," (ключ для localStorage) та ",[5535,11637,11638],{},"initialValue: string",[5506,11640,11641,11642,11645,11646,11649],{},"Повертає кортеж ",[5535,11643,11644],{},"[value, setValue, isSaving]",", де ",[5535,11647,11648],{},"isSaving"," вказує, чи відбувається збереження.",[5506,11651,11652,11653,6196,11655,5622],{},"Використовує композицію ",[5535,11654,5888],{},[5535,11656,9200],{},[5479,11658,11659],{},[5483,11660,11661],{},"Сигнатура:",[5696,11663,11665],{"className":5698,"code":11664,"language":5700,"meta":5701,"style":5701},"function useAutoSave(\n  key: string,\n  initialValue: string\n): [string, (value: string) => void, boolean] {\n  \u002F\u002F Ваша реалізація\n}\n",[5535,11666,11667,11677,11687,11696,11722,11727],{"__ignoreMap":5701},[5705,11668,11669,11671,11674],{"class":5707,"line":5708},[5705,11670,5719],{"class":5718},[5705,11672,11673],{"class":5722}," useAutoSave",[5705,11675,11676],{"class":5726},"(\n",[5705,11678,11679,11681,11683,11685],{"class":5707,"line":5715},[5705,11680,8291],{"class":5741},[5705,11682,5745],{"class":5726},[5705,11684,5749],{"class":5748},[5705,11686,8298],{"class":5726},[5705,11688,11689,11691,11693],{"class":5707,"line":5730},[5705,11690,8303],{"class":5741},[5705,11692,5745],{"class":5726},[5705,11694,11695],{"class":5748},"string\n",[5705,11697,11698,11700,11702,11704,11706,11708,11710,11712,11714,11716,11718,11720],{"class":5707,"line":5755},[5705,11699,8313],{"class":5726},[5705,11701,5749],{"class":5748},[5705,11703,8318],{"class":5726},[5705,11705,5772],{"class":5741},[5705,11707,5745],{"class":5726},[5705,11709,5749],{"class":5748},[5705,11711,8337],{"class":5726},[5705,11713,5955],{"class":5718},[5705,11715,8350],{"class":5748},[5705,11717,5580],{"class":5726},[5705,11719,6253],{"class":5748},[5705,11721,8353],{"class":5726},[5705,11723,11724],{"class":5707,"line":5791},[5705,11725,11726],{"class":5711},"  \u002F\u002F Ваша реалізація\n",[5705,11728,11729],{"class":5707,"line":5798},[5705,11730,6144],{"class":5726},[11608,11732,11735,12553,12558],{"icon":11733,"label":11734},"i-lucide-check-circle","✅ Розв'язок завдання 1",[5696,11736,11738],{"className":5698,"code":11737,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from \"react\";\n\nfunction useAutoSave(\n  key: string,\n  initialValue: string\n): [string, (value: string) => void, boolean] {\n  \u002F\u002F Стан поточного значення (змінюється при кожному введенні)\n  const [value, setValue] = useState\u003Cstring>(() => {\n    const stored = localStorage.getItem(key);\n    return stored !== null ? stored : initialValue;\n  });\n\n  \u002F\u002F Відкладене значення (оновлюється через 2 секунди після останнього введення)\n  const [debouncedValue, setDebouncedValue] = useState\u003Cstring>(value);\n\n  \u002F\u002F Індикатор збереження\n  const [isSaving, setIsSaving] = useState\u003Cboolean>(false);\n\n  \u002F\u002F Debounce для value\n  useEffect(() => {\n    const timerId = setTimeout(() => {\n      setDebouncedValue(value);\n    }, 2000);\n\n    return () => clearTimeout(timerId);\n  }, [value]);\n\n  \u002F\u002F Збереження у localStorage при зміні debouncedValue\n  useEffect(() => {\n    if (debouncedValue !== value) {\n      return; \u002F\u002F Якщо значення ще не debounced — не зберігаємо\n    }\n\n    setIsSaving(true);\n    \n    \u002F\u002F Імітація асинхронного збереження (у реальному застосунку — fetch)\n    const saveTimer = setTimeout(() => {\n      localStorage.setItem(key, debouncedValue);\n      console.log(`✅ Збережено у localStorage: ${key} = \"${debouncedValue}\"`);\n      setIsSaving(false);\n    }, 500);\n\n    return () => clearTimeout(saveTimer);\n  }, [debouncedValue, key, value]);\n\n  return [value, setValue, isSaving];\n}\n\n\u002F\u002F Використання\nfunction AutoSaveForm() {\n  const [text, setText, isSaving] = useAutoSave(\"draft\", \"\");\n\n  return (\n    \u003Cdiv>\n      \u003Ctextarea\n        value={text}\n        onChange={(e) => setText(e.target.value)}\n        placeholder=\"Введіть текст...\"\n        rows={5}\n        style={{ width: \"100%\", padding: \"0.5rem\" }}\n      \u002F>\n      {isSaving && \u003Cp className=\"saving-indicator\">💾 Збереження...\u003C\u002Fp>}\n      {!isSaving && text && \u003Cp className=\"saved-indicator\">✅ Збережено\u003C\u002Fp>}\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,11739,11740,11760,11764,11772,11782,11790,11816,11821,11847,11868,11889,11893,11897,11902,11928,11932,11937,11964,11968,11973,11983,11999,12009,12018,12022,12039,12047,12051,12056,12066,12081,12091,12095,12099,12110,12115,12120,12137,12156,12190,12201,12209,12213,12230,12246,12250,12268,12272,12276,12281,12290,12323,12327,12333,12341,12349,12362,12398,12408,12423,12455,12460,12493,12534,12543,12548],{"__ignoreMap":5701},[5705,11741,11742,11744,11746,11748,11750,11752,11754,11756,11758],{"class":5707,"line":5708},[5705,11743,6214],{"class":6060},[5705,11745,5958],{"class":5726},[5705,11747,5579],{"class":5741},[5705,11749,5580],{"class":5726},[5705,11751,5583],{"class":5741},[5705,11753,6225],{"class":5726},[5705,11755,6228],{"class":6060},[5705,11757,6231],{"class":6019},[5705,11759,6138],{"class":5726},[5705,11761,11762],{"class":5707,"line":5715},[5705,11763,5795],{"emptyLinePlaceholder":5794},[5705,11765,11766,11768,11770],{"class":5707,"line":5730},[5705,11767,5719],{"class":5718},[5705,11769,11673],{"class":5722},[5705,11771,11676],{"class":5726},[5705,11773,11774,11776,11778,11780],{"class":5707,"line":5755},[5705,11775,8291],{"class":5741},[5705,11777,5745],{"class":5726},[5705,11779,5749],{"class":5748},[5705,11781,8298],{"class":5726},[5705,11783,11784,11786,11788],{"class":5707,"line":5791},[5705,11785,8303],{"class":5741},[5705,11787,5745],{"class":5726},[5705,11789,11695],{"class":5748},[5705,11791,11792,11794,11796,11798,11800,11802,11804,11806,11808,11810,11812,11814],{"class":5707,"line":5798},[5705,11793,8313],{"class":5726},[5705,11795,5749],{"class":5748},[5705,11797,8318],{"class":5726},[5705,11799,5772],{"class":5741},[5705,11801,5745],{"class":5726},[5705,11803,5749],{"class":5748},[5705,11805,8337],{"class":5726},[5705,11807,5955],{"class":5718},[5705,11809,8350],{"class":5748},[5705,11811,5580],{"class":5726},[5705,11813,6253],{"class":5748},[5705,11815,8353],{"class":5726},[5705,11817,11818],{"class":5707,"line":5804},[5705,11819,11820],{"class":5711},"  \u002F\u002F Стан поточного значення (змінюється при кожному введенні)\n",[5705,11822,11823,11825,11827,11829,11831,11833,11835,11837,11839,11841,11843,11845],{"class":5707,"line":5818},[5705,11824,5907],{"class":5718},[5705,11826,5910],{"class":5726},[5705,11828,5772],{"class":5913},[5705,11830,5580],{"class":5726},[5705,11832,8952],{"class":5913},[5705,11834,5922],{"class":5726},[5705,11836,5579],{"class":5722},[5705,11838,5763],{"class":5726},[5705,11840,5749],{"class":5748},[5705,11842,8383],{"class":5726},[5705,11844,5955],{"class":5718},[5705,11846,6069],{"class":5726},[5705,11848,11849,11851,11854,11856,11858,11860,11862,11864,11866],{"class":5707,"line":6031},[5705,11850,7339],{"class":5718},[5705,11852,11853],{"class":5913}," stored",[5705,11855,6525],{"class":5726},[5705,11857,5628],{"class":5741},[5705,11859,5622],{"class":5726},[5705,11861,8416],{"class":5722},[5705,11863,5738],{"class":5726},[5705,11865,8421],{"class":5741},[5705,11867,6028],{"class":5726},[5705,11869,11870,11872,11874,11876,11878,11880,11883,11885,11887],{"class":5707,"line":6052},[5705,11871,6061],{"class":6060},[5705,11873,11853],{"class":5741},[5705,11875,7615],{"class":5726},[5705,11877,7157],{"class":5718},[5705,11879,8596],{"class":5726},[5705,11881,11882],{"class":5741},"stored",[5705,11884,9061],{"class":5726},[5705,11886,8459],{"class":5741},[5705,11888,6138],{"class":5726},[5705,11890,11891],{"class":5707,"line":6057},[5705,11892,8521],{"class":5726},[5705,11894,11895],{"class":5707,"line":6072},[5705,11896,5795],{"emptyLinePlaceholder":5794},[5705,11898,11899],{"class":5707,"line":6093},[5705,11900,11901],{"class":5711},"  \u002F\u002F Відкладене значення (оновлюється через 2 секунди після останнього введення)\n",[5705,11903,11904,11906,11908,11910,11912,11914,11916,11918,11920,11922,11924,11926],{"class":5707,"line":6112},[5705,11905,5907],{"class":5718},[5705,11907,5910],{"class":5726},[5705,11909,9284],{"class":5913},[5705,11911,5580],{"class":5726},[5705,11913,9289],{"class":5913},[5705,11915,5922],{"class":5726},[5705,11917,5579],{"class":5722},[5705,11919,5763],{"class":5726},[5705,11921,5749],{"class":5748},[5705,11923,5769],{"class":5726},[5705,11925,5772],{"class":5741},[5705,11927,6028],{"class":5726},[5705,11929,11930],{"class":5707,"line":6118},[5705,11931,5795],{"emptyLinePlaceholder":5794},[5705,11933,11934],{"class":5707,"line":6124},[5705,11935,11936],{"class":5711},"  \u002F\u002F Індикатор збереження\n",[5705,11938,11939,11941,11943,11945,11947,11950,11952,11954,11956,11958,11960,11962],{"class":5707,"line":6129},[5705,11940,5907],{"class":5718},[5705,11942,5910],{"class":5726},[5705,11944,11648],{"class":5913},[5705,11946,5580],{"class":5726},[5705,11948,11949],{"class":5913},"setIsSaving",[5705,11951,5922],{"class":5726},[5705,11953,5579],{"class":5722},[5705,11955,5763],{"class":5726},[5705,11957,6253],{"class":5748},[5705,11959,5769],{"class":5726},[5705,11961,5998],{"class":5718},[5705,11963,6028],{"class":5726},[5705,11965,11966],{"class":5707,"line":6141},[5705,11967,5795],{"emptyLinePlaceholder":5794},[5705,11969,11970],{"class":5707,"line":6389},[5705,11971,11972],{"class":5711},"  \u002F\u002F Debounce для value\n",[5705,11974,11975,11977,11979,11981],{"class":5707,"line":6408},[5705,11976,5949],{"class":5722},[5705,11978,5952],{"class":5726},[5705,11980,5955],{"class":5718},[5705,11982,6069],{"class":5726},[5705,11984,11985,11987,11989,11991,11993,11995,11997],{"class":5707,"line":6413},[5705,11986,7339],{"class":5718},[5705,11988,9329],{"class":5913},[5705,11990,6525],{"class":5726},[5705,11992,9334],{"class":5722},[5705,11994,5952],{"class":5726},[5705,11996,5955],{"class":5718},[5705,11998,6069],{"class":5726},[5705,12000,12001,12003,12005,12007],{"class":5707,"line":6419},[5705,12002,9345],{"class":5722},[5705,12004,5738],{"class":5726},[5705,12006,5772],{"class":5741},[5705,12008,6028],{"class":5726},[5705,12010,12011,12013,12016],{"class":5707,"line":6430},[5705,12012,9356],{"class":5726},[5705,12014,12015],{"class":9489},"2000",[5705,12017,6028],{"class":5726},[5705,12019,12020],{"class":5707,"line":6449},[5705,12021,5795],{"emptyLinePlaceholder":5794},[5705,12023,12024,12026,12028,12030,12033,12035,12037],{"class":5707,"line":6468},[5705,12025,6061],{"class":6060},[5705,12027,6064],{"class":5726},[5705,12029,5955],{"class":5718},[5705,12031,12032],{"class":5722}," clearTimeout",[5705,12034,5738],{"class":5726},[5705,12036,9389],{"class":5741},[5705,12038,6028],{"class":5726},[5705,12040,12041,12043,12045],{"class":5707,"line":6473},[5705,12042,7760],{"class":5726},[5705,12044,5772],{"class":5741},[5705,12046,8935],{"class":5726},[5705,12048,12049],{"class":5707,"line":6482},[5705,12050,5795],{"emptyLinePlaceholder":5794},[5705,12052,12053],{"class":5707,"line":6487},[5705,12054,12055],{"class":5711},"  \u002F\u002F Збереження у localStorage при зміні debouncedValue\n",[5705,12057,12058,12060,12062,12064],{"class":5707,"line":6496},[5705,12059,5949],{"class":5722},[5705,12061,5952],{"class":5726},[5705,12063,5955],{"class":5718},[5705,12065,6069],{"class":5726},[5705,12067,12068,12071,12073,12075,12077,12079],{"class":5707,"line":7008},[5705,12069,12070],{"class":6060},"    if",[5705,12072,7055],{"class":5726},[5705,12074,9284],{"class":5741},[5705,12076,7615],{"class":5726},[5705,12078,5772],{"class":5741},[5705,12080,7479],{"class":5726},[5705,12082,12083,12085,12088],{"class":5707,"line":7014},[5705,12084,8428],{"class":6060},[5705,12086,12087],{"class":5726},"; ",[5705,12089,12090],{"class":5711},"\u002F\u002F Якщо значення ще не debounced — не зберігаємо\n",[5705,12092,12093],{"class":5707,"line":7020},[5705,12094,6333],{"class":5726},[5705,12096,12097],{"class":5707,"line":7026},[5705,12098,5795],{"emptyLinePlaceholder":5794},[5705,12100,12101,12104,12106,12108],{"class":5707,"line":7032},[5705,12102,12103],{"class":5722},"    setIsSaving",[5705,12105,5738],{"class":5726},[5705,12107,5979],{"class":5718},[5705,12109,6028],{"class":5726},[5705,12111,12112],{"class":5707,"line":7037},[5705,12113,12114],{"class":5726},"    \n",[5705,12116,12117],{"class":5707,"line":7639},[5705,12118,12119],{"class":5711},"    \u002F\u002F Імітація асинхронного збереження (у реальному застосунку — fetch)\n",[5705,12121,12122,12124,12127,12129,12131,12133,12135],{"class":5707,"line":7644},[5705,12123,7339],{"class":5718},[5705,12125,12126],{"class":5913}," saveTimer",[5705,12128,6525],{"class":5726},[5705,12130,9334],{"class":5722},[5705,12132,5952],{"class":5726},[5705,12134,5955],{"class":5718},[5705,12136,6069],{"class":5726},[5705,12138,12139,12142,12144,12146,12148,12150,12152,12154],{"class":5707,"line":7654},[5705,12140,12141],{"class":5741},"      localStorage",[5705,12143,5622],{"class":5726},[5705,12145,8646],{"class":5722},[5705,12147,5738],{"class":5726},[5705,12149,8421],{"class":5741},[5705,12151,5580],{"class":5726},[5705,12153,9284],{"class":5741},[5705,12155,6028],{"class":5726},[5705,12157,12158,12160,12162,12165,12167,12170,12172,12174,12176,12179,12181,12183,12185,12188],{"class":5707,"line":7660},[5705,12159,8479],{"class":5741},[5705,12161,5622],{"class":5726},[5705,12163,12164],{"class":5722},"log",[5705,12166,5738],{"class":5726},[5705,12168,12169],{"class":6019},"`✅ Збережено у localStorage: ",[5705,12171,6570],{"class":5718},[5705,12173,8421],{"class":5741},[5705,12175,6587],{"class":5718},[5705,12177,12178],{"class":6019}," = \"",[5705,12180,6570],{"class":5718},[5705,12182,9284],{"class":5741},[5705,12184,6587],{"class":5718},[5705,12186,12187],{"class":6019},"\"`",[5705,12189,6028],{"class":5726},[5705,12191,12192,12195,12197,12199],{"class":5707,"line":7676},[5705,12193,12194],{"class":5722},"      setIsSaving",[5705,12196,5738],{"class":5726},[5705,12198,5998],{"class":5718},[5705,12200,6028],{"class":5726},[5705,12202,12203,12205,12207],{"class":5707,"line":7688},[5705,12204,9356],{"class":5726},[5705,12206,9490],{"class":9489},[5705,12208,6028],{"class":5726},[5705,12210,12211],{"class":5707,"line":7693},[5705,12212,5795],{"emptyLinePlaceholder":5794},[5705,12214,12215,12217,12219,12221,12223,12225,12228],{"class":5707,"line":7699},[5705,12216,6061],{"class":6060},[5705,12218,6064],{"class":5726},[5705,12220,5955],{"class":5718},[5705,12222,12032],{"class":5722},[5705,12224,5738],{"class":5726},[5705,12226,12227],{"class":5741},"saveTimer",[5705,12229,6028],{"class":5726},[5705,12231,12232,12234,12236,12238,12240,12242,12244],{"class":5707,"line":7704},[5705,12233,7760],{"class":5726},[5705,12235,9284],{"class":5741},[5705,12237,5580],{"class":5726},[5705,12239,8421],{"class":5741},[5705,12241,5580],{"class":5726},[5705,12243,5772],{"class":5741},[5705,12245,8935],{"class":5726},[5705,12247,12248],{"class":5707,"line":7709},[5705,12249,5795],{"emptyLinePlaceholder":5794},[5705,12251,12252,12254,12256,12258,12260,12262,12264,12266],{"class":5707,"line":7717},[5705,12253,6132],{"class":6060},[5705,12255,5910],{"class":5726},[5705,12257,5772],{"class":5741},[5705,12259,5580],{"class":5726},[5705,12261,8952],{"class":5741},[5705,12263,5580],{"class":5726},[5705,12265,11648],{"class":5741},[5705,12267,8955],{"class":5726},[5705,12269,12270],{"class":5707,"line":7722},[5705,12271,6144],{"class":5726},[5705,12273,12274],{"class":5707,"line":7728},[5705,12275,5795],{"emptyLinePlaceholder":5794},[5705,12277,12278],{"class":5707,"line":7739},[5705,12279,12280],{"class":5711},"\u002F\u002F Використання\n",[5705,12282,12283,12285,12288],{"class":5707,"line":7752},[5705,12284,5719],{"class":5718},[5705,12286,12287],{"class":5722}," AutoSaveForm",[5705,12289,5902],{"class":5726},[5705,12291,12292,12294,12296,12299,12301,12304,12306,12308,12310,12312,12314,12317,12319,12321],{"class":5707,"line":7757},[5705,12293,5907],{"class":5718},[5705,12295,5910],{"class":5726},[5705,12297,12298],{"class":5913},"text",[5705,12300,5580],{"class":5726},[5705,12302,12303],{"class":5913},"setText",[5705,12305,5580],{"class":5726},[5705,12307,11648],{"class":5913},[5705,12309,5922],{"class":5726},[5705,12311,11617],{"class":5722},[5705,12313,5738],{"class":5726},[5705,12315,12316],{"class":6019},"\"draft\"",[5705,12318,5580],{"class":5726},[5705,12320,9467],{"class":6019},[5705,12322,6028],{"class":5726},[5705,12324,12325],{"class":5707,"line":7771},[5705,12326,5795],{"emptyLinePlaceholder":5794},[5705,12328,12329,12331],{"class":5707,"line":7776},[5705,12330,6132],{"class":6060},[5705,12332,6544],{"class":5726},[5705,12334,12335,12337,12339],{"class":5707,"line":7796},[5705,12336,6550],{"class":6549},[5705,12338,6554],{"class":6553},[5705,12340,6595],{"class":6549},[5705,12342,12344,12346],{"class":5707,"line":12343},55,[5705,12345,6775],{"class":6549},[5705,12347,12348],{"class":6553},"textarea\n",[5705,12350,12352,12354,12356,12358,12360],{"class":5707,"line":12351},56,[5705,12353,9601],{"class":6557},[5705,12355,6561],{"class":5726},[5705,12357,6564],{"class":5718},[5705,12359,12298],{"class":5741},[5705,12361,6144],{"class":5718},[5705,12363,12365,12367,12369,12371,12373,12375,12377,12379,12382,12384,12386,12388,12390,12392,12394,12396],{"class":5707,"line":12364},57,[5705,12366,9614],{"class":6557},[5705,12368,6561],{"class":5726},[5705,12370,6564],{"class":5718},[5705,12372,5738],{"class":7502},[5705,12374,9623],{"class":5741},[5705,12376,8337],{"class":7502},[5705,12378,5955],{"class":5718},[5705,12380,12381],{"class":5722}," setText",[5705,12383,5738],{"class":7502},[5705,12385,9623],{"class":5741},[5705,12387,5622],{"class":7502},[5705,12389,9639],{"class":5741},[5705,12391,5622],{"class":7502},[5705,12393,5772],{"class":5741},[5705,12395,9646],{"class":7502},[5705,12397,6144],{"class":5718},[5705,12399,12401,12403,12405],{"class":5707,"line":12400},58,[5705,12402,9653],{"class":6557},[5705,12404,6561],{"class":5726},[5705,12406,12407],{"class":6019},"\"Введіть текст...\"\n",[5705,12409,12411,12414,12416,12418,12421],{"class":5707,"line":12410},59,[5705,12412,12413],{"class":6557},"        rows",[5705,12415,6561],{"class":5726},[5705,12417,6564],{"class":5718},[5705,12419,12420],{"class":9489},"5",[5705,12422,6144],{"class":5718},[5705,12424,12426,12429,12431,12433,12436,12439,12442,12444,12447,12450,12453],{"class":5707,"line":12425},60,[5705,12427,12428],{"class":6557},"        style",[5705,12430,6561],{"class":5726},[5705,12432,6564],{"class":5718},[5705,12434,12435],{"class":7502},"{ ",[5705,12437,12438],{"class":5741},"width:",[5705,12440,12441],{"class":6019}," \"100%\"",[5705,12443,5580],{"class":7502},[5705,12445,12446],{"class":5741},"padding:",[5705,12448,12449],{"class":6019}," \"0.5rem\"",[5705,12451,12452],{"class":7502}," }",[5705,12454,6144],{"class":5718},[5705,12456,12458],{"class":5707,"line":12457},61,[5705,12459,9663],{"class":6549},[5705,12461,12463,12465,12467,12469,12471,12473,12475,12477,12480,12482,12485,12487,12489,12491],{"class":5707,"line":12462},62,[5705,12464,6600],{"class":5718},[5705,12466,11648],{"class":5741},[5705,12468,9676],{"class":5726},[5705,12470,7958],{"class":6549},[5705,12472,5479],{"class":6553},[5705,12474,6558],{"class":6557},[5705,12476,6561],{"class":5726},[5705,12478,12479],{"class":6019},"\"saving-indicator\"",[5705,12481,6780],{"class":6549},[5705,12483,12484],{"class":7502},"💾 Збереження...",[5705,12486,6803],{"class":6549},[5705,12488,5479],{"class":6553},[5705,12490,6780],{"class":6549},[5705,12492,6144],{"class":5718},[5705,12494,12496,12498,12501,12503,12505,12508,12510,12512,12514,12516,12518,12521,12523,12526,12528,12530,12532],{"class":5707,"line":12495},63,[5705,12497,6600],{"class":5718},[5705,12499,12500],{"class":5726},"!",[5705,12502,11648],{"class":5741},[5705,12504,9676],{"class":5726},[5705,12506,12507],{"class":5741}," text",[5705,12509,9676],{"class":5726},[5705,12511,7958],{"class":6549},[5705,12513,5479],{"class":6553},[5705,12515,6558],{"class":6557},[5705,12517,6561],{"class":5726},[5705,12519,12520],{"class":6019},"\"saved-indicator\"",[5705,12522,6780],{"class":6549},[5705,12524,12525],{"class":7502},"✅ Збережено",[5705,12527,6803],{"class":6549},[5705,12529,5479],{"class":6553},[5705,12531,6780],{"class":6549},[5705,12533,6144],{"class":5718},[5705,12535,12537,12539,12541],{"class":5707,"line":12536},64,[5705,12538,6619],{"class":6549},[5705,12540,6554],{"class":6553},[5705,12542,6595],{"class":6549},[5705,12544,12546],{"class":5707,"line":12545},65,[5705,12547,6628],{"class":5726},[5705,12549,12551],{"class":5707,"line":12550},66,[5705,12552,6144],{"class":5726},[5479,12554,12555],{},[5483,12556,12557],{},"Покрокове пояснення:",[6642,12559,12560,12568,12576,12590,12603],{},[5506,12561,12562,12567],{},[5483,12563,12564],{},[5535,12565,12566],{},"useState(value)"," — основний стан, що оновлюється при кожному натисканні клавіші.",[5506,12569,12570,12575],{},[5483,12571,12572],{},[5535,12573,12574],{},"useState(debouncedValue)"," — відкладений стан, що оновлюється через 2 секунди після останнього введення.",[5506,12577,12578,12583,12584,12586,12587,12589],{},[5483,12579,12580,12581],{},"Перший ",[5535,12582,5583],{}," — створює таймер при кожній зміні ",[5535,12585,5772],{},". Якщо користувач продовжує вводити (таймер скидається), ",[5535,12588,9284],{}," не оновлюється.",[5506,12591,12592,12597,12598,12600,12601,5622],{},[5483,12593,12594,12595],{},"Другий ",[5535,12596,5583],{}," — спрацьовує, коли ",[5535,12599,9284],{}," змінюється. Це означає, що користувач припинив вводити на 2 секунди. Тоді відбувається збереження у ",[5535,12602,5628],{},[5506,12604,12605,12609],{},[5483,12606,12607],{},[5535,12608,11648],{}," — індикатор стану збереження для відображення спінера у UI.",[11608,12611,12613,12619,12623,12652,12656],{"icon":11610,"label":12612},"📋 Завдання 2: Хук інтервального опитування API",[5479,12614,11614,12615,12618],{},[5535,12616,12617],{},"usePolling",", що виконує HTTP-запит до API кожні N секунд (polling) і автоматично зупиняється при розмонтуванні компонента.",[5479,12620,12621],{},[5483,12622,11626],{},[5503,12624,12625,12633,12639,12642],{},[5506,12626,11631,12627,6196,12630,5622],{},[5535,12628,12629],{},"url: string",[5535,12631,12632],{},"intervalMs: number",[5506,12634,12635,12636,5622],{},"Повертає ",[5535,12637,12638],{},"{ data, isLoading, error }",[5506,12640,12641],{},"Перший запит виконується негайно, наступні — через інтервал.",[5506,12643,12644,12645,12647,12648,12651],{},"При зміні ",[5535,12646,5742],{}," або ",[5535,12649,12650],{},"intervalMs"," таймер перестворюється.",[5479,12653,12654],{},[5483,12655,11661],{},[5696,12657,12659],{"className":5698,"code":12658,"language":5700,"meta":5701,"style":5701},"function usePolling\u003CT>(url: string, intervalMs: number): {\n  data: T | null;\n  isLoading: boolean;\n  error: string | null;\n} {\n  \u002F\u002F Ваша реалізація\n}\n",[5535,12660,12661,12691,12705,12715,12729,12734,12738],{"__ignoreMap":5701},[5705,12662,12663,12665,12668,12670,12672,12674,12676,12678,12680,12682,12684,12686,12688],{"class":5707,"line":5708},[5705,12664,5719],{"class":5718},[5705,12666,12667],{"class":5722}," usePolling",[5705,12669,5763],{"class":5726},[5705,12671,5766],{"class":5748},[5705,12673,5769],{"class":5726},[5705,12675,5742],{"class":5741},[5705,12677,5745],{"class":5726},[5705,12679,5749],{"class":5748},[5705,12681,5580],{"class":5726},[5705,12683,12650],{"class":5741},[5705,12685,5745],{"class":5726},[5705,12687,5786],{"class":5748},[5705,12689,12690],{"class":5726},"): {\n",[5705,12692,12693,12695,12697,12699,12701,12703],{"class":5707,"line":5715},[5705,12694,7147],{"class":5741},[5705,12696,5745],{"class":5726},[5705,12698,5766],{"class":5748},[5705,12700,7154],{"class":5726},[5705,12702,7157],{"class":5748},[5705,12704,6138],{"class":5726},[5705,12706,12707,12709,12711,12713],{"class":5707,"line":5730},[5705,12708,7164],{"class":5741},[5705,12710,5745],{"class":5726},[5705,12712,6253],{"class":5748},[5705,12714,6138],{"class":5726},[5705,12716,12717,12719,12721,12723,12725,12727],{"class":5707,"line":5755},[5705,12718,7175],{"class":5741},[5705,12720,5745],{"class":5726},[5705,12722,5749],{"class":5748},[5705,12724,7154],{"class":5726},[5705,12726,7157],{"class":5748},[5705,12728,6138],{"class":5726},[5705,12730,12731],{"class":5707,"line":5791},[5705,12732,12733],{"class":5726},"} {\n",[5705,12735,12736],{"class":5707,"line":5798},[5705,12737,11726],{"class":5711},[5705,12739,12740],{"class":5707,"line":5804},[5705,12741,6144],{"class":5726},[11608,12743,12745,13783,13787,13835],{"icon":11733,"label":12744},"✅ Розв'язок завдання 2",[5696,12746,12748],{"className":5698,"code":12747,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect, useRef } from \"react\";\n\nfunction usePolling\u003CT>(url: string, intervalMs: number): {\n  data: T | null;\n  isLoading: boolean;\n  error: string | null;\n} {\n  const [data, setData] = useState\u003CT | null>(null);\n  const [isLoading, setIsLoading] = useState\u003Cboolean>(true);\n  const [error, setError] = useState\u003Cstring | null>(null);\n\n  \u002F\u002F Реф для зберігання функції fetch (уникаємо застарілих замикань)\n  const fetchDataRef = useRef\u003C() => Promise\u003Cvoid>>();\n\n  fetchDataRef.current = async () => {\n    try {\n      setIsLoading(true);\n      setError(null);\n\n      const response = await fetch(url);\n\n      if (!response.ok) {\n        throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n      }\n\n      const result: T = await response.json();\n      setData(result);\n    } catch (err) {\n      if (err instanceof Error) {\n        setError(err.message);\n      }\n    } finally {\n      setIsLoading(false);\n    }\n  };\n\n  useEffect(() => {\n    \u002F\u002F Перший запит негайно\n    fetchDataRef.current?.();\n\n    \u002F\u002F Наступні запити через інтервал\n    const intervalId = setInterval(() => {\n      fetchDataRef.current?.();\n    }, intervalMs);\n\n    return () => {\n      clearInterval(intervalId);\n    };\n  }, [url, intervalMs]);\n\n  return { data, isLoading, error };\n}\n\n\u002F\u002F Використання\ninterface ServerStatus {\n  status: \"online\" | \"offline\";\n  uptime: number;\n  lastCheck: string;\n}\n\nfunction ServerMonitor() {\n  const { data, isLoading, error } = usePolling\u003CServerStatus>(\n    \"https:\u002F\u002Fapi.example.com\u002Fstatus\",\n    5000 \u002F\u002F Опитування кожні 5 секунд\n  );\n\n  if (error) {\n    return \u003Cdiv className=\"error\">Помилка: {error}\u003C\u002Fdiv>;\n  }\n\n  return (\n    \u003Cdiv className=\"monitor\">\n      {isLoading && !data && \u003Cp>Ініціалізація...\u003C\u002Fp>}\n      \n      {data && (\n        \u003C>\n          \u003Ch2>Статус сервера: {data.status === \"online\" ? \"🟢 Онлайн\" : \"🔴 Офлайн\"}\u003C\u002Fh2>\n          \u003Cp>Uptime: {data.uptime} секунд\u003C\u002Fp>\n          \u003Cp>Остання перевірка: {data.lastCheck}\u003C\u002Fp>\n        \u003C\u002F>\n      )}\n      \n      {isLoading && \u003Cspan className=\"refresh-indicator\">🔄 Оновлення...\u003C\u002Fspan>}\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,12749,12750,12774,12778,12806,12820,12830,12844,12848,12878,12904,12934,12938,12943,12969,12973,12994,13000,13011,13022,13026,13044,13048,13062,13102,13106,13110,13132,13143,13155,13169,13183,13187,13195,13205,13209,13213,13217,13227,13232,13244,13248,13253,13271,13282,13290,13294,13304,13316,13320,13332,13336,13354,13358,13362,13366,13375,13390,13401,13412,13416,13420,13429,13456,13463,13471,13475,13479,13490,13523,13528,13533,13540,13556,13589,13595,13606,13612,13652,13684,13713,13719,13726,13731,13764,13773,13778],{"__ignoreMap":5701},[5705,12751,12752,12754,12756,12758,12760,12762,12764,12766,12768,12770,12772],{"class":5707,"line":5708},[5705,12753,6214],{"class":6060},[5705,12755,5958],{"class":5726},[5705,12757,5579],{"class":5741},[5705,12759,5580],{"class":5726},[5705,12761,5583],{"class":5741},[5705,12763,5580],{"class":5726},[5705,12765,5586],{"class":5741},[5705,12767,6225],{"class":5726},[5705,12769,6228],{"class":6060},[5705,12771,6231],{"class":6019},[5705,12773,6138],{"class":5726},[5705,12775,12776],{"class":5707,"line":5715},[5705,12777,5795],{"emptyLinePlaceholder":5794},[5705,12779,12780,12782,12784,12786,12788,12790,12792,12794,12796,12798,12800,12802,12804],{"class":5707,"line":5730},[5705,12781,5719],{"class":5718},[5705,12783,12667],{"class":5722},[5705,12785,5763],{"class":5726},[5705,12787,5766],{"class":5748},[5705,12789,5769],{"class":5726},[5705,12791,5742],{"class":5741},[5705,12793,5745],{"class":5726},[5705,12795,5749],{"class":5748},[5705,12797,5580],{"class":5726},[5705,12799,12650],{"class":5741},[5705,12801,5745],{"class":5726},[5705,12803,5786],{"class":5748},[5705,12805,12690],{"class":5726},[5705,12807,12808,12810,12812,12814,12816,12818],{"class":5707,"line":5755},[5705,12809,7147],{"class":5741},[5705,12811,5745],{"class":5726},[5705,12813,5766],{"class":5748},[5705,12815,7154],{"class":5726},[5705,12817,7157],{"class":5748},[5705,12819,6138],{"class":5726},[5705,12821,12822,12824,12826,12828],{"class":5707,"line":5791},[5705,12823,7164],{"class":5741},[5705,12825,5745],{"class":5726},[5705,12827,6253],{"class":5748},[5705,12829,6138],{"class":5726},[5705,12831,12832,12834,12836,12838,12840,12842],{"class":5707,"line":5798},[5705,12833,7175],{"class":5741},[5705,12835,5745],{"class":5726},[5705,12837,5749],{"class":5748},[5705,12839,7154],{"class":5726},[5705,12841,7157],{"class":5748},[5705,12843,6138],{"class":5726},[5705,12845,12846],{"class":5707,"line":5804},[5705,12847,12733],{"class":5726},[5705,12849,12850,12852,12854,12856,12858,12860,12862,12864,12866,12868,12870,12872,12874,12876],{"class":5707,"line":5818},[5705,12851,5907],{"class":5718},[5705,12853,5910],{"class":5726},[5705,12855,5621],{"class":5913},[5705,12857,5580],{"class":5726},[5705,12859,7238],{"class":5913},[5705,12861,5922],{"class":5726},[5705,12863,5579],{"class":5722},[5705,12865,5763],{"class":5726},[5705,12867,5766],{"class":5748},[5705,12869,7154],{"class":5726},[5705,12871,7157],{"class":5748},[5705,12873,5769],{"class":5726},[5705,12875,7157],{"class":5718},[5705,12877,6028],{"class":5726},[5705,12879,12880,12882,12884,12886,12888,12890,12892,12894,12896,12898,12900,12902],{"class":5707,"line":6031},[5705,12881,5907],{"class":5718},[5705,12883,5910],{"class":5726},[5705,12885,7265],{"class":5913},[5705,12887,5580],{"class":5726},[5705,12889,7270],{"class":5913},[5705,12891,5922],{"class":5726},[5705,12893,5579],{"class":5722},[5705,12895,5763],{"class":5726},[5705,12897,6253],{"class":5748},[5705,12899,5769],{"class":5726},[5705,12901,5979],{"class":5718},[5705,12903,6028],{"class":5726},[5705,12905,12906,12908,12910,12912,12914,12916,12918,12920,12922,12924,12926,12928,12930,12932],{"class":5707,"line":6052},[5705,12907,5907],{"class":5718},[5705,12909,5910],{"class":5726},[5705,12911,5618],{"class":5913},[5705,12913,5580],{"class":5726},[5705,12915,7297],{"class":5913},[5705,12917,5922],{"class":5726},[5705,12919,5579],{"class":5722},[5705,12921,5763],{"class":5726},[5705,12923,5749],{"class":5748},[5705,12925,7154],{"class":5726},[5705,12927,7157],{"class":5748},[5705,12929,5769],{"class":5726},[5705,12931,7157],{"class":5718},[5705,12933,6028],{"class":5726},[5705,12935,12936],{"class":5707,"line":6057},[5705,12937,5795],{"emptyLinePlaceholder":5794},[5705,12939,12940],{"class":5707,"line":6072},[5705,12941,12942],{"class":5711},"  \u002F\u002F Реф для зберігання функції fetch (уникаємо застарілих замикань)\n",[5705,12944,12945,12947,12950,12952,12954,12957,12959,12962,12964,12966],{"class":5707,"line":6093},[5705,12946,5907],{"class":5718},[5705,12948,12949],{"class":5913}," fetchDataRef",[5705,12951,6525],{"class":5726},[5705,12953,5586],{"class":5722},[5705,12955,12956],{"class":5726},"\u003C() ",[5705,12958,5955],{"class":5718},[5705,12960,12961],{"class":5748}," Promise",[5705,12963,5763],{"class":5726},[5705,12965,7393],{"class":5748},[5705,12967,12968],{"class":5726},">>();\n",[5705,12970,12971],{"class":5707,"line":6112},[5705,12972,5795],{"emptyLinePlaceholder":5794},[5705,12974,12975,12978,12980,12983,12985,12988,12990,12992],{"class":5707,"line":6118},[5705,12976,12977],{"class":5741},"  fetchDataRef",[5705,12979,5622],{"class":5726},[5705,12981,12982],{"class":5722},"current",[5705,12984,6525],{"class":5726},[5705,12986,12987],{"class":5718},"async",[5705,12989,6064],{"class":5726},[5705,12991,5955],{"class":5718},[5705,12993,6069],{"class":5726},[5705,12995,12996,12998],{"class":5707,"line":6124},[5705,12997,8392],{"class":6060},[5705,12999,6069],{"class":5726},[5705,13001,13002,13005,13007,13009],{"class":5707,"line":6129},[5705,13003,13004],{"class":5722},"      setIsLoading",[5705,13006,5738],{"class":5726},[5705,13008,5979],{"class":5718},[5705,13010,6028],{"class":5726},[5705,13012,13013,13016,13018,13020],{"class":5707,"line":6141},[5705,13014,13015],{"class":5722},"      setError",[5705,13017,5738],{"class":5726},[5705,13019,7157],{"class":5718},[5705,13021,6028],{"class":5726},[5705,13023,13024],{"class":5707,"line":6389},[5705,13025,5795],{"emptyLinePlaceholder":5794},[5705,13027,13028,13030,13032,13034,13036,13038,13040,13042],{"class":5707,"line":6408},[5705,13029,8399],{"class":5718},[5705,13031,7436],{"class":5913},[5705,13033,6525],{"class":5726},[5705,13035,7441],{"class":6060},[5705,13037,7444],{"class":5722},[5705,13039,5738],{"class":5726},[5705,13041,5742],{"class":5741},[5705,13043,6028],{"class":5726},[5705,13045,13046],{"class":5707,"line":6413},[5705,13047,5795],{"emptyLinePlaceholder":5794},[5705,13049,13050,13052,13054,13056,13058,13060],{"class":5707,"line":6419},[5705,13051,8757],{"class":6060},[5705,13053,7468],{"class":5726},[5705,13055,7471],{"class":5741},[5705,13057,5622],{"class":5726},[5705,13059,7476],{"class":5741},[5705,13061,7479],{"class":5726},[5705,13063,13064,13067,13069,13071,13073,13076,13078,13080,13082,13084,13086,13088,13090,13092,13094,13096,13098,13100],{"class":5707,"line":6430},[5705,13065,13066],{"class":6060},"        throw",[5705,13068,7487],{"class":5718},[5705,13070,7490],{"class":5722},[5705,13072,5738],{"class":5726},[5705,13074,13075],{"class":6019},"`HTTP ",[5705,13077,6570],{"class":5718},[5705,13079,7471],{"class":5741},[5705,13081,5622],{"class":7502},[5705,13083,7505],{"class":5741},[5705,13085,6587],{"class":5718},[5705,13087,5745],{"class":6019},[5705,13089,6570],{"class":5718},[5705,13091,7471],{"class":5741},[5705,13093,5622],{"class":7502},[5705,13095,7518],{"class":5741},[5705,13097,6587],{"class":5718},[5705,13099,6590],{"class":6019},[5705,13101,6028],{"class":5726},[5705,13103,13104],{"class":5707,"line":6449},[5705,13105,7696],{"class":5726},[5705,13107,13108],{"class":5707,"line":6468},[5705,13109,5795],{"emptyLinePlaceholder":5794},[5705,13111,13112,13114,13116,13118,13120,13122,13124,13126,13128,13130],{"class":5707,"line":6473},[5705,13113,8399],{"class":5718},[5705,13115,7540],{"class":5913},[5705,13117,5745],{"class":5726},[5705,13119,5766],{"class":5748},[5705,13121,6525],{"class":5726},[5705,13123,7441],{"class":6060},[5705,13125,7436],{"class":5741},[5705,13127,5622],{"class":5726},[5705,13129,7555],{"class":5722},[5705,13131,7353],{"class":5726},[5705,13133,13134,13137,13139,13141],{"class":5707,"line":6482},[5705,13135,13136],{"class":5722},"      setData",[5705,13138,5738],{"class":5726},[5705,13140,7567],{"class":5741},[5705,13142,6028],{"class":5726},[5705,13144,13145,13147,13149,13151,13153],{"class":5707,"line":6487},[5705,13146,8466],{"class":5726},[5705,13148,7577],{"class":6060},[5705,13150,7055],{"class":5726},[5705,13152,7582],{"class":5741},[5705,13154,7479],{"class":5726},[5705,13156,13157,13159,13161,13163,13165,13167],{"class":5707,"line":6496},[5705,13158,8757],{"class":6060},[5705,13160,7055],{"class":5726},[5705,13162,7582],{"class":5741},[5705,13164,7600],{"class":5718},[5705,13166,7490],{"class":5748},[5705,13168,7479],{"class":5726},[5705,13170,13171,13173,13175,13177,13179,13181],{"class":5707,"line":7008},[5705,13172,7418],{"class":5722},[5705,13174,5738],{"class":5726},[5705,13176,7582],{"class":5741},[5705,13178,5622],{"class":5726},[5705,13180,7634],{"class":5741},[5705,13182,6028],{"class":5726},[5705,13184,13185],{"class":5707,"line":7014},[5705,13186,7696],{"class":5726},[5705,13188,13189,13191,13193],{"class":5707,"line":7020},[5705,13190,8466],{"class":5726},[5705,13192,7649],{"class":6060},[5705,13194,6069],{"class":5726},[5705,13196,13197,13199,13201,13203],{"class":5707,"line":7026},[5705,13198,13004],{"class":5722},[5705,13200,5738],{"class":5726},[5705,13202,5998],{"class":5718},[5705,13204,6028],{"class":5726},[5705,13206,13207],{"class":5707,"line":7032},[5705,13208,6333],{"class":5726},[5705,13210,13211],{"class":5707,"line":7037},[5705,13212,8714],{"class":5726},[5705,13214,13215],{"class":5707,"line":7639},[5705,13216,5795],{"emptyLinePlaceholder":5794},[5705,13218,13219,13221,13223,13225],{"class":5707,"line":7644},[5705,13220,5949],{"class":5722},[5705,13222,5952],{"class":5726},[5705,13224,5955],{"class":5718},[5705,13226,6069],{"class":5726},[5705,13228,13229],{"class":5707,"line":7654},[5705,13230,13231],{"class":5711},"    \u002F\u002F Перший запит негайно\n",[5705,13233,13234,13237,13239,13241],{"class":5707,"line":7660},[5705,13235,13236],{"class":5741},"    fetchDataRef",[5705,13238,5622],{"class":5726},[5705,13240,12982],{"class":5722},[5705,13242,13243],{"class":5726},"?.();\n",[5705,13245,13246],{"class":5707,"line":7676},[5705,13247,5795],{"emptyLinePlaceholder":5794},[5705,13249,13250],{"class":5707,"line":7688},[5705,13251,13252],{"class":5711},"    \u002F\u002F Наступні запити через інтервал\n",[5705,13254,13255,13257,13260,13262,13265,13267,13269],{"class":5707,"line":7693},[5705,13256,7339],{"class":5718},[5705,13258,13259],{"class":5913}," intervalId",[5705,13261,6525],{"class":5726},[5705,13263,13264],{"class":5722},"setInterval",[5705,13266,5952],{"class":5726},[5705,13268,5955],{"class":5718},[5705,13270,6069],{"class":5726},[5705,13272,13273,13276,13278,13280],{"class":5707,"line":7699},[5705,13274,13275],{"class":5741},"      fetchDataRef",[5705,13277,5622],{"class":5726},[5705,13279,12982],{"class":5722},[5705,13281,13243],{"class":5726},[5705,13283,13284,13286,13288],{"class":5707,"line":7704},[5705,13285,9356],{"class":5726},[5705,13287,12650],{"class":5741},[5705,13289,6028],{"class":5726},[5705,13291,13292],{"class":5707,"line":7709},[5705,13293,5795],{"emptyLinePlaceholder":5794},[5705,13295,13296,13298,13300,13302],{"class":5707,"line":7717},[5705,13297,6061],{"class":6060},[5705,13299,6064],{"class":5726},[5705,13301,5955],{"class":5718},[5705,13303,6069],{"class":5726},[5705,13305,13306,13309,13311,13314],{"class":5707,"line":7722},[5705,13307,13308],{"class":5722},"      clearInterval",[5705,13310,5738],{"class":5726},[5705,13312,13313],{"class":5741},"intervalId",[5705,13315,6028],{"class":5726},[5705,13317,13318],{"class":5707,"line":7728},[5705,13319,6115],{"class":5726},[5705,13321,13322,13324,13326,13328,13330],{"class":5707,"line":7739},[5705,13323,7760],{"class":5726},[5705,13325,5742],{"class":5741},[5705,13327,5580],{"class":5726},[5705,13329,12650],{"class":5741},[5705,13331,8935],{"class":5726},[5705,13333,13334],{"class":5707,"line":7752},[5705,13335,5795],{"emptyLinePlaceholder":5794},[5705,13337,13338,13340,13342,13344,13346,13348,13350,13352],{"class":5707,"line":7757},[5705,13339,6132],{"class":6060},[5705,13341,5958],{"class":5726},[5705,13343,5621],{"class":5741},[5705,13345,5580],{"class":5726},[5705,13347,7265],{"class":5741},[5705,13349,5580],{"class":5726},[5705,13351,5618],{"class":5741},[5705,13353,7793],{"class":5726},[5705,13355,13356],{"class":5707,"line":7771},[5705,13357,6144],{"class":5726},[5705,13359,13360],{"class":5707,"line":7776},[5705,13361,5795],{"emptyLinePlaceholder":5794},[5705,13363,13364],{"class":5707,"line":7796},[5705,13365,12280],{"class":5711},[5705,13367,13368,13370,13373],{"class":5707,"line":12343},[5705,13369,7132],{"class":5718},[5705,13371,13372],{"class":5748}," ServerStatus",[5705,13374,6069],{"class":5726},[5705,13376,13377,13380,13382,13384,13386,13388],{"class":5707,"line":12351},[5705,13378,13379],{"class":5741},"  status",[5705,13381,5745],{"class":5726},[5705,13383,6020],{"class":6019},[5705,13385,7154],{"class":5726},[5705,13387,6042],{"class":6019},[5705,13389,6138],{"class":5726},[5705,13391,13392,13395,13397,13399],{"class":5707,"line":12364},[5705,13393,13394],{"class":5741},"  uptime",[5705,13396,5745],{"class":5726},[5705,13398,5786],{"class":5748},[5705,13400,6138],{"class":5726},[5705,13402,13403,13406,13408,13410],{"class":5707,"line":12400},[5705,13404,13405],{"class":5741},"  lastCheck",[5705,13407,5745],{"class":5726},[5705,13409,5749],{"class":5748},[5705,13411,6138],{"class":5726},[5705,13413,13414],{"class":5707,"line":12410},[5705,13415,6144],{"class":5726},[5705,13417,13418],{"class":5707,"line":12425},[5705,13419,5795],{"emptyLinePlaceholder":5794},[5705,13421,13422,13424,13427],{"class":5707,"line":12457},[5705,13423,5719],{"class":5718},[5705,13425,13426],{"class":5722}," ServerMonitor",[5705,13428,5902],{"class":5726},[5705,13430,13431,13433,13435,13437,13439,13441,13443,13445,13447,13449,13451,13454],{"class":5707,"line":12462},[5705,13432,5907],{"class":5718},[5705,13434,5958],{"class":5726},[5705,13436,5621],{"class":5913},[5705,13438,5580],{"class":5726},[5705,13440,7265],{"class":5913},[5705,13442,5580],{"class":5726},[5705,13444,5618],{"class":5913},[5705,13446,7365],{"class":5726},[5705,13448,12617],{"class":5722},[5705,13450,5763],{"class":5726},[5705,13452,13453],{"class":5748},"ServerStatus",[5705,13455,7918],{"class":5726},[5705,13457,13458,13461],{"class":5707,"line":12495},[5705,13459,13460],{"class":6019},"    \"https:\u002F\u002Fapi.example.com\u002Fstatus\"",[5705,13462,8298],{"class":5726},[5705,13464,13465,13468],{"class":5707,"line":12536},[5705,13466,13467],{"class":9489},"    5000",[5705,13469,13470],{"class":5711}," \u002F\u002F Опитування кожні 5 секунд\n",[5705,13472,13473],{"class":5707,"line":12545},[5705,13474,6628],{"class":5726},[5705,13476,13477],{"class":5707,"line":12550},[5705,13478,5795],{"emptyLinePlaceholder":5794},[5705,13480,13482,13484,13486,13488],{"class":5707,"line":13481},67,[5705,13483,7945],{"class":6060},[5705,13485,7055],{"class":5726},[5705,13487,5618],{"class":5741},[5705,13489,7479],{"class":5726},[5705,13491,13493,13495,13497,13499,13501,13503,13505,13507,13509,13511,13513,13515,13517,13519,13521],{"class":5707,"line":13492},68,[5705,13494,6061],{"class":6060},[5705,13496,7958],{"class":6549},[5705,13498,6554],{"class":6553},[5705,13500,6558],{"class":6557},[5705,13502,6561],{"class":5726},[5705,13504,8013],{"class":6019},[5705,13506,6780],{"class":6549},[5705,13508,8018],{"class":5726},[5705,13510,6564],{"class":5718},[5705,13512,5618],{"class":5741},[5705,13514,6587],{"class":5718},[5705,13516,6803],{"class":6549},[5705,13518,6554],{"class":6553},[5705,13520,6780],{"class":6549},[5705,13522,6138],{"class":5726},[5705,13524,13526],{"class":5707,"line":13525},69,[5705,13527,6940],{"class":5726},[5705,13529,13531],{"class":5707,"line":13530},70,[5705,13532,5795],{"emptyLinePlaceholder":5794},[5705,13534,13536,13538],{"class":5707,"line":13535},71,[5705,13537,6132],{"class":6060},[5705,13539,6544],{"class":5726},[5705,13541,13543,13545,13547,13549,13551,13554],{"class":5707,"line":13542},72,[5705,13544,6550],{"class":6549},[5705,13546,6554],{"class":6553},[5705,13548,6558],{"class":6557},[5705,13550,6561],{"class":5726},[5705,13552,13553],{"class":6019},"\"monitor\"",[5705,13555,6595],{"class":6549},[5705,13557,13559,13561,13563,13565,13568,13570,13572,13574,13576,13578,13581,13583,13585,13587],{"class":5707,"line":13558},73,[5705,13560,6600],{"class":5718},[5705,13562,7265],{"class":5741},[5705,13564,9676],{"class":5726},[5705,13566,13567],{"class":5726}," !",[5705,13569,5621],{"class":5741},[5705,13571,9676],{"class":5726},[5705,13573,7958],{"class":6549},[5705,13575,5479],{"class":6553},[5705,13577,6780],{"class":6549},[5705,13579,13580],{"class":7502},"Ініціалізація...",[5705,13582,6803],{"class":6549},[5705,13584,5479],{"class":6553},[5705,13586,6780],{"class":6549},[5705,13588,6144],{"class":5718},[5705,13590,13592],{"class":5707,"line":13591},74,[5705,13593,13594],{"class":5726},"      \n",[5705,13596,13598,13600,13602,13604],{"class":5707,"line":13597},75,[5705,13599,6600],{"class":5718},[5705,13601,5621],{"class":5741},[5705,13603,9676],{"class":5726},[5705,13605,6544],{"class":7502},[5705,13607,13609],{"class":5707,"line":13608},76,[5705,13610,13611],{"class":6549},"        \u003C>\n",[5705,13613,13615,13617,13619,13621,13624,13626,13628,13630,13632,13634,13636,13638,13640,13642,13644,13646,13648,13650],{"class":5707,"line":13614},77,[5705,13616,10727],{"class":6549},[5705,13618,5570],{"class":6553},[5705,13620,6780],{"class":6549},[5705,13622,13623],{"class":7502},"Статус сервера: ",[5705,13625,6564],{"class":5718},[5705,13627,5621],{"class":5741},[5705,13629,5622],{"class":7502},[5705,13631,7505],{"class":5741},[5705,13633,9137],{"class":5726},[5705,13635,6578],{"class":6019},[5705,13637,6575],{"class":5726},[5705,13639,6607],{"class":6019},[5705,13641,6581],{"class":5726},[5705,13643,6612],{"class":6019},[5705,13645,6587],{"class":5718},[5705,13647,6803],{"class":6549},[5705,13649,5570],{"class":6553},[5705,13651,6595],{"class":6549},[5705,13653,13655,13657,13659,13661,13664,13666,13668,13670,13673,13675,13678,13680,13682],{"class":5707,"line":13654},78,[5705,13656,10727],{"class":6549},[5705,13658,5479],{"class":6553},[5705,13660,6780],{"class":6549},[5705,13662,13663],{"class":7502},"Uptime: ",[5705,13665,6564],{"class":5718},[5705,13667,5621],{"class":5741},[5705,13669,5622],{"class":7502},[5705,13671,13672],{"class":5741},"uptime",[5705,13674,6587],{"class":5718},[5705,13676,13677],{"class":7502}," секунд",[5705,13679,6803],{"class":6549},[5705,13681,5479],{"class":6553},[5705,13683,6595],{"class":6549},[5705,13685,13687,13689,13691,13693,13696,13698,13700,13702,13705,13707,13709,13711],{"class":5707,"line":13686},79,[5705,13688,10727],{"class":6549},[5705,13690,5479],{"class":6553},[5705,13692,6780],{"class":6549},[5705,13694,13695],{"class":7502},"Остання перевірка: ",[5705,13697,6564],{"class":5718},[5705,13699,5621],{"class":5741},[5705,13701,5622],{"class":7502},[5705,13703,13704],{"class":5741},"lastCheck",[5705,13706,6587],{"class":5718},[5705,13708,6803],{"class":6549},[5705,13710,5479],{"class":6553},[5705,13712,6595],{"class":6549},[5705,13714,13716],{"class":5707,"line":13715},80,[5705,13717,13718],{"class":6549},"        \u003C\u002F>\n",[5705,13720,13722,13724],{"class":5707,"line":13721},81,[5705,13723,9796],{"class":7502},[5705,13725,6144],{"class":5718},[5705,13727,13729],{"class":5707,"line":13728},82,[5705,13730,13594],{"class":5726},[5705,13732,13734,13736,13738,13740,13742,13744,13746,13748,13751,13753,13756,13758,13760,13762],{"class":5707,"line":13733},83,[5705,13735,6600],{"class":5718},[5705,13737,7265],{"class":5741},[5705,13739,9676],{"class":5726},[5705,13741,7958],{"class":6549},[5705,13743,5705],{"class":6553},[5705,13745,6558],{"class":6557},[5705,13747,6561],{"class":5726},[5705,13749,13750],{"class":6019},"\"refresh-indicator\"",[5705,13752,6780],{"class":6549},[5705,13754,13755],{"class":7502},"🔄 Оновлення...",[5705,13757,6803],{"class":6549},[5705,13759,5705],{"class":6553},[5705,13761,6780],{"class":6549},[5705,13763,6144],{"class":5718},[5705,13765,13767,13769,13771],{"class":5707,"line":13766},84,[5705,13768,6619],{"class":6549},[5705,13770,6554],{"class":6553},[5705,13772,6595],{"class":6549},[5705,13774,13776],{"class":5707,"line":13775},85,[5705,13777,6628],{"class":5726},[5705,13779,13781],{"class":5707,"line":13780},86,[5705,13782,6144],{"class":5726},[5479,13784,13785],{},[5483,13786,12557],{},[6642,13788,13789,13803,13816,13827],{},[5506,13790,13791,13796,13797,13799,13800,13802],{},[5483,13792,13793],{},[5535,13794,13795],{},"fetchDataRef.current = async () => { ... }"," — зберігаємо функцію завантаження даних у рефі. Це дозволяє ",[5535,13798,13264],{}," завжди викликати актуальну версію функції, яка має свіжі значення ",[5535,13801,5742],{}," із замикання.",[5506,13804,13805,13810,13811,13813,13814,5622],{},[5483,13806,13807],{},[5535,13808,13809],{},"fetchDataRef.current?.()"," — перший виклик відбувається негайно при монтуванні або зміні ",[5535,13812,5742],{},"\u002F",[5535,13815,12650],{},[5506,13817,13818,13823,13824,13826],{},[5483,13819,13820],{},[5535,13821,13822],{},"setInterval(() => { fetchDataRef.current?.(); }, intervalMs)"," — створюємо таймер, що викликає функцію кожні ",[5535,13825,12650],{}," мілісекунд.",[5506,13828,13829,13834],{},[5483,13830,13831],{},[5535,13832,13833],{},"clearInterval(intervalId)"," — очищаємо таймер при розмонтуванні або зміні залежностей.",[5479,13836,13837,13839],{},[5483,13838,10072],{}," Компонент автоматично опитує API кожні 5 секунд, показуючи актуальний статус сервера без ручного оновлення сторінки.",[5567,13841],{},[5570,13843,13845],{"id":13844},"архітектурні-патерни-організації-кастомних-хуків","Архітектурні патерни організації кастомних хуків",[5479,13847,13848],{},"У великих проєктах кількість кастомних хуків може зрости до десятків або сотень. Важливо організувати їх структуровано.",[5685,13850,13852],{"id":13851},"рекомендована-структура-папок","Рекомендована структура папок",[5696,13854,13858],{"className":13855,"code":13857,"language":12298,"meta":5701},[13856],"language-text","src\u002F\n├── hooks\u002F\n│   ├── api\u002F\n│   │   ├── useFetch.ts\n│   │   ├── usePolling.ts\n│   │   └── useMutation.ts\n│   ├── browser\u002F\n│   │   ├── useOnlineStatus.ts\n│   │   ├── useWindowSize.ts\n│   │   └── useMediaQuery.ts\n│   ├── form\u002F\n│   │   ├── useFormValidation.ts\n│   │   ├── useAutoSave.ts\n│   │   └── useDebounce.ts\n│   ├── storage\u002F\n│   │   ├── useLocalStorage.ts\n│   │   └── useSessionStorage.ts\n│   └── index.ts  \u002F\u002F Barrel export\n├── components\u002F\n└── ...\n",[5535,13859,13857],{"__ignoreMap":5701},[5479,13861,13862],{},[5483,13863,13864,13865,5532],{},"Barrel export (",[5535,13866,13867],{},"src\u002Fhooks\u002Findex.ts",[5696,13869,13871],{"className":5698,"code":13870,"language":5700,"meta":5701,"style":5701},"\u002F\u002F API хуки\nexport { useFetch } from \".\u002Fapi\u002FuseFetch\";\nexport { usePolling } from \".\u002Fapi\u002FusePolling\";\nexport { useMutation } from \".\u002Fapi\u002FuseMutation\";\n\n\u002F\u002F Browser хуки\nexport { useOnlineStatus } from \".\u002Fbrowser\u002FuseOnlineStatus\";\nexport { useWindowSize } from \".\u002Fbrowser\u002FuseWindowSize\";\nexport { useMediaQuery } from \".\u002Fbrowser\u002FuseMediaQuery\";\n\n\u002F\u002F Form хуки\nexport { useFormValidation } from \".\u002Fform\u002FuseFormValidation\";\nexport { useAutoSave } from \".\u002Fform\u002FuseAutoSave\";\nexport { useDebounce } from \".\u002Fform\u002FuseDebounce\";\n\n\u002F\u002F Storage хуки\nexport { useLocalStorage } from \".\u002Fstorage\u002FuseLocalStorage\";\nexport { useSessionStorage } from \".\u002Fstorage\u002FuseSessionStorage\";\n",[5535,13872,13873,13878,13895,13912,13930,13934,13939,13956,13973,13991,13995,14000,14018,14035,14052,14056,14061,14078],{"__ignoreMap":5701},[5705,13874,13875],{"class":5707,"line":5708},[5705,13876,13877],{"class":5711},"\u002F\u002F API хуки\n",[5705,13879,13880,13882,13884,13886,13888,13890,13893],{"class":5707,"line":5715},[5705,13881,6242],{"class":6060},[5705,13883,5958],{"class":5726},[5705,13885,5885],{"class":5741},[5705,13887,6225],{"class":5726},[5705,13889,6228],{"class":6060},[5705,13891,13892],{"class":6019}," \".\u002Fapi\u002FuseFetch\"",[5705,13894,6138],{"class":5726},[5705,13896,13897,13899,13901,13903,13905,13907,13910],{"class":5707,"line":5730},[5705,13898,6242],{"class":6060},[5705,13900,5958],{"class":5726},[5705,13902,12617],{"class":5741},[5705,13904,6225],{"class":5726},[5705,13906,6228],{"class":6060},[5705,13908,13909],{"class":6019}," \".\u002Fapi\u002FusePolling\"",[5705,13911,6138],{"class":5726},[5705,13913,13914,13916,13918,13921,13923,13925,13928],{"class":5707,"line":5755},[5705,13915,6242],{"class":6060},[5705,13917,5958],{"class":5726},[5705,13919,13920],{"class":5741},"useMutation",[5705,13922,6225],{"class":5726},[5705,13924,6228],{"class":6060},[5705,13926,13927],{"class":6019}," \".\u002Fapi\u002FuseMutation\"",[5705,13929,6138],{"class":5726},[5705,13931,13932],{"class":5707,"line":5791},[5705,13933,5795],{"emptyLinePlaceholder":5794},[5705,13935,13936],{"class":5707,"line":5798},[5705,13937,13938],{"class":5711},"\u002F\u002F Browser хуки\n",[5705,13940,13941,13943,13945,13947,13949,13951,13954],{"class":5707,"line":5804},[5705,13942,6242],{"class":6060},[5705,13944,5958],{"class":5726},[5705,13946,5882],{"class":5741},[5705,13948,6225],{"class":5726},[5705,13950,6228],{"class":6060},[5705,13952,13953],{"class":6019}," \".\u002Fbrowser\u002FuseOnlineStatus\"",[5705,13955,6138],{"class":5726},[5705,13957,13958,13960,13962,13964,13966,13968,13971],{"class":5707,"line":5818},[5705,13959,6242],{"class":6060},[5705,13961,5958],{"class":5726},[5705,13963,10912],{"class":5741},[5705,13965,6225],{"class":5726},[5705,13967,6228],{"class":6060},[5705,13969,13970],{"class":6019}," \".\u002Fbrowser\u002FuseWindowSize\"",[5705,13972,6138],{"class":5726},[5705,13974,13975,13977,13979,13982,13984,13986,13989],{"class":5707,"line":6031},[5705,13976,6242],{"class":6060},[5705,13978,5958],{"class":5726},[5705,13980,13981],{"class":5741},"useMediaQuery",[5705,13983,6225],{"class":5726},[5705,13985,6228],{"class":6060},[5705,13987,13988],{"class":6019}," \".\u002Fbrowser\u002FuseMediaQuery\"",[5705,13990,6138],{"class":5726},[5705,13992,13993],{"class":5707,"line":6052},[5705,13994,5795],{"emptyLinePlaceholder":5794},[5705,13996,13997],{"class":5707,"line":6057},[5705,13998,13999],{"class":5711},"\u002F\u002F Form хуки\n",[5705,14001,14002,14004,14006,14009,14011,14013,14016],{"class":5707,"line":6072},[5705,14003,6242],{"class":6060},[5705,14005,5958],{"class":5726},[5705,14007,14008],{"class":5741},"useFormValidation",[5705,14010,6225],{"class":5726},[5705,14012,6228],{"class":6060},[5705,14014,14015],{"class":6019}," \".\u002Fform\u002FuseFormValidation\"",[5705,14017,6138],{"class":5726},[5705,14019,14020,14022,14024,14026,14028,14030,14033],{"class":5707,"line":6093},[5705,14021,6242],{"class":6060},[5705,14023,5958],{"class":5726},[5705,14025,11617],{"class":5741},[5705,14027,6225],{"class":5726},[5705,14029,6228],{"class":6060},[5705,14031,14032],{"class":6019}," \".\u002Fform\u002FuseAutoSave\"",[5705,14034,6138],{"class":5726},[5705,14036,14037,14039,14041,14043,14045,14047,14050],{"class":5707,"line":6112},[5705,14038,6242],{"class":6060},[5705,14040,5958],{"class":5726},[5705,14042,9200],{"class":5741},[5705,14044,6225],{"class":5726},[5705,14046,6228],{"class":6060},[5705,14048,14049],{"class":6019}," \".\u002Fform\u002FuseDebounce\"",[5705,14051,6138],{"class":5726},[5705,14053,14054],{"class":5707,"line":6118},[5705,14055,5795],{"emptyLinePlaceholder":5794},[5705,14057,14058],{"class":5707,"line":6124},[5705,14059,14060],{"class":5711},"\u002F\u002F Storage хуки\n",[5705,14062,14063,14065,14067,14069,14071,14073,14076],{"class":5707,"line":6129},[5705,14064,6242],{"class":6060},[5705,14066,5958],{"class":5726},[5705,14068,5888],{"class":5741},[5705,14070,6225],{"class":5726},[5705,14072,6228],{"class":6060},[5705,14074,14075],{"class":6019}," \".\u002Fstorage\u002FuseLocalStorage\"",[5705,14077,6138],{"class":5726},[5705,14079,14080,14082,14084,14087,14089,14091,14094],{"class":5707,"line":6141},[5705,14081,6242],{"class":6060},[5705,14083,5958],{"class":5726},[5705,14085,14086],{"class":5741},"useSessionStorage",[5705,14088,6225],{"class":5726},[5705,14090,6228],{"class":6060},[5705,14092,14093],{"class":6019}," \".\u002Fstorage\u002FuseSessionStorage\"",[5705,14095,6138],{"class":5726},[5479,14097,14098],{},[5483,14099,14100],{},"Використання:",[5696,14102,14104],{"className":5698,"code":14103,"language":5700,"meta":5701,"style":5701},"import { useFetch, useOnlineStatus, useLocalStorage } from \"@\u002Fhooks\";\n",[5535,14105,14106],{"__ignoreMap":5701},[5705,14107,14108,14110,14112,14114,14116,14118,14120,14122,14124,14126,14129],{"class":5707,"line":5708},[5705,14109,6214],{"class":6060},[5705,14111,5958],{"class":5726},[5705,14113,5885],{"class":5741},[5705,14115,5580],{"class":5726},[5705,14117,5882],{"class":5741},[5705,14119,5580],{"class":5726},[5705,14121,5888],{"class":5741},[5705,14123,6225],{"class":5726},[5705,14125,6228],{"class":6060},[5705,14127,14128],{"class":6019}," \"@\u002Fhooks\"",[5705,14130,6138],{"class":5726},[5567,14132],{},[5570,14134,14136],{"id":14135},"тестування-кастомних-хуків","Тестування кастомних хуків",[5479,14138,14139,14140,14143,14144,14147],{},"Кастомні хуки можна тестувати ізольовано за допомогою ",[5535,14141,14142],{},"@testing-library\u002Freact-hooks"," (для React ≤ 18) або ",[5535,14145,14146],{},"@testing-library\u002Freact"," (для React 19+).",[5685,14149,14151,14152],{"id":14150},"приклад-тесту-для-usedebounce","Приклад тесту для ",[5535,14153,9200],{},[5696,14155,14157],{"className":5698,"code":14156,"language":5700,"meta":5701,"style":5701},"import { renderHook, act } from \"@testing-library\u002Freact\";\nimport { useDebounce } from \".\u002FuseDebounce\";\n\ndescribe(\"useDebounce\", () => {\n  beforeEach(() => {\n    jest.useFakeTimers();\n  });\n\n  afterEach(() => {\n    jest.useRealTimers();\n  });\n\n  it(\"повертає початкове значення негайно\", () => {\n    const { result } = renderHook(() => useDebounce(\"initial\", 500));\n    expect(result.current).toBe(\"initial\");\n  });\n\n  it(\"оновлює значення після затримки\", () => {\n    const { result, rerender } = renderHook(\n      ({ value, delay }) => useDebounce(value, delay),\n      { initialProps: { value: \"first\", delay: 500 } }\n    );\n\n    expect(result.current).toBe(\"first\");\n\n    \u002F\u002F Змінюємо value\n    rerender({ value: \"second\", delay: 500 });\n\n    \u002F\u002F Значення ще не оновилося\n    expect(result.current).toBe(\"first\");\n\n    \u002F\u002F Прокручуємо час на 500мс\n    act(() => {\n      jest.advanceTimersByTime(500);\n    });\n\n    \u002F\u002F Тепер значення оновилося\n    expect(result.current).toBe(\"second\");\n  });\n\n  it(\"скидає таймер при повторній зміні\", () => {\n    const { result, rerender } = renderHook(\n      ({ value }) => useDebounce(value, 500),\n      { initialProps: { value: \"a\" } }\n    );\n\n    rerender({ value: \"b\" });\n    act(() => { jest.advanceTimersByTime(300); });\n\n    rerender({ value: \"c\" });\n    act(() => { jest.advanceTimersByTime(300); });\n\n    \u002F\u002F Значення досі \"a\", бо таймер постійно скидався\n    expect(result.current).toBe(\"a\");\n\n    \u002F\u002F Тепер чекаємо повні 500мс\n    act(() => { jest.advanceTimersByTime(500); });\n\n    \u002F\u002F Значення оновилося до останнього\n    expect(result.current).toBe(\"c\");\n  });\n});\n",[5535,14158,14159,14182,14199,14203,14220,14231,14243,14247,14251,14262,14273,14277,14281,14297,14326,14350,14354,14358,14373,14392,14421,14448,14453,14457,14480,14484,14489,14509,14513,14518,14540,14544,14549,14560,14576,14581,14585,14590,14613,14617,14621,14636,14654,14676,14691,14695,14699,14712,14737,14741,14754,14776,14780,14785,14808,14812,14817,14839,14843,14848,14871,14875],{"__ignoreMap":5701},[5705,14160,14161,14163,14165,14168,14170,14173,14175,14177,14180],{"class":5707,"line":5708},[5705,14162,6214],{"class":6060},[5705,14164,5958],{"class":5726},[5705,14166,14167],{"class":5741},"renderHook",[5705,14169,5580],{"class":5726},[5705,14171,14172],{"class":5741},"act",[5705,14174,6225],{"class":5726},[5705,14176,6228],{"class":6060},[5705,14178,14179],{"class":6019}," \"@testing-library\u002Freact\"",[5705,14181,6138],{"class":5726},[5705,14183,14184,14186,14188,14190,14192,14194,14197],{"class":5707,"line":5715},[5705,14185,6214],{"class":6060},[5705,14187,5958],{"class":5726},[5705,14189,9200],{"class":5741},[5705,14191,6225],{"class":5726},[5705,14193,6228],{"class":6060},[5705,14195,14196],{"class":6019}," \".\u002FuseDebounce\"",[5705,14198,6138],{"class":5726},[5705,14200,14201],{"class":5707,"line":5730},[5705,14202,5795],{"emptyLinePlaceholder":5794},[5705,14204,14205,14208,14210,14213,14216,14218],{"class":5707,"line":5755},[5705,14206,14207],{"class":5722},"describe",[5705,14209,5738],{"class":5726},[5705,14211,14212],{"class":6019},"\"useDebounce\"",[5705,14214,14215],{"class":5726},", () ",[5705,14217,5955],{"class":5718},[5705,14219,6069],{"class":5726},[5705,14221,14222,14225,14227,14229],{"class":5707,"line":5791},[5705,14223,14224],{"class":5722},"  beforeEach",[5705,14226,5952],{"class":5726},[5705,14228,5955],{"class":5718},[5705,14230,6069],{"class":5726},[5705,14232,14233,14236,14238,14241],{"class":5707,"line":5798},[5705,14234,14235],{"class":5741},"    jest",[5705,14237,5622],{"class":5726},[5705,14239,14240],{"class":5722},"useFakeTimers",[5705,14242,7353],{"class":5726},[5705,14244,14245],{"class":5707,"line":5804},[5705,14246,8521],{"class":5726},[5705,14248,14249],{"class":5707,"line":5818},[5705,14250,5795],{"emptyLinePlaceholder":5794},[5705,14252,14253,14256,14258,14260],{"class":5707,"line":6031},[5705,14254,14255],{"class":5722},"  afterEach",[5705,14257,5952],{"class":5726},[5705,14259,5955],{"class":5718},[5705,14261,6069],{"class":5726},[5705,14263,14264,14266,14268,14271],{"class":5707,"line":6052},[5705,14265,14235],{"class":5741},[5705,14267,5622],{"class":5726},[5705,14269,14270],{"class":5722},"useRealTimers",[5705,14272,7353],{"class":5726},[5705,14274,14275],{"class":5707,"line":6057},[5705,14276,8521],{"class":5726},[5705,14278,14279],{"class":5707,"line":6072},[5705,14280,5795],{"emptyLinePlaceholder":5794},[5705,14282,14283,14286,14288,14291,14293,14295],{"class":5707,"line":6093},[5705,14284,14285],{"class":5722},"  it",[5705,14287,5738],{"class":5726},[5705,14289,14290],{"class":6019},"\"повертає початкове значення негайно\"",[5705,14292,14215],{"class":5726},[5705,14294,5955],{"class":5718},[5705,14296,6069],{"class":5726},[5705,14298,14299,14301,14303,14305,14307,14309,14311,14313,14315,14317,14320,14322,14324],{"class":5707,"line":6112},[5705,14300,7339],{"class":5718},[5705,14302,5958],{"class":5726},[5705,14304,7567],{"class":5913},[5705,14306,7365],{"class":5726},[5705,14308,14167],{"class":5722},[5705,14310,5952],{"class":5726},[5705,14312,5955],{"class":5718},[5705,14314,5760],{"class":5722},[5705,14316,5738],{"class":5726},[5705,14318,14319],{"class":6019},"\"initial\"",[5705,14321,5580],{"class":5726},[5705,14323,9490],{"class":9489},[5705,14325,8666],{"class":5726},[5705,14327,14328,14331,14333,14335,14337,14339,14341,14344,14346,14348],{"class":5707,"line":6118},[5705,14329,14330],{"class":5722},"    expect",[5705,14332,5738],{"class":5726},[5705,14334,7567],{"class":5741},[5705,14336,5622],{"class":5726},[5705,14338,12982],{"class":5741},[5705,14340,5609],{"class":5726},[5705,14342,14343],{"class":5722},"toBe",[5705,14345,5738],{"class":5726},[5705,14347,14319],{"class":6019},[5705,14349,6028],{"class":5726},[5705,14351,14352],{"class":5707,"line":6124},[5705,14353,8521],{"class":5726},[5705,14355,14356],{"class":5707,"line":6129},[5705,14357,5795],{"emptyLinePlaceholder":5794},[5705,14359,14360,14362,14364,14367,14369,14371],{"class":5707,"line":6141},[5705,14361,14285],{"class":5722},[5705,14363,5738],{"class":5726},[5705,14365,14366],{"class":6019},"\"оновлює значення після затримки\"",[5705,14368,14215],{"class":5726},[5705,14370,5955],{"class":5718},[5705,14372,6069],{"class":5726},[5705,14374,14375,14377,14379,14381,14383,14386,14388,14390],{"class":5707,"line":6389},[5705,14376,7339],{"class":5718},[5705,14378,5958],{"class":5726},[5705,14380,7567],{"class":5913},[5705,14382,5580],{"class":5726},[5705,14384,14385],{"class":5913},"rerender",[5705,14387,7365],{"class":5726},[5705,14389,14167],{"class":5722},[5705,14391,11676],{"class":5726},[5705,14393,14394,14397,14399,14401,14403,14406,14408,14410,14412,14414,14416,14418],{"class":5707,"line":6408},[5705,14395,14396],{"class":5726},"      ({ ",[5705,14398,5772],{"class":5741},[5705,14400,5580],{"class":5726},[5705,14402,5781],{"class":5741},[5705,14404,14405],{"class":5726}," }) ",[5705,14407,5955],{"class":5718},[5705,14409,5760],{"class":5722},[5705,14411,5738],{"class":5726},[5705,14413,5772],{"class":5741},[5705,14415,5580],{"class":5726},[5705,14417,5781],{"class":5741},[5705,14419,14420],{"class":5726},"),\n",[5705,14422,14423,14426,14429,14431,14434,14437,14439,14442,14445],{"class":5707,"line":6413},[5705,14424,14425],{"class":5726},"      { ",[5705,14427,14428],{"class":5741},"initialProps:",[5705,14430,5958],{"class":5726},[5705,14432,14433],{"class":5741},"value:",[5705,14435,14436],{"class":6019}," \"first\"",[5705,14438,5580],{"class":5726},[5705,14440,14441],{"class":5741},"delay:",[5705,14443,14444],{"class":9489}," 500",[5705,14446,14447],{"class":5726}," } }\n",[5705,14449,14450],{"class":5707,"line":6419},[5705,14451,14452],{"class":5726},"    );\n",[5705,14454,14455],{"class":5707,"line":6430},[5705,14456,5795],{"emptyLinePlaceholder":5794},[5705,14458,14459,14461,14463,14465,14467,14469,14471,14473,14475,14478],{"class":5707,"line":6449},[5705,14460,14330],{"class":5722},[5705,14462,5738],{"class":5726},[5705,14464,7567],{"class":5741},[5705,14466,5622],{"class":5726},[5705,14468,12982],{"class":5741},[5705,14470,5609],{"class":5726},[5705,14472,14343],{"class":5722},[5705,14474,5738],{"class":5726},[5705,14476,14477],{"class":6019},"\"first\"",[5705,14479,6028],{"class":5726},[5705,14481,14482],{"class":5707,"line":6468},[5705,14483,5795],{"emptyLinePlaceholder":5794},[5705,14485,14486],{"class":5707,"line":6473},[5705,14487,14488],{"class":5711},"    \u002F\u002F Змінюємо value\n",[5705,14490,14491,14494,14496,14498,14501,14503,14505,14507],{"class":5707,"line":6482},[5705,14492,14493],{"class":5722},"    rerender",[5705,14495,7870],{"class":5726},[5705,14497,14433],{"class":5741},[5705,14499,14500],{"class":6019}," \"second\"",[5705,14502,5580],{"class":5726},[5705,14504,14441],{"class":5741},[5705,14506,14444],{"class":9489},[5705,14508,7456],{"class":5726},[5705,14510,14511],{"class":5707,"line":6487},[5705,14512,5795],{"emptyLinePlaceholder":5794},[5705,14514,14515],{"class":5707,"line":6496},[5705,14516,14517],{"class":5711},"    \u002F\u002F Значення ще не оновилося\n",[5705,14519,14520,14522,14524,14526,14528,14530,14532,14534,14536,14538],{"class":5707,"line":7008},[5705,14521,14330],{"class":5722},[5705,14523,5738],{"class":5726},[5705,14525,7567],{"class":5741},[5705,14527,5622],{"class":5726},[5705,14529,12982],{"class":5741},[5705,14531,5609],{"class":5726},[5705,14533,14343],{"class":5722},[5705,14535,5738],{"class":5726},[5705,14537,14477],{"class":6019},[5705,14539,6028],{"class":5726},[5705,14541,14542],{"class":5707,"line":7014},[5705,14543,5795],{"emptyLinePlaceholder":5794},[5705,14545,14546],{"class":5707,"line":7020},[5705,14547,14548],{"class":5711},"    \u002F\u002F Прокручуємо час на 500мс\n",[5705,14550,14551,14554,14556,14558],{"class":5707,"line":7026},[5705,14552,14553],{"class":5722},"    act",[5705,14555,5952],{"class":5726},[5705,14557,5955],{"class":5718},[5705,14559,6069],{"class":5726},[5705,14561,14562,14565,14567,14570,14572,14574],{"class":5707,"line":7032},[5705,14563,14564],{"class":5741},"      jest",[5705,14566,5622],{"class":5726},[5705,14568,14569],{"class":5722},"advanceTimersByTime",[5705,14571,5738],{"class":5726},[5705,14573,9490],{"class":9489},[5705,14575,6028],{"class":5726},[5705,14577,14578],{"class":5707,"line":7037},[5705,14579,14580],{"class":5726},"    });\n",[5705,14582,14583],{"class":5707,"line":7639},[5705,14584,5795],{"emptyLinePlaceholder":5794},[5705,14586,14587],{"class":5707,"line":7644},[5705,14588,14589],{"class":5711},"    \u002F\u002F Тепер значення оновилося\n",[5705,14591,14592,14594,14596,14598,14600,14602,14604,14606,14608,14611],{"class":5707,"line":7654},[5705,14593,14330],{"class":5722},[5705,14595,5738],{"class":5726},[5705,14597,7567],{"class":5741},[5705,14599,5622],{"class":5726},[5705,14601,12982],{"class":5741},[5705,14603,5609],{"class":5726},[5705,14605,14343],{"class":5722},[5705,14607,5738],{"class":5726},[5705,14609,14610],{"class":6019},"\"second\"",[5705,14612,6028],{"class":5726},[5705,14614,14615],{"class":5707,"line":7660},[5705,14616,8521],{"class":5726},[5705,14618,14619],{"class":5707,"line":7676},[5705,14620,5795],{"emptyLinePlaceholder":5794},[5705,14622,14623,14625,14627,14630,14632,14634],{"class":5707,"line":7688},[5705,14624,14285],{"class":5722},[5705,14626,5738],{"class":5726},[5705,14628,14629],{"class":6019},"\"скидає таймер при повторній зміні\"",[5705,14631,14215],{"class":5726},[5705,14633,5955],{"class":5718},[5705,14635,6069],{"class":5726},[5705,14637,14638,14640,14642,14644,14646,14648,14650,14652],{"class":5707,"line":7693},[5705,14639,7339],{"class":5718},[5705,14641,5958],{"class":5726},[5705,14643,7567],{"class":5913},[5705,14645,5580],{"class":5726},[5705,14647,14385],{"class":5913},[5705,14649,7365],{"class":5726},[5705,14651,14167],{"class":5722},[5705,14653,11676],{"class":5726},[5705,14655,14656,14658,14660,14662,14664,14666,14668,14670,14672,14674],{"class":5707,"line":7699},[5705,14657,14396],{"class":5726},[5705,14659,5772],{"class":5741},[5705,14661,14405],{"class":5726},[5705,14663,5955],{"class":5718},[5705,14665,5760],{"class":5722},[5705,14667,5738],{"class":5726},[5705,14669,5772],{"class":5741},[5705,14671,5580],{"class":5726},[5705,14673,9490],{"class":9489},[5705,14675,14420],{"class":5726},[5705,14677,14678,14680,14682,14684,14686,14689],{"class":5707,"line":7704},[5705,14679,14425],{"class":5726},[5705,14681,14428],{"class":5741},[5705,14683,5958],{"class":5726},[5705,14685,14433],{"class":5741},[5705,14687,14688],{"class":6019}," \"a\"",[5705,14690,14447],{"class":5726},[5705,14692,14693],{"class":5707,"line":7709},[5705,14694,14452],{"class":5726},[5705,14696,14697],{"class":5707,"line":7717},[5705,14698,5795],{"emptyLinePlaceholder":5794},[5705,14700,14701,14703,14705,14707,14710],{"class":5707,"line":7722},[5705,14702,14493],{"class":5722},[5705,14704,7870],{"class":5726},[5705,14706,14433],{"class":5741},[5705,14708,14709],{"class":6019}," \"b\"",[5705,14711,7456],{"class":5726},[5705,14713,14714,14716,14718,14720,14722,14725,14727,14729,14731,14734],{"class":5707,"line":7728},[5705,14715,14553],{"class":5722},[5705,14717,5952],{"class":5726},[5705,14719,5955],{"class":5718},[5705,14721,5958],{"class":5726},[5705,14723,14724],{"class":5741},"jest",[5705,14726,5622],{"class":5726},[5705,14728,14569],{"class":5722},[5705,14730,5738],{"class":5726},[5705,14732,14733],{"class":9489},"300",[5705,14735,14736],{"class":5726},"); });\n",[5705,14738,14739],{"class":5707,"line":7739},[5705,14740,5795],{"emptyLinePlaceholder":5794},[5705,14742,14743,14745,14747,14749,14752],{"class":5707,"line":7752},[5705,14744,14493],{"class":5722},[5705,14746,7870],{"class":5726},[5705,14748,14433],{"class":5741},[5705,14750,14751],{"class":6019}," \"c\"",[5705,14753,7456],{"class":5726},[5705,14755,14756,14758,14760,14762,14764,14766,14768,14770,14772,14774],{"class":5707,"line":7757},[5705,14757,14553],{"class":5722},[5705,14759,5952],{"class":5726},[5705,14761,5955],{"class":5718},[5705,14763,5958],{"class":5726},[5705,14765,14724],{"class":5741},[5705,14767,5622],{"class":5726},[5705,14769,14569],{"class":5722},[5705,14771,5738],{"class":5726},[5705,14773,14733],{"class":9489},[5705,14775,14736],{"class":5726},[5705,14777,14778],{"class":5707,"line":7771},[5705,14779,5795],{"emptyLinePlaceholder":5794},[5705,14781,14782],{"class":5707,"line":7776},[5705,14783,14784],{"class":5711},"    \u002F\u002F Значення досі \"a\", бо таймер постійно скидався\n",[5705,14786,14787,14789,14791,14793,14795,14797,14799,14801,14803,14806],{"class":5707,"line":7796},[5705,14788,14330],{"class":5722},[5705,14790,5738],{"class":5726},[5705,14792,7567],{"class":5741},[5705,14794,5622],{"class":5726},[5705,14796,12982],{"class":5741},[5705,14798,5609],{"class":5726},[5705,14800,14343],{"class":5722},[5705,14802,5738],{"class":5726},[5705,14804,14805],{"class":6019},"\"a\"",[5705,14807,6028],{"class":5726},[5705,14809,14810],{"class":5707,"line":12343},[5705,14811,5795],{"emptyLinePlaceholder":5794},[5705,14813,14814],{"class":5707,"line":12351},[5705,14815,14816],{"class":5711},"    \u002F\u002F Тепер чекаємо повні 500мс\n",[5705,14818,14819,14821,14823,14825,14827,14829,14831,14833,14835,14837],{"class":5707,"line":12364},[5705,14820,14553],{"class":5722},[5705,14822,5952],{"class":5726},[5705,14824,5955],{"class":5718},[5705,14826,5958],{"class":5726},[5705,14828,14724],{"class":5741},[5705,14830,5622],{"class":5726},[5705,14832,14569],{"class":5722},[5705,14834,5738],{"class":5726},[5705,14836,9490],{"class":9489},[5705,14838,14736],{"class":5726},[5705,14840,14841],{"class":5707,"line":12400},[5705,14842,5795],{"emptyLinePlaceholder":5794},[5705,14844,14845],{"class":5707,"line":12410},[5705,14846,14847],{"class":5711},"    \u002F\u002F Значення оновилося до останнього\n",[5705,14849,14850,14852,14854,14856,14858,14860,14862,14864,14866,14869],{"class":5707,"line":12425},[5705,14851,14330],{"class":5722},[5705,14853,5738],{"class":5726},[5705,14855,7567],{"class":5741},[5705,14857,5622],{"class":5726},[5705,14859,12982],{"class":5741},[5705,14861,5609],{"class":5726},[5705,14863,14343],{"class":5722},[5705,14865,5738],{"class":5726},[5705,14867,14868],{"class":6019},"\"c\"",[5705,14870,6028],{"class":5726},[5705,14872,14873],{"class":5707,"line":12457},[5705,14874,8521],{"class":5726},[5705,14876,14877],{"class":5707,"line":12462},[5705,14878,14879],{"class":5726},"});\n",[5567,14881],{},[5570,14883,14885],{"id":14884},"інтерактивна-демонстрація-композиція-хуків","Інтерактивна демонстрація: композиція хуків",[14887,14888,14892,15445,15726,16377,16948,17195,17381,17928],"react-project-preview",{":height":14889,"entry":14890,"title":14891},"720","src\u002FApp.tsx","Кастомні хуки у дії",[5696,14893,14895],{"className":5698,"code":14894,"filename":14890,"language":5700,"meta":5701,"style":5701},"import { useState } from 'react';\nimport { OnlineStatusDemo } from '.\u002Fcomponents\u002FOnlineStatusDemo';\nimport { SearchDemo } from '.\u002Fcomponents\u002FSearchDemo';\nimport { ThemeDemo } from '.\u002Fcomponents\u002FThemeDemo';\nimport '.\u002Fstyles.css';\n\nexport default function App() {\n  const [activeDemo, setActiveDemo] = useState\u003C'online' | 'search' | 'theme'>('online');\n\n  return (\n    \u003Cdiv className=\"app\">\n      \u003Cheader className=\"header\">\n        \u003Ch1>🎣 Кастомні хуки React\u003C\u002Fh1>\n        \u003Cnav className=\"demo-tabs\">\n          \u003Cbutton\n            className={activeDemo === 'online' ? 'active' : ''}\n            onClick={() => setActiveDemo('online')}\n          >\n            📡 Online Status\n          \u003C\u002Fbutton>\n          \u003Cbutton\n            className={activeDemo === 'search' ? 'active' : ''}\n            onClick={() => setActiveDemo('search')}\n          >\n            🔍 Search + Debounce\n          \u003C\u002Fbutton>\n          \u003Cbutton\n            className={activeDemo === 'theme' ? 'active' : ''}\n            onClick={() => setActiveDemo('theme')}\n          >\n            🎨 LocalStorage\n          \u003C\u002Fbutton>\n        \u003C\u002Fnav>\n      \u003C\u002Fheader>\n\n      \u003Cmain className=\"main\">\n        {activeDemo === 'online' && \u003COnlineStatusDemo \u002F>}\n        {activeDemo === 'search' && \u003CSearchDemo \u002F>}\n        {activeDemo === 'theme' && \u003CThemeDemo \u002F>}\n      \u003C\u002Fmain>\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,14896,14897,14914,14932,14950,14968,14977,14981,14995,15034,15038,15044,15059,15075,15092,15108,15115,15143,15168,15173,15178,15186,15192,15217,15239,15243,15248,15256,15262,15287,15309,15313,15318,15326,15334,15342,15346,15361,15381,15401,15421,15429,15437,15441],{"__ignoreMap":5701},[5705,14898,14899,14901,14903,14905,14907,14909,14912],{"class":5707,"line":5708},[5705,14900,6214],{"class":6060},[5705,14902,5958],{"class":5726},[5705,14904,5579],{"class":5741},[5705,14906,6225],{"class":5726},[5705,14908,6228],{"class":6060},[5705,14910,14911],{"class":6019}," 'react'",[5705,14913,6138],{"class":5726},[5705,14915,14916,14918,14920,14923,14925,14927,14930],{"class":5707,"line":5715},[5705,14917,6214],{"class":6060},[5705,14919,5958],{"class":5726},[5705,14921,14922],{"class":5741},"OnlineStatusDemo",[5705,14924,6225],{"class":5726},[5705,14926,6228],{"class":6060},[5705,14928,14929],{"class":6019}," '.\u002Fcomponents\u002FOnlineStatusDemo'",[5705,14931,6138],{"class":5726},[5705,14933,14934,14936,14938,14941,14943,14945,14948],{"class":5707,"line":5730},[5705,14935,6214],{"class":6060},[5705,14937,5958],{"class":5726},[5705,14939,14940],{"class":5741},"SearchDemo",[5705,14942,6225],{"class":5726},[5705,14944,6228],{"class":6060},[5705,14946,14947],{"class":6019}," '.\u002Fcomponents\u002FSearchDemo'",[5705,14949,6138],{"class":5726},[5705,14951,14952,14954,14956,14959,14961,14963,14966],{"class":5707,"line":5755},[5705,14953,6214],{"class":6060},[5705,14955,5958],{"class":5726},[5705,14957,14958],{"class":5741},"ThemeDemo",[5705,14960,6225],{"class":5726},[5705,14962,6228],{"class":6060},[5705,14964,14965],{"class":6019}," '.\u002Fcomponents\u002FThemeDemo'",[5705,14967,6138],{"class":5726},[5705,14969,14970,14972,14975],{"class":5707,"line":5791},[5705,14971,6214],{"class":6060},[5705,14973,14974],{"class":6019}," '.\u002Fstyles.css'",[5705,14976,6138],{"class":5726},[5705,14978,14979],{"class":5707,"line":5798},[5705,14980,5795],{"emptyLinePlaceholder":5794},[5705,14982,14983,14985,14988,14990,14993],{"class":5707,"line":5804},[5705,14984,6242],{"class":6060},[5705,14986,14987],{"class":6060}," default",[5705,14989,6245],{"class":5718},[5705,14991,14992],{"class":5722}," App",[5705,14994,5902],{"class":5726},[5705,14996,14997,14999,15001,15004,15006,15009,15011,15013,15015,15018,15020,15023,15025,15028,15030,15032],{"class":5707,"line":5818},[5705,14998,5907],{"class":5718},[5705,15000,5910],{"class":5726},[5705,15002,15003],{"class":5913},"activeDemo",[5705,15005,5580],{"class":5726},[5705,15007,15008],{"class":5913},"setActiveDemo",[5705,15010,5922],{"class":5726},[5705,15012,5579],{"class":5722},[5705,15014,5763],{"class":5726},[5705,15016,15017],{"class":6019},"'online'",[5705,15019,7154],{"class":5726},[5705,15021,15022],{"class":6019},"'search'",[5705,15024,7154],{"class":5726},[5705,15026,15027],{"class":6019},"'theme'",[5705,15029,5769],{"class":5726},[5705,15031,15017],{"class":6019},[5705,15033,6028],{"class":5726},[5705,15035,15036],{"class":5707,"line":6031},[5705,15037,5795],{"emptyLinePlaceholder":5794},[5705,15039,15040,15042],{"class":5707,"line":6052},[5705,15041,6132],{"class":6060},[5705,15043,6544],{"class":5726},[5705,15045,15046,15048,15050,15052,15054,15057],{"class":5707,"line":6057},[5705,15047,6550],{"class":6549},[5705,15049,6554],{"class":6553},[5705,15051,6558],{"class":6557},[5705,15053,6561],{"class":5726},[5705,15055,15056],{"class":6019},"\"app\"",[5705,15058,6595],{"class":6549},[5705,15060,15061,15063,15066,15068,15070,15073],{"class":5707,"line":6072},[5705,15062,6775],{"class":6549},[5705,15064,15065],{"class":6553},"header",[5705,15067,6558],{"class":6557},[5705,15069,6561],{"class":5726},[5705,15071,15072],{"class":6019},"\"header\"",[5705,15074,6595],{"class":6549},[5705,15076,15077,15079,15081,15083,15086,15088,15090],{"class":5707,"line":6093},[5705,15078,9712],{"class":6549},[5705,15080,5472],{"class":6553},[5705,15082,6780],{"class":6549},[5705,15084,15085],{"class":5726},"🎣 Кастомні хуки React",[5705,15087,6803],{"class":6549},[5705,15089,5472],{"class":6553},[5705,15091,6595],{"class":6549},[5705,15093,15094,15096,15099,15101,15103,15106],{"class":5707,"line":6112},[5705,15095,9712],{"class":6549},[5705,15097,15098],{"class":6553},"nav",[5705,15100,6558],{"class":6557},[5705,15102,6561],{"class":5726},[5705,15104,15105],{"class":6019},"\"demo-tabs\"",[5705,15107,6595],{"class":6549},[5705,15109,15110,15112],{"class":5707,"line":6118},[5705,15111,10727],{"class":6549},[5705,15113,15114],{"class":6553},"button\n",[5705,15116,15117,15120,15122,15124,15126,15128,15131,15133,15136,15138,15141],{"class":5707,"line":6124},[5705,15118,15119],{"class":6557},"            className",[5705,15121,6561],{"class":5726},[5705,15123,6564],{"class":5718},[5705,15125,15003],{"class":5741},[5705,15127,9137],{"class":5726},[5705,15129,15130],{"class":6019}," 'online'",[5705,15132,6575],{"class":5726},[5705,15134,15135],{"class":6019}," 'active'",[5705,15137,6581],{"class":5726},[5705,15139,15140],{"class":6019}," ''",[5705,15142,6144],{"class":5718},[5705,15144,15145,15148,15150,15152,15155,15157,15160,15162,15164,15166],{"class":5707,"line":6129},[5705,15146,15147],{"class":6557},"            onClick",[5705,15149,6561],{"class":5726},[5705,15151,6564],{"class":5718},[5705,15153,15154],{"class":7502},"() ",[5705,15156,5955],{"class":5718},[5705,15158,15159],{"class":5722}," setActiveDemo",[5705,15161,5738],{"class":7502},[5705,15163,15017],{"class":6019},[5705,15165,9646],{"class":7502},[5705,15167,6144],{"class":5718},[5705,15169,15170],{"class":5707,"line":6141},[5705,15171,15172],{"class":6549},"          >\n",[5705,15174,15175],{"class":5707,"line":6389},[5705,15176,15177],{"class":5726},"            📡 Online Status\n",[5705,15179,15180,15182,15184],{"class":5707,"line":6408},[5705,15181,10832],{"class":6549},[5705,15183,9113],{"class":6553},[5705,15185,6595],{"class":6549},[5705,15187,15188,15190],{"class":5707,"line":6413},[5705,15189,10727],{"class":6549},[5705,15191,15114],{"class":6553},[5705,15193,15194,15196,15198,15200,15202,15204,15207,15209,15211,15213,15215],{"class":5707,"line":6419},[5705,15195,15119],{"class":6557},[5705,15197,6561],{"class":5726},[5705,15199,6564],{"class":5718},[5705,15201,15003],{"class":5741},[5705,15203,9137],{"class":5726},[5705,15205,15206],{"class":6019}," 'search'",[5705,15208,6575],{"class":5726},[5705,15210,15135],{"class":6019},[5705,15212,6581],{"class":5726},[5705,15214,15140],{"class":6019},[5705,15216,6144],{"class":5718},[5705,15218,15219,15221,15223,15225,15227,15229,15231,15233,15235,15237],{"class":5707,"line":6430},[5705,15220,15147],{"class":6557},[5705,15222,6561],{"class":5726},[5705,15224,6564],{"class":5718},[5705,15226,15154],{"class":7502},[5705,15228,5955],{"class":5718},[5705,15230,15159],{"class":5722},[5705,15232,5738],{"class":7502},[5705,15234,15022],{"class":6019},[5705,15236,9646],{"class":7502},[5705,15238,6144],{"class":5718},[5705,15240,15241],{"class":5707,"line":6449},[5705,15242,15172],{"class":6549},[5705,15244,15245],{"class":5707,"line":6468},[5705,15246,15247],{"class":5726},"            🔍 Search + Debounce\n",[5705,15249,15250,15252,15254],{"class":5707,"line":6473},[5705,15251,10832],{"class":6549},[5705,15253,9113],{"class":6553},[5705,15255,6595],{"class":6549},[5705,15257,15258,15260],{"class":5707,"line":6482},[5705,15259,10727],{"class":6549},[5705,15261,15114],{"class":6553},[5705,15263,15264,15266,15268,15270,15272,15274,15277,15279,15281,15283,15285],{"class":5707,"line":6487},[5705,15265,15119],{"class":6557},[5705,15267,6561],{"class":5726},[5705,15269,6564],{"class":5718},[5705,15271,15003],{"class":5741},[5705,15273,9137],{"class":5726},[5705,15275,15276],{"class":6019}," 'theme'",[5705,15278,6575],{"class":5726},[5705,15280,15135],{"class":6019},[5705,15282,6581],{"class":5726},[5705,15284,15140],{"class":6019},[5705,15286,6144],{"class":5718},[5705,15288,15289,15291,15293,15295,15297,15299,15301,15303,15305,15307],{"class":5707,"line":6496},[5705,15290,15147],{"class":6557},[5705,15292,6561],{"class":5726},[5705,15294,6564],{"class":5718},[5705,15296,15154],{"class":7502},[5705,15298,5955],{"class":5718},[5705,15300,15159],{"class":5722},[5705,15302,5738],{"class":7502},[5705,15304,15027],{"class":6019},[5705,15306,9646],{"class":7502},[5705,15308,6144],{"class":5718},[5705,15310,15311],{"class":5707,"line":7008},[5705,15312,15172],{"class":6549},[5705,15314,15315],{"class":5707,"line":7014},[5705,15316,15317],{"class":5726},"            🎨 LocalStorage\n",[5705,15319,15320,15322,15324],{"class":5707,"line":7020},[5705,15321,10832],{"class":6549},[5705,15323,9113],{"class":6553},[5705,15325,6595],{"class":6549},[5705,15327,15328,15330,15332],{"class":5707,"line":7026},[5705,15329,9787],{"class":6549},[5705,15331,15098],{"class":6553},[5705,15333,6595],{"class":6549},[5705,15335,15336,15338,15340],{"class":5707,"line":7032},[5705,15337,9157],{"class":6549},[5705,15339,15065],{"class":6553},[5705,15341,6595],{"class":6549},[5705,15343,15344],{"class":5707,"line":7037},[5705,15345,5795],{"emptyLinePlaceholder":5794},[5705,15347,15348,15350,15352,15354,15356,15359],{"class":5707,"line":7639},[5705,15349,6775],{"class":6549},[5705,15351,11410],{"class":6553},[5705,15353,6558],{"class":6557},[5705,15355,6561],{"class":5726},[5705,15357,15358],{"class":6019},"\"main\"",[5705,15360,6595],{"class":6549},[5705,15362,15363,15365,15367,15369,15371,15373,15375,15377,15379],{"class":5707,"line":7644},[5705,15364,9132],{"class":5718},[5705,15366,15003],{"class":5741},[5705,15368,9137],{"class":5726},[5705,15370,15130],{"class":6019},[5705,15372,9676],{"class":5726},[5705,15374,7958],{"class":6549},[5705,15376,14922],{"class":5748},[5705,15378,11361],{"class":6549},[5705,15380,6144],{"class":5718},[5705,15382,15383,15385,15387,15389,15391,15393,15395,15397,15399],{"class":5707,"line":7654},[5705,15384,9132],{"class":5718},[5705,15386,15003],{"class":5741},[5705,15388,9137],{"class":5726},[5705,15390,15206],{"class":6019},[5705,15392,9676],{"class":5726},[5705,15394,7958],{"class":6549},[5705,15396,14940],{"class":5748},[5705,15398,11361],{"class":6549},[5705,15400,6144],{"class":5718},[5705,15402,15403,15405,15407,15409,15411,15413,15415,15417,15419],{"class":5707,"line":7660},[5705,15404,9132],{"class":5718},[5705,15406,15003],{"class":5741},[5705,15408,9137],{"class":5726},[5705,15410,15276],{"class":6019},[5705,15412,9676],{"class":5726},[5705,15414,7958],{"class":6549},[5705,15416,14958],{"class":5748},[5705,15418,11361],{"class":6549},[5705,15420,6144],{"class":5718},[5705,15422,15423,15425,15427],{"class":5707,"line":7676},[5705,15424,9157],{"class":6549},[5705,15426,11410],{"class":6553},[5705,15428,6595],{"class":6549},[5705,15430,15431,15433,15435],{"class":5707,"line":7688},[5705,15432,6619],{"class":6549},[5705,15434,6554],{"class":6553},[5705,15436,6595],{"class":6549},[5705,15438,15439],{"class":5707,"line":7693},[5705,15440,6628],{"class":5726},[5705,15442,15443],{"class":5707,"line":7699},[5705,15444,6144],{"class":5726},[5696,15446,15449],{"className":5698,"code":15447,"filename":15448,"language":5700,"meta":5701,"style":5701},"import { useOnlineStatus } from '..\u002Fhooks\u002FuseOnlineStatus';\n\nexport function OnlineStatusDemo() {\n  const isOnline = useOnlineStatus();\n\n  return (\n    \u003Cdiv className=\"demo-card\">\n      \u003Ch2>Відстеження статусу з'єднання\u003C\u002Fh2>\n      \u003Cdiv className={`status-indicator ${isOnline ? 'online' : 'offline'}`}>\n        \u003Cdiv className=\"status-dot\">\u003C\u002Fdiv>\n        \u003Cspan className=\"status-text\">\n          {isOnline ? '🟢 Ви онлайн' : '🔴 Ви офлайн'}\n        \u003C\u002Fspan>\n      \u003C\u002Fdiv>\n      \u003Cp className=\"hint\">\n        💡 Спробуйте вимкнути мережу у DevTools (Network → Offline)\n      \u003C\u002Fp>\n      \u003Cdiv className=\"code-preview\">\n        \u003Ccode>const isOnline = useOnlineStatus();\u003C\u002Fcode>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  );\n}\n","src\u002Fcomponents\u002FOnlineStatusDemo.tsx",[5535,15450,15451,15468,15472,15483,15495,15499,15505,15520,15537,15573,15593,15608,15626,15634,15642,15657,15662,15670,15685,15702,15710,15718,15722],{"__ignoreMap":5701},[5705,15452,15453,15455,15457,15459,15461,15463,15466],{"class":5707,"line":5708},[5705,15454,6214],{"class":6060},[5705,15456,5958],{"class":5726},[5705,15458,5882],{"class":5741},[5705,15460,6225],{"class":5726},[5705,15462,6228],{"class":6060},[5705,15464,15465],{"class":6019}," '..\u002Fhooks\u002FuseOnlineStatus'",[5705,15467,6138],{"class":5726},[5705,15469,15470],{"class":5707,"line":5715},[5705,15471,5795],{"emptyLinePlaceholder":5794},[5705,15473,15474,15476,15478,15481],{"class":5707,"line":5730},[5705,15475,6242],{"class":6060},[5705,15477,6245],{"class":5718},[5705,15479,15480],{"class":5722}," OnlineStatusDemo",[5705,15482,5902],{"class":5726},[5705,15484,15485,15487,15489,15491,15493],{"class":5707,"line":5755},[5705,15486,5907],{"class":5718},[5705,15488,6135],{"class":5913},[5705,15490,6525],{"class":5726},[5705,15492,5882],{"class":5722},[5705,15494,7353],{"class":5726},[5705,15496,15497],{"class":5707,"line":5791},[5705,15498,5795],{"emptyLinePlaceholder":5794},[5705,15500,15501,15503],{"class":5707,"line":5798},[5705,15502,6132],{"class":6060},[5705,15504,6544],{"class":5726},[5705,15506,15507,15509,15511,15513,15515,15518],{"class":5707,"line":5804},[5705,15508,6550],{"class":6549},[5705,15510,6554],{"class":6553},[5705,15512,6558],{"class":6557},[5705,15514,6561],{"class":5726},[5705,15516,15517],{"class":6019},"\"demo-card\"",[5705,15519,6595],{"class":6549},[5705,15521,15522,15524,15526,15528,15531,15533,15535],{"class":5707,"line":5818},[5705,15523,6775],{"class":6549},[5705,15525,5570],{"class":6553},[5705,15527,6780],{"class":6549},[5705,15529,15530],{"class":5726},"Відстеження статусу з'єднання",[5705,15532,6803],{"class":6549},[5705,15534,5570],{"class":6553},[5705,15536,6595],{"class":6549},[5705,15538,15539,15541,15543,15545,15547,15549,15552,15554,15556,15558,15560,15562,15565,15567,15569,15571],{"class":5707,"line":6031},[5705,15540,6775],{"class":6549},[5705,15542,6554],{"class":6553},[5705,15544,6558],{"class":6557},[5705,15546,6561],{"class":5726},[5705,15548,6564],{"class":5718},[5705,15550,15551],{"class":6019},"`status-indicator ",[5705,15553,6570],{"class":5718},[5705,15555,5914],{"class":5741},[5705,15557,6575],{"class":5726},[5705,15559,15130],{"class":6019},[5705,15561,6581],{"class":5726},[5705,15563,15564],{"class":6019}," 'offline'",[5705,15566,6587],{"class":5718},[5705,15568,6590],{"class":6019},[5705,15570,6587],{"class":5718},[5705,15572,6595],{"class":6549},[5705,15574,15575,15577,15579,15581,15583,15586,15589,15591],{"class":5707,"line":6052},[5705,15576,9712],{"class":6549},[5705,15578,6554],{"class":6553},[5705,15580,6558],{"class":6557},[5705,15582,6561],{"class":5726},[5705,15584,15585],{"class":6019},"\"status-dot\"",[5705,15587,15588],{"class":6549},">\u003C\u002F",[5705,15590,6554],{"class":6553},[5705,15592,6595],{"class":6549},[5705,15594,15595,15597,15599,15601,15603,15606],{"class":5707,"line":6057},[5705,15596,9712],{"class":6549},[5705,15598,5705],{"class":6553},[5705,15600,6558],{"class":6557},[5705,15602,6561],{"class":5726},[5705,15604,15605],{"class":6019},"\"status-text\"",[5705,15607,6595],{"class":6549},[5705,15609,15610,15612,15614,15616,15619,15621,15624],{"class":5707,"line":6072},[5705,15611,9721],{"class":5718},[5705,15613,5914],{"class":5741},[5705,15615,6575],{"class":5726},[5705,15617,15618],{"class":6019}," '🟢 Ви онлайн'",[5705,15620,6581],{"class":5726},[5705,15622,15623],{"class":6019}," '🔴 Ви офлайн'",[5705,15625,6144],{"class":5718},[5705,15627,15628,15630,15632],{"class":5707,"line":6093},[5705,15629,9787],{"class":6549},[5705,15631,5705],{"class":6553},[5705,15633,6595],{"class":6549},[5705,15635,15636,15638,15640],{"class":5707,"line":6112},[5705,15637,9157],{"class":6549},[5705,15639,6554],{"class":6553},[5705,15641,6595],{"class":6549},[5705,15643,15644,15646,15648,15650,15652,15655],{"class":5707,"line":6118},[5705,15645,6775],{"class":6549},[5705,15647,5479],{"class":6553},[5705,15649,6558],{"class":6557},[5705,15651,6561],{"class":5726},[5705,15653,15654],{"class":6019},"\"hint\"",[5705,15656,6595],{"class":6549},[5705,15658,15659],{"class":5707,"line":6124},[5705,15660,15661],{"class":5726},"        💡 Спробуйте вимкнути мережу у DevTools (Network → Offline)\n",[5705,15663,15664,15666,15668],{"class":5707,"line":6129},[5705,15665,9157],{"class":6549},[5705,15667,5479],{"class":6553},[5705,15669,6595],{"class":6549},[5705,15671,15672,15674,15676,15678,15680,15683],{"class":5707,"line":6141},[5705,15673,6775],{"class":6549},[5705,15675,6554],{"class":6553},[5705,15677,6558],{"class":6557},[5705,15679,6561],{"class":5726},[5705,15681,15682],{"class":6019},"\"code-preview\"",[5705,15684,6595],{"class":6549},[5705,15686,15687,15689,15691,15693,15696,15698,15700],{"class":5707,"line":6389},[5705,15688,9712],{"class":6549},[5705,15690,5535],{"class":6553},[5705,15692,6780],{"class":6549},[5705,15694,15695],{"class":5726},"const isOnline = useOnlineStatus();",[5705,15697,6803],{"class":6549},[5705,15699,5535],{"class":6553},[5705,15701,6595],{"class":6549},[5705,15703,15704,15706,15708],{"class":5707,"line":6408},[5705,15705,9157],{"class":6549},[5705,15707,6554],{"class":6553},[5705,15709,6595],{"class":6549},[5705,15711,15712,15714,15716],{"class":5707,"line":6413},[5705,15713,6619],{"class":6549},[5705,15715,6554],{"class":6553},[5705,15717,6595],{"class":6549},[5705,15719,15720],{"class":5707,"line":6419},[5705,15721,6628],{"class":5726},[5705,15723,15724],{"class":5707,"line":6430},[5705,15725,6144],{"class":5726},[5696,15727,15730],{"className":5698,"code":15728,"filename":15729,"language":5700,"meta":5701,"style":5701},"import { useState } from 'react';\nimport { useDebounce } from '..\u002Fhooks\u002FuseDebounce';\n\nconst MOCK_RESULTS = [\n  'React Hooks',\n  'React Router',\n  'React Context',\n  'React Query',\n  'React Testing Library',\n  'React Spring',\n  'React Native',\n];\n\nexport function SearchDemo() {\n  const [query, setQuery] = useState('');\n  const debouncedQuery = useDebounce(query, 500);\n\n  const results = debouncedQuery\n    ? MOCK_RESULTS.filter((item) =>\n        item.toLowerCase().includes(debouncedQuery.toLowerCase())\n      )\n    : [];\n\n  return (\n    \u003Cdiv className=\"demo-card\">\n      \u003Ch2>Пошук із затримкою (Debounce)\u003C\u002Fh2>\n      \u003Cinput\n        type=\"text\"\n        className=\"search-input\"\n        value={query}\n        onChange={(e) => setQuery(e.target.value)}\n        placeholder=\"Введіть пошуковий запит...\"\n      \u002F>\n      \u003Cdiv className=\"search-info\">\n        \u003Cp>Поточний запит: \u003Cstrong>{query || '(порожньо)'}\u003C\u002Fstrong>\u003C\u002Fp>\n        \u003Cp>Debounced запит: \u003Cstrong>{debouncedQuery || '(порожньо)'}\u003C\u002Fstrong>\u003C\u002Fp>\n      \u003C\u002Fdiv>\n      {results.length > 0 && (\n        \u003Cul className=\"search-results\">\n          {results.map((item) => (\n            \u003Cli key={item}>{item}\u003C\u002Fli>\n          ))}\n        \u003C\u002Ful>\n      )}\n      \u003Cp className=\"hint\">\n        💡 API-запит виконується лише після 500мс без змін\n      \u003C\u002Fp>\n      \u003Cdiv className=\"code-preview\">\n        \u003Ccode>const debouncedQuery = useDebounce(query, 500);\u003C\u002Fcode>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  );\n}\n","src\u002Fcomponents\u002FSearchDemo.tsx",[5535,15731,15732,15748,15765,15769,15780,15787,15794,15801,15808,15815,15822,15829,15833,15837,15848,15871,15891,15895,15907,15929,15956,15961,15966,15970,15976,15990,16007,16013,16021,16031,16043,16077,16086,16090,16105,16144,16181,16189,16210,16225,16245,16275,16281,16289,16295,16309,16314,16322,16336,16353,16361,16369,16373],{"__ignoreMap":5701},[5705,15733,15734,15736,15738,15740,15742,15744,15746],{"class":5707,"line":5708},[5705,15735,6214],{"class":6060},[5705,15737,5958],{"class":5726},[5705,15739,5579],{"class":5741},[5705,15741,6225],{"class":5726},[5705,15743,6228],{"class":6060},[5705,15745,14911],{"class":6019},[5705,15747,6138],{"class":5726},[5705,15749,15750,15752,15754,15756,15758,15760,15763],{"class":5707,"line":5715},[5705,15751,6214],{"class":6060},[5705,15753,5958],{"class":5726},[5705,15755,9200],{"class":5741},[5705,15757,6225],{"class":5726},[5705,15759,6228],{"class":6060},[5705,15761,15762],{"class":6019}," '..\u002Fhooks\u002FuseDebounce'",[5705,15764,6138],{"class":5726},[5705,15766,15767],{"class":5707,"line":5730},[5705,15768,5795],{"emptyLinePlaceholder":5794},[5705,15770,15771,15774,15777],{"class":5707,"line":5755},[5705,15772,15773],{"class":5718},"const",[5705,15775,15776],{"class":5913}," MOCK_RESULTS",[5705,15778,15779],{"class":5726}," = [\n",[5705,15781,15782,15785],{"class":5707,"line":5791},[5705,15783,15784],{"class":6019},"  'React Hooks'",[5705,15786,8298],{"class":5726},[5705,15788,15789,15792],{"class":5707,"line":5798},[5705,15790,15791],{"class":6019},"  'React Router'",[5705,15793,8298],{"class":5726},[5705,15795,15796,15799],{"class":5707,"line":5804},[5705,15797,15798],{"class":6019},"  'React Context'",[5705,15800,8298],{"class":5726},[5705,15802,15803,15806],{"class":5707,"line":5818},[5705,15804,15805],{"class":6019},"  'React Query'",[5705,15807,8298],{"class":5726},[5705,15809,15810,15813],{"class":5707,"line":6031},[5705,15811,15812],{"class":6019},"  'React Testing Library'",[5705,15814,8298],{"class":5726},[5705,15816,15817,15820],{"class":5707,"line":6052},[5705,15818,15819],{"class":6019},"  'React Spring'",[5705,15821,8298],{"class":5726},[5705,15823,15824,15827],{"class":5707,"line":6057},[5705,15825,15826],{"class":6019},"  'React Native'",[5705,15828,8298],{"class":5726},[5705,15830,15831],{"class":5707,"line":6072},[5705,15832,8955],{"class":5726},[5705,15834,15835],{"class":5707,"line":6093},[5705,15836,5795],{"emptyLinePlaceholder":5794},[5705,15838,15839,15841,15843,15846],{"class":5707,"line":6112},[5705,15840,6242],{"class":6060},[5705,15842,6245],{"class":5718},[5705,15844,15845],{"class":5722}," SearchDemo",[5705,15847,5902],{"class":5726},[5705,15849,15850,15852,15854,15856,15858,15860,15862,15864,15866,15869],{"class":5707,"line":6118},[5705,15851,5907],{"class":5718},[5705,15853,5910],{"class":5726},[5705,15855,10273],{"class":5913},[5705,15857,5580],{"class":5726},[5705,15859,10278],{"class":5913},[5705,15861,5922],{"class":5726},[5705,15863,5579],{"class":5722},[5705,15865,5738],{"class":5726},[5705,15867,15868],{"class":6019},"''",[5705,15870,6028],{"class":5726},[5705,15872,15873,15875,15877,15879,15881,15883,15885,15887,15889],{"class":5707,"line":6124},[5705,15874,5907],{"class":5718},[5705,15876,9476],{"class":5913},[5705,15878,6525],{"class":5726},[5705,15880,9200],{"class":5722},[5705,15882,5738],{"class":5726},[5705,15884,10273],{"class":5741},[5705,15886,5580],{"class":5726},[5705,15888,9490],{"class":9489},[5705,15890,6028],{"class":5726},[5705,15892,15893],{"class":5707,"line":6129},[5705,15894,5795],{"emptyLinePlaceholder":5794},[5705,15896,15897,15899,15902,15904],{"class":5707,"line":6141},[5705,15898,5907],{"class":5718},[5705,15900,15901],{"class":5913}," results",[5705,15903,6525],{"class":5726},[5705,15905,15906],{"class":5741},"debouncedQuery\n",[5705,15908,15909,15912,15915,15917,15920,15922,15924,15926],{"class":5707,"line":6389},[5705,15910,15911],{"class":5726},"    ? ",[5705,15913,15914],{"class":5913},"MOCK_RESULTS",[5705,15916,5622],{"class":5726},[5705,15918,15919],{"class":5722},"filter",[5705,15921,9039],{"class":5726},[5705,15923,8446],{"class":5741},[5705,15925,8337],{"class":5726},[5705,15927,15928],{"class":5718},"=>\n",[5705,15930,15931,15934,15936,15939,15942,15945,15947,15949,15951,15953],{"class":5707,"line":6408},[5705,15932,15933],{"class":5741},"        item",[5705,15935,5622],{"class":5726},[5705,15937,15938],{"class":5722},"toLowerCase",[5705,15940,15941],{"class":5726},"().",[5705,15943,15944],{"class":5722},"includes",[5705,15946,5738],{"class":5726},[5705,15948,9545],{"class":5741},[5705,15950,5622],{"class":5726},[5705,15952,15938],{"class":5722},[5705,15954,15955],{"class":5726},"())\n",[5705,15957,15958],{"class":5707,"line":6413},[5705,15959,15960],{"class":5726},"      )\n",[5705,15962,15963],{"class":5707,"line":6419},[5705,15964,15965],{"class":5726},"    : [];\n",[5705,15967,15968],{"class":5707,"line":6430},[5705,15969,5795],{"emptyLinePlaceholder":5794},[5705,15971,15972,15974],{"class":5707,"line":6449},[5705,15973,6132],{"class":6060},[5705,15975,6544],{"class":5726},[5705,15977,15978,15980,15982,15984,15986,15988],{"class":5707,"line":6468},[5705,15979,6550],{"class":6549},[5705,15981,6554],{"class":6553},[5705,15983,6558],{"class":6557},[5705,15985,6561],{"class":5726},[5705,15987,15517],{"class":6019},[5705,15989,6595],{"class":6549},[5705,15991,15992,15994,15996,15998,16001,16003,16005],{"class":5707,"line":6473},[5705,15993,6775],{"class":6549},[5705,15995,5570],{"class":6553},[5705,15997,6780],{"class":6549},[5705,15999,16000],{"class":5726},"Пошук із затримкою (Debounce)",[5705,16002,6803],{"class":6549},[5705,16004,5570],{"class":6553},[5705,16006,6595],{"class":6549},[5705,16008,16009,16011],{"class":5707,"line":6482},[5705,16010,6775],{"class":6549},[5705,16012,9586],{"class":6553},[5705,16014,16015,16017,16019],{"class":5707,"line":6487},[5705,16016,9591],{"class":6557},[5705,16018,6561],{"class":5726},[5705,16020,9596],{"class":6019},[5705,16022,16023,16026,16028],{"class":5707,"line":6496},[5705,16024,16025],{"class":6557},"        className",[5705,16027,6561],{"class":5726},[5705,16029,16030],{"class":6019},"\"search-input\"\n",[5705,16032,16033,16035,16037,16039,16041],{"class":5707,"line":7008},[5705,16034,9601],{"class":6557},[5705,16036,6561],{"class":5726},[5705,16038,6564],{"class":5718},[5705,16040,10273],{"class":5741},[5705,16042,6144],{"class":5718},[5705,16044,16045,16047,16049,16051,16053,16055,16057,16059,16061,16063,16065,16067,16069,16071,16073,16075],{"class":5707,"line":7014},[5705,16046,9614],{"class":6557},[5705,16048,6561],{"class":5726},[5705,16050,6564],{"class":5718},[5705,16052,5738],{"class":7502},[5705,16054,9623],{"class":5741},[5705,16056,8337],{"class":7502},[5705,16058,5955],{"class":5718},[5705,16060,10609],{"class":5722},[5705,16062,5738],{"class":7502},[5705,16064,9623],{"class":5741},[5705,16066,5622],{"class":7502},[5705,16068,9639],{"class":5741},[5705,16070,5622],{"class":7502},[5705,16072,5772],{"class":5741},[5705,16074,9646],{"class":7502},[5705,16076,6144],{"class":5718},[5705,16078,16079,16081,16083],{"class":5707,"line":7020},[5705,16080,9653],{"class":6557},[5705,16082,6561],{"class":5726},[5705,16084,16085],{"class":6019},"\"Введіть пошуковий запит...\"\n",[5705,16087,16088],{"class":5707,"line":7026},[5705,16089,9663],{"class":6549},[5705,16091,16092,16094,16096,16098,16100,16103],{"class":5707,"line":7032},[5705,16093,6775],{"class":6549},[5705,16095,6554],{"class":6553},[5705,16097,6558],{"class":6557},[5705,16099,6561],{"class":5726},[5705,16101,16102],{"class":6019},"\"search-info\"",[5705,16104,6595],{"class":6549},[5705,16106,16107,16109,16111,16113,16116,16118,16120,16122,16124,16126,16129,16132,16134,16136,16138,16140,16142],{"class":5707,"line":7037},[5705,16108,9712],{"class":6549},[5705,16110,5479],{"class":6553},[5705,16112,6780],{"class":6549},[5705,16114,16115],{"class":5726},"Поточний запит: ",[5705,16117,5763],{"class":6549},[5705,16119,5483],{"class":6553},[5705,16121,6780],{"class":6549},[5705,16123,6564],{"class":5718},[5705,16125,10273],{"class":5741},[5705,16127,16128],{"class":5726}," ||",[5705,16130,16131],{"class":6019}," '(порожньо)'",[5705,16133,6587],{"class":5718},[5705,16135,6803],{"class":6549},[5705,16137,5483],{"class":6553},[5705,16139,15588],{"class":6549},[5705,16141,5479],{"class":6553},[5705,16143,6595],{"class":6549},[5705,16145,16146,16148,16150,16152,16155,16157,16159,16161,16163,16165,16167,16169,16171,16173,16175,16177,16179],{"class":5707,"line":7639},[5705,16147,9712],{"class":6549},[5705,16149,5479],{"class":6553},[5705,16151,6780],{"class":6549},[5705,16153,16154],{"class":5726},"Debounced запит: ",[5705,16156,5763],{"class":6549},[5705,16158,5483],{"class":6553},[5705,16160,6780],{"class":6549},[5705,16162,6564],{"class":5718},[5705,16164,9545],{"class":5741},[5705,16166,16128],{"class":5726},[5705,16168,16131],{"class":6019},[5705,16170,6587],{"class":5718},[5705,16172,6803],{"class":6549},[5705,16174,5483],{"class":6553},[5705,16176,15588],{"class":6549},[5705,16178,5479],{"class":6553},[5705,16180,6595],{"class":6549},[5705,16182,16183,16185,16187],{"class":5707,"line":7644},[5705,16184,9157],{"class":6549},[5705,16186,6554],{"class":6553},[5705,16188,6595],{"class":6549},[5705,16190,16191,16193,16195,16197,16200,16203,16206,16208],{"class":5707,"line":7654},[5705,16192,6600],{"class":5718},[5705,16194,9512],{"class":5741},[5705,16196,5622],{"class":7502},[5705,16198,16199],{"class":5741},"length",[5705,16201,16202],{"class":5726}," >",[5705,16204,16205],{"class":9489}," 0",[5705,16207,9676],{"class":5726},[5705,16209,6544],{"class":7502},[5705,16211,16212,16214,16216,16218,16220,16223],{"class":5707,"line":7660},[5705,16213,9712],{"class":6549},[5705,16215,5503],{"class":6553},[5705,16217,6558],{"class":6557},[5705,16219,6561],{"class":5726},[5705,16221,16222],{"class":6019},"\"search-results\"",[5705,16224,6595],{"class":6549},[5705,16226,16227,16229,16231,16233,16235,16237,16239,16241,16243],{"class":5707,"line":7676},[5705,16228,9721],{"class":5718},[5705,16230,9512],{"class":5741},[5705,16232,5622],{"class":7502},[5705,16234,9728],{"class":5722},[5705,16236,9039],{"class":7502},[5705,16238,8446],{"class":5741},[5705,16240,8337],{"class":7502},[5705,16242,5955],{"class":5718},[5705,16244,6544],{"class":7502},[5705,16246,16247,16249,16251,16253,16255,16257,16259,16261,16263,16265,16267,16269,16271,16273],{"class":5707,"line":7688},[5705,16248,9748],{"class":6549},[5705,16250,5506],{"class":6553},[5705,16252,9753],{"class":6557},[5705,16254,6561],{"class":5726},[5705,16256,6564],{"class":5718},[5705,16258,8446],{"class":5741},[5705,16260,6587],{"class":5718},[5705,16262,6780],{"class":6549},[5705,16264,6564],{"class":5718},[5705,16266,8446],{"class":5741},[5705,16268,6587],{"class":5718},[5705,16270,6803],{"class":6549},[5705,16272,5506],{"class":6553},[5705,16274,6595],{"class":6549},[5705,16276,16277,16279],{"class":5707,"line":7693},[5705,16278,9780],{"class":7502},[5705,16280,6144],{"class":5718},[5705,16282,16283,16285,16287],{"class":5707,"line":7699},[5705,16284,9787],{"class":6549},[5705,16286,5503],{"class":6553},[5705,16288,6595],{"class":6549},[5705,16290,16291,16293],{"class":5707,"line":7704},[5705,16292,9796],{"class":7502},[5705,16294,6144],{"class":5718},[5705,16296,16297,16299,16301,16303,16305,16307],{"class":5707,"line":7709},[5705,16298,6775],{"class":6549},[5705,16300,5479],{"class":6553},[5705,16302,6558],{"class":6557},[5705,16304,6561],{"class":5726},[5705,16306,15654],{"class":6019},[5705,16308,6595],{"class":6549},[5705,16310,16311],{"class":5707,"line":7717},[5705,16312,16313],{"class":5726},"        💡 API-запит виконується лише після 500мс без змін\n",[5705,16315,16316,16318,16320],{"class":5707,"line":7722},[5705,16317,9157],{"class":6549},[5705,16319,5479],{"class":6553},[5705,16321,6595],{"class":6549},[5705,16323,16324,16326,16328,16330,16332,16334],{"class":5707,"line":7728},[5705,16325,6775],{"class":6549},[5705,16327,6554],{"class":6553},[5705,16329,6558],{"class":6557},[5705,16331,6561],{"class":5726},[5705,16333,15682],{"class":6019},[5705,16335,6595],{"class":6549},[5705,16337,16338,16340,16342,16344,16347,16349,16351],{"class":5707,"line":7739},[5705,16339,9712],{"class":6549},[5705,16341,5535],{"class":6553},[5705,16343,6780],{"class":6549},[5705,16345,16346],{"class":5726},"const debouncedQuery = useDebounce(query, 500);",[5705,16348,6803],{"class":6549},[5705,16350,5535],{"class":6553},[5705,16352,6595],{"class":6549},[5705,16354,16355,16357,16359],{"class":5707,"line":7752},[5705,16356,9157],{"class":6549},[5705,16358,6554],{"class":6553},[5705,16360,6595],{"class":6549},[5705,16362,16363,16365,16367],{"class":5707,"line":7757},[5705,16364,6619],{"class":6549},[5705,16366,6554],{"class":6553},[5705,16368,6595],{"class":6549},[5705,16370,16371],{"class":5707,"line":7771},[5705,16372,6628],{"class":5726},[5705,16374,16375],{"class":5707,"line":7776},[5705,16376,6144],{"class":5726},[5696,16378,16381],{"className":5698,"code":16379,"filename":16380,"language":5700,"meta":5701,"style":5701},"import { useLocalStorage } from '..\u002Fhooks\u002FuseLocalStorage';\n\nexport function ThemeDemo() {\n  const [theme, setTheme] = useLocalStorage\u003C'light' | 'dark'>('demo-theme', 'light');\n  const [count, setCount] = useLocalStorage\u003Cnumber>('demo-count', 0);\n\n  return (\n    \u003Cdiv className={`demo-card theme-${theme}`}>\n      \u003Ch2>Синхронізація з LocalStorage\u003C\u002Fh2>\n      \n      \u003Cdiv className=\"theme-controls\">\n        \u003Cbutton\n          className=\"theme-btn\"\n          onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}\n        >\n          {theme === 'light' ? '🌙 Темна тема' : '☀️ Світла тема'}\n        \u003C\u002Fbutton>\n      \u003C\u002Fdiv>\n\n      \u003Cdiv className=\"counter\">\n        \u003Cp>Лічильник: \u003Cstrong>{count}\u003C\u002Fstrong>\u003C\u002Fp>\n        \u003Cdiv className=\"counter-controls\">\n          \u003Cbutton onClick={() => setCount(count + 1)}>+1\u003C\u002Fbutton>\n          \u003Cbutton onClick={() => setCount(count - 1)}>-1\u003C\u002Fbutton>\n          \u003Cbutton onClick={() => setCount(0)}>Скинути\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n\n      \u003Cp className=\"hint\">\n        💡 Оновіть сторінку — дані збережуться!\n      \u003C\u002Fp>\n      \u003Cdiv className=\"code-preview\">\n        \u003Ccode>const [theme, setTheme] = useLocalStorage('theme', 'light');\u003C\u002Fcode>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  );\n}\n","src\u002Fcomponents\u002FThemeDemo.tsx",[5535,16382,16383,16400,16404,16415,16452,16486,16490,16496,16523,16540,16544,16559,16565,16575,16613,16618,16640,16648,16656,16660,16675,16708,16723,16767,16809,16846,16854,16862,16866,16880,16885,16893,16907,16924,16932,16940,16944],{"__ignoreMap":5701},[5705,16384,16385,16387,16389,16391,16393,16395,16398],{"class":5707,"line":5708},[5705,16386,6214],{"class":6060},[5705,16388,5958],{"class":5726},[5705,16390,5888],{"class":5741},[5705,16392,6225],{"class":5726},[5705,16394,6228],{"class":6060},[5705,16396,16397],{"class":6019}," '..\u002Fhooks\u002FuseLocalStorage'",[5705,16399,6138],{"class":5726},[5705,16401,16402],{"class":5707,"line":5715},[5705,16403,5795],{"emptyLinePlaceholder":5794},[5705,16405,16406,16408,16410,16413],{"class":5707,"line":5730},[5705,16407,6242],{"class":6060},[5705,16409,6245],{"class":5718},[5705,16411,16412],{"class":5722}," ThemeDemo",[5705,16414,5902],{"class":5726},[5705,16416,16417,16419,16421,16423,16425,16427,16429,16431,16433,16436,16438,16441,16443,16446,16448,16450],{"class":5707,"line":5755},[5705,16418,5907],{"class":5718},[5705,16420,5910],{"class":5726},[5705,16422,8987],{"class":5913},[5705,16424,5580],{"class":5726},[5705,16426,8992],{"class":5913},[5705,16428,5922],{"class":5726},[5705,16430,5888],{"class":5722},[5705,16432,5763],{"class":5726},[5705,16434,16435],{"class":6019},"'light'",[5705,16437,7154],{"class":5726},[5705,16439,16440],{"class":6019},"'dark'",[5705,16442,5769],{"class":5726},[5705,16444,16445],{"class":6019},"'demo-theme'",[5705,16447,5580],{"class":5726},[5705,16449,16435],{"class":6019},[5705,16451,6028],{"class":5726},[5705,16453,16454,16456,16458,16461,16463,16466,16468,16470,16472,16474,16476,16479,16481,16484],{"class":5707,"line":5791},[5705,16455,5907],{"class":5718},[5705,16457,5910],{"class":5726},[5705,16459,16460],{"class":5913},"count",[5705,16462,5580],{"class":5726},[5705,16464,16465],{"class":5913},"setCount",[5705,16467,5922],{"class":5726},[5705,16469,5888],{"class":5722},[5705,16471,5763],{"class":5726},[5705,16473,5786],{"class":5748},[5705,16475,5769],{"class":5726},[5705,16477,16478],{"class":6019},"'demo-count'",[5705,16480,5580],{"class":5726},[5705,16482,16483],{"class":9489},"0",[5705,16485,6028],{"class":5726},[5705,16487,16488],{"class":5707,"line":5798},[5705,16489,5795],{"emptyLinePlaceholder":5794},[5705,16491,16492,16494],{"class":5707,"line":5804},[5705,16493,6132],{"class":6060},[5705,16495,6544],{"class":5726},[5705,16497,16498,16500,16502,16504,16506,16508,16511,16513,16515,16517,16519,16521],{"class":5707,"line":5818},[5705,16499,6550],{"class":6549},[5705,16501,6554],{"class":6553},[5705,16503,6558],{"class":6557},[5705,16505,6561],{"class":5726},[5705,16507,6564],{"class":5718},[5705,16509,16510],{"class":6019},"`demo-card theme-",[5705,16512,6570],{"class":5718},[5705,16514,8987],{"class":5741},[5705,16516,6587],{"class":5718},[5705,16518,6590],{"class":6019},[5705,16520,6587],{"class":5718},[5705,16522,6595],{"class":6549},[5705,16524,16525,16527,16529,16531,16534,16536,16538],{"class":5707,"line":6031},[5705,16526,6775],{"class":6549},[5705,16528,5570],{"class":6553},[5705,16530,6780],{"class":6549},[5705,16532,16533],{"class":5726},"Синхронізація з LocalStorage",[5705,16535,6803],{"class":6549},[5705,16537,5570],{"class":6553},[5705,16539,6595],{"class":6549},[5705,16541,16542],{"class":5707,"line":6052},[5705,16543,13594],{"class":5726},[5705,16545,16546,16548,16550,16552,16554,16557],{"class":5707,"line":6057},[5705,16547,6775],{"class":6549},[5705,16549,6554],{"class":6553},[5705,16551,6558],{"class":6557},[5705,16553,6561],{"class":5726},[5705,16555,16556],{"class":6019},"\"theme-controls\"",[5705,16558,6595],{"class":6549},[5705,16560,16561,16563],{"class":5707,"line":6072},[5705,16562,9712],{"class":6549},[5705,16564,15114],{"class":6553},[5705,16566,16567,16570,16572],{"class":5707,"line":6093},[5705,16568,16569],{"class":6557},"          className",[5705,16571,6561],{"class":5726},[5705,16573,16574],{"class":6019},"\"theme-btn\"\n",[5705,16576,16577,16580,16582,16584,16586,16588,16591,16593,16595,16597,16600,16602,16605,16607,16609,16611],{"class":5707,"line":6112},[5705,16578,16579],{"class":6557},"          onClick",[5705,16581,6561],{"class":5726},[5705,16583,6564],{"class":5718},[5705,16585,15154],{"class":7502},[5705,16587,5955],{"class":5718},[5705,16589,16590],{"class":5722}," setTheme",[5705,16592,5738],{"class":7502},[5705,16594,8987],{"class":5741},[5705,16596,9137],{"class":5726},[5705,16598,16599],{"class":6019}," 'light'",[5705,16601,6575],{"class":5726},[5705,16603,16604],{"class":6019}," 'dark'",[5705,16606,6581],{"class":5726},[5705,16608,16599],{"class":6019},[5705,16610,9646],{"class":7502},[5705,16612,6144],{"class":5718},[5705,16614,16615],{"class":5707,"line":6118},[5705,16616,16617],{"class":6549},"        >\n",[5705,16619,16620,16622,16624,16626,16628,16630,16633,16635,16638],{"class":5707,"line":6124},[5705,16621,9721],{"class":5718},[5705,16623,8987],{"class":5741},[5705,16625,9137],{"class":5726},[5705,16627,16599],{"class":6019},[5705,16629,6575],{"class":5726},[5705,16631,16632],{"class":6019}," '🌙 Темна тема'",[5705,16634,6581],{"class":5726},[5705,16636,16637],{"class":6019}," '☀️ Світла тема'",[5705,16639,6144],{"class":5718},[5705,16641,16642,16644,16646],{"class":5707,"line":6129},[5705,16643,9787],{"class":6549},[5705,16645,9113],{"class":6553},[5705,16647,6595],{"class":6549},[5705,16649,16650,16652,16654],{"class":5707,"line":6141},[5705,16651,9157],{"class":6549},[5705,16653,6554],{"class":6553},[5705,16655,6595],{"class":6549},[5705,16657,16658],{"class":5707,"line":6389},[5705,16659,5795],{"emptyLinePlaceholder":5794},[5705,16661,16662,16664,16666,16668,16670,16673],{"class":5707,"line":6408},[5705,16663,6775],{"class":6549},[5705,16665,6554],{"class":6553},[5705,16667,6558],{"class":6557},[5705,16669,6561],{"class":5726},[5705,16671,16672],{"class":6019},"\"counter\"",[5705,16674,6595],{"class":6549},[5705,16676,16677,16679,16681,16683,16686,16688,16690,16692,16694,16696,16698,16700,16702,16704,16706],{"class":5707,"line":6413},[5705,16678,9712],{"class":6549},[5705,16680,5479],{"class":6553},[5705,16682,6780],{"class":6549},[5705,16684,16685],{"class":5726},"Лічильник: ",[5705,16687,5763],{"class":6549},[5705,16689,5483],{"class":6553},[5705,16691,6780],{"class":6549},[5705,16693,6564],{"class":5718},[5705,16695,16460],{"class":5741},[5705,16697,6587],{"class":5718},[5705,16699,6803],{"class":6549},[5705,16701,5483],{"class":6553},[5705,16703,15588],{"class":6549},[5705,16705,5479],{"class":6553},[5705,16707,6595],{"class":6549},[5705,16709,16710,16712,16714,16716,16718,16721],{"class":5707,"line":6419},[5705,16711,9712],{"class":6549},[5705,16713,6554],{"class":6553},[5705,16715,6558],{"class":6557},[5705,16717,6561],{"class":5726},[5705,16719,16720],{"class":6019},"\"counter-controls\"",[5705,16722,6595],{"class":6549},[5705,16724,16725,16727,16729,16731,16733,16735,16737,16739,16742,16744,16746,16749,16752,16754,16756,16758,16761,16763,16765],{"class":5707,"line":6430},[5705,16726,10727],{"class":6549},[5705,16728,9113],{"class":6553},[5705,16730,9116],{"class":6557},[5705,16732,6561],{"class":5726},[5705,16734,6564],{"class":5718},[5705,16736,15154],{"class":7502},[5705,16738,5955],{"class":5718},[5705,16740,16741],{"class":5722}," setCount",[5705,16743,5738],{"class":7502},[5705,16745,16460],{"class":5741},[5705,16747,16748],{"class":5726}," +",[5705,16750,16751],{"class":9489}," 1",[5705,16753,9646],{"class":7502},[5705,16755,6587],{"class":5718},[5705,16757,6780],{"class":6549},[5705,16759,16760],{"class":5726},"+1",[5705,16762,6803],{"class":6549},[5705,16764,9113],{"class":6553},[5705,16766,6595],{"class":6549},[5705,16768,16769,16771,16773,16775,16777,16779,16781,16783,16785,16787,16789,16792,16794,16796,16798,16800,16803,16805,16807],{"class":5707,"line":6449},[5705,16770,10727],{"class":6549},[5705,16772,9113],{"class":6553},[5705,16774,9116],{"class":6557},[5705,16776,6561],{"class":5726},[5705,16778,6564],{"class":5718},[5705,16780,15154],{"class":7502},[5705,16782,5955],{"class":5718},[5705,16784,16741],{"class":5722},[5705,16786,5738],{"class":7502},[5705,16788,16460],{"class":5741},[5705,16790,16791],{"class":5726}," -",[5705,16793,16751],{"class":9489},[5705,16795,9646],{"class":7502},[5705,16797,6587],{"class":5718},[5705,16799,6780],{"class":6549},[5705,16801,16802],{"class":5726},"-1",[5705,16804,6803],{"class":6549},[5705,16806,9113],{"class":6553},[5705,16808,6595],{"class":6549},[5705,16810,16811,16813,16815,16817,16819,16821,16823,16825,16827,16829,16831,16833,16835,16837,16840,16842,16844],{"class":5707,"line":6468},[5705,16812,10727],{"class":6549},[5705,16814,9113],{"class":6553},[5705,16816,9116],{"class":6557},[5705,16818,6561],{"class":5726},[5705,16820,6564],{"class":5718},[5705,16822,15154],{"class":7502},[5705,16824,5955],{"class":5718},[5705,16826,16741],{"class":5722},[5705,16828,5738],{"class":7502},[5705,16830,16483],{"class":9489},[5705,16832,9646],{"class":7502},[5705,16834,6587],{"class":5718},[5705,16836,6780],{"class":6549},[5705,16838,16839],{"class":5726},"Скинути",[5705,16841,6803],{"class":6549},[5705,16843,9113],{"class":6553},[5705,16845,6595],{"class":6549},[5705,16847,16848,16850,16852],{"class":5707,"line":6473},[5705,16849,9787],{"class":6549},[5705,16851,6554],{"class":6553},[5705,16853,6595],{"class":6549},[5705,16855,16856,16858,16860],{"class":5707,"line":6482},[5705,16857,9157],{"class":6549},[5705,16859,6554],{"class":6553},[5705,16861,6595],{"class":6549},[5705,16863,16864],{"class":5707,"line":6487},[5705,16865,5795],{"emptyLinePlaceholder":5794},[5705,16867,16868,16870,16872,16874,16876,16878],{"class":5707,"line":6496},[5705,16869,6775],{"class":6549},[5705,16871,5479],{"class":6553},[5705,16873,6558],{"class":6557},[5705,16875,6561],{"class":5726},[5705,16877,15654],{"class":6019},[5705,16879,6595],{"class":6549},[5705,16881,16882],{"class":5707,"line":7008},[5705,16883,16884],{"class":5726},"        💡 Оновіть сторінку — дані збережуться!\n",[5705,16886,16887,16889,16891],{"class":5707,"line":7014},[5705,16888,9157],{"class":6549},[5705,16890,5479],{"class":6553},[5705,16892,6595],{"class":6549},[5705,16894,16895,16897,16899,16901,16903,16905],{"class":5707,"line":7020},[5705,16896,6775],{"class":6549},[5705,16898,6554],{"class":6553},[5705,16900,6558],{"class":6557},[5705,16902,6561],{"class":5726},[5705,16904,15682],{"class":6019},[5705,16906,6595],{"class":6549},[5705,16908,16909,16911,16913,16915,16918,16920,16922],{"class":5707,"line":7026},[5705,16910,9712],{"class":6549},[5705,16912,5535],{"class":6553},[5705,16914,6780],{"class":6549},[5705,16916,16917],{"class":5726},"const [theme, setTheme] = useLocalStorage('theme', 'light');",[5705,16919,6803],{"class":6549},[5705,16921,5535],{"class":6553},[5705,16923,6595],{"class":6549},[5705,16925,16926,16928,16930],{"class":5707,"line":7032},[5705,16927,9157],{"class":6549},[5705,16929,6554],{"class":6553},[5705,16931,6595],{"class":6549},[5705,16933,16934,16936,16938],{"class":5707,"line":7037},[5705,16935,6619],{"class":6549},[5705,16937,6554],{"class":6553},[5705,16939,6595],{"class":6549},[5705,16941,16942],{"class":5707,"line":7639},[5705,16943,6628],{"class":5726},[5705,16945,16946],{"class":5707,"line":7644},[5705,16947,6144],{"class":5726},[5696,16949,16952],{"className":5698,"code":16950,"filename":16951,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from 'react';\n\nexport function useOnlineStatus(): boolean {\n  const [isOnline, setIsOnline] = useState(navigator.onLine);\n\n  useEffect(() => {\n    function handleOnline() {\n      setIsOnline(true);\n    }\n\n    function handleOffline() {\n      setIsOnline(false);\n    }\n\n    window.addEventListener('online', handleOnline);\n    window.addEventListener('offline', handleOffline);\n\n    return () => {\n      window.removeEventListener('online', handleOnline);\n      window.removeEventListener('offline', handleOffline);\n    };\n  }, []);\n\n  return isOnline;\n}\n","src\u002Fhooks\u002FuseOnlineStatus.ts",[5535,16953,16954,16974,16978,16992,17018,17022,17032,17040,17050,17054,17058,17066,17076,17080,17084,17102,17121,17125,17135,17153,17171,17175,17179,17183,17191],{"__ignoreMap":5701},[5705,16955,16956,16958,16960,16962,16964,16966,16968,16970,16972],{"class":5707,"line":5708},[5705,16957,6214],{"class":6060},[5705,16959,5958],{"class":5726},[5705,16961,5579],{"class":5741},[5705,16963,5580],{"class":5726},[5705,16965,5583],{"class":5741},[5705,16967,6225],{"class":5726},[5705,16969,6228],{"class":6060},[5705,16971,14911],{"class":6019},[5705,16973,6138],{"class":5726},[5705,16975,16976],{"class":5707,"line":5715},[5705,16977,5795],{"emptyLinePlaceholder":5794},[5705,16979,16980,16982,16984,16986,16988,16990],{"class":5707,"line":5730},[5705,16981,6242],{"class":6060},[5705,16983,6245],{"class":5718},[5705,16985,5723],{"class":5722},[5705,16987,6250],{"class":5726},[5705,16989,6253],{"class":5748},[5705,16991,6069],{"class":5726},[5705,16993,16994,16996,16998,17000,17002,17004,17006,17008,17010,17012,17014,17016],{"class":5707,"line":5755},[5705,16995,5907],{"class":5718},[5705,16997,5910],{"class":5726},[5705,16999,5914],{"class":5913},[5705,17001,5580],{"class":5726},[5705,17003,5919],{"class":5913},[5705,17005,5922],{"class":5726},[5705,17007,5579],{"class":5722},[5705,17009,5738],{"class":5726},[5705,17011,5929],{"class":5741},[5705,17013,5622],{"class":5726},[5705,17015,5934],{"class":5741},[5705,17017,6028],{"class":5726},[5705,17019,17020],{"class":5707,"line":5791},[5705,17021,5795],{"emptyLinePlaceholder":5794},[5705,17023,17024,17026,17028,17030],{"class":5707,"line":5798},[5705,17025,5949],{"class":5722},[5705,17027,5952],{"class":5726},[5705,17029,5955],{"class":5718},[5705,17031,6069],{"class":5726},[5705,17033,17034,17036,17038],{"class":5707,"line":5804},[5705,17035,5966],{"class":5718},[5705,17037,5969],{"class":5722},[5705,17039,5902],{"class":5726},[5705,17041,17042,17044,17046,17048],{"class":5707,"line":5818},[5705,17043,6322],{"class":5722},[5705,17045,5738],{"class":5726},[5705,17047,5979],{"class":5718},[5705,17049,6028],{"class":5726},[5705,17051,17052],{"class":5707,"line":6031},[5705,17053,6333],{"class":5726},[5705,17055,17056],{"class":5707,"line":6052},[5705,17057,5795],{"emptyLinePlaceholder":5794},[5705,17059,17060,17062,17064],{"class":5707,"line":6057},[5705,17061,5966],{"class":5718},[5705,17063,5989],{"class":5722},[5705,17065,5902],{"class":5726},[5705,17067,17068,17070,17072,17074],{"class":5707,"line":6072},[5705,17069,6322],{"class":5722},[5705,17071,5738],{"class":5726},[5705,17073,5998],{"class":5718},[5705,17075,6028],{"class":5726},[5705,17077,17078],{"class":5707,"line":6093},[5705,17079,6333],{"class":5726},[5705,17081,17082],{"class":5707,"line":6112},[5705,17083,5795],{"emptyLinePlaceholder":5794},[5705,17085,17086,17088,17090,17092,17094,17096,17098,17100],{"class":5707,"line":6118},[5705,17087,6009],{"class":5741},[5705,17089,5622],{"class":5726},[5705,17091,6014],{"class":5722},[5705,17093,5738],{"class":5726},[5705,17095,15017],{"class":6019},[5705,17097,5580],{"class":5726},[5705,17099,6025],{"class":5741},[5705,17101,6028],{"class":5726},[5705,17103,17104,17106,17108,17110,17112,17115,17117,17119],{"class":5707,"line":6124},[5705,17105,6009],{"class":5741},[5705,17107,5622],{"class":5726},[5705,17109,6014],{"class":5722},[5705,17111,5738],{"class":5726},[5705,17113,17114],{"class":6019},"'offline'",[5705,17116,5580],{"class":5726},[5705,17118,6047],{"class":5741},[5705,17120,6028],{"class":5726},[5705,17122,17123],{"class":5707,"line":6129},[5705,17124,5795],{"emptyLinePlaceholder":5794},[5705,17126,17127,17129,17131,17133],{"class":5707,"line":6141},[5705,17128,6061],{"class":6060},[5705,17130,6064],{"class":5726},[5705,17132,5955],{"class":5718},[5705,17134,6069],{"class":5726},[5705,17136,17137,17139,17141,17143,17145,17147,17149,17151],{"class":5707,"line":6389},[5705,17138,6075],{"class":5741},[5705,17140,5622],{"class":5726},[5705,17142,6080],{"class":5722},[5705,17144,5738],{"class":5726},[5705,17146,15017],{"class":6019},[5705,17148,5580],{"class":5726},[5705,17150,6025],{"class":5741},[5705,17152,6028],{"class":5726},[5705,17154,17155,17157,17159,17161,17163,17165,17167,17169],{"class":5707,"line":6408},[5705,17156,6075],{"class":5741},[5705,17158,5622],{"class":5726},[5705,17160,6080],{"class":5722},[5705,17162,5738],{"class":5726},[5705,17164,17114],{"class":6019},[5705,17166,5580],{"class":5726},[5705,17168,6047],{"class":5741},[5705,17170,6028],{"class":5726},[5705,17172,17173],{"class":5707,"line":6413},[5705,17174,6115],{"class":5726},[5705,17176,17177],{"class":5707,"line":6419},[5705,17178,6121],{"class":5726},[5705,17180,17181],{"class":5707,"line":6430},[5705,17182,5795],{"emptyLinePlaceholder":5794},[5705,17184,17185,17187,17189],{"class":5707,"line":6449},[5705,17186,6132],{"class":6060},[5705,17188,6135],{"class":5741},[5705,17190,6138],{"class":5726},[5705,17192,17193],{"class":5707,"line":6468},[5705,17194,6144],{"class":5726},[5696,17196,17199],{"className":5698,"code":17197,"filename":17198,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from 'react';\n\nexport function useDebounce\u003CT>(value: T, delay: number): T {\n  const [debouncedValue, setDebouncedValue] = useState\u003CT>(value);\n\n  useEffect(() => {\n    const timerId = setTimeout(() => {\n      setDebouncedValue(value);\n    }, delay);\n\n    return () => clearTimeout(timerId);\n  }, [value, delay]);\n\n  return debouncedValue;\n}\n","src\u002Fhooks\u002FuseDebounce.ts",[5535,17200,17201,17221,17225,17259,17285,17289,17299,17315,17325,17333,17337,17353,17365,17369,17377],{"__ignoreMap":5701},[5705,17202,17203,17205,17207,17209,17211,17213,17215,17217,17219],{"class":5707,"line":5708},[5705,17204,6214],{"class":6060},[5705,17206,5958],{"class":5726},[5705,17208,5579],{"class":5741},[5705,17210,5580],{"class":5726},[5705,17212,5583],{"class":5741},[5705,17214,6225],{"class":5726},[5705,17216,6228],{"class":6060},[5705,17218,14911],{"class":6019},[5705,17220,6138],{"class":5726},[5705,17222,17223],{"class":5707,"line":5715},[5705,17224,5795],{"emptyLinePlaceholder":5794},[5705,17226,17227,17229,17231,17233,17235,17237,17239,17241,17243,17245,17247,17249,17251,17253,17255,17257],{"class":5707,"line":5730},[5705,17228,6242],{"class":6060},[5705,17230,6245],{"class":5718},[5705,17232,5760],{"class":5722},[5705,17234,5763],{"class":5726},[5705,17236,5766],{"class":5748},[5705,17238,5769],{"class":5726},[5705,17240,5772],{"class":5741},[5705,17242,5745],{"class":5726},[5705,17244,5766],{"class":5748},[5705,17246,5580],{"class":5726},[5705,17248,5781],{"class":5741},[5705,17250,5745],{"class":5726},[5705,17252,5786],{"class":5748},[5705,17254,7216],{"class":5726},[5705,17256,5766],{"class":5748},[5705,17258,6069],{"class":5726},[5705,17260,17261,17263,17265,17267,17269,17271,17273,17275,17277,17279,17281,17283],{"class":5707,"line":5755},[5705,17262,5907],{"class":5718},[5705,17264,5910],{"class":5726},[5705,17266,9284],{"class":5913},[5705,17268,5580],{"class":5726},[5705,17270,9289],{"class":5913},[5705,17272,5922],{"class":5726},[5705,17274,5579],{"class":5722},[5705,17276,5763],{"class":5726},[5705,17278,5766],{"class":5748},[5705,17280,5769],{"class":5726},[5705,17282,5772],{"class":5741},[5705,17284,6028],{"class":5726},[5705,17286,17287],{"class":5707,"line":5791},[5705,17288,5795],{"emptyLinePlaceholder":5794},[5705,17290,17291,17293,17295,17297],{"class":5707,"line":5798},[5705,17292,5949],{"class":5722},[5705,17294,5952],{"class":5726},[5705,17296,5955],{"class":5718},[5705,17298,6069],{"class":5726},[5705,17300,17301,17303,17305,17307,17309,17311,17313],{"class":5707,"line":5804},[5705,17302,7339],{"class":5718},[5705,17304,9329],{"class":5913},[5705,17306,6525],{"class":5726},[5705,17308,9334],{"class":5722},[5705,17310,5952],{"class":5726},[5705,17312,5955],{"class":5718},[5705,17314,6069],{"class":5726},[5705,17316,17317,17319,17321,17323],{"class":5707,"line":5818},[5705,17318,9345],{"class":5722},[5705,17320,5738],{"class":5726},[5705,17322,5772],{"class":5741},[5705,17324,6028],{"class":5726},[5705,17326,17327,17329,17331],{"class":5707,"line":6031},[5705,17328,9356],{"class":5726},[5705,17330,5781],{"class":5741},[5705,17332,6028],{"class":5726},[5705,17334,17335],{"class":5707,"line":6052},[5705,17336,5795],{"emptyLinePlaceholder":5794},[5705,17338,17339,17341,17343,17345,17347,17349,17351],{"class":5707,"line":6057},[5705,17340,6061],{"class":6060},[5705,17342,6064],{"class":5726},[5705,17344,5955],{"class":5718},[5705,17346,12032],{"class":5722},[5705,17348,5738],{"class":5726},[5705,17350,9389],{"class":5741},[5705,17352,6028],{"class":5726},[5705,17354,17355,17357,17359,17361,17363],{"class":5707,"line":6072},[5705,17356,7760],{"class":5726},[5705,17358,5772],{"class":5741},[5705,17360,5580],{"class":5726},[5705,17362,5781],{"class":5741},[5705,17364,8935],{"class":5726},[5705,17366,17367],{"class":5707,"line":6093},[5705,17368,5795],{"emptyLinePlaceholder":5794},[5705,17370,17371,17373,17375],{"class":5707,"line":6112},[5705,17372,6132],{"class":6060},[5705,17374,9418],{"class":5741},[5705,17376,6138],{"class":5726},[5705,17378,17379],{"class":5707,"line":6118},[5705,17380,6144],{"class":5726},[5696,17382,17385],{"className":5698,"code":17383,"filename":17384,"language":5700,"meta":5701,"style":5701},"import { useState, useEffect } from 'react';\n\nexport function useLocalStorage\u003CT>(\n  key: string,\n  initialValue: T\n): [T, (value: T | ((prev: T) => T)) => void] {\n  const [storedValue, setStoredValue] = useState\u003CT>(() => {\n    try {\n      const item = window.localStorage.getItem(key);\n      return item ? (JSON.parse(item) as T) : initialValue;\n    } catch {\n      return initialValue;\n    }\n  });\n\n  const setValue = (value: T | ((prev: T) => T)) => {\n    try {\n      const valueToStore = value instanceof Function ? value(storedValue) : value;\n      setStoredValue(valueToStore);\n      window.localStorage.setItem(key, JSON.stringify(valueToStore));\n    } catch (error) {\n      console.error('Помилка запису у localStorage:', error);\n    }\n  };\n\n  useEffect(() => {\n    function handleStorageChange(event: StorageEvent) {\n      if (event.key === key && event.newValue !== null) {\n        try {\n          setStoredValue(JSON.parse(event.newValue) as T);\n        } catch {}\n      }\n    }\n\n    window.addEventListener('storage', handleStorageChange);\n    return () => window.removeEventListener('storage', handleStorageChange);\n  }, [key]);\n\n  return [storedValue, setValue];\n}\n","src\u002Fhooks\u002FuseLocalStorage.ts",[5535,17386,17387,17407,17411,17425,17435,17443,17479,17505,17511,17535,17565,17573,17581,17585,17589,17593,17627,17633,17661,17671,17701,17713,17732,17736,17740,17744,17754,17770,17800,17806,17834,17843,17847,17851,17855,17874,17898,17906,17910,17924],{"__ignoreMap":5701},[5705,17388,17389,17391,17393,17395,17397,17399,17401,17403,17405],{"class":5707,"line":5708},[5705,17390,6214],{"class":6060},[5705,17392,5958],{"class":5726},[5705,17394,5579],{"class":5741},[5705,17396,5580],{"class":5726},[5705,17398,5583],{"class":5741},[5705,17400,6225],{"class":5726},[5705,17402,6228],{"class":6060},[5705,17404,14911],{"class":6019},[5705,17406,6138],{"class":5726},[5705,17408,17409],{"class":5707,"line":5715},[5705,17410,5795],{"emptyLinePlaceholder":5794},[5705,17412,17413,17415,17417,17419,17421,17423],{"class":5707,"line":5730},[5705,17414,6242],{"class":6060},[5705,17416,6245],{"class":5718},[5705,17418,8280],{"class":5722},[5705,17420,5763],{"class":5726},[5705,17422,5766],{"class":5748},[5705,17424,7918],{"class":5726},[5705,17426,17427,17429,17431,17433],{"class":5707,"line":5755},[5705,17428,8291],{"class":5741},[5705,17430,5745],{"class":5726},[5705,17432,5749],{"class":5748},[5705,17434,8298],{"class":5726},[5705,17436,17437,17439,17441],{"class":5707,"line":5791},[5705,17438,8303],{"class":5741},[5705,17440,5745],{"class":5726},[5705,17442,8308],{"class":5748},[5705,17444,17445,17447,17449,17451,17453,17455,17457,17459,17461,17463,17465,17467,17469,17471,17473,17475,17477],{"class":5707,"line":5798},[5705,17446,8313],{"class":5726},[5705,17448,5766],{"class":5748},[5705,17450,8318],{"class":5726},[5705,17452,5772],{"class":5741},[5705,17454,5745],{"class":5726},[5705,17456,5766],{"class":5748},[5705,17458,8327],{"class":5726},[5705,17460,8330],{"class":5741},[5705,17462,5745],{"class":5726},[5705,17464,5766],{"class":5748},[5705,17466,8337],{"class":5726},[5705,17468,5955],{"class":5718},[5705,17470,8342],{"class":5748},[5705,17472,8345],{"class":5726},[5705,17474,5955],{"class":5718},[5705,17476,8350],{"class":5748},[5705,17478,8353],{"class":5726},[5705,17480,17481,17483,17485,17487,17489,17491,17493,17495,17497,17499,17501,17503],{"class":5707,"line":5804},[5705,17482,5907],{"class":5718},[5705,17484,5910],{"class":5726},[5705,17486,8367],{"class":5913},[5705,17488,5580],{"class":5726},[5705,17490,8372],{"class":5913},[5705,17492,5922],{"class":5726},[5705,17494,5579],{"class":5722},[5705,17496,5763],{"class":5726},[5705,17498,5766],{"class":5748},[5705,17500,8383],{"class":5726},[5705,17502,5955],{"class":5718},[5705,17504,6069],{"class":5726},[5705,17506,17507,17509],{"class":5707,"line":5818},[5705,17508,8392],{"class":6060},[5705,17510,6069],{"class":5726},[5705,17512,17513,17515,17517,17519,17521,17523,17525,17527,17529,17531,17533],{"class":5707,"line":6031},[5705,17514,8399],{"class":5718},[5705,17516,8402],{"class":5913},[5705,17518,6525],{"class":5726},[5705,17520,8407],{"class":5741},[5705,17522,5622],{"class":5726},[5705,17524,5628],{"class":5741},[5705,17526,5622],{"class":5726},[5705,17528,8416],{"class":5722},[5705,17530,5738],{"class":5726},[5705,17532,8421],{"class":5741},[5705,17534,6028],{"class":5726},[5705,17536,17537,17539,17541,17543,17545,17547,17549,17551,17553,17555,17557,17559,17561,17563],{"class":5707,"line":6052},[5705,17538,8428],{"class":6060},[5705,17540,8402],{"class":5741},[5705,17542,8433],{"class":5726},[5705,17544,8436],{"class":5913},[5705,17546,5622],{"class":5726},[5705,17548,8441],{"class":5722},[5705,17550,5738],{"class":5726},[5705,17552,8446],{"class":5741},[5705,17554,8337],{"class":5726},[5705,17556,8451],{"class":6060},[5705,17558,8342],{"class":5748},[5705,17560,8456],{"class":5726},[5705,17562,8459],{"class":5741},[5705,17564,6138],{"class":5726},[5705,17566,17567,17569,17571],{"class":5707,"line":6057},[5705,17568,8466],{"class":5726},[5705,17570,7577],{"class":6060},[5705,17572,6069],{"class":5726},[5705,17574,17575,17577,17579],{"class":5707,"line":6072},[5705,17576,8428],{"class":6060},[5705,17578,8510],{"class":5741},[5705,17580,6138],{"class":5726},[5705,17582,17583],{"class":5707,"line":6093},[5705,17584,6333],{"class":5726},[5705,17586,17587],{"class":5707,"line":6112},[5705,17588,8521],{"class":5726},[5705,17590,17591],{"class":5707,"line":6118},[5705,17592,5795],{"emptyLinePlaceholder":5794},[5705,17594,17595,17597,17599,17601,17603,17605,17607,17609,17611,17613,17615,17617,17619,17621,17623,17625],{"class":5707,"line":6124},[5705,17596,5907],{"class":5718},[5705,17598,8537],{"class":5722},[5705,17600,8540],{"class":5726},[5705,17602,5772],{"class":5741},[5705,17604,5745],{"class":5726},[5705,17606,5766],{"class":5748},[5705,17608,8327],{"class":5726},[5705,17610,8330],{"class":5741},[5705,17612,5745],{"class":5726},[5705,17614,5766],{"class":5748},[5705,17616,8337],{"class":5726},[5705,17618,5955],{"class":5718},[5705,17620,8342],{"class":5748},[5705,17622,8345],{"class":5726},[5705,17624,5955],{"class":5718},[5705,17626,6069],{"class":5726},[5705,17628,17629,17631],{"class":5707,"line":6129},[5705,17630,8392],{"class":6060},[5705,17632,6069],{"class":5726},[5705,17634,17635,17637,17639,17641,17643,17645,17647,17649,17651,17653,17655,17657,17659],{"class":5707,"line":6141},[5705,17636,8399],{"class":5718},[5705,17638,8584],{"class":5913},[5705,17640,6525],{"class":5726},[5705,17642,5772],{"class":5741},[5705,17644,7600],{"class":5718},[5705,17646,8593],{"class":5748},[5705,17648,8596],{"class":5726},[5705,17650,5772],{"class":5722},[5705,17652,5738],{"class":5726},[5705,17654,8367],{"class":5741},[5705,17656,8456],{"class":5726},[5705,17658,5772],{"class":5741},[5705,17660,6138],{"class":5726},[5705,17662,17663,17665,17667,17669],{"class":5707,"line":6389},[5705,17664,8617],{"class":5722},[5705,17666,5738],{"class":5726},[5705,17668,8622],{"class":5741},[5705,17670,6028],{"class":5726},[5705,17672,17673,17675,17677,17679,17681,17683,17685,17687,17689,17691,17693,17695,17697,17699],{"class":5707,"line":6408},[5705,17674,6075],{"class":5741},[5705,17676,5622],{"class":5726},[5705,17678,5628],{"class":5741},[5705,17680,5622],{"class":5726},[5705,17682,8646],{"class":5722},[5705,17684,5738],{"class":5726},[5705,17686,8421],{"class":5741},[5705,17688,5580],{"class":5726},[5705,17690,8436],{"class":5913},[5705,17692,5622],{"class":5726},[5705,17694,8659],{"class":5722},[5705,17696,5738],{"class":5726},[5705,17698,8622],{"class":5741},[5705,17700,8666],{"class":5726},[5705,17702,17703,17705,17707,17709,17711],{"class":5707,"line":6413},[5705,17704,8466],{"class":5726},[5705,17706,7577],{"class":6060},[5705,17708,7055],{"class":5726},[5705,17710,5618],{"class":5741},[5705,17712,7479],{"class":5726},[5705,17714,17715,17717,17719,17721,17723,17726,17728,17730],{"class":5707,"line":6419},[5705,17716,8479],{"class":5741},[5705,17718,5622],{"class":5726},[5705,17720,5618],{"class":5722},[5705,17722,5738],{"class":5726},[5705,17724,17725],{"class":6019},"'Помилка запису у localStorage:'",[5705,17727,5580],{"class":5726},[5705,17729,5618],{"class":5741},[5705,17731,6028],{"class":5726},[5705,17733,17734],{"class":5707,"line":6430},[5705,17735,6333],{"class":5726},[5705,17737,17738],{"class":5707,"line":6449},[5705,17739,8714],{"class":5726},[5705,17741,17742],{"class":5707,"line":6468},[5705,17743,5795],{"emptyLinePlaceholder":5794},[5705,17745,17746,17748,17750,17752],{"class":5707,"line":6473},[5705,17747,5949],{"class":5722},[5705,17749,5952],{"class":5726},[5705,17751,5955],{"class":5718},[5705,17753,6069],{"class":5726},[5705,17755,17756,17758,17760,17762,17764,17766,17768],{"class":5707,"line":6482},[5705,17757,5966],{"class":5718},[5705,17759,8740],{"class":5722},[5705,17761,5738],{"class":5726},[5705,17763,8745],{"class":5741},[5705,17765,5745],{"class":5726},[5705,17767,8750],{"class":5748},[5705,17769,7479],{"class":5726},[5705,17771,17772,17774,17776,17778,17780,17782,17784,17786,17788,17790,17792,17794,17796,17798],{"class":5707,"line":6487},[5705,17773,8757],{"class":6060},[5705,17775,7055],{"class":5726},[5705,17777,8745],{"class":5741},[5705,17779,5622],{"class":5726},[5705,17781,8421],{"class":5741},[5705,17783,8768],{"class":5726},[5705,17785,8421],{"class":5741},[5705,17787,7605],{"class":5726},[5705,17789,8745],{"class":5741},[5705,17791,5622],{"class":5726},[5705,17793,8779],{"class":5741},[5705,17795,7615],{"class":5726},[5705,17797,7157],{"class":5718},[5705,17799,7479],{"class":5726},[5705,17801,17802,17804],{"class":5707,"line":6496},[5705,17803,8790],{"class":6060},[5705,17805,6069],{"class":5726},[5705,17807,17808,17810,17812,17814,17816,17818,17820,17822,17824,17826,17828,17830,17832],{"class":5707,"line":7008},[5705,17809,8797],{"class":5722},[5705,17811,5738],{"class":5726},[5705,17813,8436],{"class":5913},[5705,17815,5622],{"class":5726},[5705,17817,8441],{"class":5722},[5705,17819,5738],{"class":5726},[5705,17821,8745],{"class":5741},[5705,17823,5622],{"class":5726},[5705,17825,8779],{"class":5741},[5705,17827,8337],{"class":5726},[5705,17829,8451],{"class":6060},[5705,17831,8342],{"class":5748},[5705,17833,6028],{"class":5726},[5705,17835,17836,17838,17840],{"class":5707,"line":7014},[5705,17837,8826],{"class":5726},[5705,17839,7577],{"class":6060},[5705,17841,17842],{"class":5726}," {}\n",[5705,17844,17845],{"class":5707,"line":7020},[5705,17846,7696],{"class":5726},[5705,17848,17849],{"class":5707,"line":7026},[5705,17850,6333],{"class":5726},[5705,17852,17853],{"class":5707,"line":7032},[5705,17854,5795],{"emptyLinePlaceholder":5794},[5705,17856,17857,17859,17861,17863,17865,17868,17870,17872],{"class":5707,"line":7037},[5705,17858,6009],{"class":5741},[5705,17860,5622],{"class":5726},[5705,17862,6014],{"class":5722},[5705,17864,5738],{"class":5726},[5705,17866,17867],{"class":6019},"'storage'",[5705,17869,5580],{"class":5726},[5705,17871,8888],{"class":5741},[5705,17873,6028],{"class":5726},[5705,17875,17876,17878,17880,17882,17884,17886,17888,17890,17892,17894,17896],{"class":5707,"line":7639},[5705,17877,6061],{"class":6060},[5705,17879,6064],{"class":5726},[5705,17881,5955],{"class":5718},[5705,17883,11037],{"class":5741},[5705,17885,5622],{"class":5726},[5705,17887,6080],{"class":5722},[5705,17889,5738],{"class":5726},[5705,17891,17867],{"class":6019},[5705,17893,5580],{"class":5726},[5705,17895,8888],{"class":5741},[5705,17897,6028],{"class":5726},[5705,17899,17900,17902,17904],{"class":5707,"line":7644},[5705,17901,7760],{"class":5726},[5705,17903,8421],{"class":5741},[5705,17905,8935],{"class":5726},[5705,17907,17908],{"class":5707,"line":7654},[5705,17909,5795],{"emptyLinePlaceholder":5794},[5705,17911,17912,17914,17916,17918,17920,17922],{"class":5707,"line":7660},[5705,17913,6132],{"class":6060},[5705,17915,5910],{"class":5726},[5705,17917,8367],{"class":5741},[5705,17919,5580],{"class":5726},[5705,17921,8952],{"class":5741},[5705,17923,8955],{"class":5726},[5705,17925,17926],{"class":5707,"line":7676},[5705,17927,6144],{"class":5726},[5696,17929,17934],{"className":17930,"code":17931,"filename":17932,"language":17933,"meta":5701,"style":5701},"language-css shiki shiki-themes light-plus dark-plus dark-plus","* {\n  box-sizing: border-box;\n  margin: 0;\n  padding: 0;\n}\n\n.app {\n  min-height: 100vh;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  font-family: system-ui, -apple-system, sans-serif;\n}\n\n.header {\n  padding: 2rem;\n  background: rgba(255, 255, 255, 0.1);\n  backdrop-filter: blur(10px);\n  border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n}\n\n.header h1 {\n  color: white;\n  font-size: 1.75rem;\n  margin-bottom: 1rem;\n  text-align: center;\n}\n\n.demo-tabs {\n  display: flex;\n  gap: 0.5rem;\n  justify-content: center;\n  flex-wrap: wrap;\n}\n\n.demo-tabs button {\n  padding: 0.75rem 1.5rem;\n  border: none;\n  border-radius: 0.5rem;\n  background: rgba(255, 255, 255, 0.2);\n  color: white;\n  font-weight: 600;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.demo-tabs button:hover {\n  background: rgba(255, 255, 255, 0.3);\n}\n\n.demo-tabs button.active {\n  background: white;\n  color: #667eea;\n}\n\n.main {\n  padding: 2rem;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  min-height: calc(100vh - 180px);\n}\n\n.demo-card {\n  max-width: 600px;\n  width: 100%;\n  padding: 2rem;\n  background: white;\n  border-radius: 1rem;\n  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n}\n\n.demo-card h2 {\n  font-size: 1.5rem;\n  margin-bottom: 1.5rem;\n  color: #1e293b;\n}\n\n.status-indicator {\n  display: flex;\n  align-items: center;\n  gap: 1rem;\n  padding: 1.5rem;\n  border-radius: 0.75rem;\n  margin-bottom: 1rem;\n}\n\n.status-indicator.online {\n  background: #dcfce7;\n  border: 2px solid #22c55e;\n}\n\n.status-indicator.offline {\n  background: #fee2e2;\n  border: 2px solid #ef4444;\n}\n\n.status-dot {\n  width: 16px;\n  height: 16px;\n  border-radius: 50%;\n}\n\n.status-indicator.online .status-dot {\n  background: #22c55e;\n  box-shadow: 0 0 12px #22c55e;\n}\n\n.status-indicator.offline .status-dot {\n  background: #ef4444;\n  box-shadow: 0 0 12px #ef4444;\n}\n\n.status-text {\n  font-size: 1.25rem;\n  font-weight: 600;\n}\n\n.search-input {\n  width: 100%;\n  padding: 0.75rem 1rem;\n  font-size: 1rem;\n  border: 2px solid #e2e8f0;\n  border-radius: 0.5rem;\n  margin-bottom: 1rem;\n}\n\n.search-input:focus {\n  outline: none;\n  border-color: #667eea;\n}\n\n.search-info {\n  padding: 1rem;\n  background: #f1f5f9;\n  border-radius: 0.5rem;\n  margin-bottom: 1rem;\n}\n\n.search-info p {\n  margin: 0.25rem 0;\n  font-size: 0.9rem;\n  color: #475569;\n}\n\n.search-results {\n  list-style: none;\n  padding: 0;\n  margin: 1rem 0;\n}\n\n.search-results li {\n  padding: 0.75rem 1rem;\n  background: #f8fafc;\n  border-left: 3px solid #667eea;\n  margin-bottom: 0.5rem;\n  border-radius: 0.25rem;\n}\n\n.theme-controls {\n  margin-bottom: 1.5rem;\n}\n\n.theme-btn {\n  padding: 0.75rem 1.5rem;\n  border: none;\n  border-radius: 0.5rem;\n  background: #667eea;\n  color: white;\n  font-weight: 600;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.theme-btn:hover {\n  background: #5568d3;\n}\n\n.demo-card.theme-dark {\n  background: #1e293b;\n  color: white;\n}\n\n.demo-card.theme-dark h2 {\n  color: white;\n}\n\n.demo-card.theme-dark .search-info {\n  background: #334155;\n  color: #e2e8f0;\n}\n\n.counter {\n  margin-bottom: 1.5rem;\n}\n\n.counter p {\n  font-size: 1.25rem;\n  margin-bottom: 1rem;\n}\n\n.counter-controls {\n  display: flex;\n  gap: 0.5rem;\n}\n\n.counter-controls button {\n  padding: 0.5rem 1rem;\n  border: 2px solid #e2e8f0;\n  border-radius: 0.5rem;\n  background: white;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.counter-controls button:hover {\n  border-color: #667eea;\n  color: #667eea;\n}\n\n.hint {\n  margin: 1rem 0;\n  padding: 0.75rem;\n  background: #fef3c7;\n  border-left: 3px solid #f59e0b;\n  border-radius: 0.25rem;\n  font-size: 0.9rem;\n  color: #92400e;\n}\n\n.code-preview {\n  margin-top: 1.5rem;\n  padding: 1rem;\n  background: #1e293b;\n  border-radius: 0.5rem;\n  overflow-x: auto;\n}\n\n.code-preview code {\n  color: #e2e8f0;\n  font-family: 'Courier New', monospace;\n  font-size: 0.9rem;\n}\n","src\u002Fstyles.css","css",[5535,17935,17936,17943,17956,17967,17978,17982,17986,17994,18006,18039,18057,18061,18065,18072,18083,18112,18129,18164,18168,18172,18181,18193,18205,18217,18229,18233,18237,18244,18256,18268,18279,18291,18295,18299,18308,18322,18334,18345,18371,18381,18393,18405,18420,18424,18428,18437,18464,18468,18472,18481,18491,18501,18505,18509,18516,18526,18536,18546,18557,18578,18582,18586,18593,18605,18616,18626,18636,18646,18681,18685,18689,18698,18709,18719,18730,18734,18738,18745,18755,18765,18775,18785,18795,18805,18809,18813,18820,18832,18849,18854,18859,18867,18879,18895,18900,18905,18913,18925,18936,18948,18953,18958,18968,18980,18998,19003,19008,19017,19029,19046,19051,19056,19064,19076,19087,19092,19097,19105,19116,19130,19141,19157,19168,19179,19184,19189,19197,19209,19221,19226,19231,19239,19250,19262,19273,19284,19289,19294,19304,19318,19330,19342,19347,19352,19360,19372,19383,19396,19401,19406,19416,19429,19441,19459,19470,19481,19486,19491,19499,19510,19515,19520,19528,19541,19552,19563,19574,19585,19596,19607,19620,19625,19630,19638,19650,19655,19660,19668,19679,19690,19695,19700,19709,19720,19725,19730,19740,19752,19764,19769,19774,19782,19793,19798,19803,19812,19823,19834,19839,19844,19852,19863,19874,19879,19884,19893,19906,19921,19932,19943,19954,19967,19972,19977,19986,19997,20008,20013,20018,20026,20039,20050,20062,20078,20089,20100,20112,20117,20122,20130,20142,20153,20164,20175,20188,20193,20198,20208,20219,20236,20247],{"__ignoreMap":5701},[5705,17937,17938,17941],{"class":5707,"line":5708},[5705,17939,17940],{"class":6553},"*",[5705,17942,6069],{"class":5726},[5705,17944,17945,17948,17950,17954],{"class":5707,"line":5715},[5705,17946,17947],{"class":6557},"  box-sizing",[5705,17949,5745],{"class":5726},[5705,17951,17953],{"class":17952},"sDUd3","border-box",[5705,17955,6138],{"class":5726},[5705,17957,17958,17961,17963,17965],{"class":5707,"line":5730},[5705,17959,17960],{"class":6557},"  margin",[5705,17962,5745],{"class":5726},[5705,17964,16483],{"class":9489},[5705,17966,6138],{"class":5726},[5705,17968,17969,17972,17974,17976],{"class":5707,"line":5755},[5705,17970,17971],{"class":6557},"  padding",[5705,17973,5745],{"class":5726},[5705,17975,16483],{"class":9489},[5705,17977,6138],{"class":5726},[5705,17979,17980],{"class":5707,"line":5791},[5705,17981,6144],{"class":5726},[5705,17983,17984],{"class":5707,"line":5798},[5705,17985,5795],{"emptyLinePlaceholder":5794},[5705,17987,17988,17992],{"class":5707,"line":5804},[5705,17989,17991],{"class":17990},"sqdDX",".app",[5705,17993,6069],{"class":5726},[5705,17995,17996,17999,18001,18004],{"class":5707,"line":5818},[5705,17997,17998],{"class":6557},"  min-height",[5705,18000,5745],{"class":5726},[5705,18002,18003],{"class":9489},"100vh",[5705,18005,6138],{"class":5726},[5705,18007,18008,18011,18013,18016,18018,18021,18023,18026,18029,18031,18034,18037],{"class":5707,"line":6031},[5705,18009,18010],{"class":6557},"  background",[5705,18012,5745],{"class":5726},[5705,18014,18015],{"class":5722},"linear-gradient",[5705,18017,5738],{"class":5726},[5705,18019,18020],{"class":9489},"135deg",[5705,18022,5580],{"class":5726},[5705,18024,18025],{"class":17952},"#667eea",[5705,18027,18028],{"class":9489}," 0%",[5705,18030,5580],{"class":5726},[5705,18032,18033],{"class":17952},"#764ba2",[5705,18035,18036],{"class":9489}," 100%",[5705,18038,6028],{"class":5726},[5705,18040,18041,18044,18046,18049,18052,18055],{"class":5707,"line":6052},[5705,18042,18043],{"class":6557},"  font-family",[5705,18045,5745],{"class":5726},[5705,18047,18048],{"class":17952},"system-ui",[5705,18050,18051],{"class":5726},", -apple-system, ",[5705,18053,18054],{"class":17952},"sans-serif",[5705,18056,6138],{"class":5726},[5705,18058,18059],{"class":5707,"line":6057},[5705,18060,6144],{"class":5726},[5705,18062,18063],{"class":5707,"line":6072},[5705,18064,5795],{"emptyLinePlaceholder":5794},[5705,18066,18067,18070],{"class":5707,"line":6093},[5705,18068,18069],{"class":17990},".header",[5705,18071,6069],{"class":5726},[5705,18073,18074,18076,18078,18081],{"class":5707,"line":6112},[5705,18075,17971],{"class":6557},[5705,18077,5745],{"class":5726},[5705,18079,18080],{"class":9489},"2rem",[5705,18082,6138],{"class":5726},[5705,18084,18085,18087,18089,18092,18094,18097,18099,18101,18103,18105,18107,18110],{"class":5707,"line":6118},[5705,18086,18010],{"class":6557},[5705,18088,5745],{"class":5726},[5705,18090,18091],{"class":5722},"rgba",[5705,18093,5738],{"class":5726},[5705,18095,18096],{"class":9489},"255",[5705,18098,5580],{"class":5726},[5705,18100,18096],{"class":9489},[5705,18102,5580],{"class":5726},[5705,18104,18096],{"class":9489},[5705,18106,5580],{"class":5726},[5705,18108,18109],{"class":9489},"0.1",[5705,18111,6028],{"class":5726},[5705,18113,18114,18117,18119,18122,18124,18127],{"class":5707,"line":6124},[5705,18115,18116],{"class":6557},"  backdrop-filter",[5705,18118,5745],{"class":5726},[5705,18120,18121],{"class":5722},"blur",[5705,18123,5738],{"class":5726},[5705,18125,18126],{"class":9489},"10px",[5705,18128,6028],{"class":5726},[5705,18130,18131,18134,18136,18139,18142,18145,18147,18149,18151,18153,18155,18157,18159,18162],{"class":5707,"line":6129},[5705,18132,18133],{"class":6557},"  border-bottom",[5705,18135,5745],{"class":5726},[5705,18137,18138],{"class":9489},"1px",[5705,18140,18141],{"class":17952}," solid",[5705,18143,18144],{"class":5722}," rgba",[5705,18146,5738],{"class":5726},[5705,18148,18096],{"class":9489},[5705,18150,5580],{"class":5726},[5705,18152,18096],{"class":9489},[5705,18154,5580],{"class":5726},[5705,18156,18096],{"class":9489},[5705,18158,5580],{"class":5726},[5705,18160,18161],{"class":9489},"0.2",[5705,18163,6028],{"class":5726},[5705,18165,18166],{"class":5707,"line":6141},[5705,18167,6144],{"class":5726},[5705,18169,18170],{"class":5707,"line":6389},[5705,18171,5795],{"emptyLinePlaceholder":5794},[5705,18173,18174,18176,18179],{"class":5707,"line":6408},[5705,18175,18069],{"class":17990},[5705,18177,18178],{"class":17990}," h1",[5705,18180,6069],{"class":5726},[5705,18182,18183,18186,18188,18191],{"class":5707,"line":6413},[5705,18184,18185],{"class":6557},"  color",[5705,18187,5745],{"class":5726},[5705,18189,18190],{"class":17952},"white",[5705,18192,6138],{"class":5726},[5705,18194,18195,18198,18200,18203],{"class":5707,"line":6419},[5705,18196,18197],{"class":6557},"  font-size",[5705,18199,5745],{"class":5726},[5705,18201,18202],{"class":9489},"1.75rem",[5705,18204,6138],{"class":5726},[5705,18206,18207,18210,18212,18215],{"class":5707,"line":6430},[5705,18208,18209],{"class":6557},"  margin-bottom",[5705,18211,5745],{"class":5726},[5705,18213,18214],{"class":9489},"1rem",[5705,18216,6138],{"class":5726},[5705,18218,18219,18222,18224,18227],{"class":5707,"line":6449},[5705,18220,18221],{"class":6557},"  text-align",[5705,18223,5745],{"class":5726},[5705,18225,18226],{"class":17952},"center",[5705,18228,6138],{"class":5726},[5705,18230,18231],{"class":5707,"line":6468},[5705,18232,6144],{"class":5726},[5705,18234,18235],{"class":5707,"line":6473},[5705,18236,5795],{"emptyLinePlaceholder":5794},[5705,18238,18239,18242],{"class":5707,"line":6482},[5705,18240,18241],{"class":17990},".demo-tabs",[5705,18243,6069],{"class":5726},[5705,18245,18246,18249,18251,18254],{"class":5707,"line":6487},[5705,18247,18248],{"class":6557},"  display",[5705,18250,5745],{"class":5726},[5705,18252,18253],{"class":17952},"flex",[5705,18255,6138],{"class":5726},[5705,18257,18258,18261,18263,18266],{"class":5707,"line":6496},[5705,18259,18260],{"class":6557},"  gap",[5705,18262,5745],{"class":5726},[5705,18264,18265],{"class":9489},"0.5rem",[5705,18267,6138],{"class":5726},[5705,18269,18270,18273,18275,18277],{"class":5707,"line":7008},[5705,18271,18272],{"class":6557},"  justify-content",[5705,18274,5745],{"class":5726},[5705,18276,18226],{"class":17952},[5705,18278,6138],{"class":5726},[5705,18280,18281,18284,18286,18289],{"class":5707,"line":7014},[5705,18282,18283],{"class":6557},"  flex-wrap",[5705,18285,5745],{"class":5726},[5705,18287,18288],{"class":17952},"wrap",[5705,18290,6138],{"class":5726},[5705,18292,18293],{"class":5707,"line":7020},[5705,18294,6144],{"class":5726},[5705,18296,18297],{"class":5707,"line":7026},[5705,18298,5795],{"emptyLinePlaceholder":5794},[5705,18300,18301,18303,18306],{"class":5707,"line":7032},[5705,18302,18241],{"class":17990},[5705,18304,18305],{"class":17990}," button",[5705,18307,6069],{"class":5726},[5705,18309,18310,18312,18314,18317,18320],{"class":5707,"line":7037},[5705,18311,17971],{"class":6557},[5705,18313,5745],{"class":5726},[5705,18315,18316],{"class":9489},"0.75rem",[5705,18318,18319],{"class":9489}," 1.5rem",[5705,18321,6138],{"class":5726},[5705,18323,18324,18327,18329,18332],{"class":5707,"line":7639},[5705,18325,18326],{"class":6557},"  border",[5705,18328,5745],{"class":5726},[5705,18330,18331],{"class":17952},"none",[5705,18333,6138],{"class":5726},[5705,18335,18336,18339,18341,18343],{"class":5707,"line":7644},[5705,18337,18338],{"class":6557},"  border-radius",[5705,18340,5745],{"class":5726},[5705,18342,18265],{"class":9489},[5705,18344,6138],{"class":5726},[5705,18346,18347,18349,18351,18353,18355,18357,18359,18361,18363,18365,18367,18369],{"class":5707,"line":7654},[5705,18348,18010],{"class":6557},[5705,18350,5745],{"class":5726},[5705,18352,18091],{"class":5722},[5705,18354,5738],{"class":5726},[5705,18356,18096],{"class":9489},[5705,18358,5580],{"class":5726},[5705,18360,18096],{"class":9489},[5705,18362,5580],{"class":5726},[5705,18364,18096],{"class":9489},[5705,18366,5580],{"class":5726},[5705,18368,18161],{"class":9489},[5705,18370,6028],{"class":5726},[5705,18372,18373,18375,18377,18379],{"class":5707,"line":7660},[5705,18374,18185],{"class":6557},[5705,18376,5745],{"class":5726},[5705,18378,18190],{"class":17952},[5705,18380,6138],{"class":5726},[5705,18382,18383,18386,18388,18391],{"class":5707,"line":7676},[5705,18384,18385],{"class":6557},"  font-weight",[5705,18387,5745],{"class":5726},[5705,18389,18390],{"class":9489},"600",[5705,18392,6138],{"class":5726},[5705,18394,18395,18398,18400,18403],{"class":5707,"line":7688},[5705,18396,18397],{"class":6557},"  cursor",[5705,18399,5745],{"class":5726},[5705,18401,18402],{"class":17952},"pointer",[5705,18404,6138],{"class":5726},[5705,18406,18407,18410,18412,18415,18418],{"class":5707,"line":7693},[5705,18408,18409],{"class":6557},"  transition",[5705,18411,5745],{"class":5726},[5705,18413,18414],{"class":17952},"all",[5705,18416,18417],{"class":9489}," 0.2s",[5705,18419,6138],{"class":5726},[5705,18421,18422],{"class":5707,"line":7699},[5705,18423,6144],{"class":5726},[5705,18425,18426],{"class":5707,"line":7704},[5705,18427,5795],{"emptyLinePlaceholder":5794},[5705,18429,18430,18432,18435],{"class":5707,"line":7709},[5705,18431,18241],{"class":17990},[5705,18433,18434],{"class":17990}," button:hover",[5705,18436,6069],{"class":5726},[5705,18438,18439,18441,18443,18445,18447,18449,18451,18453,18455,18457,18459,18462],{"class":5707,"line":7717},[5705,18440,18010],{"class":6557},[5705,18442,5745],{"class":5726},[5705,18444,18091],{"class":5722},[5705,18446,5738],{"class":5726},[5705,18448,18096],{"class":9489},[5705,18450,5580],{"class":5726},[5705,18452,18096],{"class":9489},[5705,18454,5580],{"class":5726},[5705,18456,18096],{"class":9489},[5705,18458,5580],{"class":5726},[5705,18460,18461],{"class":9489},"0.3",[5705,18463,6028],{"class":5726},[5705,18465,18466],{"class":5707,"line":7722},[5705,18467,6144],{"class":5726},[5705,18469,18470],{"class":5707,"line":7728},[5705,18471,5795],{"emptyLinePlaceholder":5794},[5705,18473,18474,18476,18479],{"class":5707,"line":7739},[5705,18475,18241],{"class":17990},[5705,18477,18478],{"class":17990}," button.active",[5705,18480,6069],{"class":5726},[5705,18482,18483,18485,18487,18489],{"class":5707,"line":7752},[5705,18484,18010],{"class":6557},[5705,18486,5745],{"class":5726},[5705,18488,18190],{"class":17952},[5705,18490,6138],{"class":5726},[5705,18492,18493,18495,18497,18499],{"class":5707,"line":7757},[5705,18494,18185],{"class":6557},[5705,18496,5745],{"class":5726},[5705,18498,18025],{"class":17952},[5705,18500,6138],{"class":5726},[5705,18502,18503],{"class":5707,"line":7771},[5705,18504,6144],{"class":5726},[5705,18506,18507],{"class":5707,"line":7776},[5705,18508,5795],{"emptyLinePlaceholder":5794},[5705,18510,18511,18514],{"class":5707,"line":7796},[5705,18512,18513],{"class":17990},".main",[5705,18515,6069],{"class":5726},[5705,18517,18518,18520,18522,18524],{"class":5707,"line":12343},[5705,18519,17971],{"class":6557},[5705,18521,5745],{"class":5726},[5705,18523,18080],{"class":9489},[5705,18525,6138],{"class":5726},[5705,18527,18528,18530,18532,18534],{"class":5707,"line":12351},[5705,18529,18248],{"class":6557},[5705,18531,5745],{"class":5726},[5705,18533,18253],{"class":17952},[5705,18535,6138],{"class":5726},[5705,18537,18538,18540,18542,18544],{"class":5707,"line":12364},[5705,18539,18272],{"class":6557},[5705,18541,5745],{"class":5726},[5705,18543,18226],{"class":17952},[5705,18545,6138],{"class":5726},[5705,18547,18548,18551,18553,18555],{"class":5707,"line":12400},[5705,18549,18550],{"class":6557},"  align-items",[5705,18552,5745],{"class":5726},[5705,18554,18226],{"class":17952},[5705,18556,6138],{"class":5726},[5705,18558,18559,18561,18563,18566,18568,18570,18573,18576],{"class":5707,"line":12410},[5705,18560,17998],{"class":6557},[5705,18562,5745],{"class":5726},[5705,18564,18565],{"class":5722},"calc",[5705,18567,5738],{"class":5726},[5705,18569,18003],{"class":9489},[5705,18571,18572],{"class":5726}," - ",[5705,18574,18575],{"class":9489},"180px",[5705,18577,6028],{"class":5726},[5705,18579,18580],{"class":5707,"line":12425},[5705,18581,6144],{"class":5726},[5705,18583,18584],{"class":5707,"line":12457},[5705,18585,5795],{"emptyLinePlaceholder":5794},[5705,18587,18588,18591],{"class":5707,"line":12462},[5705,18589,18590],{"class":17990},".demo-card",[5705,18592,6069],{"class":5726},[5705,18594,18595,18598,18600,18603],{"class":5707,"line":12495},[5705,18596,18597],{"class":6557},"  max-width",[5705,18599,5745],{"class":5726},[5705,18601,18602],{"class":9489},"600px",[5705,18604,6138],{"class":5726},[5705,18606,18607,18609,18611,18614],{"class":5707,"line":12536},[5705,18608,10963],{"class":6557},[5705,18610,5745],{"class":5726},[5705,18612,18613],{"class":9489},"100%",[5705,18615,6138],{"class":5726},[5705,18617,18618,18620,18622,18624],{"class":5707,"line":12545},[5705,18619,17971],{"class":6557},[5705,18621,5745],{"class":5726},[5705,18623,18080],{"class":9489},[5705,18625,6138],{"class":5726},[5705,18627,18628,18630,18632,18634],{"class":5707,"line":12550},[5705,18629,18010],{"class":6557},[5705,18631,5745],{"class":5726},[5705,18633,18190],{"class":17952},[5705,18635,6138],{"class":5726},[5705,18637,18638,18640,18642,18644],{"class":5707,"line":13481},[5705,18639,18338],{"class":6557},[5705,18641,5745],{"class":5726},[5705,18643,18214],{"class":9489},[5705,18645,6138],{"class":5726},[5705,18647,18648,18651,18653,18655,18658,18661,18663,18665,18667,18669,18671,18673,18675,18677,18679],{"class":5707,"line":13492},[5705,18649,18650],{"class":6557},"  box-shadow",[5705,18652,5745],{"class":5726},[5705,18654,16483],{"class":9489},[5705,18656,18657],{"class":9489}," 20px",[5705,18659,18660],{"class":9489}," 60px",[5705,18662,18144],{"class":5722},[5705,18664,5738],{"class":5726},[5705,18666,16483],{"class":9489},[5705,18668,5580],{"class":5726},[5705,18670,16483],{"class":9489},[5705,18672,5580],{"class":5726},[5705,18674,16483],{"class":9489},[5705,18676,5580],{"class":5726},[5705,18678,18461],{"class":9489},[5705,18680,6028],{"class":5726},[5705,18682,18683],{"class":5707,"line":13525},[5705,18684,6144],{"class":5726},[5705,18686,18687],{"class":5707,"line":13530},[5705,18688,5795],{"emptyLinePlaceholder":5794},[5705,18690,18691,18693,18696],{"class":5707,"line":13535},[5705,18692,18590],{"class":17990},[5705,18694,18695],{"class":17990}," h2",[5705,18697,6069],{"class":5726},[5705,18699,18700,18702,18704,18707],{"class":5707,"line":13542},[5705,18701,18197],{"class":6557},[5705,18703,5745],{"class":5726},[5705,18705,18706],{"class":9489},"1.5rem",[5705,18708,6138],{"class":5726},[5705,18710,18711,18713,18715,18717],{"class":5707,"line":13558},[5705,18712,18209],{"class":6557},[5705,18714,5745],{"class":5726},[5705,18716,18706],{"class":9489},[5705,18718,6138],{"class":5726},[5705,18720,18721,18723,18725,18728],{"class":5707,"line":13591},[5705,18722,18185],{"class":6557},[5705,18724,5745],{"class":5726},[5705,18726,18727],{"class":17952},"#1e293b",[5705,18729,6138],{"class":5726},[5705,18731,18732],{"class":5707,"line":13597},[5705,18733,6144],{"class":5726},[5705,18735,18736],{"class":5707,"line":13608},[5705,18737,5795],{"emptyLinePlaceholder":5794},[5705,18739,18740,18743],{"class":5707,"line":13614},[5705,18741,18742],{"class":17990},".status-indicator",[5705,18744,6069],{"class":5726},[5705,18746,18747,18749,18751,18753],{"class":5707,"line":13654},[5705,18748,18248],{"class":6557},[5705,18750,5745],{"class":5726},[5705,18752,18253],{"class":17952},[5705,18754,6138],{"class":5726},[5705,18756,18757,18759,18761,18763],{"class":5707,"line":13686},[5705,18758,18550],{"class":6557},[5705,18760,5745],{"class":5726},[5705,18762,18226],{"class":17952},[5705,18764,6138],{"class":5726},[5705,18766,18767,18769,18771,18773],{"class":5707,"line":13715},[5705,18768,18260],{"class":6557},[5705,18770,5745],{"class":5726},[5705,18772,18214],{"class":9489},[5705,18774,6138],{"class":5726},[5705,18776,18777,18779,18781,18783],{"class":5707,"line":13721},[5705,18778,17971],{"class":6557},[5705,18780,5745],{"class":5726},[5705,18782,18706],{"class":9489},[5705,18784,6138],{"class":5726},[5705,18786,18787,18789,18791,18793],{"class":5707,"line":13728},[5705,18788,18338],{"class":6557},[5705,18790,5745],{"class":5726},[5705,18792,18316],{"class":9489},[5705,18794,6138],{"class":5726},[5705,18796,18797,18799,18801,18803],{"class":5707,"line":13733},[5705,18798,18209],{"class":6557},[5705,18800,5745],{"class":5726},[5705,18802,18214],{"class":9489},[5705,18804,6138],{"class":5726},[5705,18806,18807],{"class":5707,"line":13766},[5705,18808,6144],{"class":5726},[5705,18810,18811],{"class":5707,"line":13775},[5705,18812,5795],{"emptyLinePlaceholder":5794},[5705,18814,18815,18818],{"class":5707,"line":13780},[5705,18816,18817],{"class":17990},".status-indicator.online",[5705,18819,6069],{"class":5726},[5705,18821,18823,18825,18827,18830],{"class":5707,"line":18822},87,[5705,18824,18010],{"class":6557},[5705,18826,5745],{"class":5726},[5705,18828,18829],{"class":17952},"#dcfce7",[5705,18831,6138],{"class":5726},[5705,18833,18835,18837,18839,18842,18844,18847],{"class":5707,"line":18834},88,[5705,18836,18326],{"class":6557},[5705,18838,5745],{"class":5726},[5705,18840,18841],{"class":9489},"2px",[5705,18843,18141],{"class":17952},[5705,18845,18846],{"class":17952}," #22c55e",[5705,18848,6138],{"class":5726},[5705,18850,18852],{"class":5707,"line":18851},89,[5705,18853,6144],{"class":5726},[5705,18855,18857],{"class":5707,"line":18856},90,[5705,18858,5795],{"emptyLinePlaceholder":5794},[5705,18860,18862,18865],{"class":5707,"line":18861},91,[5705,18863,18864],{"class":17990},".status-indicator.offline",[5705,18866,6069],{"class":5726},[5705,18868,18870,18872,18874,18877],{"class":5707,"line":18869},92,[5705,18871,18010],{"class":6557},[5705,18873,5745],{"class":5726},[5705,18875,18876],{"class":17952},"#fee2e2",[5705,18878,6138],{"class":5726},[5705,18880,18882,18884,18886,18888,18890,18893],{"class":5707,"line":18881},93,[5705,18883,18326],{"class":6557},[5705,18885,5745],{"class":5726},[5705,18887,18841],{"class":9489},[5705,18889,18141],{"class":17952},[5705,18891,18892],{"class":17952}," #ef4444",[5705,18894,6138],{"class":5726},[5705,18896,18898],{"class":5707,"line":18897},94,[5705,18899,6144],{"class":5726},[5705,18901,18903],{"class":5707,"line":18902},95,[5705,18904,5795],{"emptyLinePlaceholder":5794},[5705,18906,18908,18911],{"class":5707,"line":18907},96,[5705,18909,18910],{"class":17990},".status-dot",[5705,18912,6069],{"class":5726},[5705,18914,18916,18918,18920,18923],{"class":5707,"line":18915},97,[5705,18917,10963],{"class":6557},[5705,18919,5745],{"class":5726},[5705,18921,18922],{"class":9489},"16px",[5705,18924,6138],{"class":5726},[5705,18926,18928,18930,18932,18934],{"class":5707,"line":18927},98,[5705,18929,10974],{"class":6557},[5705,18931,5745],{"class":5726},[5705,18933,18922],{"class":9489},[5705,18935,6138],{"class":5726},[5705,18937,18939,18941,18943,18946],{"class":5707,"line":18938},99,[5705,18940,18338],{"class":6557},[5705,18942,5745],{"class":5726},[5705,18944,18945],{"class":9489},"50%",[5705,18947,6138],{"class":5726},[5705,18949,18951],{"class":5707,"line":18950},100,[5705,18952,6144],{"class":5726},[5705,18954,18956],{"class":5707,"line":18955},101,[5705,18957,5795],{"emptyLinePlaceholder":5794},[5705,18959,18961,18963,18966],{"class":5707,"line":18960},102,[5705,18962,18817],{"class":17990},[5705,18964,18965],{"class":17990}," .status-dot",[5705,18967,6069],{"class":5726},[5705,18969,18971,18973,18975,18978],{"class":5707,"line":18970},103,[5705,18972,18010],{"class":6557},[5705,18974,5745],{"class":5726},[5705,18976,18977],{"class":17952},"#22c55e",[5705,18979,6138],{"class":5726},[5705,18981,18983,18985,18987,18989,18991,18994,18996],{"class":5707,"line":18982},104,[5705,18984,18650],{"class":6557},[5705,18986,5745],{"class":5726},[5705,18988,16483],{"class":9489},[5705,18990,16205],{"class":9489},[5705,18992,18993],{"class":9489}," 12px",[5705,18995,18846],{"class":17952},[5705,18997,6138],{"class":5726},[5705,18999,19001],{"class":5707,"line":19000},105,[5705,19002,6144],{"class":5726},[5705,19004,19006],{"class":5707,"line":19005},106,[5705,19007,5795],{"emptyLinePlaceholder":5794},[5705,19009,19011,19013,19015],{"class":5707,"line":19010},107,[5705,19012,18864],{"class":17990},[5705,19014,18965],{"class":17990},[5705,19016,6069],{"class":5726},[5705,19018,19020,19022,19024,19027],{"class":5707,"line":19019},108,[5705,19021,18010],{"class":6557},[5705,19023,5745],{"class":5726},[5705,19025,19026],{"class":17952},"#ef4444",[5705,19028,6138],{"class":5726},[5705,19030,19032,19034,19036,19038,19040,19042,19044],{"class":5707,"line":19031},109,[5705,19033,18650],{"class":6557},[5705,19035,5745],{"class":5726},[5705,19037,16483],{"class":9489},[5705,19039,16205],{"class":9489},[5705,19041,18993],{"class":9489},[5705,19043,18892],{"class":17952},[5705,19045,6138],{"class":5726},[5705,19047,19049],{"class":5707,"line":19048},110,[5705,19050,6144],{"class":5726},[5705,19052,19054],{"class":5707,"line":19053},111,[5705,19055,5795],{"emptyLinePlaceholder":5794},[5705,19057,19059,19062],{"class":5707,"line":19058},112,[5705,19060,19061],{"class":17990},".status-text",[5705,19063,6069],{"class":5726},[5705,19065,19067,19069,19071,19074],{"class":5707,"line":19066},113,[5705,19068,18197],{"class":6557},[5705,19070,5745],{"class":5726},[5705,19072,19073],{"class":9489},"1.25rem",[5705,19075,6138],{"class":5726},[5705,19077,19079,19081,19083,19085],{"class":5707,"line":19078},114,[5705,19080,18385],{"class":6557},[5705,19082,5745],{"class":5726},[5705,19084,18390],{"class":9489},[5705,19086,6138],{"class":5726},[5705,19088,19090],{"class":5707,"line":19089},115,[5705,19091,6144],{"class":5726},[5705,19093,19095],{"class":5707,"line":19094},116,[5705,19096,5795],{"emptyLinePlaceholder":5794},[5705,19098,19100,19103],{"class":5707,"line":19099},117,[5705,19101,19102],{"class":17990},".search-input",[5705,19104,6069],{"class":5726},[5705,19106,19108,19110,19112,19114],{"class":5707,"line":19107},118,[5705,19109,10963],{"class":6557},[5705,19111,5745],{"class":5726},[5705,19113,18613],{"class":9489},[5705,19115,6138],{"class":5726},[5705,19117,19119,19121,19123,19125,19128],{"class":5707,"line":19118},119,[5705,19120,17971],{"class":6557},[5705,19122,5745],{"class":5726},[5705,19124,18316],{"class":9489},[5705,19126,19127],{"class":9489}," 1rem",[5705,19129,6138],{"class":5726},[5705,19131,19133,19135,19137,19139],{"class":5707,"line":19132},120,[5705,19134,18197],{"class":6557},[5705,19136,5745],{"class":5726},[5705,19138,18214],{"class":9489},[5705,19140,6138],{"class":5726},[5705,19142,19144,19146,19148,19150,19152,19155],{"class":5707,"line":19143},121,[5705,19145,18326],{"class":6557},[5705,19147,5745],{"class":5726},[5705,19149,18841],{"class":9489},[5705,19151,18141],{"class":17952},[5705,19153,19154],{"class":17952}," #e2e8f0",[5705,19156,6138],{"class":5726},[5705,19158,19160,19162,19164,19166],{"class":5707,"line":19159},122,[5705,19161,18338],{"class":6557},[5705,19163,5745],{"class":5726},[5705,19165,18265],{"class":9489},[5705,19167,6138],{"class":5726},[5705,19169,19171,19173,19175,19177],{"class":5707,"line":19170},123,[5705,19172,18209],{"class":6557},[5705,19174,5745],{"class":5726},[5705,19176,18214],{"class":9489},[5705,19178,6138],{"class":5726},[5705,19180,19182],{"class":5707,"line":19181},124,[5705,19183,6144],{"class":5726},[5705,19185,19187],{"class":5707,"line":19186},125,[5705,19188,5795],{"emptyLinePlaceholder":5794},[5705,19190,19192,19195],{"class":5707,"line":19191},126,[5705,19193,19194],{"class":17990},".search-input:focus",[5705,19196,6069],{"class":5726},[5705,19198,19200,19203,19205,19207],{"class":5707,"line":19199},127,[5705,19201,19202],{"class":6557},"  outline",[5705,19204,5745],{"class":5726},[5705,19206,18331],{"class":17952},[5705,19208,6138],{"class":5726},[5705,19210,19212,19215,19217,19219],{"class":5707,"line":19211},128,[5705,19213,19214],{"class":6557},"  border-color",[5705,19216,5745],{"class":5726},[5705,19218,18025],{"class":17952},[5705,19220,6138],{"class":5726},[5705,19222,19224],{"class":5707,"line":19223},129,[5705,19225,6144],{"class":5726},[5705,19227,19229],{"class":5707,"line":19228},130,[5705,19230,5795],{"emptyLinePlaceholder":5794},[5705,19232,19234,19237],{"class":5707,"line":19233},131,[5705,19235,19236],{"class":17990},".search-info",[5705,19238,6069],{"class":5726},[5705,19240,19242,19244,19246,19248],{"class":5707,"line":19241},132,[5705,19243,17971],{"class":6557},[5705,19245,5745],{"class":5726},[5705,19247,18214],{"class":9489},[5705,19249,6138],{"class":5726},[5705,19251,19253,19255,19257,19260],{"class":5707,"line":19252},133,[5705,19254,18010],{"class":6557},[5705,19256,5745],{"class":5726},[5705,19258,19259],{"class":17952},"#f1f5f9",[5705,19261,6138],{"class":5726},[5705,19263,19265,19267,19269,19271],{"class":5707,"line":19264},134,[5705,19266,18338],{"class":6557},[5705,19268,5745],{"class":5726},[5705,19270,18265],{"class":9489},[5705,19272,6138],{"class":5726},[5705,19274,19276,19278,19280,19282],{"class":5707,"line":19275},135,[5705,19277,18209],{"class":6557},[5705,19279,5745],{"class":5726},[5705,19281,18214],{"class":9489},[5705,19283,6138],{"class":5726},[5705,19285,19287],{"class":5707,"line":19286},136,[5705,19288,6144],{"class":5726},[5705,19290,19292],{"class":5707,"line":19291},137,[5705,19293,5795],{"emptyLinePlaceholder":5794},[5705,19295,19297,19299,19302],{"class":5707,"line":19296},138,[5705,19298,19236],{"class":17990},[5705,19300,19301],{"class":17990}," p",[5705,19303,6069],{"class":5726},[5705,19305,19307,19309,19311,19314,19316],{"class":5707,"line":19306},139,[5705,19308,17960],{"class":6557},[5705,19310,5745],{"class":5726},[5705,19312,19313],{"class":9489},"0.25rem",[5705,19315,16205],{"class":9489},[5705,19317,6138],{"class":5726},[5705,19319,19321,19323,19325,19328],{"class":5707,"line":19320},140,[5705,19322,18197],{"class":6557},[5705,19324,5745],{"class":5726},[5705,19326,19327],{"class":9489},"0.9rem",[5705,19329,6138],{"class":5726},[5705,19331,19333,19335,19337,19340],{"class":5707,"line":19332},141,[5705,19334,18185],{"class":6557},[5705,19336,5745],{"class":5726},[5705,19338,19339],{"class":17952},"#475569",[5705,19341,6138],{"class":5726},[5705,19343,19345],{"class":5707,"line":19344},142,[5705,19346,6144],{"class":5726},[5705,19348,19350],{"class":5707,"line":19349},143,[5705,19351,5795],{"emptyLinePlaceholder":5794},[5705,19353,19355,19358],{"class":5707,"line":19354},144,[5705,19356,19357],{"class":17990},".search-results",[5705,19359,6069],{"class":5726},[5705,19361,19363,19366,19368,19370],{"class":5707,"line":19362},145,[5705,19364,19365],{"class":6557},"  list-style",[5705,19367,5745],{"class":5726},[5705,19369,18331],{"class":17952},[5705,19371,6138],{"class":5726},[5705,19373,19375,19377,19379,19381],{"class":5707,"line":19374},146,[5705,19376,17971],{"class":6557},[5705,19378,5745],{"class":5726},[5705,19380,16483],{"class":9489},[5705,19382,6138],{"class":5726},[5705,19384,19386,19388,19390,19392,19394],{"class":5707,"line":19385},147,[5705,19387,17960],{"class":6557},[5705,19389,5745],{"class":5726},[5705,19391,18214],{"class":9489},[5705,19393,16205],{"class":9489},[5705,19395,6138],{"class":5726},[5705,19397,19399],{"class":5707,"line":19398},148,[5705,19400,6144],{"class":5726},[5705,19402,19404],{"class":5707,"line":19403},149,[5705,19405,5795],{"emptyLinePlaceholder":5794},[5705,19407,19409,19411,19414],{"class":5707,"line":19408},150,[5705,19410,19357],{"class":17990},[5705,19412,19413],{"class":17990}," li",[5705,19415,6069],{"class":5726},[5705,19417,19419,19421,19423,19425,19427],{"class":5707,"line":19418},151,[5705,19420,17971],{"class":6557},[5705,19422,5745],{"class":5726},[5705,19424,18316],{"class":9489},[5705,19426,19127],{"class":9489},[5705,19428,6138],{"class":5726},[5705,19430,19432,19434,19436,19439],{"class":5707,"line":19431},152,[5705,19433,18010],{"class":6557},[5705,19435,5745],{"class":5726},[5705,19437,19438],{"class":17952},"#f8fafc",[5705,19440,6138],{"class":5726},[5705,19442,19444,19447,19449,19452,19454,19457],{"class":5707,"line":19443},153,[5705,19445,19446],{"class":6557},"  border-left",[5705,19448,5745],{"class":5726},[5705,19450,19451],{"class":9489},"3px",[5705,19453,18141],{"class":17952},[5705,19455,19456],{"class":17952}," #667eea",[5705,19458,6138],{"class":5726},[5705,19460,19462,19464,19466,19468],{"class":5707,"line":19461},154,[5705,19463,18209],{"class":6557},[5705,19465,5745],{"class":5726},[5705,19467,18265],{"class":9489},[5705,19469,6138],{"class":5726},[5705,19471,19473,19475,19477,19479],{"class":5707,"line":19472},155,[5705,19474,18338],{"class":6557},[5705,19476,5745],{"class":5726},[5705,19478,19313],{"class":9489},[5705,19480,6138],{"class":5726},[5705,19482,19484],{"class":5707,"line":19483},156,[5705,19485,6144],{"class":5726},[5705,19487,19489],{"class":5707,"line":19488},157,[5705,19490,5795],{"emptyLinePlaceholder":5794},[5705,19492,19494,19497],{"class":5707,"line":19493},158,[5705,19495,19496],{"class":17990},".theme-controls",[5705,19498,6069],{"class":5726},[5705,19500,19502,19504,19506,19508],{"class":5707,"line":19501},159,[5705,19503,18209],{"class":6557},[5705,19505,5745],{"class":5726},[5705,19507,18706],{"class":9489},[5705,19509,6138],{"class":5726},[5705,19511,19513],{"class":5707,"line":19512},160,[5705,19514,6144],{"class":5726},[5705,19516,19518],{"class":5707,"line":19517},161,[5705,19519,5795],{"emptyLinePlaceholder":5794},[5705,19521,19523,19526],{"class":5707,"line":19522},162,[5705,19524,19525],{"class":17990},".theme-btn",[5705,19527,6069],{"class":5726},[5705,19529,19531,19533,19535,19537,19539],{"class":5707,"line":19530},163,[5705,19532,17971],{"class":6557},[5705,19534,5745],{"class":5726},[5705,19536,18316],{"class":9489},[5705,19538,18319],{"class":9489},[5705,19540,6138],{"class":5726},[5705,19542,19544,19546,19548,19550],{"class":5707,"line":19543},164,[5705,19545,18326],{"class":6557},[5705,19547,5745],{"class":5726},[5705,19549,18331],{"class":17952},[5705,19551,6138],{"class":5726},[5705,19553,19555,19557,19559,19561],{"class":5707,"line":19554},165,[5705,19556,18338],{"class":6557},[5705,19558,5745],{"class":5726},[5705,19560,18265],{"class":9489},[5705,19562,6138],{"class":5726},[5705,19564,19566,19568,19570,19572],{"class":5707,"line":19565},166,[5705,19567,18010],{"class":6557},[5705,19569,5745],{"class":5726},[5705,19571,18025],{"class":17952},[5705,19573,6138],{"class":5726},[5705,19575,19577,19579,19581,19583],{"class":5707,"line":19576},167,[5705,19578,18185],{"class":6557},[5705,19580,5745],{"class":5726},[5705,19582,18190],{"class":17952},[5705,19584,6138],{"class":5726},[5705,19586,19588,19590,19592,19594],{"class":5707,"line":19587},168,[5705,19589,18385],{"class":6557},[5705,19591,5745],{"class":5726},[5705,19593,18390],{"class":9489},[5705,19595,6138],{"class":5726},[5705,19597,19599,19601,19603,19605],{"class":5707,"line":19598},169,[5705,19600,18397],{"class":6557},[5705,19602,5745],{"class":5726},[5705,19604,18402],{"class":17952},[5705,19606,6138],{"class":5726},[5705,19608,19610,19612,19614,19616,19618],{"class":5707,"line":19609},170,[5705,19611,18409],{"class":6557},[5705,19613,5745],{"class":5726},[5705,19615,18414],{"class":17952},[5705,19617,18417],{"class":9489},[5705,19619,6138],{"class":5726},[5705,19621,19623],{"class":5707,"line":19622},171,[5705,19624,6144],{"class":5726},[5705,19626,19628],{"class":5707,"line":19627},172,[5705,19629,5795],{"emptyLinePlaceholder":5794},[5705,19631,19633,19636],{"class":5707,"line":19632},173,[5705,19634,19635],{"class":17990},".theme-btn:hover",[5705,19637,6069],{"class":5726},[5705,19639,19641,19643,19645,19648],{"class":5707,"line":19640},174,[5705,19642,18010],{"class":6557},[5705,19644,5745],{"class":5726},[5705,19646,19647],{"class":17952},"#5568d3",[5705,19649,6138],{"class":5726},[5705,19651,19653],{"class":5707,"line":19652},175,[5705,19654,6144],{"class":5726},[5705,19656,19658],{"class":5707,"line":19657},176,[5705,19659,5795],{"emptyLinePlaceholder":5794},[5705,19661,19663,19666],{"class":5707,"line":19662},177,[5705,19664,19665],{"class":17990},".demo-card.theme-dark",[5705,19667,6069],{"class":5726},[5705,19669,19671,19673,19675,19677],{"class":5707,"line":19670},178,[5705,19672,18010],{"class":6557},[5705,19674,5745],{"class":5726},[5705,19676,18727],{"class":17952},[5705,19678,6138],{"class":5726},[5705,19680,19682,19684,19686,19688],{"class":5707,"line":19681},179,[5705,19683,18185],{"class":6557},[5705,19685,5745],{"class":5726},[5705,19687,18190],{"class":17952},[5705,19689,6138],{"class":5726},[5705,19691,19693],{"class":5707,"line":19692},180,[5705,19694,6144],{"class":5726},[5705,19696,19698],{"class":5707,"line":19697},181,[5705,19699,5795],{"emptyLinePlaceholder":5794},[5705,19701,19703,19705,19707],{"class":5707,"line":19702},182,[5705,19704,19665],{"class":17990},[5705,19706,18695],{"class":17990},[5705,19708,6069],{"class":5726},[5705,19710,19712,19714,19716,19718],{"class":5707,"line":19711},183,[5705,19713,18185],{"class":6557},[5705,19715,5745],{"class":5726},[5705,19717,18190],{"class":17952},[5705,19719,6138],{"class":5726},[5705,19721,19723],{"class":5707,"line":19722},184,[5705,19724,6144],{"class":5726},[5705,19726,19728],{"class":5707,"line":19727},185,[5705,19729,5795],{"emptyLinePlaceholder":5794},[5705,19731,19733,19735,19738],{"class":5707,"line":19732},186,[5705,19734,19665],{"class":17990},[5705,19736,19737],{"class":17990}," .search-info",[5705,19739,6069],{"class":5726},[5705,19741,19743,19745,19747,19750],{"class":5707,"line":19742},187,[5705,19744,18010],{"class":6557},[5705,19746,5745],{"class":5726},[5705,19748,19749],{"class":17952},"#334155",[5705,19751,6138],{"class":5726},[5705,19753,19755,19757,19759,19762],{"class":5707,"line":19754},188,[5705,19756,18185],{"class":6557},[5705,19758,5745],{"class":5726},[5705,19760,19761],{"class":17952},"#e2e8f0",[5705,19763,6138],{"class":5726},[5705,19765,19767],{"class":5707,"line":19766},189,[5705,19768,6144],{"class":5726},[5705,19770,19772],{"class":5707,"line":19771},190,[5705,19773,5795],{"emptyLinePlaceholder":5794},[5705,19775,19777,19780],{"class":5707,"line":19776},191,[5705,19778,19779],{"class":17990},".counter",[5705,19781,6069],{"class":5726},[5705,19783,19785,19787,19789,19791],{"class":5707,"line":19784},192,[5705,19786,18209],{"class":6557},[5705,19788,5745],{"class":5726},[5705,19790,18706],{"class":9489},[5705,19792,6138],{"class":5726},[5705,19794,19796],{"class":5707,"line":19795},193,[5705,19797,6144],{"class":5726},[5705,19799,19801],{"class":5707,"line":19800},194,[5705,19802,5795],{"emptyLinePlaceholder":5794},[5705,19804,19806,19808,19810],{"class":5707,"line":19805},195,[5705,19807,19779],{"class":17990},[5705,19809,19301],{"class":17990},[5705,19811,6069],{"class":5726},[5705,19813,19815,19817,19819,19821],{"class":5707,"line":19814},196,[5705,19816,18197],{"class":6557},[5705,19818,5745],{"class":5726},[5705,19820,19073],{"class":9489},[5705,19822,6138],{"class":5726},[5705,19824,19826,19828,19830,19832],{"class":5707,"line":19825},197,[5705,19827,18209],{"class":6557},[5705,19829,5745],{"class":5726},[5705,19831,18214],{"class":9489},[5705,19833,6138],{"class":5726},[5705,19835,19837],{"class":5707,"line":19836},198,[5705,19838,6144],{"class":5726},[5705,19840,19842],{"class":5707,"line":19841},199,[5705,19843,5795],{"emptyLinePlaceholder":5794},[5705,19845,19847,19850],{"class":5707,"line":19846},200,[5705,19848,19849],{"class":17990},".counter-controls",[5705,19851,6069],{"class":5726},[5705,19853,19855,19857,19859,19861],{"class":5707,"line":19854},201,[5705,19856,18248],{"class":6557},[5705,19858,5745],{"class":5726},[5705,19860,18253],{"class":17952},[5705,19862,6138],{"class":5726},[5705,19864,19866,19868,19870,19872],{"class":5707,"line":19865},202,[5705,19867,18260],{"class":6557},[5705,19869,5745],{"class":5726},[5705,19871,18265],{"class":9489},[5705,19873,6138],{"class":5726},[5705,19875,19877],{"class":5707,"line":19876},203,[5705,19878,6144],{"class":5726},[5705,19880,19882],{"class":5707,"line":19881},204,[5705,19883,5795],{"emptyLinePlaceholder":5794},[5705,19885,19887,19889,19891],{"class":5707,"line":19886},205,[5705,19888,19849],{"class":17990},[5705,19890,18305],{"class":17990},[5705,19892,6069],{"class":5726},[5705,19894,19896,19898,19900,19902,19904],{"class":5707,"line":19895},206,[5705,19897,17971],{"class":6557},[5705,19899,5745],{"class":5726},[5705,19901,18265],{"class":9489},[5705,19903,19127],{"class":9489},[5705,19905,6138],{"class":5726},[5705,19907,19909,19911,19913,19915,19917,19919],{"class":5707,"line":19908},207,[5705,19910,18326],{"class":6557},[5705,19912,5745],{"class":5726},[5705,19914,18841],{"class":9489},[5705,19916,18141],{"class":17952},[5705,19918,19154],{"class":17952},[5705,19920,6138],{"class":5726},[5705,19922,19924,19926,19928,19930],{"class":5707,"line":19923},208,[5705,19925,18338],{"class":6557},[5705,19927,5745],{"class":5726},[5705,19929,18265],{"class":9489},[5705,19931,6138],{"class":5726},[5705,19933,19935,19937,19939,19941],{"class":5707,"line":19934},209,[5705,19936,18010],{"class":6557},[5705,19938,5745],{"class":5726},[5705,19940,18190],{"class":17952},[5705,19942,6138],{"class":5726},[5705,19944,19946,19948,19950,19952],{"class":5707,"line":19945},210,[5705,19947,18397],{"class":6557},[5705,19949,5745],{"class":5726},[5705,19951,18402],{"class":17952},[5705,19953,6138],{"class":5726},[5705,19955,19957,19959,19961,19963,19965],{"class":5707,"line":19956},211,[5705,19958,18409],{"class":6557},[5705,19960,5745],{"class":5726},[5705,19962,18414],{"class":17952},[5705,19964,18417],{"class":9489},[5705,19966,6138],{"class":5726},[5705,19968,19970],{"class":5707,"line":19969},212,[5705,19971,6144],{"class":5726},[5705,19973,19975],{"class":5707,"line":19974},213,[5705,19976,5795],{"emptyLinePlaceholder":5794},[5705,19978,19980,19982,19984],{"class":5707,"line":19979},214,[5705,19981,19849],{"class":17990},[5705,19983,18434],{"class":17990},[5705,19985,6069],{"class":5726},[5705,19987,19989,19991,19993,19995],{"class":5707,"line":19988},215,[5705,19990,19214],{"class":6557},[5705,19992,5745],{"class":5726},[5705,19994,18025],{"class":17952},[5705,19996,6138],{"class":5726},[5705,19998,20000,20002,20004,20006],{"class":5707,"line":19999},216,[5705,20001,18185],{"class":6557},[5705,20003,5745],{"class":5726},[5705,20005,18025],{"class":17952},[5705,20007,6138],{"class":5726},[5705,20009,20011],{"class":5707,"line":20010},217,[5705,20012,6144],{"class":5726},[5705,20014,20016],{"class":5707,"line":20015},218,[5705,20017,5795],{"emptyLinePlaceholder":5794},[5705,20019,20021,20024],{"class":5707,"line":20020},219,[5705,20022,20023],{"class":17990},".hint",[5705,20025,6069],{"class":5726},[5705,20027,20029,20031,20033,20035,20037],{"class":5707,"line":20028},220,[5705,20030,17960],{"class":6557},[5705,20032,5745],{"class":5726},[5705,20034,18214],{"class":9489},[5705,20036,16205],{"class":9489},[5705,20038,6138],{"class":5726},[5705,20040,20042,20044,20046,20048],{"class":5707,"line":20041},221,[5705,20043,17971],{"class":6557},[5705,20045,5745],{"class":5726},[5705,20047,18316],{"class":9489},[5705,20049,6138],{"class":5726},[5705,20051,20053,20055,20057,20060],{"class":5707,"line":20052},222,[5705,20054,18010],{"class":6557},[5705,20056,5745],{"class":5726},[5705,20058,20059],{"class":17952},"#fef3c7",[5705,20061,6138],{"class":5726},[5705,20063,20065,20067,20069,20071,20073,20076],{"class":5707,"line":20064},223,[5705,20066,19446],{"class":6557},[5705,20068,5745],{"class":5726},[5705,20070,19451],{"class":9489},[5705,20072,18141],{"class":17952},[5705,20074,20075],{"class":17952}," #f59e0b",[5705,20077,6138],{"class":5726},[5705,20079,20081,20083,20085,20087],{"class":5707,"line":20080},224,[5705,20082,18338],{"class":6557},[5705,20084,5745],{"class":5726},[5705,20086,19313],{"class":9489},[5705,20088,6138],{"class":5726},[5705,20090,20092,20094,20096,20098],{"class":5707,"line":20091},225,[5705,20093,18197],{"class":6557},[5705,20095,5745],{"class":5726},[5705,20097,19327],{"class":9489},[5705,20099,6138],{"class":5726},[5705,20101,20103,20105,20107,20110],{"class":5707,"line":20102},226,[5705,20104,18185],{"class":6557},[5705,20106,5745],{"class":5726},[5705,20108,20109],{"class":17952},"#92400e",[5705,20111,6138],{"class":5726},[5705,20113,20115],{"class":5707,"line":20114},227,[5705,20116,6144],{"class":5726},[5705,20118,20120],{"class":5707,"line":20119},228,[5705,20121,5795],{"emptyLinePlaceholder":5794},[5705,20123,20125,20128],{"class":5707,"line":20124},229,[5705,20126,20127],{"class":17990},".code-preview",[5705,20129,6069],{"class":5726},[5705,20131,20133,20136,20138,20140],{"class":5707,"line":20132},230,[5705,20134,20135],{"class":6557},"  margin-top",[5705,20137,5745],{"class":5726},[5705,20139,18706],{"class":9489},[5705,20141,6138],{"class":5726},[5705,20143,20145,20147,20149,20151],{"class":5707,"line":20144},231,[5705,20146,17971],{"class":6557},[5705,20148,5745],{"class":5726},[5705,20150,18214],{"class":9489},[5705,20152,6138],{"class":5726},[5705,20154,20156,20158,20160,20162],{"class":5707,"line":20155},232,[5705,20157,18010],{"class":6557},[5705,20159,5745],{"class":5726},[5705,20161,18727],{"class":17952},[5705,20163,6138],{"class":5726},[5705,20165,20167,20169,20171,20173],{"class":5707,"line":20166},233,[5705,20168,18338],{"class":6557},[5705,20170,5745],{"class":5726},[5705,20172,18265],{"class":9489},[5705,20174,6138],{"class":5726},[5705,20176,20178,20181,20183,20186],{"class":5707,"line":20177},234,[5705,20179,20180],{"class":6557},"  overflow-x",[5705,20182,5745],{"class":5726},[5705,20184,20185],{"class":17952},"auto",[5705,20187,6138],{"class":5726},[5705,20189,20191],{"class":5707,"line":20190},235,[5705,20192,6144],{"class":5726},[5705,20194,20196],{"class":5707,"line":20195},236,[5705,20197,5795],{"emptyLinePlaceholder":5794},[5705,20199,20201,20203,20206],{"class":5707,"line":20200},237,[5705,20202,20127],{"class":17990},[5705,20204,20205],{"class":17990}," code",[5705,20207,6069],{"class":5726},[5705,20209,20211,20213,20215,20217],{"class":5707,"line":20210},238,[5705,20212,18185],{"class":6557},[5705,20214,5745],{"class":5726},[5705,20216,19761],{"class":17952},[5705,20218,6138],{"class":5726},[5705,20220,20222,20224,20226,20229,20231,20234],{"class":5707,"line":20221},239,[5705,20223,18043],{"class":6557},[5705,20225,5745],{"class":5726},[5705,20227,20228],{"class":6019},"'Courier New'",[5705,20230,5580],{"class":5726},[5705,20232,20233],{"class":17952},"monospace",[5705,20235,6138],{"class":5726},[5705,20237,20239,20241,20243,20245],{"class":5707,"line":20238},240,[5705,20240,18197],{"class":6557},[5705,20242,5745],{"class":5726},[5705,20244,19327],{"class":9489},[5705,20246,6138],{"class":5726},[5705,20248,20250],{"class":5707,"line":20249},241,[5705,20251,6144],{"class":5726},[5567,20253],{},[5570,20255,20257],{"id":20256},"просунуті-патерни-хуки-з-параметрами-конфігурації","Просунуті патерни: хуки з параметрами конфігурації",[5479,20259,20260,20261,5622],{},"Коли хук стає складнішим, передача безлічі окремих параметрів стає незручною. У таких випадках використовують ",[5483,20262,20263],{},"об'єкт конфігурації",[5685,20265,10105,20267],{"id":20266},"приклад-usefetchwithconfig",[5535,20268,20269],{},"useFetchWithConfig",[5696,20271,20273],{"className":5698,"code":20272,"language":5700,"meta":5701,"style":5701},"interface FetchConfig {\n  method?: 'GET' | 'POST' | 'PUT' | 'DELETE';\n  headers?: Record\u003Cstring, string>;\n  body?: any;\n  enabled?: boolean; \u002F\u002F Чи автоматично виконувати запит\n  refetchInterval?: number; \u002F\u002F Автоматичне повторне завантаження\n  onSuccess?: (data: any) => void;\n  onError?: (error: Error) => void;\n}\n\ninterface UseFetchWithConfigResult\u003CT> {\n  data: T | null;\n  isLoading: boolean;\n  error: string | null;\n  refetch: () => void;\n}\n\nexport function useFetchWithConfig\u003CT>(\n  url: string,\n  config: FetchConfig = {}\n): UseFetchWithConfigResult\u003CT> {\n  const {\n    method = 'GET',\n    headers = {},\n    body,\n    enabled = true,\n    refetchInterval,\n    onSuccess,\n    onError,\n  } = config;\n\n  const [data, setData] = useState\u003CT | null>(null);\n  const [isLoading, setIsLoading] = useState\u003Cboolean>(false);\n  const [error, setError] = useState\u003Cstring | null>(null);\n  const [refetchTrigger, setRefetchTrigger] = useState\u003Cnumber>(0);\n\n  useEffect(() => {\n    if (!enabled) return;\n\n    const controller = new AbortController();\n\n    async function fetchData(): Promise\u003Cvoid> {\n      try {\n        setIsLoading(true);\n        setError(null);\n\n        const options: RequestInit = {\n          method,\n          headers: {\n            'Content-Type': 'application\u002Fjson',\n            ...headers,\n          },\n          signal: controller.signal,\n        };\n\n        if (body && method !== 'GET') {\n          options.body = JSON.stringify(body);\n        }\n\n        const response = await fetch(url, options);\n\n        if (!response.ok) {\n          throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n        }\n\n        const result: T = await response.json();\n        setData(result);\n\n        if (onSuccess) {\n          onSuccess(result);\n        }\n      } catch (err) {\n        if (err instanceof Error && err.name !== 'AbortError') {\n          setError(err.message);\n          if (onError) {\n            onError(err);\n          }\n        }\n      } finally {\n        if (!controller.signal.aborted) {\n          setIsLoading(false);\n        }\n      }\n    }\n\n    fetchData();\n\n    \u002F\u002F Автоматичне повторне завантаження\n    let intervalId: NodeJS.Timeout | undefined;\n    if (refetchInterval) {\n      intervalId = setInterval(() => {\n        fetchData();\n      }, refetchInterval);\n    }\n\n    return () => {\n      controller.abort();\n      if (intervalId) {\n        clearInterval(intervalId);\n      }\n    };\n  }, [url, method, enabled, refetchTrigger, refetchInterval]);\n\n  const refetch = () => {\n    setRefetchTrigger((prev) => prev + 1);\n  };\n\n  return { data, isLoading, error, refetch };\n}\n",[5535,20274,20275,20284,20312,20333,20345,20359,20373,20395,20417,20421,20425,20438,20452,20462,20476,20490,20494,20498,20513,20524,20537,20550,20556,20567,20575,20582,20593,20600,20607,20614,20624,20628,20658,20684,20714,20742,20746,20756,20771,20775,20789,20793,20811,20817,20827,20837,20841,20856,20863,20870,20882,20892,20897,20910,20915,20919,20939,20962,20966,20970,20993,20997,21011,21049,21053,21057,21079,21089,21093,21104,21115,21119,21131,21158,21172,21184,21195,21200,21204,21212,21230,21240,21244,21248,21252,21256,21262,21266,21271,21295,21306,21321,21328,21337,21341,21345,21355,21365,21375,21386,21390,21394,21418,21422,21436,21459,21463,21467,21490],{"__ignoreMap":5701},[5705,20276,20277,20279,20282],{"class":5707,"line":5708},[5705,20278,7132],{"class":5718},[5705,20280,20281],{"class":5748}," FetchConfig",[5705,20283,6069],{"class":5726},[5705,20285,20286,20289,20292,20295,20297,20300,20302,20305,20307,20310],{"class":5707,"line":5715},[5705,20287,20288],{"class":5741},"  method",[5705,20290,20291],{"class":5726},"?: ",[5705,20293,20294],{"class":6019},"'GET'",[5705,20296,7154],{"class":5726},[5705,20298,20299],{"class":6019},"'POST'",[5705,20301,7154],{"class":5726},[5705,20303,20304],{"class":6019},"'PUT'",[5705,20306,7154],{"class":5726},[5705,20308,20309],{"class":6019},"'DELETE'",[5705,20311,6138],{"class":5726},[5705,20313,20314,20317,20319,20322,20324,20326,20328,20330],{"class":5707,"line":5730},[5705,20315,20316],{"class":5741},"  headers",[5705,20318,20291],{"class":5726},[5705,20320,20321],{"class":5748},"Record",[5705,20323,5763],{"class":5726},[5705,20325,5749],{"class":5748},[5705,20327,5580],{"class":5726},[5705,20329,5749],{"class":5748},[5705,20331,20332],{"class":5726},">;\n",[5705,20334,20335,20338,20340,20343],{"class":5707,"line":5755},[5705,20336,20337],{"class":5741},"  body",[5705,20339,20291],{"class":5726},[5705,20341,20342],{"class":5748},"any",[5705,20344,6138],{"class":5726},[5705,20346,20347,20350,20352,20354,20356],{"class":5707,"line":5791},[5705,20348,20349],{"class":5741},"  enabled",[5705,20351,20291],{"class":5726},[5705,20353,6253],{"class":5748},[5705,20355,12087],{"class":5726},[5705,20357,20358],{"class":5711},"\u002F\u002F Чи автоматично виконувати запит\n",[5705,20360,20361,20364,20366,20368,20370],{"class":5707,"line":5798},[5705,20362,20363],{"class":5741},"  refetchInterval",[5705,20365,20291],{"class":5726},[5705,20367,5786],{"class":5748},[5705,20369,12087],{"class":5726},[5705,20371,20372],{"class":5711},"\u002F\u002F Автоматичне повторне завантаження\n",[5705,20374,20375,20378,20381,20383,20385,20387,20389,20391,20393],{"class":5707,"line":5804},[5705,20376,20377],{"class":5722},"  onSuccess",[5705,20379,20380],{"class":5726},"?: (",[5705,20382,5621],{"class":5741},[5705,20384,5745],{"class":5726},[5705,20386,20342],{"class":5748},[5705,20388,8337],{"class":5726},[5705,20390,5955],{"class":5718},[5705,20392,8350],{"class":5748},[5705,20394,6138],{"class":5726},[5705,20396,20397,20400,20402,20404,20406,20409,20411,20413,20415],{"class":5707,"line":5818},[5705,20398,20399],{"class":5722},"  onError",[5705,20401,20380],{"class":5726},[5705,20403,5618],{"class":5741},[5705,20405,5745],{"class":5726},[5705,20407,20408],{"class":5748},"Error",[5705,20410,8337],{"class":5726},[5705,20412,5955],{"class":5718},[5705,20414,8350],{"class":5748},[5705,20416,6138],{"class":5726},[5705,20418,20419],{"class":5707,"line":6031},[5705,20420,6144],{"class":5726},[5705,20422,20423],{"class":5707,"line":6052},[5705,20424,5795],{"emptyLinePlaceholder":5794},[5705,20426,20427,20429,20432,20434,20436],{"class":5707,"line":6057},[5705,20428,7132],{"class":5718},[5705,20430,20431],{"class":5748}," UseFetchWithConfigResult",[5705,20433,5763],{"class":5726},[5705,20435,5766],{"class":5748},[5705,20437,7142],{"class":5726},[5705,20439,20440,20442,20444,20446,20448,20450],{"class":5707,"line":6072},[5705,20441,7147],{"class":5741},[5705,20443,5745],{"class":5726},[5705,20445,5766],{"class":5748},[5705,20447,7154],{"class":5726},[5705,20449,7157],{"class":5748},[5705,20451,6138],{"class":5726},[5705,20453,20454,20456,20458,20460],{"class":5707,"line":6093},[5705,20455,7164],{"class":5741},[5705,20457,5745],{"class":5726},[5705,20459,6253],{"class":5748},[5705,20461,6138],{"class":5726},[5705,20463,20464,20466,20468,20470,20472,20474],{"class":5707,"line":6112},[5705,20465,7175],{"class":5741},[5705,20467,5745],{"class":5726},[5705,20469,5749],{"class":5748},[5705,20471,7154],{"class":5726},[5705,20473,7157],{"class":5748},[5705,20475,6138],{"class":5726},[5705,20477,20478,20481,20484,20486,20488],{"class":5707,"line":6118},[5705,20479,20480],{"class":5722},"  refetch",[5705,20482,20483],{"class":5726},": () ",[5705,20485,5955],{"class":5718},[5705,20487,8350],{"class":5748},[5705,20489,6138],{"class":5726},[5705,20491,20492],{"class":5707,"line":6124},[5705,20493,6144],{"class":5726},[5705,20495,20496],{"class":5707,"line":6129},[5705,20497,5795],{"emptyLinePlaceholder":5794},[5705,20499,20500,20502,20504,20507,20509,20511],{"class":5707,"line":6141},[5705,20501,6242],{"class":6060},[5705,20503,6245],{"class":5718},[5705,20505,20506],{"class":5722}," useFetchWithConfig",[5705,20508,5763],{"class":5726},[5705,20510,5766],{"class":5748},[5705,20512,7918],{"class":5726},[5705,20514,20515,20518,20520,20522],{"class":5707,"line":6389},[5705,20516,20517],{"class":5741},"  url",[5705,20519,5745],{"class":5726},[5705,20521,5749],{"class":5748},[5705,20523,8298],{"class":5726},[5705,20525,20526,20529,20531,20534],{"class":5707,"line":6408},[5705,20527,20528],{"class":5741},"  config",[5705,20530,5745],{"class":5726},[5705,20532,20533],{"class":5748},"FetchConfig",[5705,20535,20536],{"class":5726}," = {}\n",[5705,20538,20539,20541,20544,20546,20548],{"class":5707,"line":6413},[5705,20540,7216],{"class":5726},[5705,20542,20543],{"class":5748},"UseFetchWithConfigResult",[5705,20545,5763],{"class":5726},[5705,20547,5766],{"class":5748},[5705,20549,7142],{"class":5726},[5705,20551,20552,20554],{"class":5707,"line":6419},[5705,20553,5907],{"class":5718},[5705,20555,6069],{"class":5726},[5705,20557,20558,20561,20563,20565],{"class":5707,"line":6430},[5705,20559,20560],{"class":5913},"    method",[5705,20562,6525],{"class":5726},[5705,20564,20294],{"class":6019},[5705,20566,8298],{"class":5726},[5705,20568,20569,20572],{"class":5707,"line":6449},[5705,20570,20571],{"class":5913},"    headers",[5705,20573,20574],{"class":5726}," = {},\n",[5705,20576,20577,20580],{"class":5707,"line":6468},[5705,20578,20579],{"class":5913},"    body",[5705,20581,8298],{"class":5726},[5705,20583,20584,20587,20589,20591],{"class":5707,"line":6473},[5705,20585,20586],{"class":5913},"    enabled",[5705,20588,6525],{"class":5726},[5705,20590,5979],{"class":5718},[5705,20592,8298],{"class":5726},[5705,20594,20595,20598],{"class":5707,"line":6482},[5705,20596,20597],{"class":5913},"    refetchInterval",[5705,20599,8298],{"class":5726},[5705,20601,20602,20605],{"class":5707,"line":6487},[5705,20603,20604],{"class":5913},"    onSuccess",[5705,20606,8298],{"class":5726},[5705,20608,20609,20612],{"class":5707,"line":6496},[5705,20610,20611],{"class":5913},"    onError",[5705,20613,8298],{"class":5726},[5705,20615,20616,20619,20622],{"class":5707,"line":7008},[5705,20617,20618],{"class":5726},"  } = ",[5705,20620,20621],{"class":5741},"config",[5705,20623,6138],{"class":5726},[5705,20625,20626],{"class":5707,"line":7014},[5705,20627,5795],{"emptyLinePlaceholder":5794},[5705,20629,20630,20632,20634,20636,20638,20640,20642,20644,20646,20648,20650,20652,20654,20656],{"class":5707,"line":7020},[5705,20631,5907],{"class":5718},[5705,20633,5910],{"class":5726},[5705,20635,5621],{"class":5913},[5705,20637,5580],{"class":5726},[5705,20639,7238],{"class":5913},[5705,20641,5922],{"class":5726},[5705,20643,5579],{"class":5722},[5705,20645,5763],{"class":5726},[5705,20647,5766],{"class":5748},[5705,20649,7154],{"class":5726},[5705,20651,7157],{"class":5748},[5705,20653,5769],{"class":5726},[5705,20655,7157],{"class":5718},[5705,20657,6028],{"class":5726},[5705,20659,20660,20662,20664,20666,20668,20670,20672,20674,20676,20678,20680,20682],{"class":5707,"line":7026},[5705,20661,5907],{"class":5718},[5705,20663,5910],{"class":5726},[5705,20665,7265],{"class":5913},[5705,20667,5580],{"class":5726},[5705,20669,7270],{"class":5913},[5705,20671,5922],{"class":5726},[5705,20673,5579],{"class":5722},[5705,20675,5763],{"class":5726},[5705,20677,6253],{"class":5748},[5705,20679,5769],{"class":5726},[5705,20681,5998],{"class":5718},[5705,20683,6028],{"class":5726},[5705,20685,20686,20688,20690,20692,20694,20696,20698,20700,20702,20704,20706,20708,20710,20712],{"class":5707,"line":7032},[5705,20687,5907],{"class":5718},[5705,20689,5910],{"class":5726},[5705,20691,5618],{"class":5913},[5705,20693,5580],{"class":5726},[5705,20695,7297],{"class":5913},[5705,20697,5922],{"class":5726},[5705,20699,5579],{"class":5722},[5705,20701,5763],{"class":5726},[5705,20703,5749],{"class":5748},[5705,20705,7154],{"class":5726},[5705,20707,7157],{"class":5748},[5705,20709,5769],{"class":5726},[5705,20711,7157],{"class":5718},[5705,20713,6028],{"class":5726},[5705,20715,20716,20718,20720,20723,20725,20728,20730,20732,20734,20736,20738,20740],{"class":5707,"line":7037},[5705,20717,5907],{"class":5718},[5705,20719,5910],{"class":5726},[5705,20721,20722],{"class":5913},"refetchTrigger",[5705,20724,5580],{"class":5726},[5705,20726,20727],{"class":5913},"setRefetchTrigger",[5705,20729,5922],{"class":5726},[5705,20731,5579],{"class":5722},[5705,20733,5763],{"class":5726},[5705,20735,5786],{"class":5748},[5705,20737,5769],{"class":5726},[5705,20739,16483],{"class":9489},[5705,20741,6028],{"class":5726},[5705,20743,20744],{"class":5707,"line":7639},[5705,20745,5795],{"emptyLinePlaceholder":5794},[5705,20747,20748,20750,20752,20754],{"class":5707,"line":7644},[5705,20749,5949],{"class":5722},[5705,20751,5952],{"class":5726},[5705,20753,5955],{"class":5718},[5705,20755,6069],{"class":5726},[5705,20757,20758,20760,20762,20765,20767,20769],{"class":5707,"line":7654},[5705,20759,12070],{"class":6060},[5705,20761,7468],{"class":5726},[5705,20763,20764],{"class":5741},"enabled",[5705,20766,8337],{"class":5726},[5705,20768,6170],{"class":6060},[5705,20770,6138],{"class":5726},[5705,20772,20773],{"class":5707,"line":7660},[5705,20774,5795],{"emptyLinePlaceholder":5794},[5705,20776,20777,20779,20781,20783,20785,20787],{"class":5707,"line":7676},[5705,20778,7339],{"class":5718},[5705,20780,7342],{"class":5913},[5705,20782,6525],{"class":5726},[5705,20784,7347],{"class":5718},[5705,20786,7350],{"class":5722},[5705,20788,7353],{"class":5726},[5705,20790,20791],{"class":5707,"line":7688},[5705,20792,5795],{"emptyLinePlaceholder":5794},[5705,20794,20795,20797,20799,20801,20803,20805,20807,20809],{"class":5707,"line":7693},[5705,20796,7379],{"class":5718},[5705,20798,6245],{"class":5718},[5705,20800,5823],{"class":5722},[5705,20802,6250],{"class":5726},[5705,20804,7388],{"class":5748},[5705,20806,5763],{"class":5726},[5705,20808,7393],{"class":5748},[5705,20810,7142],{"class":5726},[5705,20812,20813,20815],{"class":5707,"line":7699},[5705,20814,7400],{"class":6060},[5705,20816,6069],{"class":5726},[5705,20818,20819,20821,20823,20825],{"class":5707,"line":7704},[5705,20820,7407],{"class":5722},[5705,20822,5738],{"class":5726},[5705,20824,5979],{"class":5718},[5705,20826,6028],{"class":5726},[5705,20828,20829,20831,20833,20835],{"class":5707,"line":7709},[5705,20830,7418],{"class":5722},[5705,20832,5738],{"class":5726},[5705,20834,7157],{"class":5718},[5705,20836,6028],{"class":5726},[5705,20838,20839],{"class":5707,"line":7717},[5705,20840,5795],{"emptyLinePlaceholder":5794},[5705,20842,20843,20845,20848,20850,20853],{"class":5707,"line":7722},[5705,20844,7433],{"class":5718},[5705,20846,20847],{"class":5913}," options",[5705,20849,5745],{"class":5726},[5705,20851,20852],{"class":5748},"RequestInit",[5705,20854,20855],{"class":5726}," = {\n",[5705,20857,20858,20861],{"class":5707,"line":7728},[5705,20859,20860],{"class":5741},"          method",[5705,20862,8298],{"class":5726},[5705,20864,20865,20868],{"class":5707,"line":7739},[5705,20866,20867],{"class":5741},"          headers:",[5705,20869,6069],{"class":5726},[5705,20871,20872,20875,20877,20880],{"class":5707,"line":7752},[5705,20873,20874],{"class":6019},"            'Content-Type'",[5705,20876,5600],{"class":5741},[5705,20878,20879],{"class":6019}," 'application\u002Fjson'",[5705,20881,8298],{"class":5726},[5705,20883,20884,20887,20890],{"class":5707,"line":7757},[5705,20885,20886],{"class":5726},"            ...",[5705,20888,20889],{"class":5741},"headers",[5705,20891,8298],{"class":5726},[5705,20893,20894],{"class":5707,"line":7771},[5705,20895,20896],{"class":5726},"          },\n",[5705,20898,20899,20902,20904,20906,20908],{"class":5707,"line":7776},[5705,20900,20901],{"class":5741},"          signal:",[5705,20903,7342],{"class":5741},[5705,20905,5622],{"class":5726},[5705,20907,7362],{"class":5741},[5705,20909,8298],{"class":5726},[5705,20911,20912],{"class":5707,"line":7796},[5705,20913,20914],{"class":5726},"        };\n",[5705,20916,20917],{"class":5707,"line":12343},[5705,20918,5795],{"emptyLinePlaceholder":5794},[5705,20920,20921,20923,20925,20928,20930,20933,20935,20937],{"class":5707,"line":12351},[5705,20922,7465],{"class":6060},[5705,20924,7055],{"class":5726},[5705,20926,20927],{"class":5741},"body",[5705,20929,7605],{"class":5726},[5705,20931,20932],{"class":5741},"method",[5705,20934,7615],{"class":5726},[5705,20936,20294],{"class":6019},[5705,20938,7479],{"class":5726},[5705,20940,20941,20944,20946,20948,20950,20952,20954,20956,20958,20960],{"class":5707,"line":12364},[5705,20942,20943],{"class":5741},"          options",[5705,20945,5622],{"class":5726},[5705,20947,20927],{"class":5741},[5705,20949,6525],{"class":5726},[5705,20951,8436],{"class":5913},[5705,20953,5622],{"class":5726},[5705,20955,8659],{"class":5722},[5705,20957,5738],{"class":5726},[5705,20959,20927],{"class":5741},[5705,20961,6028],{"class":5726},[5705,20963,20964],{"class":5707,"line":12400},[5705,20965,7529],{"class":5726},[5705,20967,20968],{"class":5707,"line":12410},[5705,20969,5795],{"emptyLinePlaceholder":5794},[5705,20971,20972,20974,20976,20978,20980,20982,20984,20986,20988,20991],{"class":5707,"line":12425},[5705,20973,7433],{"class":5718},[5705,20975,7436],{"class":5913},[5705,20977,6525],{"class":5726},[5705,20979,7441],{"class":6060},[5705,20981,7444],{"class":5722},[5705,20983,5738],{"class":5726},[5705,20985,5742],{"class":5741},[5705,20987,5580],{"class":5726},[5705,20989,20990],{"class":5741},"options",[5705,20992,6028],{"class":5726},[5705,20994,20995],{"class":5707,"line":12457},[5705,20996,5795],{"emptyLinePlaceholder":5794},[5705,20998,20999,21001,21003,21005,21007,21009],{"class":5707,"line":12462},[5705,21000,7465],{"class":6060},[5705,21002,7468],{"class":5726},[5705,21004,7471],{"class":5741},[5705,21006,5622],{"class":5726},[5705,21008,7476],{"class":5741},[5705,21010,7479],{"class":5726},[5705,21012,21013,21015,21017,21019,21021,21023,21025,21027,21029,21031,21033,21035,21037,21039,21041,21043,21045,21047],{"class":5707,"line":12495},[5705,21014,7484],{"class":6060},[5705,21016,7487],{"class":5718},[5705,21018,7490],{"class":5722},[5705,21020,5738],{"class":5726},[5705,21022,13075],{"class":6019},[5705,21024,6570],{"class":5718},[5705,21026,7471],{"class":5741},[5705,21028,5622],{"class":7502},[5705,21030,7505],{"class":5741},[5705,21032,6587],{"class":5718},[5705,21034,5745],{"class":6019},[5705,21036,6570],{"class":5718},[5705,21038,7471],{"class":5741},[5705,21040,5622],{"class":7502},[5705,21042,7518],{"class":5741},[5705,21044,6587],{"class":5718},[5705,21046,6590],{"class":6019},[5705,21048,6028],{"class":5726},[5705,21050,21051],{"class":5707,"line":12536},[5705,21052,7529],{"class":5726},[5705,21054,21055],{"class":5707,"line":12545},[5705,21056,5795],{"emptyLinePlaceholder":5794},[5705,21058,21059,21061,21063,21065,21067,21069,21071,21073,21075,21077],{"class":5707,"line":12550},[5705,21060,7433],{"class":5718},[5705,21062,7540],{"class":5913},[5705,21064,5745],{"class":5726},[5705,21066,5766],{"class":5748},[5705,21068,6525],{"class":5726},[5705,21070,7441],{"class":6060},[5705,21072,7436],{"class":5741},[5705,21074,5622],{"class":5726},[5705,21076,7555],{"class":5722},[5705,21078,7353],{"class":5726},[5705,21080,21081,21083,21085,21087],{"class":5707,"line":13481},[5705,21082,7562],{"class":5722},[5705,21084,5738],{"class":5726},[5705,21086,7567],{"class":5741},[5705,21088,6028],{"class":5726},[5705,21090,21091],{"class":5707,"line":13492},[5705,21092,5795],{"emptyLinePlaceholder":5794},[5705,21094,21095,21097,21099,21102],{"class":5707,"line":13525},[5705,21096,7465],{"class":6060},[5705,21098,7055],{"class":5726},[5705,21100,21101],{"class":5741},"onSuccess",[5705,21103,7479],{"class":5726},[5705,21105,21106,21109,21111,21113],{"class":5707,"line":13530},[5705,21107,21108],{"class":5722},"          onSuccess",[5705,21110,5738],{"class":5726},[5705,21112,7567],{"class":5741},[5705,21114,6028],{"class":5726},[5705,21116,21117],{"class":5707,"line":13535},[5705,21118,7529],{"class":5726},[5705,21120,21121,21123,21125,21127,21129],{"class":5707,"line":13542},[5705,21122,7574],{"class":5726},[5705,21124,7577],{"class":6060},[5705,21126,7055],{"class":5726},[5705,21128,7582],{"class":5741},[5705,21130,7479],{"class":5726},[5705,21132,21133,21135,21137,21139,21141,21143,21145,21147,21149,21151,21153,21156],{"class":5707,"line":13558},[5705,21134,7465],{"class":6060},[5705,21136,7055],{"class":5726},[5705,21138,7582],{"class":5741},[5705,21140,7600],{"class":5718},[5705,21142,7490],{"class":5748},[5705,21144,7605],{"class":5726},[5705,21146,7582],{"class":5741},[5705,21148,5622],{"class":5726},[5705,21150,7612],{"class":5741},[5705,21152,7615],{"class":5726},[5705,21154,21155],{"class":6019},"'AbortError'",[5705,21157,7479],{"class":5726},[5705,21159,21160,21162,21164,21166,21168,21170],{"class":5707,"line":13591},[5705,21161,7625],{"class":5722},[5705,21163,5738],{"class":5726},[5705,21165,7582],{"class":5741},[5705,21167,5622],{"class":5726},[5705,21169,7634],{"class":5741},[5705,21171,6028],{"class":5726},[5705,21173,21174,21177,21179,21182],{"class":5707,"line":13597},[5705,21175,21176],{"class":6060},"          if",[5705,21178,7055],{"class":5726},[5705,21180,21181],{"class":5741},"onError",[5705,21183,7479],{"class":5726},[5705,21185,21186,21189,21191,21193],{"class":5707,"line":13608},[5705,21187,21188],{"class":5722},"            onError",[5705,21190,5738],{"class":5726},[5705,21192,7582],{"class":5741},[5705,21194,6028],{"class":5726},[5705,21196,21197],{"class":5707,"line":13614},[5705,21198,21199],{"class":5726},"          }\n",[5705,21201,21202],{"class":5707,"line":13654},[5705,21203,7529],{"class":5726},[5705,21205,21206,21208,21210],{"class":5707,"line":13686},[5705,21207,7574],{"class":5726},[5705,21209,7649],{"class":6060},[5705,21211,6069],{"class":5726},[5705,21213,21214,21216,21218,21220,21222,21224,21226,21228],{"class":5707,"line":13715},[5705,21215,7465],{"class":6060},[5705,21217,7468],{"class":5726},[5705,21219,7368],{"class":5741},[5705,21221,5622],{"class":5726},[5705,21223,7362],{"class":5741},[5705,21225,5622],{"class":5726},[5705,21227,7671],{"class":5741},[5705,21229,7479],{"class":5726},[5705,21231,21232,21234,21236,21238],{"class":5707,"line":13721},[5705,21233,7679],{"class":5722},[5705,21235,5738],{"class":5726},[5705,21237,5998],{"class":5718},[5705,21239,6028],{"class":5726},[5705,21241,21242],{"class":5707,"line":13728},[5705,21243,7529],{"class":5726},[5705,21245,21246],{"class":5707,"line":13733},[5705,21247,7696],{"class":5726},[5705,21249,21250],{"class":5707,"line":13766},[5705,21251,6333],{"class":5726},[5705,21253,21254],{"class":5707,"line":13775},[5705,21255,5795],{"emptyLinePlaceholder":5794},[5705,21257,21258,21260],{"class":5707,"line":13780},[5705,21259,7712],{"class":5722},[5705,21261,7353],{"class":5726},[5705,21263,21264],{"class":5707,"line":18822},[5705,21265,5795],{"emptyLinePlaceholder":5794},[5705,21267,21268],{"class":5707,"line":18834},[5705,21269,21270],{"class":5711},"    \u002F\u002F Автоматичне повторне завантаження\n",[5705,21272,21273,21276,21278,21280,21283,21285,21288,21290,21293],{"class":5707,"line":18851},[5705,21274,21275],{"class":5718},"    let",[5705,21277,13259],{"class":5741},[5705,21279,5745],{"class":5726},[5705,21281,21282],{"class":5748},"NodeJS",[5705,21284,5622],{"class":5726},[5705,21286,21287],{"class":5748},"Timeout",[5705,21289,7154],{"class":5726},[5705,21291,21292],{"class":5748},"undefined",[5705,21294,6138],{"class":5726},[5705,21296,21297,21299,21301,21304],{"class":5707,"line":18856},[5705,21298,12070],{"class":6060},[5705,21300,7055],{"class":5726},[5705,21302,21303],{"class":5741},"refetchInterval",[5705,21305,7479],{"class":5726},[5705,21307,21308,21311,21313,21315,21317,21319],{"class":5707,"line":18861},[5705,21309,21310],{"class":5741},"      intervalId",[5705,21312,6525],{"class":5726},[5705,21314,13264],{"class":5722},[5705,21316,5952],{"class":5726},[5705,21318,5955],{"class":5718},[5705,21320,6069],{"class":5726},[5705,21322,21323,21326],{"class":5707,"line":18869},[5705,21324,21325],{"class":5722},"        fetchData",[5705,21327,7353],{"class":5726},[5705,21329,21330,21333,21335],{"class":5707,"line":18881},[5705,21331,21332],{"class":5726},"      }, ",[5705,21334,21303],{"class":5741},[5705,21336,6028],{"class":5726},[5705,21338,21339],{"class":5707,"line":18897},[5705,21340,6333],{"class":5726},[5705,21342,21343],{"class":5707,"line":18902},[5705,21344,5795],{"emptyLinePlaceholder":5794},[5705,21346,21347,21349,21351,21353],{"class":5707,"line":18907},[5705,21348,6061],{"class":6060},[5705,21350,6064],{"class":5726},[5705,21352,5955],{"class":5718},[5705,21354,6069],{"class":5726},[5705,21356,21357,21359,21361,21363],{"class":5707,"line":18915},[5705,21358,7742],{"class":5741},[5705,21360,5622],{"class":5726},[5705,21362,7747],{"class":5722},[5705,21364,7353],{"class":5726},[5705,21366,21367,21369,21371,21373],{"class":5707,"line":18927},[5705,21368,8757],{"class":6060},[5705,21370,7055],{"class":5726},[5705,21372,13313],{"class":5741},[5705,21374,7479],{"class":5726},[5705,21376,21377,21380,21382,21384],{"class":5707,"line":18938},[5705,21378,21379],{"class":5722},"        clearInterval",[5705,21381,5738],{"class":5726},[5705,21383,13313],{"class":5741},[5705,21385,6028],{"class":5726},[5705,21387,21388],{"class":5707,"line":18950},[5705,21389,7696],{"class":5726},[5705,21391,21392],{"class":5707,"line":18955},[5705,21393,6115],{"class":5726},[5705,21395,21396,21398,21400,21402,21404,21406,21408,21410,21412,21414,21416],{"class":5707,"line":18960},[5705,21397,7760],{"class":5726},[5705,21399,5742],{"class":5741},[5705,21401,5580],{"class":5726},[5705,21403,20932],{"class":5741},[5705,21405,5580],{"class":5726},[5705,21407,20764],{"class":5741},[5705,21409,5580],{"class":5726},[5705,21411,20722],{"class":5741},[5705,21413,5580],{"class":5726},[5705,21415,21303],{"class":5741},[5705,21417,8935],{"class":5726},[5705,21419,21420],{"class":5707,"line":18970},[5705,21421,5795],{"emptyLinePlaceholder":5794},[5705,21423,21424,21426,21429,21432,21434],{"class":5707,"line":18982},[5705,21425,5907],{"class":5718},[5705,21427,21428],{"class":5722}," refetch",[5705,21430,21431],{"class":5726}," = () ",[5705,21433,5955],{"class":5718},[5705,21435,6069],{"class":5726},[5705,21437,21438,21441,21443,21445,21447,21449,21452,21454,21457],{"class":5707,"line":19000},[5705,21439,21440],{"class":5722},"    setRefetchTrigger",[5705,21442,9039],{"class":5726},[5705,21444,8330],{"class":5741},[5705,21446,8337],{"class":5726},[5705,21448,5955],{"class":5718},[5705,21450,21451],{"class":5741}," prev",[5705,21453,10886],{"class":5726},[5705,21455,21456],{"class":9489},"1",[5705,21458,6028],{"class":5726},[5705,21460,21461],{"class":5707,"line":19005},[5705,21462,8714],{"class":5726},[5705,21464,21465],{"class":5707,"line":19010},[5705,21466,5795],{"emptyLinePlaceholder":5794},[5705,21468,21469,21471,21473,21475,21477,21479,21481,21483,21485,21488],{"class":5707,"line":19019},[5705,21470,6132],{"class":6060},[5705,21472,5958],{"class":5726},[5705,21474,5621],{"class":5741},[5705,21476,5580],{"class":5726},[5705,21478,7265],{"class":5741},[5705,21480,5580],{"class":5726},[5705,21482,5618],{"class":5741},[5705,21484,5580],{"class":5726},[5705,21486,21487],{"class":5741},"refetch",[5705,21489,7793],{"class":5726},[5705,21491,21492],{"class":5707,"line":19031},[5705,21493,6144],{"class":5726},[5685,21495,21497],{"id":21496},"використання-з-конфігурацією","Використання з конфігурацією",[5696,21499,21501],{"className":5698,"code":21500,"language":5700,"meta":5701,"style":5701},"interface Product {\n  id: number;\n  name: string;\n  price: number;\n}\n\nfunction ProductList() {\n  const [enabled, setEnabled] = useState(true);\n\n  const { data, isLoading, error, refetch } = useFetchWithConfig\u003CProduct[]>(\n    'https:\u002F\u002Fapi.example.com\u002Fproducts',\n    {\n      enabled,\n      refetchInterval: 30000, \u002F\u002F Автооновлення кожні 30 секунд\n      headers: {\n        Authorization: 'Bearer token123',\n      },\n      onSuccess: (products) => {\n        console.log(`Завантажено ${products.length} товарів`);\n      },\n      onError: (err) => {\n        console.error('Помилка завантаження:', err);\n      },\n    }\n  );\n\n  return (\n    \u003Cdiv>\n      \u003Cdiv className=\"controls\">\n        \u003Cbutton onClick={() => setEnabled(!enabled)}>\n          {enabled ? 'Вимкнути' : 'Увімкнути'} автозавантаження\n        \u003C\u002Fbutton>\n        \u003Cbutton onClick={refetch} disabled={!enabled}>\n          🔄 Оновити вручну\n        \u003C\u002Fbutton>\n      \u003C\u002Fdiv>\n\n      {isLoading && \u003Cp>Завантаження...\u003C\u002Fp>}\n      {error && \u003Cp className=\"error\">{error}\u003C\u002Fp>}\n\n      {data && (\n        \u003Cul>\n          {data.map((product) => (\n            \u003Cli key={product.id}>\n              {product.name} — {product.price} грн\n            \u003C\u002Fli>\n          ))}\n        \u003C\u002Ful>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n",[5535,21502,21503,21512,21522,21532,21543,21547,21551,21560,21583,21587,21618,21625,21630,21637,21650,21657,21667,21672,21690,21719,21723,21740,21759,21763,21767,21771,21775,21781,21789,21804,21835,21856,21864,21895,21900,21908,21916,21920,21944,21978,21982,21992,22000,22021,22044,22074,22083,22089,22097,22103,22111,22115],{"__ignoreMap":5701},[5705,21504,21505,21507,21510],{"class":5707,"line":5708},[5705,21506,7132],{"class":5718},[5705,21508,21509],{"class":5748}," Product",[5705,21511,6069],{"class":5726},[5705,21513,21514,21516,21518,21520],{"class":5707,"line":5715},[5705,21515,7824],{"class":5741},[5705,21517,5745],{"class":5726},[5705,21519,5786],{"class":5748},[5705,21521,6138],{"class":5726},[5705,21523,21524,21526,21528,21530],{"class":5707,"line":5730},[5705,21525,7835],{"class":5741},[5705,21527,5745],{"class":5726},[5705,21529,5749],{"class":5748},[5705,21531,6138],{"class":5726},[5705,21533,21534,21537,21539,21541],{"class":5707,"line":5755},[5705,21535,21536],{"class":5741},"  price",[5705,21538,5745],{"class":5726},[5705,21540,5786],{"class":5748},[5705,21542,6138],{"class":5726},[5705,21544,21545],{"class":5707,"line":5791},[5705,21546,6144],{"class":5726},[5705,21548,21549],{"class":5707,"line":5798},[5705,21550,5795],{"emptyLinePlaceholder":5794},[5705,21552,21553,21555,21558],{"class":5707,"line":5804},[5705,21554,5719],{"class":5718},[5705,21556,21557],{"class":5722}," ProductList",[5705,21559,5902],{"class":5726},[5705,21561,21562,21564,21566,21568,21570,21573,21575,21577,21579,21581],{"class":5707,"line":5818},[5705,21563,5907],{"class":5718},[5705,21565,5910],{"class":5726},[5705,21567,20764],{"class":5913},[5705,21569,5580],{"class":5726},[5705,21571,21572],{"class":5913},"setEnabled",[5705,21574,5922],{"class":5726},[5705,21576,5579],{"class":5722},[5705,21578,5738],{"class":5726},[5705,21580,5979],{"class":5718},[5705,21582,6028],{"class":5726},[5705,21584,21585],{"class":5707,"line":6031},[5705,21586,5795],{"emptyLinePlaceholder":5794},[5705,21588,21589,21591,21593,21595,21597,21599,21601,21603,21605,21607,21609,21611,21613,21616],{"class":5707,"line":6052},[5705,21590,5907],{"class":5718},[5705,21592,5958],{"class":5726},[5705,21594,5621],{"class":5913},[5705,21596,5580],{"class":5726},[5705,21598,7265],{"class":5913},[5705,21600,5580],{"class":5726},[5705,21602,5618],{"class":5913},[5705,21604,5580],{"class":5726},[5705,21606,21487],{"class":5913},[5705,21608,7365],{"class":5726},[5705,21610,20269],{"class":5722},[5705,21612,5763],{"class":5726},[5705,21614,21615],{"class":5748},"Product",[5705,21617,9527],{"class":5726},[5705,21619,21620,21623],{"class":5707,"line":6057},[5705,21621,21622],{"class":6019},"    'https:\u002F\u002Fapi.example.com\u002Fproducts'",[5705,21624,8298],{"class":5726},[5705,21626,21627],{"class":5707,"line":6072},[5705,21628,21629],{"class":5726},"    {\n",[5705,21631,21632,21635],{"class":5707,"line":6093},[5705,21633,21634],{"class":5741},"      enabled",[5705,21636,8298],{"class":5726},[5705,21638,21639,21642,21645,21647],{"class":5707,"line":6112},[5705,21640,21641],{"class":5741},"      refetchInterval:",[5705,21643,21644],{"class":9489}," 30000",[5705,21646,5580],{"class":5726},[5705,21648,21649],{"class":5711},"\u002F\u002F Автооновлення кожні 30 секунд\n",[5705,21651,21652,21655],{"class":5707,"line":6118},[5705,21653,21654],{"class":5741},"      headers:",[5705,21656,6069],{"class":5726},[5705,21658,21659,21662,21665],{"class":5707,"line":6124},[5705,21660,21661],{"class":5741},"        Authorization:",[5705,21663,21664],{"class":6019}," 'Bearer token123'",[5705,21666,8298],{"class":5726},[5705,21668,21669],{"class":5707,"line":6129},[5705,21670,21671],{"class":5726},"      },\n",[5705,21673,21674,21677,21679,21681,21684,21686,21688],{"class":5707,"line":6141},[5705,21675,21676],{"class":5722},"      onSuccess",[5705,21678,5600],{"class":5741},[5705,21680,7055],{"class":5726},[5705,21682,21683],{"class":5741},"products",[5705,21685,8337],{"class":5726},[5705,21687,5955],{"class":5718},[5705,21689,6069],{"class":5726},[5705,21691,21692,21695,21697,21699,21701,21704,21706,21708,21710,21712,21714,21717],{"class":5707,"line":6389},[5705,21693,21694],{"class":5741},"        console",[5705,21696,5622],{"class":5726},[5705,21698,12164],{"class":5722},[5705,21700,5738],{"class":5726},[5705,21702,21703],{"class":6019},"`Завантажено ",[5705,21705,6570],{"class":5718},[5705,21707,21683],{"class":5741},[5705,21709,5622],{"class":7502},[5705,21711,16199],{"class":5741},[5705,21713,6587],{"class":5718},[5705,21715,21716],{"class":6019}," товарів`",[5705,21718,6028],{"class":5726},[5705,21720,21721],{"class":5707,"line":6408},[5705,21722,21671],{"class":5726},[5705,21724,21725,21728,21730,21732,21734,21736,21738],{"class":5707,"line":6413},[5705,21726,21727],{"class":5722},"      onError",[5705,21729,5600],{"class":5741},[5705,21731,7055],{"class":5726},[5705,21733,7582],{"class":5741},[5705,21735,8337],{"class":5726},[5705,21737,5955],{"class":5718},[5705,21739,6069],{"class":5726},[5705,21741,21742,21744,21746,21748,21750,21753,21755,21757],{"class":5707,"line":6419},[5705,21743,21694],{"class":5741},[5705,21745,5622],{"class":5726},[5705,21747,5618],{"class":5722},[5705,21749,5738],{"class":5726},[5705,21751,21752],{"class":6019},"'Помилка завантаження:'",[5705,21754,5580],{"class":5726},[5705,21756,7582],{"class":5741},[5705,21758,6028],{"class":5726},[5705,21760,21761],{"class":5707,"line":6430},[5705,21762,21671],{"class":5726},[5705,21764,21765],{"class":5707,"line":6449},[5705,21766,6333],{"class":5726},[5705,21768,21769],{"class":5707,"line":6468},[5705,21770,6628],{"class":5726},[5705,21772,21773],{"class":5707,"line":6473},[5705,21774,5795],{"emptyLinePlaceholder":5794},[5705,21776,21777,21779],{"class":5707,"line":6482},[5705,21778,6132],{"class":6060},[5705,21780,6544],{"class":5726},[5705,21782,21783,21785,21787],{"class":5707,"line":6487},[5705,21784,6550],{"class":6549},[5705,21786,6554],{"class":6553},[5705,21788,6595],{"class":6549},[5705,21790,21791,21793,21795,21797,21799,21802],{"class":5707,"line":6496},[5705,21792,6775],{"class":6549},[5705,21794,6554],{"class":6553},[5705,21796,6558],{"class":6557},[5705,21798,6561],{"class":5726},[5705,21800,21801],{"class":6019},"\"controls\"",[5705,21803,6595],{"class":6549},[5705,21805,21806,21808,21810,21812,21814,21816,21818,21820,21823,21825,21827,21829,21831,21833],{"class":5707,"line":7008},[5705,21807,9712],{"class":6549},[5705,21809,9113],{"class":6553},[5705,21811,9116],{"class":6557},[5705,21813,6561],{"class":5726},[5705,21815,6564],{"class":5718},[5705,21817,15154],{"class":7502},[5705,21819,5955],{"class":5718},[5705,21821,21822],{"class":5722}," setEnabled",[5705,21824,5738],{"class":7502},[5705,21826,12500],{"class":5726},[5705,21828,20764],{"class":5741},[5705,21830,9646],{"class":7502},[5705,21832,6587],{"class":5718},[5705,21834,6595],{"class":6549},[5705,21836,21837,21839,21841,21843,21846,21848,21851,21853],{"class":5707,"line":7014},[5705,21838,9721],{"class":5718},[5705,21840,20764],{"class":5741},[5705,21842,6575],{"class":5726},[5705,21844,21845],{"class":6019}," 'Вимкнути'",[5705,21847,6581],{"class":5726},[5705,21849,21850],{"class":6019}," 'Увімкнути'",[5705,21852,6587],{"class":5718},[5705,21854,21855],{"class":5726}," автозавантаження\n",[5705,21857,21858,21860,21862],{"class":5707,"line":7020},[5705,21859,9787],{"class":6549},[5705,21861,9113],{"class":6553},[5705,21863,6595],{"class":6549},[5705,21865,21866,21868,21870,21872,21874,21876,21878,21880,21883,21885,21887,21889,21891,21893],{"class":5707,"line":7026},[5705,21867,9712],{"class":6549},[5705,21869,9113],{"class":6553},[5705,21871,9116],{"class":6557},[5705,21873,6561],{"class":5726},[5705,21875,6564],{"class":5718},[5705,21877,21487],{"class":5741},[5705,21879,6587],{"class":5718},[5705,21881,21882],{"class":6557}," disabled",[5705,21884,6561],{"class":5726},[5705,21886,6564],{"class":5718},[5705,21888,12500],{"class":5726},[5705,21890,20764],{"class":5741},[5705,21892,6587],{"class":5718},[5705,21894,6595],{"class":6549},[5705,21896,21897],{"class":5707,"line":7032},[5705,21898,21899],{"class":5726},"          🔄 Оновити вручну\n",[5705,21901,21902,21904,21906],{"class":5707,"line":7037},[5705,21903,9787],{"class":6549},[5705,21905,9113],{"class":6553},[5705,21907,6595],{"class":6549},[5705,21909,21910,21912,21914],{"class":5707,"line":7639},[5705,21911,9157],{"class":6549},[5705,21913,6554],{"class":6553},[5705,21915,6595],{"class":6549},[5705,21917,21918],{"class":5707,"line":7644},[5705,21919,5795],{"emptyLinePlaceholder":5794},[5705,21921,21922,21924,21926,21928,21930,21932,21934,21936,21938,21940,21942],{"class":5707,"line":7654},[5705,21923,6600],{"class":5718},[5705,21925,7265],{"class":5741},[5705,21927,9676],{"class":5726},[5705,21929,7958],{"class":6549},[5705,21931,5479],{"class":6553},[5705,21933,6780],{"class":6549},[5705,21935,7972],{"class":7502},[5705,21937,6803],{"class":6549},[5705,21939,5479],{"class":6553},[5705,21941,6780],{"class":6549},[5705,21943,6144],{"class":5718},[5705,21945,21946,21948,21950,21952,21954,21956,21958,21960,21962,21964,21966,21968,21970,21972,21974,21976],{"class":5707,"line":7660},[5705,21947,6600],{"class":5718},[5705,21949,5618],{"class":5741},[5705,21951,9676],{"class":5726},[5705,21953,7958],{"class":6549},[5705,21955,5479],{"class":6553},[5705,21957,6558],{"class":6557},[5705,21959,6561],{"class":5726},[5705,21961,8013],{"class":6019},[5705,21963,6780],{"class":6549},[5705,21965,6564],{"class":5718},[5705,21967,5618],{"class":5741},[5705,21969,6587],{"class":5718},[5705,21971,6803],{"class":6549},[5705,21973,5479],{"class":6553},[5705,21975,6780],{"class":6549},[5705,21977,6144],{"class":5718},[5705,21979,21980],{"class":5707,"line":7676},[5705,21981,5795],{"emptyLinePlaceholder":5794},[5705,21983,21984,21986,21988,21990],{"class":5707,"line":7688},[5705,21985,6600],{"class":5718},[5705,21987,5621],{"class":5741},[5705,21989,9676],{"class":5726},[5705,21991,6544],{"class":7502},[5705,21993,21994,21996,21998],{"class":5707,"line":7693},[5705,21995,9712],{"class":6549},[5705,21997,5503],{"class":6553},[5705,21999,6595],{"class":6549},[5705,22001,22002,22004,22006,22008,22010,22012,22015,22017,22019],{"class":5707,"line":7699},[5705,22003,9721],{"class":5718},[5705,22005,5621],{"class":5741},[5705,22007,5622],{"class":7502},[5705,22009,9728],{"class":5722},[5705,22011,9039],{"class":7502},[5705,22013,22014],{"class":5741},"product",[5705,22016,8337],{"class":7502},[5705,22018,5955],{"class":5718},[5705,22020,6544],{"class":7502},[5705,22022,22023,22025,22027,22029,22031,22033,22035,22037,22040,22042],{"class":5707,"line":7704},[5705,22024,9748],{"class":6549},[5705,22026,5506],{"class":6553},[5705,22028,9753],{"class":6557},[5705,22030,6561],{"class":5726},[5705,22032,6564],{"class":5718},[5705,22034,22014],{"class":5741},[5705,22036,5622],{"class":7502},[5705,22038,22039],{"class":5741},"id",[5705,22041,6587],{"class":5718},[5705,22043,6595],{"class":6549},[5705,22045,22046,22049,22051,22053,22055,22057,22060,22062,22064,22066,22069,22071],{"class":5707,"line":7709},[5705,22047,22048],{"class":5718},"              {",[5705,22050,22014],{"class":5741},[5705,22052,5622],{"class":7502},[5705,22054,7612],{"class":5741},[5705,22056,6587],{"class":5718},[5705,22058,22059],{"class":7502}," — ",[5705,22061,6564],{"class":5718},[5705,22063,22014],{"class":5741},[5705,22065,5622],{"class":7502},[5705,22067,22068],{"class":5741},"price",[5705,22070,6587],{"class":5718},[5705,22072,22073],{"class":7502}," грн\n",[5705,22075,22076,22079,22081],{"class":5707,"line":7717},[5705,22077,22078],{"class":6549},"            \u003C\u002F",[5705,22080,5506],{"class":6553},[5705,22082,6595],{"class":6549},[5705,22084,22085,22087],{"class":5707,"line":7722},[5705,22086,9780],{"class":7502},[5705,22088,6144],{"class":5718},[5705,22090,22091,22093,22095],{"class":5707,"line":7728},[5705,22092,9787],{"class":6549},[5705,22094,5503],{"class":6553},[5705,22096,6595],{"class":6549},[5705,22098,22099,22101],{"class":5707,"line":7739},[5705,22100,9796],{"class":7502},[5705,22102,6144],{"class":5718},[5705,22104,22105,22107,22109],{"class":5707,"line":7752},[5705,22106,6619],{"class":6549},[5705,22108,6554],{"class":6553},[5705,22110,6595],{"class":6549},[5705,22112,22113],{"class":5707,"line":7757},[5705,22114,6628],{"class":5726},[5705,22116,22117],{"class":5707,"line":7771},[5705,22118,6144],{"class":5726},[6634,22120,22121,22126],{},[5479,22122,22123],{},[5483,22124,22125],{},"Переваги об'єкта конфігурації:",[6642,22127,22128,22133,22139,22145],{},[5506,22129,22130,22132],{},[5483,22131,6673],{}," Явні назви параметрів у виклику хука.",[5506,22134,22135,22138],{},[5483,22136,22137],{},"Розширюваність:"," Легко додати нові опції без зміни сигнатури функції.",[5506,22140,22141,22144],{},[5483,22142,22143],{},"Опціональність:"," Більшість параметрів мають значення за замовчуванням.",[5506,22146,22147,22150],{},[5483,22148,22149],{},"TypeScript-підказки:"," IDE показує всі доступні опції при автодоповненні.",[5567,22152],{},[5570,22154,22156,22157],{"id":22155},"хук-для-роботи-з-формами-useform","Хук для роботи з формами: ",[5535,22158,22159],{},"useForm",[5479,22161,22162],{},"Створимо універсальний хук для управління станом форми із валідацією.",[5685,22164,7095,22166],{"id":22165},"реалізація-useform",[5535,22167,22159],{},[5696,22169,22171],{"className":5698,"code":22170,"language":5700,"meta":5701,"style":5701},"interface ValidationRule\u003CT> {\n  validate: (value: T) => boolean;\n  message: string;\n}\n\ninterface FieldConfig\u003CT> {\n  initialValue: T;\n  rules?: ValidationRule\u003CT>[];\n}\n\ninterface UseFormResult\u003CT> {\n  values: T;\n  errors: Partial\u003CRecord\u003Ckeyof T, string>>;\n  touched: Partial\u003CRecord\u003Ckeyof T, boolean>>;\n  handleChange: (field: keyof T) => (value: any) => void;\n  handleBlur: (field: keyof T) => () => void;\n  handleSubmit: (onSubmit: (values: T) => void) => (e: React.FormEvent) => void;\n  reset: () => void;\n  isValid: boolean;\n}\n\nexport function useForm\u003CT extends Record\u003Cstring, any>>(\n  config: Record\u003Ckeyof T, FieldConfig\u003CT[keyof T]>>\n): UseFormResult\u003CT> {\n  const initialValues = Object.keys(config).reduce((acc, key) => {\n    acc[key as keyof T] = config[key as keyof T].initialValue;\n    return acc;\n  }, {} as T);\n\n  const [values, setValues] = useState\u003CT>(initialValues);\n  const [errors, setErrors] = useState\u003CPartial\u003CRecord\u003Ckeyof T, string>>>({});\n  const [touched, setTouched] = useState\u003CPartial\u003CRecord\u003Ckeyof T, boolean>>>({});\n\n  const validateField = (field: keyof T, value: any): string | null => {\n    const rules = config[field].rules;\n    if (!rules) return null;\n\n    for (const rule of rules) {\n      if (!rule.validate(value)) {\n        return rule.message;\n      }\n    }\n    return null;\n  };\n\n  const handleChange = (field: keyof T) => (value: any) => {\n    setValues((prev) => ({ ...prev, [field]: value }));\n\n    const error = validateField(field, value);\n    setErrors((prev) => ({\n      ...prev,\n      [field]: error || undefined,\n    }));\n  };\n\n  const handleBlur = (field: keyof T) => () => {\n    setTouched((prev) => ({ ...prev, [field]: true }));\n  };\n\n  const handleSubmit = (onSubmit: (values: T) => void) => (e: React.FormEvent) => {\n    e.preventDefault();\n\n    \u002F\u002F Позначаємо всі поля як торкнуті\n    const allTouched = Object.keys(config).reduce((acc, key) => {\n      acc[key as keyof T] = true;\n      return acc;\n    }, {} as Partial\u003CRecord\u003Ckeyof T, boolean>>);\n    setTouched(allTouched);\n\n    \u002F\u002F Валідуємо всі поля\n    const allErrors: Partial\u003CRecord\u003Ckeyof T, string>> = {};\n    let hasErrors = false;\n\n    for (const field of Object.keys(config) as Array\u003Ckeyof T>) {\n      const error = validateField(field, values[field]);\n      if (error) {\n        allErrors[field] = error;\n        hasErrors = true;\n      }\n    }\n\n    setErrors(allErrors);\n\n    if (!hasErrors) {\n      onSubmit(values);\n    }\n  };\n\n  const reset = () => {\n    setValues(initialValues);\n    setErrors({});\n    setTouched({});\n  };\n\n  const isValid = Object.keys(errors).length === 0;\n\n  return {\n    values,\n    errors,\n    touched,\n    handleChange,\n    handleBlur,\n    handleSubmit,\n    reset,\n    isValid,\n  };\n}\n",[5535,22172,22173,22186,22208,22219,22223,22227,22240,22250,22267,22271,22275,22288,22299,22327,22352,22388,22415,22465,22478,22489,22493,22497,22527,22560,22573,22614,22652,22661,22672,22676,22704,22743,22781,22785,22823,22845,22862,22866,22885,22906,22919,22923,22927,22935,22939,22943,22978,23007,23011,23033,23049,23058,23072,23077,23081,23085,23112,23138,23142,23146,23193,23205,23209,23214,23251,23272,23280,23307,23318,23322,23327,23355,23368,23372,23412,23436,23446,23461,23472,23476,23480,23484,23495,23499,23510,23521,23525,23529,23533,23546,23556,23563,23569,23573,23577,23606,23610,23616,23623,23630,23637,23644,23651,23658,23665,23672,23676],{"__ignoreMap":5701},[5705,22174,22175,22177,22180,22182,22184],{"class":5707,"line":5708},[5705,22176,7132],{"class":5718},[5705,22178,22179],{"class":5748}," ValidationRule",[5705,22181,5763],{"class":5726},[5705,22183,5766],{"class":5748},[5705,22185,7142],{"class":5726},[5705,22187,22188,22191,22193,22195,22197,22199,22201,22203,22206],{"class":5707,"line":5715},[5705,22189,22190],{"class":5722},"  validate",[5705,22192,10150],{"class":5726},[5705,22194,5772],{"class":5741},[5705,22196,5745],{"class":5726},[5705,22198,5766],{"class":5748},[5705,22200,8337],{"class":5726},[5705,22202,5955],{"class":5718},[5705,22204,22205],{"class":5748}," boolean",[5705,22207,6138],{"class":5726},[5705,22209,22210,22213,22215,22217],{"class":5707,"line":5730},[5705,22211,22212],{"class":5741},"  message",[5705,22214,5745],{"class":5726},[5705,22216,5749],{"class":5748},[5705,22218,6138],{"class":5726},[5705,22220,22221],{"class":5707,"line":5755},[5705,22222,6144],{"class":5726},[5705,22224,22225],{"class":5707,"line":5791},[5705,22226,5795],{"emptyLinePlaceholder":5794},[5705,22228,22229,22231,22234,22236,22238],{"class":5707,"line":5798},[5705,22230,7132],{"class":5718},[5705,22232,22233],{"class":5748}," FieldConfig",[5705,22235,5763],{"class":5726},[5705,22237,5766],{"class":5748},[5705,22239,7142],{"class":5726},[5705,22241,22242,22244,22246,22248],{"class":5707,"line":5804},[5705,22243,8303],{"class":5741},[5705,22245,5745],{"class":5726},[5705,22247,5766],{"class":5748},[5705,22249,6138],{"class":5726},[5705,22251,22252,22255,22257,22260,22262,22264],{"class":5707,"line":5818},[5705,22253,22254],{"class":5741},"  rules",[5705,22256,20291],{"class":5726},[5705,22258,22259],{"class":5748},"ValidationRule",[5705,22261,5763],{"class":5726},[5705,22263,5766],{"class":5748},[5705,22265,22266],{"class":5726},">[];\n",[5705,22268,22269],{"class":5707,"line":6031},[5705,22270,6144],{"class":5726},[5705,22272,22273],{"class":5707,"line":6052},[5705,22274,5795],{"emptyLinePlaceholder":5794},[5705,22276,22277,22279,22282,22284,22286],{"class":5707,"line":6057},[5705,22278,7132],{"class":5718},[5705,22280,22281],{"class":5748}," UseFormResult",[5705,22283,5763],{"class":5726},[5705,22285,5766],{"class":5748},[5705,22287,7142],{"class":5726},[5705,22289,22290,22293,22295,22297],{"class":5707,"line":6072},[5705,22291,22292],{"class":5741},"  values",[5705,22294,5745],{"class":5726},[5705,22296,5766],{"class":5748},[5705,22298,6138],{"class":5726},[5705,22300,22301,22304,22306,22309,22311,22313,22315,22318,22320,22322,22324],{"class":5707,"line":6093},[5705,22302,22303],{"class":5741},"  errors",[5705,22305,5745],{"class":5726},[5705,22307,22308],{"class":5748},"Partial",[5705,22310,5763],{"class":5726},[5705,22312,20321],{"class":5748},[5705,22314,5763],{"class":5726},[5705,22316,22317],{"class":5718},"keyof",[5705,22319,8342],{"class":5748},[5705,22321,5580],{"class":5726},[5705,22323,5749],{"class":5748},[5705,22325,22326],{"class":5726},">>;\n",[5705,22328,22329,22332,22334,22336,22338,22340,22342,22344,22346,22348,22350],{"class":5707,"line":6112},[5705,22330,22331],{"class":5741},"  touched",[5705,22333,5745],{"class":5726},[5705,22335,22308],{"class":5748},[5705,22337,5763],{"class":5726},[5705,22339,20321],{"class":5748},[5705,22341,5763],{"class":5726},[5705,22343,22317],{"class":5718},[5705,22345,8342],{"class":5748},[5705,22347,5580],{"class":5726},[5705,22349,6253],{"class":5748},[5705,22351,22326],{"class":5726},[5705,22353,22354,22357,22359,22362,22364,22366,22368,22370,22372,22374,22376,22378,22380,22382,22384,22386],{"class":5707,"line":6118},[5705,22355,22356],{"class":5722},"  handleChange",[5705,22358,10150],{"class":5726},[5705,22360,22361],{"class":5741},"field",[5705,22363,5745],{"class":5726},[5705,22365,22317],{"class":5718},[5705,22367,8342],{"class":5748},[5705,22369,8337],{"class":5726},[5705,22371,5955],{"class":5718},[5705,22373,7055],{"class":5726},[5705,22375,5772],{"class":5741},[5705,22377,5745],{"class":5726},[5705,22379,20342],{"class":5748},[5705,22381,8337],{"class":5726},[5705,22383,5955],{"class":5718},[5705,22385,8350],{"class":5748},[5705,22387,6138],{"class":5726},[5705,22389,22390,22393,22395,22397,22399,22401,22403,22405,22407,22409,22411,22413],{"class":5707,"line":6124},[5705,22391,22392],{"class":5722},"  handleBlur",[5705,22394,10150],{"class":5726},[5705,22396,22361],{"class":5741},[5705,22398,5745],{"class":5726},[5705,22400,22317],{"class":5718},[5705,22402,8342],{"class":5748},[5705,22404,8337],{"class":5726},[5705,22406,5955],{"class":5718},[5705,22408,6064],{"class":5726},[5705,22410,5955],{"class":5718},[5705,22412,8350],{"class":5748},[5705,22414,6138],{"class":5726},[5705,22416,22417,22420,22422,22425,22427,22430,22432,22434,22436,22438,22440,22442,22444,22446,22448,22450,22452,22454,22457,22459,22461,22463],{"class":5707,"line":6129},[5705,22418,22419],{"class":5722},"  handleSubmit",[5705,22421,10150],{"class":5726},[5705,22423,22424],{"class":5722},"onSubmit",[5705,22426,10150],{"class":5726},[5705,22428,22429],{"class":5741},"values",[5705,22431,5745],{"class":5726},[5705,22433,5766],{"class":5748},[5705,22435,8337],{"class":5726},[5705,22437,5955],{"class":5718},[5705,22439,8350],{"class":5748},[5705,22441,8337],{"class":5726},[5705,22443,5955],{"class":5718},[5705,22445,7055],{"class":5726},[5705,22447,9623],{"class":5741},[5705,22449,5745],{"class":5726},[5705,22451,2303],{"class":5748},[5705,22453,5622],{"class":5726},[5705,22455,22456],{"class":5748},"FormEvent",[5705,22458,8337],{"class":5726},[5705,22460,5955],{"class":5718},[5705,22462,8350],{"class":5748},[5705,22464,6138],{"class":5726},[5705,22466,22467,22470,22472,22474,22476],{"class":5707,"line":6141},[5705,22468,22469],{"class":5722},"  reset",[5705,22471,20483],{"class":5726},[5705,22473,5955],{"class":5718},[5705,22475,8350],{"class":5748},[5705,22477,6138],{"class":5726},[5705,22479,22480,22483,22485,22487],{"class":5707,"line":6389},[5705,22481,22482],{"class":5741},"  isValid",[5705,22484,5745],{"class":5726},[5705,22486,6253],{"class":5748},[5705,22488,6138],{"class":5726},[5705,22490,22491],{"class":5707,"line":6408},[5705,22492,6144],{"class":5726},[5705,22494,22495],{"class":5707,"line":6413},[5705,22496,5795],{"emptyLinePlaceholder":5794},[5705,22498,22499,22501,22503,22506,22508,22510,22513,22516,22518,22520,22522,22524],{"class":5707,"line":6419},[5705,22500,6242],{"class":6060},[5705,22502,6245],{"class":5718},[5705,22504,22505],{"class":5722}," useForm",[5705,22507,5763],{"class":5726},[5705,22509,5766],{"class":5748},[5705,22511,22512],{"class":5718}," extends",[5705,22514,22515],{"class":5748}," Record",[5705,22517,5763],{"class":5726},[5705,22519,5749],{"class":5748},[5705,22521,5580],{"class":5726},[5705,22523,20342],{"class":5748},[5705,22525,22526],{"class":5726},">>(\n",[5705,22528,22529,22531,22533,22535,22537,22539,22541,22543,22546,22548,22550,22553,22555,22557],{"class":5707,"line":6430},[5705,22530,20528],{"class":5741},[5705,22532,5745],{"class":5726},[5705,22534,20321],{"class":5748},[5705,22536,5763],{"class":5726},[5705,22538,22317],{"class":5718},[5705,22540,8342],{"class":5748},[5705,22542,5580],{"class":5726},[5705,22544,22545],{"class":5748},"FieldConfig",[5705,22547,5763],{"class":5726},[5705,22549,5766],{"class":5748},[5705,22551,22552],{"class":5726},"[",[5705,22554,22317],{"class":5718},[5705,22556,8342],{"class":5748},[5705,22558,22559],{"class":5726},"]>>\n",[5705,22561,22562,22564,22567,22569,22571],{"class":5707,"line":6449},[5705,22563,7216],{"class":5726},[5705,22565,22566],{"class":5748},"UseFormResult",[5705,22568,5763],{"class":5726},[5705,22570,5766],{"class":5748},[5705,22572,7142],{"class":5726},[5705,22574,22575,22577,22580,22582,22585,22587,22590,22592,22594,22596,22599,22601,22604,22606,22608,22610,22612],{"class":5707,"line":6468},[5705,22576,5907],{"class":5718},[5705,22578,22579],{"class":5913}," initialValues",[5705,22581,6525],{"class":5726},[5705,22583,22584],{"class":5741},"Object",[5705,22586,5622],{"class":5726},[5705,22588,22589],{"class":5722},"keys",[5705,22591,5738],{"class":5726},[5705,22593,20621],{"class":5741},[5705,22595,5609],{"class":5726},[5705,22597,22598],{"class":5722},"reduce",[5705,22600,9039],{"class":5726},[5705,22602,22603],{"class":5741},"acc",[5705,22605,5580],{"class":5726},[5705,22607,8421],{"class":5741},[5705,22609,8337],{"class":5726},[5705,22611,5955],{"class":5718},[5705,22613,6069],{"class":5726},[5705,22615,22616,22619,22621,22623,22626,22629,22631,22633,22635,22637,22639,22641,22643,22645,22648,22650],{"class":5707,"line":6473},[5705,22617,22618],{"class":5741},"    acc",[5705,22620,22552],{"class":5726},[5705,22622,8421],{"class":5741},[5705,22624,22625],{"class":6060}," as",[5705,22627,22628],{"class":5718}," keyof",[5705,22630,8342],{"class":5748},[5705,22632,5922],{"class":5726},[5705,22634,20621],{"class":5741},[5705,22636,22552],{"class":5726},[5705,22638,8421],{"class":5741},[5705,22640,22625],{"class":6060},[5705,22642,22628],{"class":5718},[5705,22644,8342],{"class":5748},[5705,22646,22647],{"class":5726},"].",[5705,22649,8459],{"class":5741},[5705,22651,6138],{"class":5726},[5705,22653,22654,22656,22659],{"class":5707,"line":6482},[5705,22655,6061],{"class":6060},[5705,22657,22658],{"class":5741}," acc",[5705,22660,6138],{"class":5726},[5705,22662,22663,22666,22668,22670],{"class":5707,"line":6487},[5705,22664,22665],{"class":5726},"  }, {} ",[5705,22667,8451],{"class":6060},[5705,22669,8342],{"class":5748},[5705,22671,6028],{"class":5726},[5705,22673,22674],{"class":5707,"line":6496},[5705,22675,5795],{"emptyLinePlaceholder":5794},[5705,22677,22678,22680,22682,22684,22686,22689,22691,22693,22695,22697,22699,22702],{"class":5707,"line":7008},[5705,22679,5907],{"class":5718},[5705,22681,5910],{"class":5726},[5705,22683,22429],{"class":5913},[5705,22685,5580],{"class":5726},[5705,22687,22688],{"class":5913},"setValues",[5705,22690,5922],{"class":5726},[5705,22692,5579],{"class":5722},[5705,22694,5763],{"class":5726},[5705,22696,5766],{"class":5748},[5705,22698,5769],{"class":5726},[5705,22700,22701],{"class":5741},"initialValues",[5705,22703,6028],{"class":5726},[5705,22705,22706,22708,22710,22713,22715,22718,22720,22722,22724,22726,22728,22730,22732,22734,22736,22738,22740],{"class":5707,"line":7014},[5705,22707,5907],{"class":5718},[5705,22709,5910],{"class":5726},[5705,22711,22712],{"class":5913},"errors",[5705,22714,5580],{"class":5726},[5705,22716,22717],{"class":5913},"setErrors",[5705,22719,5922],{"class":5726},[5705,22721,5579],{"class":5722},[5705,22723,5763],{"class":5726},[5705,22725,22308],{"class":5748},[5705,22727,5763],{"class":5726},[5705,22729,20321],{"class":5748},[5705,22731,5763],{"class":5726},[5705,22733,22317],{"class":5718},[5705,22735,8342],{"class":5748},[5705,22737,5580],{"class":5726},[5705,22739,5749],{"class":5748},[5705,22741,22742],{"class":5726},">>>({});\n",[5705,22744,22745,22747,22749,22752,22754,22757,22759,22761,22763,22765,22767,22769,22771,22773,22775,22777,22779],{"class":5707,"line":7020},[5705,22746,5907],{"class":5718},[5705,22748,5910],{"class":5726},[5705,22750,22751],{"class":5913},"touched",[5705,22753,5580],{"class":5726},[5705,22755,22756],{"class":5913},"setTouched",[5705,22758,5922],{"class":5726},[5705,22760,5579],{"class":5722},[5705,22762,5763],{"class":5726},[5705,22764,22308],{"class":5748},[5705,22766,5763],{"class":5726},[5705,22768,20321],{"class":5748},[5705,22770,5763],{"class":5726},[5705,22772,22317],{"class":5718},[5705,22774,8342],{"class":5748},[5705,22776,5580],{"class":5726},[5705,22778,6253],{"class":5748},[5705,22780,22742],{"class":5726},[5705,22782,22783],{"class":5707,"line":7026},[5705,22784,5795],{"emptyLinePlaceholder":5794},[5705,22786,22787,22789,22792,22794,22796,22798,22800,22802,22804,22806,22808,22810,22812,22814,22816,22818,22821],{"class":5707,"line":7032},[5705,22788,5907],{"class":5718},[5705,22790,22791],{"class":5722}," validateField",[5705,22793,8540],{"class":5726},[5705,22795,22361],{"class":5741},[5705,22797,5745],{"class":5726},[5705,22799,22317],{"class":5718},[5705,22801,8342],{"class":5748},[5705,22803,5580],{"class":5726},[5705,22805,5772],{"class":5741},[5705,22807,5745],{"class":5726},[5705,22809,20342],{"class":5748},[5705,22811,7216],{"class":5726},[5705,22813,5749],{"class":5748},[5705,22815,7154],{"class":5726},[5705,22817,7157],{"class":5748},[5705,22819,22820],{"class":5718}," =>",[5705,22822,6069],{"class":5726},[5705,22824,22825,22827,22830,22832,22834,22836,22838,22840,22843],{"class":5707,"line":7037},[5705,22826,7339],{"class":5718},[5705,22828,22829],{"class":5913}," rules",[5705,22831,6525],{"class":5726},[5705,22833,20621],{"class":5741},[5705,22835,22552],{"class":5726},[5705,22837,22361],{"class":5741},[5705,22839,22647],{"class":5726},[5705,22841,22842],{"class":5741},"rules",[5705,22844,6138],{"class":5726},[5705,22846,22847,22849,22851,22853,22855,22857,22860],{"class":5707,"line":7639},[5705,22848,12070],{"class":6060},[5705,22850,7468],{"class":5726},[5705,22852,22842],{"class":5741},[5705,22854,8337],{"class":5726},[5705,22856,6170],{"class":6060},[5705,22858,22859],{"class":5718}," null",[5705,22861,6138],{"class":5726},[5705,22863,22864],{"class":5707,"line":7644},[5705,22865,5795],{"emptyLinePlaceholder":5794},[5705,22867,22868,22871,22873,22875,22878,22881,22883],{"class":5707,"line":7654},[5705,22869,22870],{"class":6060},"    for",[5705,22872,7055],{"class":5726},[5705,22874,15773],{"class":5718},[5705,22876,22877],{"class":5913}," rule",[5705,22879,22880],{"class":5718}," of",[5705,22882,22829],{"class":5741},[5705,22884,7479],{"class":5726},[5705,22886,22887,22889,22891,22894,22896,22899,22901,22903],{"class":5707,"line":7660},[5705,22888,8757],{"class":6060},[5705,22890,7468],{"class":5726},[5705,22892,22893],{"class":5741},"rule",[5705,22895,5622],{"class":5726},[5705,22897,22898],{"class":5722},"validate",[5705,22900,5738],{"class":5726},[5705,22902,5772],{"class":5741},[5705,22904,22905],{"class":5726},")) {\n",[5705,22907,22908,22911,22913,22915,22917],{"class":5707,"line":7676},[5705,22909,22910],{"class":6060},"        return",[5705,22912,22877],{"class":5741},[5705,22914,5622],{"class":5726},[5705,22916,7634],{"class":5741},[5705,22918,6138],{"class":5726},[5705,22920,22921],{"class":5707,"line":7688},[5705,22922,7696],{"class":5726},[5705,22924,22925],{"class":5707,"line":7693},[5705,22926,6333],{"class":5726},[5705,22928,22929,22931,22933],{"class":5707,"line":7699},[5705,22930,6061],{"class":6060},[5705,22932,22859],{"class":5718},[5705,22934,6138],{"class":5726},[5705,22936,22937],{"class":5707,"line":7704},[5705,22938,8714],{"class":5726},[5705,22940,22941],{"class":5707,"line":7709},[5705,22942,5795],{"emptyLinePlaceholder":5794},[5705,22944,22945,22947,22950,22952,22954,22956,22958,22960,22962,22964,22966,22968,22970,22972,22974,22976],{"class":5707,"line":7717},[5705,22946,5907],{"class":5718},[5705,22948,22949],{"class":5722}," handleChange",[5705,22951,8540],{"class":5726},[5705,22953,22361],{"class":5741},[5705,22955,5745],{"class":5726},[5705,22957,22317],{"class":5718},[5705,22959,8342],{"class":5748},[5705,22961,8337],{"class":5726},[5705,22963,5955],{"class":5718},[5705,22965,7055],{"class":5726},[5705,22967,5772],{"class":5741},[5705,22969,5745],{"class":5726},[5705,22971,20342],{"class":5748},[5705,22973,8337],{"class":5726},[5705,22975,5955],{"class":5718},[5705,22977,6069],{"class":5726},[5705,22979,22980,22983,22985,22987,22989,22991,22994,22996,22998,23001,23004],{"class":5707,"line":7722},[5705,22981,22982],{"class":5722},"    setValues",[5705,22984,9039],{"class":5726},[5705,22986,8330],{"class":5741},[5705,22988,8337],{"class":5726},[5705,22990,5955],{"class":5718},[5705,22992,22993],{"class":5726}," ({ ...",[5705,22995,8330],{"class":5741},[5705,22997,5580],{"class":5726},[5705,22999,23000],{"class":5741},"[field]:",[5705,23002,23003],{"class":5741}," value",[5705,23005,23006],{"class":5726}," }));\n",[5705,23008,23009],{"class":5707,"line":7728},[5705,23010,5795],{"emptyLinePlaceholder":5794},[5705,23012,23013,23015,23018,23020,23023,23025,23027,23029,23031],{"class":5707,"line":7739},[5705,23014,7339],{"class":5718},[5705,23016,23017],{"class":5913}," error",[5705,23019,6525],{"class":5726},[5705,23021,23022],{"class":5722},"validateField",[5705,23024,5738],{"class":5726},[5705,23026,22361],{"class":5741},[5705,23028,5580],{"class":5726},[5705,23030,5772],{"class":5741},[5705,23032,6028],{"class":5726},[5705,23034,23035,23038,23040,23042,23044,23046],{"class":5707,"line":7752},[5705,23036,23037],{"class":5722},"    setErrors",[5705,23039,9039],{"class":5726},[5705,23041,8330],{"class":5741},[5705,23043,8337],{"class":5726},[5705,23045,5955],{"class":5718},[5705,23047,23048],{"class":5726}," ({\n",[5705,23050,23051,23054,23056],{"class":5707,"line":7757},[5705,23052,23053],{"class":5726},"      ...",[5705,23055,8330],{"class":5741},[5705,23057,8298],{"class":5726},[5705,23059,23060,23063,23065,23068,23070],{"class":5707,"line":7771},[5705,23061,23062],{"class":5741},"      [field]:",[5705,23064,23017],{"class":5741},[5705,23066,23067],{"class":5726}," || ",[5705,23069,21292],{"class":5718},[5705,23071,8298],{"class":5726},[5705,23073,23074],{"class":5707,"line":7776},[5705,23075,23076],{"class":5726},"    }));\n",[5705,23078,23079],{"class":5707,"line":7796},[5705,23080,8714],{"class":5726},[5705,23082,23083],{"class":5707,"line":12343},[5705,23084,5795],{"emptyLinePlaceholder":5794},[5705,23086,23087,23089,23092,23094,23096,23098,23100,23102,23104,23106,23108,23110],{"class":5707,"line":12351},[5705,23088,5907],{"class":5718},[5705,23090,23091],{"class":5722}," handleBlur",[5705,23093,8540],{"class":5726},[5705,23095,22361],{"class":5741},[5705,23097,5745],{"class":5726},[5705,23099,22317],{"class":5718},[5705,23101,8342],{"class":5748},[5705,23103,8337],{"class":5726},[5705,23105,5955],{"class":5718},[5705,23107,6064],{"class":5726},[5705,23109,5955],{"class":5718},[5705,23111,6069],{"class":5726},[5705,23113,23114,23117,23119,23121,23123,23125,23127,23129,23131,23133,23136],{"class":5707,"line":12364},[5705,23115,23116],{"class":5722},"    setTouched",[5705,23118,9039],{"class":5726},[5705,23120,8330],{"class":5741},[5705,23122,8337],{"class":5726},[5705,23124,5955],{"class":5718},[5705,23126,22993],{"class":5726},[5705,23128,8330],{"class":5741},[5705,23130,5580],{"class":5726},[5705,23132,23000],{"class":5741},[5705,23134,23135],{"class":5718}," true",[5705,23137,23006],{"class":5726},[5705,23139,23140],{"class":5707,"line":12400},[5705,23141,8714],{"class":5726},[5705,23143,23144],{"class":5707,"line":12410},[5705,23145,5795],{"emptyLinePlaceholder":5794},[5705,23147,23148,23150,23153,23155,23157,23159,23161,23163,23165,23167,23169,23171,23173,23175,23177,23179,23181,23183,23185,23187,23189,23191],{"class":5707,"line":12425},[5705,23149,5907],{"class":5718},[5705,23151,23152],{"class":5722}," handleSubmit",[5705,23154,8540],{"class":5726},[5705,23156,22424],{"class":5722},[5705,23158,10150],{"class":5726},[5705,23160,22429],{"class":5741},[5705,23162,5745],{"class":5726},[5705,23164,5766],{"class":5748},[5705,23166,8337],{"class":5726},[5705,23168,5955],{"class":5718},[5705,23170,8350],{"class":5748},[5705,23172,8337],{"class":5726},[5705,23174,5955],{"class":5718},[5705,23176,7055],{"class":5726},[5705,23178,9623],{"class":5741},[5705,23180,5745],{"class":5726},[5705,23182,2303],{"class":5748},[5705,23184,5622],{"class":5726},[5705,23186,22456],{"class":5748},[5705,23188,8337],{"class":5726},[5705,23190,5955],{"class":5718},[5705,23192,6069],{"class":5726},[5705,23194,23195,23198,23200,23203],{"class":5707,"line":12457},[5705,23196,23197],{"class":5741},"    e",[5705,23199,5622],{"class":5726},[5705,23201,23202],{"class":5722},"preventDefault",[5705,23204,7353],{"class":5726},[5705,23206,23207],{"class":5707,"line":12462},[5705,23208,5795],{"emptyLinePlaceholder":5794},[5705,23210,23211],{"class":5707,"line":12495},[5705,23212,23213],{"class":5711},"    \u002F\u002F Позначаємо всі поля як торкнуті\n",[5705,23215,23216,23218,23221,23223,23225,23227,23229,23231,23233,23235,23237,23239,23241,23243,23245,23247,23249],{"class":5707,"line":12536},[5705,23217,7339],{"class":5718},[5705,23219,23220],{"class":5913}," allTouched",[5705,23222,6525],{"class":5726},[5705,23224,22584],{"class":5741},[5705,23226,5622],{"class":5726},[5705,23228,22589],{"class":5722},[5705,23230,5738],{"class":5726},[5705,23232,20621],{"class":5741},[5705,23234,5609],{"class":5726},[5705,23236,22598],{"class":5722},[5705,23238,9039],{"class":5726},[5705,23240,22603],{"class":5741},[5705,23242,5580],{"class":5726},[5705,23244,8421],{"class":5741},[5705,23246,8337],{"class":5726},[5705,23248,5955],{"class":5718},[5705,23250,6069],{"class":5726},[5705,23252,23253,23256,23258,23260,23262,23264,23266,23268,23270],{"class":5707,"line":12545},[5705,23254,23255],{"class":5741},"      acc",[5705,23257,22552],{"class":5726},[5705,23259,8421],{"class":5741},[5705,23261,22625],{"class":6060},[5705,23263,22628],{"class":5718},[5705,23265,8342],{"class":5748},[5705,23267,5922],{"class":5726},[5705,23269,5979],{"class":5718},[5705,23271,6138],{"class":5726},[5705,23273,23274,23276,23278],{"class":5707,"line":12550},[5705,23275,8428],{"class":6060},[5705,23277,22658],{"class":5741},[5705,23279,6138],{"class":5726},[5705,23281,23282,23285,23287,23290,23292,23294,23296,23298,23300,23302,23304],{"class":5707,"line":13481},[5705,23283,23284],{"class":5726},"    }, {} ",[5705,23286,8451],{"class":6060},[5705,23288,23289],{"class":5748}," Partial",[5705,23291,5763],{"class":5726},[5705,23293,20321],{"class":5748},[5705,23295,5763],{"class":5726},[5705,23297,22317],{"class":5718},[5705,23299,8342],{"class":5748},[5705,23301,5580],{"class":5726},[5705,23303,6253],{"class":5748},[5705,23305,23306],{"class":5726},">>);\n",[5705,23308,23309,23311,23313,23316],{"class":5707,"line":13492},[5705,23310,23116],{"class":5722},[5705,23312,5738],{"class":5726},[5705,23314,23315],{"class":5741},"allTouched",[5705,23317,6028],{"class":5726},[5705,23319,23320],{"class":5707,"line":13525},[5705,23321,5795],{"emptyLinePlaceholder":5794},[5705,23323,23324],{"class":5707,"line":13530},[5705,23325,23326],{"class":5711},"    \u002F\u002F Валідуємо всі поля\n",[5705,23328,23329,23331,23334,23336,23338,23340,23342,23344,23346,23348,23350,23352],{"class":5707,"line":13535},[5705,23330,7339],{"class":5718},[5705,23332,23333],{"class":5913}," allErrors",[5705,23335,5745],{"class":5726},[5705,23337,22308],{"class":5748},[5705,23339,5763],{"class":5726},[5705,23341,20321],{"class":5748},[5705,23343,5763],{"class":5726},[5705,23345,22317],{"class":5718},[5705,23347,8342],{"class":5748},[5705,23349,5580],{"class":5726},[5705,23351,5749],{"class":5748},[5705,23353,23354],{"class":5726},">> = {};\n",[5705,23356,23357,23359,23362,23364,23366],{"class":5707,"line":13542},[5705,23358,21275],{"class":5718},[5705,23360,23361],{"class":5741}," hasErrors",[5705,23363,6525],{"class":5726},[5705,23365,5998],{"class":5718},[5705,23367,6138],{"class":5726},[5705,23369,23370],{"class":5707,"line":13558},[5705,23371,5795],{"emptyLinePlaceholder":5794},[5705,23373,23374,23376,23378,23380,23383,23385,23388,23390,23392,23394,23396,23398,23400,23403,23405,23407,23409],{"class":5707,"line":13591},[5705,23375,22870],{"class":6060},[5705,23377,7055],{"class":5726},[5705,23379,15773],{"class":5718},[5705,23381,23382],{"class":5913}," field",[5705,23384,22880],{"class":5718},[5705,23386,23387],{"class":5741}," Object",[5705,23389,5622],{"class":5726},[5705,23391,22589],{"class":5722},[5705,23393,5738],{"class":5726},[5705,23395,20621],{"class":5741},[5705,23397,8337],{"class":5726},[5705,23399,8451],{"class":6060},[5705,23401,23402],{"class":5748}," Array",[5705,23404,5763],{"class":5726},[5705,23406,22317],{"class":5718},[5705,23408,8342],{"class":5748},[5705,23410,23411],{"class":5726},">) {\n",[5705,23413,23414,23416,23418,23420,23422,23424,23426,23428,23430,23432,23434],{"class":5707,"line":13597},[5705,23415,8399],{"class":5718},[5705,23417,23017],{"class":5913},[5705,23419,6525],{"class":5726},[5705,23421,23022],{"class":5722},[5705,23423,5738],{"class":5726},[5705,23425,22361],{"class":5741},[5705,23427,5580],{"class":5726},[5705,23429,22429],{"class":5741},[5705,23431,22552],{"class":5726},[5705,23433,22361],{"class":5741},[5705,23435,8935],{"class":5726},[5705,23437,23438,23440,23442,23444],{"class":5707,"line":13608},[5705,23439,8757],{"class":6060},[5705,23441,7055],{"class":5726},[5705,23443,5618],{"class":5741},[5705,23445,7479],{"class":5726},[5705,23447,23448,23451,23453,23455,23457,23459],{"class":5707,"line":13614},[5705,23449,23450],{"class":5741},"        allErrors",[5705,23452,22552],{"class":5726},[5705,23454,22361],{"class":5741},[5705,23456,5922],{"class":5726},[5705,23458,5618],{"class":5741},[5705,23460,6138],{"class":5726},[5705,23462,23463,23466,23468,23470],{"class":5707,"line":13654},[5705,23464,23465],{"class":5741},"        hasErrors",[5705,23467,6525],{"class":5726},[5705,23469,5979],{"class":5718},[5705,23471,6138],{"class":5726},[5705,23473,23474],{"class":5707,"line":13686},[5705,23475,7696],{"class":5726},[5705,23477,23478],{"class":5707,"line":13715},[5705,23479,6333],{"class":5726},[5705,23481,23482],{"class":5707,"line":13721},[5705,23483,5795],{"emptyLinePlaceholder":5794},[5705,23485,23486,23488,23490,23493],{"class":5707,"line":13728},[5705,23487,23037],{"class":5722},[5705,23489,5738],{"class":5726},[5705,23491,23492],{"class":5741},"allErrors",[5705,23494,6028],{"class":5726},[5705,23496,23497],{"class":5707,"line":13733},[5705,23498,5795],{"emptyLinePlaceholder":5794},[5705,23500,23501,23503,23505,23508],{"class":5707,"line":13766},[5705,23502,12070],{"class":6060},[5705,23504,7468],{"class":5726},[5705,23506,23507],{"class":5741},"hasErrors",[5705,23509,7479],{"class":5726},[5705,23511,23512,23515,23517,23519],{"class":5707,"line":13775},[5705,23513,23514],{"class":5722},"      onSubmit",[5705,23516,5738],{"class":5726},[5705,23518,22429],{"class":5741},[5705,23520,6028],{"class":5726},[5705,23522,23523],{"class":5707,"line":13780},[5705,23524,6333],{"class":5726},[5705,23526,23527],{"class":5707,"line":18822},[5705,23528,8714],{"class":5726},[5705,23530,23531],{"class":5707,"line":18834},[5705,23532,5795],{"emptyLinePlaceholder":5794},[5705,23534,23535,23537,23540,23542,23544],{"class":5707,"line":18851},[5705,23536,5907],{"class":5718},[5705,23538,23539],{"class":5722}," reset",[5705,23541,21431],{"class":5726},[5705,23543,5955],{"class":5718},[5705,23545,6069],{"class":5726},[5705,23547,23548,23550,23552,23554],{"class":5707,"line":18856},[5705,23549,22982],{"class":5722},[5705,23551,5738],{"class":5726},[5705,23553,22701],{"class":5741},[5705,23555,6028],{"class":5726},[5705,23557,23558,23560],{"class":5707,"line":18861},[5705,23559,23037],{"class":5722},[5705,23561,23562],{"class":5726},"({});\n",[5705,23564,23565,23567],{"class":5707,"line":18869},[5705,23566,23116],{"class":5722},[5705,23568,23562],{"class":5726},[5705,23570,23571],{"class":5707,"line":18881},[5705,23572,8714],{"class":5726},[5705,23574,23575],{"class":5707,"line":18897},[5705,23576,5795],{"emptyLinePlaceholder":5794},[5705,23578,23579,23581,23584,23586,23588,23590,23592,23594,23596,23598,23600,23602,23604],{"class":5707,"line":18902},[5705,23580,5907],{"class":5718},[5705,23582,23583],{"class":5913}," isValid",[5705,23585,6525],{"class":5726},[5705,23587,22584],{"class":5741},[5705,23589,5622],{"class":5726},[5705,23591,22589],{"class":5722},[5705,23593,5738],{"class":5726},[5705,23595,22712],{"class":5741},[5705,23597,5609],{"class":5726},[5705,23599,16199],{"class":5741},[5705,23601,8768],{"class":5726},[5705,23603,16483],{"class":9489},[5705,23605,6138],{"class":5726},[5705,23607,23608],{"class":5707,"line":18907},[5705,23609,5795],{"emptyLinePlaceholder":5794},[5705,23611,23612,23614],{"class":5707,"line":18915},[5705,23613,6132],{"class":6060},[5705,23615,6069],{"class":5726},[5705,23617,23618,23621],{"class":5707,"line":18927},[5705,23619,23620],{"class":5741},"    values",[5705,23622,8298],{"class":5726},[5705,23624,23625,23628],{"class":5707,"line":18938},[5705,23626,23627],{"class":5741},"    errors",[5705,23629,8298],{"class":5726},[5705,23631,23632,23635],{"class":5707,"line":18950},[5705,23633,23634],{"class":5741},"    touched",[5705,23636,8298],{"class":5726},[5705,23638,23639,23642],{"class":5707,"line":18955},[5705,23640,23641],{"class":5741},"    handleChange",[5705,23643,8298],{"class":5726},[5705,23645,23646,23649],{"class":5707,"line":18960},[5705,23647,23648],{"class":5741},"    handleBlur",[5705,23650,8298],{"class":5726},[5705,23652,23653,23656],{"class":5707,"line":18970},[5705,23654,23655],{"class":5741},"    handleSubmit",[5705,23657,8298],{"class":5726},[5705,23659,23660,23663],{"class":5707,"line":18982},[5705,23661,23662],{"class":5741},"    reset",[5705,23664,8298],{"class":5726},[5705,23666,23667,23670],{"class":5707,"line":19000},[5705,23668,23669],{"class":5741},"    isValid",[5705,23671,8298],{"class":5726},[5705,23673,23674],{"class":5707,"line":19005},[5705,23675,8714],{"class":5726},[5705,23677,23678],{"class":5707,"line":19010},[5705,23679,6144],{"class":5726},[5685,23681,7802,23683],{"id":23682},"використання-useform",[5535,23684,22159],{},[5696,23686,23688],{"className":5698,"code":23687,"language":5700,"meta":5701,"style":5701},"interface LoginFormValues {\n  email: string;\n  password: string;\n}\n\nfunction LoginForm() {\n  const { values, errors, touched, handleChange, handleBlur, handleSubmit, reset } =\n    useForm\u003CLoginFormValues>({\n      email: {\n        initialValue: '',\n        rules: [\n          {\n            validate: (value) => value.length > 0,\n            message: \"Email є обов'язковим\",\n          },\n          {\n            validate: (value) => \u002F^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\u002F.test(value),\n            message: 'Некоректний формат email',\n          },\n        ],\n      },\n      password: {\n        initialValue: '',\n        rules: [\n          {\n            validate: (value) => value.length >= 8,\n            message: 'Пароль має містити мінімум 8 символів',\n          },\n        ],\n      },\n    });\n\n  function onSubmit(data: LoginFormValues) {\n    console.log('Відправка форми:', data);\n    \u002F\u002F Виклик API для входу\n    reset();\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit(onSubmit)}>\n      \u003Cdiv className=\"field\">\n        \u003Clabel>Email:\u003C\u002Flabel>\n        \u003Cinput\n          type=\"email\"\n          value={values.email}\n          onChange={(e) => handleChange('email')(e.target.value)}\n          onBlur={handleBlur('email')}\n        \u002F>\n        {touched.email && errors.email && (\n          \u003Cspan className=\"error\">{errors.email}\u003C\u002Fspan>\n        )}\n      \u003C\u002Fdiv>\n\n      \u003Cdiv className=\"field\">\n        \u003Clabel>Пароль:\u003C\u002Flabel>\n        \u003Cinput\n          type=\"password\"\n          value={values.password}\n          onChange={(e) => handleChange('password')(e.target.value)}\n          onBlur={handleBlur('password')}\n        \u002F>\n        {touched.password && errors.password && (\n          \u003Cspan className=\"error\">{errors.password}\u003C\u002Fspan>\n        )}\n      \u003C\u002Fdiv>\n\n      \u003Cbutton type=\"submit\">Увійти\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  );\n}\n",[5535,23689,23690,23699,23709,23720,23724,23728,23737,23775,23787,23794,23803,23811,23816,23844,23854,23858,23862,23937,23946,23950,23955,23959,23966,23974,23980,23984,24011,24020,24024,24028,24032,24036,24040,24057,24077,24082,24088,24092,24096,24102,24127,24142,24160,24166,24176,24193,24234,24253,24258,24281,24311,24318,24326,24330,24344,24361,24367,24376,24393,24432,24450,24454,24476,24506,24512,24520,24524,24549,24557,24561],{"__ignoreMap":5701},[5705,23691,23692,23694,23697],{"class":5707,"line":5708},[5705,23693,7132],{"class":5718},[5705,23695,23696],{"class":5748}," LoginFormValues",[5705,23698,6069],{"class":5726},[5705,23700,23701,23703,23705,23707],{"class":5707,"line":5715},[5705,23702,7846],{"class":5741},[5705,23704,5745],{"class":5726},[5705,23706,5749],{"class":5748},[5705,23708,6138],{"class":5726},[5705,23710,23711,23714,23716,23718],{"class":5707,"line":5730},[5705,23712,23713],{"class":5741},"  password",[5705,23715,5745],{"class":5726},[5705,23717,5749],{"class":5748},[5705,23719,6138],{"class":5726},[5705,23721,23722],{"class":5707,"line":5755},[5705,23723,6144],{"class":5726},[5705,23725,23726],{"class":5707,"line":5791},[5705,23727,5795],{"emptyLinePlaceholder":5794},[5705,23729,23730,23732,23735],{"class":5707,"line":5798},[5705,23731,5719],{"class":5718},[5705,23733,23734],{"class":5722}," LoginForm",[5705,23736,5902],{"class":5726},[5705,23738,23739,23741,23743,23745,23747,23749,23751,23753,23755,23758,23760,23763,23765,23768,23770,23773],{"class":5707,"line":5804},[5705,23740,5907],{"class":5718},[5705,23742,5958],{"class":5726},[5705,23744,22429],{"class":5913},[5705,23746,5580],{"class":5726},[5705,23748,22712],{"class":5913},[5705,23750,5580],{"class":5726},[5705,23752,22751],{"class":5913},[5705,23754,5580],{"class":5726},[5705,23756,23757],{"class":5913},"handleChange",[5705,23759,5580],{"class":5726},[5705,23761,23762],{"class":5913},"handleBlur",[5705,23764,5580],{"class":5726},[5705,23766,23767],{"class":5913},"handleSubmit",[5705,23769,5580],{"class":5726},[5705,23771,23772],{"class":5913},"reset",[5705,23774,10529],{"class":5726},[5705,23776,23777,23780,23782,23785],{"class":5707,"line":5818},[5705,23778,23779],{"class":5722},"    useForm",[5705,23781,5763],{"class":5726},[5705,23783,23784],{"class":5748},"LoginFormValues",[5705,23786,11029],{"class":5726},[5705,23788,23789,23792],{"class":5707,"line":6031},[5705,23790,23791],{"class":5741},"      email:",[5705,23793,6069],{"class":5726},[5705,23795,23796,23799,23801],{"class":5707,"line":6052},[5705,23797,23798],{"class":5741},"        initialValue:",[5705,23800,15140],{"class":6019},[5705,23802,8298],{"class":5726},[5705,23804,23805,23808],{"class":5707,"line":6057},[5705,23806,23807],{"class":5741},"        rules:",[5705,23809,23810],{"class":5726}," [\n",[5705,23812,23813],{"class":5707,"line":6072},[5705,23814,23815],{"class":5726},"          {\n",[5705,23817,23818,23821,23823,23825,23827,23829,23831,23833,23835,23837,23840,23842],{"class":5707,"line":6093},[5705,23819,23820],{"class":5722},"            validate",[5705,23822,5600],{"class":5741},[5705,23824,7055],{"class":5726},[5705,23826,5772],{"class":5741},[5705,23828,8337],{"class":5726},[5705,23830,5955],{"class":5718},[5705,23832,23003],{"class":5741},[5705,23834,5622],{"class":5726},[5705,23836,16199],{"class":5741},[5705,23838,23839],{"class":5726}," > ",[5705,23841,16483],{"class":9489},[5705,23843,8298],{"class":5726},[5705,23845,23846,23849,23852],{"class":5707,"line":6112},[5705,23847,23848],{"class":5741},"            message:",[5705,23850,23851],{"class":6019}," \"Email є обов'язковим\"",[5705,23853,8298],{"class":5726},[5705,23855,23856],{"class":5707,"line":6118},[5705,23857,20896],{"class":5726},[5705,23859,23860],{"class":5707,"line":6124},[5705,23861,23815],{"class":5726},[5705,23863,23864,23866,23868,23870,23872,23874,23876,23880,23884,23888,23891,23894,23898,23901,23903,23905,23907,23909,23913,23915,23917,23919,23921,23924,23926,23928,23931,23933,23935],{"class":5707,"line":6129},[5705,23865,23820],{"class":5722},[5705,23867,5600],{"class":5741},[5705,23869,7055],{"class":5726},[5705,23871,5772],{"class":5741},[5705,23873,8337],{"class":5726},[5705,23875,5955],{"class":5718},[5705,23877,23879],{"class":23878},"shsrj"," \u002F",[5705,23881,23883],{"class":23882},"siofk","^",[5705,23885,23887],{"class":23886},"sAV2Q","[^",[5705,23889,23890],{"class":23878},"\\s@",[5705,23892,23893],{"class":23886},"]",[5705,23895,23897],{"class":23896},"sYsli","+",[5705,23899,23900],{"class":23878},"@",[5705,23902,23887],{"class":23886},[5705,23904,23890],{"class":23878},[5705,23906,23893],{"class":23886},[5705,23908,23897],{"class":23896},[5705,23910,23912],{"class":23911},"sjcCO","\\.",[5705,23914,23887],{"class":23886},[5705,23916,23890],{"class":23878},[5705,23918,23893],{"class":23886},[5705,23920,23897],{"class":23896},[5705,23922,23923],{"class":23882},"$",[5705,23925,13813],{"class":23878},[5705,23927,5622],{"class":5726},[5705,23929,23930],{"class":5722},"test",[5705,23932,5738],{"class":5726},[5705,23934,5772],{"class":5741},[5705,23936,14420],{"class":5726},[5705,23938,23939,23941,23944],{"class":5707,"line":6141},[5705,23940,23848],{"class":5741},[5705,23942,23943],{"class":6019}," 'Некоректний формат email'",[5705,23945,8298],{"class":5726},[5705,23947,23948],{"class":5707,"line":6389},[5705,23949,20896],{"class":5726},[5705,23951,23952],{"class":5707,"line":6408},[5705,23953,23954],{"class":5726},"        ],\n",[5705,23956,23957],{"class":5707,"line":6413},[5705,23958,21671],{"class":5726},[5705,23960,23961,23964],{"class":5707,"line":6419},[5705,23962,23963],{"class":5741},"      password:",[5705,23965,6069],{"class":5726},[5705,23967,23968,23970,23972],{"class":5707,"line":6430},[5705,23969,23798],{"class":5741},[5705,23971,15140],{"class":6019},[5705,23973,8298],{"class":5726},[5705,23975,23976,23978],{"class":5707,"line":6449},[5705,23977,23807],{"class":5741},[5705,23979,23810],{"class":5726},[5705,23981,23982],{"class":5707,"line":6468},[5705,23983,23815],{"class":5726},[5705,23985,23986,23988,23990,23992,23994,23996,23998,24000,24002,24004,24006,24009],{"class":5707,"line":6473},[5705,23987,23820],{"class":5722},[5705,23989,5600],{"class":5741},[5705,23991,7055],{"class":5726},[5705,23993,5772],{"class":5741},[5705,23995,8337],{"class":5726},[5705,23997,5955],{"class":5718},[5705,23999,23003],{"class":5741},[5705,24001,5622],{"class":5726},[5705,24003,16199],{"class":5741},[5705,24005,11289],{"class":5726},[5705,24007,24008],{"class":9489},"8",[5705,24010,8298],{"class":5726},[5705,24012,24013,24015,24018],{"class":5707,"line":6482},[5705,24014,23848],{"class":5741},[5705,24016,24017],{"class":6019}," 'Пароль має містити мінімум 8 символів'",[5705,24019,8298],{"class":5726},[5705,24021,24022],{"class":5707,"line":6487},[5705,24023,20896],{"class":5726},[5705,24025,24026],{"class":5707,"line":6496},[5705,24027,23954],{"class":5726},[5705,24029,24030],{"class":5707,"line":7008},[5705,24031,21671],{"class":5726},[5705,24033,24034],{"class":5707,"line":7014},[5705,24035,14580],{"class":5726},[5705,24037,24038],{"class":5707,"line":7020},[5705,24039,5795],{"emptyLinePlaceholder":5794},[5705,24041,24042,24044,24047,24049,24051,24053,24055],{"class":5707,"line":7026},[5705,24043,9026],{"class":5718},[5705,24045,24046],{"class":5722}," onSubmit",[5705,24048,5738],{"class":5726},[5705,24050,5621],{"class":5741},[5705,24052,5745],{"class":5726},[5705,24054,23784],{"class":5748},[5705,24056,7479],{"class":5726},[5705,24058,24059,24062,24064,24066,24068,24071,24073,24075],{"class":5707,"line":7032},[5705,24060,24061],{"class":5741},"    console",[5705,24063,5622],{"class":5726},[5705,24065,12164],{"class":5722},[5705,24067,5738],{"class":5726},[5705,24069,24070],{"class":6019},"'Відправка форми:'",[5705,24072,5580],{"class":5726},[5705,24074,5621],{"class":5741},[5705,24076,6028],{"class":5726},[5705,24078,24079],{"class":5707,"line":7037},[5705,24080,24081],{"class":5711},"    \u002F\u002F Виклик API для входу\n",[5705,24083,24084,24086],{"class":5707,"line":7639},[5705,24085,23662],{"class":5722},[5705,24087,7353],{"class":5726},[5705,24089,24090],{"class":5707,"line":7644},[5705,24091,6940],{"class":5726},[5705,24093,24094],{"class":5707,"line":7654},[5705,24095,5795],{"emptyLinePlaceholder":5794},[5705,24097,24098,24100],{"class":5707,"line":7660},[5705,24099,6132],{"class":6060},[5705,24101,6544],{"class":5726},[5705,24103,24104,24106,24109,24111,24113,24115,24117,24119,24121,24123,24125],{"class":5707,"line":7676},[5705,24105,6550],{"class":6549},[5705,24107,24108],{"class":6553},"form",[5705,24110,24046],{"class":6557},[5705,24112,6561],{"class":5726},[5705,24114,6564],{"class":5718},[5705,24116,23767],{"class":5722},[5705,24118,5738],{"class":7502},[5705,24120,22424],{"class":5741},[5705,24122,9646],{"class":7502},[5705,24124,6587],{"class":5718},[5705,24126,6595],{"class":6549},[5705,24128,24129,24131,24133,24135,24137,24140],{"class":5707,"line":7688},[5705,24130,6775],{"class":6549},[5705,24132,6554],{"class":6553},[5705,24134,6558],{"class":6557},[5705,24136,6561],{"class":5726},[5705,24138,24139],{"class":6019},"\"field\"",[5705,24141,6595],{"class":6549},[5705,24143,24144,24146,24149,24151,24154,24156,24158],{"class":5707,"line":7693},[5705,24145,9712],{"class":6549},[5705,24147,24148],{"class":6553},"label",[5705,24150,6780],{"class":6549},[5705,24152,24153],{"class":5726},"Email:",[5705,24155,6803],{"class":6549},[5705,24157,24148],{"class":6553},[5705,24159,6595],{"class":6549},[5705,24161,24162,24164],{"class":5707,"line":7699},[5705,24163,9712],{"class":6549},[5705,24165,9586],{"class":6553},[5705,24167,24168,24171,24173],{"class":5707,"line":7704},[5705,24169,24170],{"class":6557},"          type",[5705,24172,6561],{"class":5726},[5705,24174,24175],{"class":6019},"\"email\"\n",[5705,24177,24178,24181,24183,24185,24187,24189,24191],{"class":5707,"line":7709},[5705,24179,24180],{"class":6557},"          value",[5705,24182,6561],{"class":5726},[5705,24184,6564],{"class":5718},[5705,24186,22429],{"class":5741},[5705,24188,5622],{"class":7502},[5705,24190,8141],{"class":5741},[5705,24192,6144],{"class":5718},[5705,24194,24195,24198,24200,24202,24204,24206,24208,24210,24212,24214,24217,24220,24222,24224,24226,24228,24230,24232],{"class":5707,"line":7717},[5705,24196,24197],{"class":6557},"          onChange",[5705,24199,6561],{"class":5726},[5705,24201,6564],{"class":5718},[5705,24203,5738],{"class":7502},[5705,24205,9623],{"class":5741},[5705,24207,8337],{"class":7502},[5705,24209,5955],{"class":5718},[5705,24211,22949],{"class":5722},[5705,24213,5738],{"class":7502},[5705,24215,24216],{"class":6019},"'email'",[5705,24218,24219],{"class":7502},")(",[5705,24221,9623],{"class":5741},[5705,24223,5622],{"class":7502},[5705,24225,9639],{"class":5741},[5705,24227,5622],{"class":7502},[5705,24229,5772],{"class":5741},[5705,24231,9646],{"class":7502},[5705,24233,6144],{"class":5718},[5705,24235,24236,24239,24241,24243,24245,24247,24249,24251],{"class":5707,"line":7722},[5705,24237,24238],{"class":6557},"          onBlur",[5705,24240,6561],{"class":5726},[5705,24242,6564],{"class":5718},[5705,24244,23762],{"class":5722},[5705,24246,5738],{"class":7502},[5705,24248,24216],{"class":6019},[5705,24250,9646],{"class":7502},[5705,24252,6144],{"class":5718},[5705,24254,24255],{"class":5707,"line":7728},[5705,24256,24257],{"class":6549},"        \u002F>\n",[5705,24259,24260,24262,24264,24266,24268,24270,24273,24275,24277,24279],{"class":5707,"line":7739},[5705,24261,9132],{"class":5718},[5705,24263,22751],{"class":5741},[5705,24265,5622],{"class":7502},[5705,24267,8141],{"class":5741},[5705,24269,9676],{"class":5726},[5705,24271,24272],{"class":5741}," errors",[5705,24274,5622],{"class":7502},[5705,24276,8141],{"class":5741},[5705,24278,9676],{"class":5726},[5705,24280,6544],{"class":7502},[5705,24282,24283,24285,24287,24289,24291,24293,24295,24297,24299,24301,24303,24305,24307,24309],{"class":5707,"line":7752},[5705,24284,10727],{"class":6549},[5705,24286,5705],{"class":6553},[5705,24288,6558],{"class":6557},[5705,24290,6561],{"class":5726},[5705,24292,8013],{"class":6019},[5705,24294,6780],{"class":6549},[5705,24296,6564],{"class":5718},[5705,24298,22712],{"class":5741},[5705,24300,5622],{"class":7502},[5705,24302,8141],{"class":5741},[5705,24304,6587],{"class":5718},[5705,24306,6803],{"class":6549},[5705,24308,5705],{"class":6553},[5705,24310,6595],{"class":6549},[5705,24312,24313,24316],{"class":5707,"line":7757},[5705,24314,24315],{"class":7502},"        )",[5705,24317,6144],{"class":5718},[5705,24319,24320,24322,24324],{"class":5707,"line":7771},[5705,24321,9157],{"class":6549},[5705,24323,6554],{"class":6553},[5705,24325,6595],{"class":6549},[5705,24327,24328],{"class":5707,"line":7776},[5705,24329,5795],{"emptyLinePlaceholder":5794},[5705,24331,24332,24334,24336,24338,24340,24342],{"class":5707,"line":7796},[5705,24333,6775],{"class":6549},[5705,24335,6554],{"class":6553},[5705,24337,6558],{"class":6557},[5705,24339,6561],{"class":5726},[5705,24341,24139],{"class":6019},[5705,24343,6595],{"class":6549},[5705,24345,24346,24348,24350,24352,24355,24357,24359],{"class":5707,"line":12343},[5705,24347,9712],{"class":6549},[5705,24349,24148],{"class":6553},[5705,24351,6780],{"class":6549},[5705,24353,24354],{"class":5726},"Пароль:",[5705,24356,6803],{"class":6549},[5705,24358,24148],{"class":6553},[5705,24360,6595],{"class":6549},[5705,24362,24363,24365],{"class":5707,"line":12351},[5705,24364,9712],{"class":6549},[5705,24366,9586],{"class":6553},[5705,24368,24369,24371,24373],{"class":5707,"line":12364},[5705,24370,24170],{"class":6557},[5705,24372,6561],{"class":5726},[5705,24374,24375],{"class":6019},"\"password\"\n",[5705,24377,24378,24380,24382,24384,24386,24388,24391],{"class":5707,"line":12400},[5705,24379,24180],{"class":6557},[5705,24381,6561],{"class":5726},[5705,24383,6564],{"class":5718},[5705,24385,22429],{"class":5741},[5705,24387,5622],{"class":7502},[5705,24389,24390],{"class":5741},"password",[5705,24392,6144],{"class":5718},[5705,24394,24395,24397,24399,24401,24403,24405,24407,24409,24411,24413,24416,24418,24420,24422,24424,24426,24428,24430],{"class":5707,"line":12410},[5705,24396,24197],{"class":6557},[5705,24398,6561],{"class":5726},[5705,24400,6564],{"class":5718},[5705,24402,5738],{"class":7502},[5705,24404,9623],{"class":5741},[5705,24406,8337],{"class":7502},[5705,24408,5955],{"class":5718},[5705,24410,22949],{"class":5722},[5705,24412,5738],{"class":7502},[5705,24414,24415],{"class":6019},"'password'",[5705,24417,24219],{"class":7502},[5705,24419,9623],{"class":5741},[5705,24421,5622],{"class":7502},[5705,24423,9639],{"class":5741},[5705,24425,5622],{"class":7502},[5705,24427,5772],{"class":5741},[5705,24429,9646],{"class":7502},[5705,24431,6144],{"class":5718},[5705,24433,24434,24436,24438,24440,24442,24444,24446,24448],{"class":5707,"line":12425},[5705,24435,24238],{"class":6557},[5705,24437,6561],{"class":5726},[5705,24439,6564],{"class":5718},[5705,24441,23762],{"class":5722},[5705,24443,5738],{"class":7502},[5705,24445,24415],{"class":6019},[5705,24447,9646],{"class":7502},[5705,24449,6144],{"class":5718},[5705,24451,24452],{"class":5707,"line":12457},[5705,24453,24257],{"class":6549},[5705,24455,24456,24458,24460,24462,24464,24466,24468,24470,24472,24474],{"class":5707,"line":12462},[5705,24457,9132],{"class":5718},[5705,24459,22751],{"class":5741},[5705,24461,5622],{"class":7502},[5705,24463,24390],{"class":5741},[5705,24465,9676],{"class":5726},[5705,24467,24272],{"class":5741},[5705,24469,5622],{"class":7502},[5705,24471,24390],{"class":5741},[5705,24473,9676],{"class":5726},[5705,24475,6544],{"class":7502},[5705,24477,24478,24480,24482,24484,24486,24488,24490,24492,24494,24496,24498,24500,24502,24504],{"class":5707,"line":12495},[5705,24479,10727],{"class":6549},[5705,24481,5705],{"class":6553},[5705,24483,6558],{"class":6557},[5705,24485,6561],{"class":5726},[5705,24487,8013],{"class":6019},[5705,24489,6780],{"class":6549},[5705,24491,6564],{"class":5718},[5705,24493,22712],{"class":5741},[5705,24495,5622],{"class":7502},[5705,24497,24390],{"class":5741},[5705,24499,6587],{"class":5718},[5705,24501,6803],{"class":6549},[5705,24503,5705],{"class":6553},[5705,24505,6595],{"class":6549},[5705,24507,24508,24510],{"class":5707,"line":12536},[5705,24509,24315],{"class":7502},[5705,24511,6144],{"class":5718},[5705,24513,24514,24516,24518],{"class":5707,"line":12545},[5705,24515,9157],{"class":6549},[5705,24517,6554],{"class":6553},[5705,24519,6595],{"class":6549},[5705,24521,24522],{"class":5707,"line":12550},[5705,24523,5795],{"emptyLinePlaceholder":5794},[5705,24525,24526,24528,24530,24533,24535,24538,24540,24543,24545,24547],{"class":5707,"line":13481},[5705,24527,6775],{"class":6549},[5705,24529,9113],{"class":6553},[5705,24531,24532],{"class":6557}," type",[5705,24534,6561],{"class":5726},[5705,24536,24537],{"class":6019},"\"submit\"",[5705,24539,6780],{"class":6549},[5705,24541,24542],{"class":5726},"Увійти",[5705,24544,6803],{"class":6549},[5705,24546,9113],{"class":6553},[5705,24548,6595],{"class":6549},[5705,24550,24551,24553,24555],{"class":5707,"line":13492},[5705,24552,6619],{"class":6549},[5705,24554,24108],{"class":6553},[5705,24556,6595],{"class":6549},[5705,24558,24559],{"class":5707,"line":13525},[5705,24560,6628],{"class":5726},[5705,24562,24563],{"class":5707,"line":13530},[5705,24564,6144],{"class":5726},[5567,24566],{},[5570,24568,24570],{"id":24569},"найпоширеніші-помилки-при-створенні-кастомних-хуків","Найпоширеніші помилки при створенні кастомних хуків",[5685,24572,24574],{"id":24573},"помилка-1-порушення-правил-хуків","Помилка 1: Порушення правил хуків",[5696,24576,24578],{"className":5698,"code":24577,"language":5700,"meta":5701,"style":5701},"\u002F\u002F ❌ ПОГАНО: хук викликається умовно\nfunction useBadHook(shouldUse: boolean) {\n  if (shouldUse) {\n    const [state, setState] = useState(0); \u002F\u002F Порушення правил!\n    return state;\n  }\n  return null;\n}\n\n\u002F\u002F ✅ ДОБРЕ: хук завжди викликається\nfunction useGoodHook(shouldUse: boolean) {\n  const [state, setState] = useState(0);\n  \n  if (!shouldUse) {\n    return null;\n  }\n  \n  return state;\n}\n",[5535,24579,24580,24585,24603,24613,24640,24649,24653,24661,24665,24669,24674,24691,24713,24717,24727,24735,24739,24743,24751],{"__ignoreMap":5701},[5705,24581,24582],{"class":5707,"line":5708},[5705,24583,24584],{"class":5711},"\u002F\u002F ❌ ПОГАНО: хук викликається умовно\n",[5705,24586,24587,24589,24592,24594,24597,24599,24601],{"class":5707,"line":5715},[5705,24588,5719],{"class":5718},[5705,24590,24591],{"class":5722}," useBadHook",[5705,24593,5738],{"class":5726},[5705,24595,24596],{"class":5741},"shouldUse",[5705,24598,5745],{"class":5726},[5705,24600,6253],{"class":5748},[5705,24602,7479],{"class":5726},[5705,24604,24605,24607,24609,24611],{"class":5707,"line":5730},[5705,24606,7945],{"class":6060},[5705,24608,7055],{"class":5726},[5705,24610,24596],{"class":5741},[5705,24612,7479],{"class":5726},[5705,24614,24615,24617,24619,24622,24624,24627,24629,24631,24633,24635,24637],{"class":5707,"line":5755},[5705,24616,7339],{"class":5718},[5705,24618,5910],{"class":5726},[5705,24620,24621],{"class":5913},"state",[5705,24623,5580],{"class":5726},[5705,24625,24626],{"class":5913},"setState",[5705,24628,5922],{"class":5726},[5705,24630,5579],{"class":5722},[5705,24632,5738],{"class":5726},[5705,24634,16483],{"class":9489},[5705,24636,5937],{"class":5726},[5705,24638,24639],{"class":5711},"\u002F\u002F Порушення правил!\n",[5705,24641,24642,24644,24647],{"class":5707,"line":5791},[5705,24643,6061],{"class":6060},[5705,24645,24646],{"class":5741}," state",[5705,24648,6138],{"class":5726},[5705,24650,24651],{"class":5707,"line":5798},[5705,24652,6940],{"class":5726},[5705,24654,24655,24657,24659],{"class":5707,"line":5804},[5705,24656,6132],{"class":6060},[5705,24658,22859],{"class":5718},[5705,24660,6138],{"class":5726},[5705,24662,24663],{"class":5707,"line":5818},[5705,24664,6144],{"class":5726},[5705,24666,24667],{"class":5707,"line":6031},[5705,24668,5795],{"emptyLinePlaceholder":5794},[5705,24670,24671],{"class":5707,"line":6052},[5705,24672,24673],{"class":5711},"\u002F\u002F ✅ ДОБРЕ: хук завжди викликається\n",[5705,24675,24676,24678,24681,24683,24685,24687,24689],{"class":5707,"line":6057},[5705,24677,5719],{"class":5718},[5705,24679,24680],{"class":5722}," useGoodHook",[5705,24682,5738],{"class":5726},[5705,24684,24596],{"class":5741},[5705,24686,5745],{"class":5726},[5705,24688,6253],{"class":5748},[5705,24690,7479],{"class":5726},[5705,24692,24693,24695,24697,24699,24701,24703,24705,24707,24709,24711],{"class":5707,"line":6072},[5705,24694,5907],{"class":5718},[5705,24696,5910],{"class":5726},[5705,24698,24621],{"class":5913},[5705,24700,5580],{"class":5726},[5705,24702,24626],{"class":5913},[5705,24704,5922],{"class":5726},[5705,24706,5579],{"class":5722},[5705,24708,5738],{"class":5726},[5705,24710,16483],{"class":9489},[5705,24712,6028],{"class":5726},[5705,24714,24715],{"class":5707,"line":6093},[5705,24716,6895],{"class":5726},[5705,24718,24719,24721,24723,24725],{"class":5707,"line":6112},[5705,24720,7945],{"class":6060},[5705,24722,7468],{"class":5726},[5705,24724,24596],{"class":5741},[5705,24726,7479],{"class":5726},[5705,24728,24729,24731,24733],{"class":5707,"line":6118},[5705,24730,6061],{"class":6060},[5705,24732,22859],{"class":5718},[5705,24734,6138],{"class":5726},[5705,24736,24737],{"class":5707,"line":6124},[5705,24738,6940],{"class":5726},[5705,24740,24741],{"class":5707,"line":6129},[5705,24742,6895],{"class":5726},[5705,24744,24745,24747,24749],{"class":5707,"line":6141},[5705,24746,6132],{"class":6060},[5705,24748,24646],{"class":5741},[5705,24750,6138],{"class":5726},[5705,24752,24753],{"class":5707,"line":6389},[5705,24754,6144],{"class":5726},[5567,24756],{},[5685,24758,24760],{"id":24759},"помилка-2-забування-мемоізації-колбеків","Помилка 2: Забування мемоізації колбеків",[5696,24762,24764],{"className":5698,"code":24763,"language":5700,"meta":5701,"style":5701},"\u002F\u002F ❌ ПОГАНО: новий колбек при кожному рендері\nfunction useBadCallback() {\n  const [count, setCount] = useState(0);\n  \n  \u002F\u002F Ця функція створюється заново при кожному рендері\n  const increment = () => setCount(count + 1);\n  \n  return { count, increment };\n}\n\n\u002F\u002F ✅ ДОБРЕ: мемоізований колбек\nfunction useGoodCallback() {\n  const [count, setCount] = useState(0);\n  \n  const increment = useCallback(() => {\n    setCount((prev) => prev + 1);\n  }, []); \u002F\u002F Стабільне посилання\n  \n  return { count, increment };\n}\n",[5535,24765,24766,24771,24780,24802,24806,24811,24834,24838,24853,24857,24861,24866,24875,24897,24901,24917,24938,24945,24949,24963],{"__ignoreMap":5701},[5705,24767,24768],{"class":5707,"line":5708},[5705,24769,24770],{"class":5711},"\u002F\u002F ❌ ПОГАНО: новий колбек при кожному рендері\n",[5705,24772,24773,24775,24778],{"class":5707,"line":5715},[5705,24774,5719],{"class":5718},[5705,24776,24777],{"class":5722}," useBadCallback",[5705,24779,5902],{"class":5726},[5705,24781,24782,24784,24786,24788,24790,24792,24794,24796,24798,24800],{"class":5707,"line":5730},[5705,24783,5907],{"class":5718},[5705,24785,5910],{"class":5726},[5705,24787,16460],{"class":5913},[5705,24789,5580],{"class":5726},[5705,24791,16465],{"class":5913},[5705,24793,5922],{"class":5726},[5705,24795,5579],{"class":5722},[5705,24797,5738],{"class":5726},[5705,24799,16483],{"class":9489},[5705,24801,6028],{"class":5726},[5705,24803,24804],{"class":5707,"line":5755},[5705,24805,6895],{"class":5726},[5705,24807,24808],{"class":5707,"line":5791},[5705,24809,24810],{"class":5711},"  \u002F\u002F Ця функція створюється заново при кожному рендері\n",[5705,24812,24813,24815,24818,24820,24822,24824,24826,24828,24830,24832],{"class":5707,"line":5798},[5705,24814,5907],{"class":5718},[5705,24816,24817],{"class":5722}," increment",[5705,24819,21431],{"class":5726},[5705,24821,5955],{"class":5718},[5705,24823,16741],{"class":5722},[5705,24825,5738],{"class":5726},[5705,24827,16460],{"class":5741},[5705,24829,10886],{"class":5726},[5705,24831,21456],{"class":9489},[5705,24833,6028],{"class":5726},[5705,24835,24836],{"class":5707,"line":5804},[5705,24837,6895],{"class":5726},[5705,24839,24840,24842,24844,24846,24848,24851],{"class":5707,"line":5818},[5705,24841,6132],{"class":6060},[5705,24843,5958],{"class":5726},[5705,24845,16460],{"class":5741},[5705,24847,5580],{"class":5726},[5705,24849,24850],{"class":5741},"increment",[5705,24852,7793],{"class":5726},[5705,24854,24855],{"class":5707,"line":6031},[5705,24856,6144],{"class":5726},[5705,24858,24859],{"class":5707,"line":6052},[5705,24860,5795],{"emptyLinePlaceholder":5794},[5705,24862,24863],{"class":5707,"line":6057},[5705,24864,24865],{"class":5711},"\u002F\u002F ✅ ДОБРЕ: мемоізований колбек\n",[5705,24867,24868,24870,24873],{"class":5707,"line":6072},[5705,24869,5719],{"class":5718},[5705,24871,24872],{"class":5722}," useGoodCallback",[5705,24874,5902],{"class":5726},[5705,24876,24877,24879,24881,24883,24885,24887,24889,24891,24893,24895],{"class":5707,"line":6093},[5705,24878,5907],{"class":5718},[5705,24880,5910],{"class":5726},[5705,24882,16460],{"class":5913},[5705,24884,5580],{"class":5726},[5705,24886,16465],{"class":5913},[5705,24888,5922],{"class":5726},[5705,24890,5579],{"class":5722},[5705,24892,5738],{"class":5726},[5705,24894,16483],{"class":9489},[5705,24896,6028],{"class":5726},[5705,24898,24899],{"class":5707,"line":6112},[5705,24900,6895],{"class":5726},[5705,24902,24903,24905,24907,24909,24911,24913,24915],{"class":5707,"line":6118},[5705,24904,5907],{"class":5718},[5705,24906,24817],{"class":5913},[5705,24908,6525],{"class":5726},[5705,24910,5873],{"class":5722},[5705,24912,5952],{"class":5726},[5705,24914,5955],{"class":5718},[5705,24916,6069],{"class":5726},[5705,24918,24919,24922,24924,24926,24928,24930,24932,24934,24936],{"class":5707,"line":6124},[5705,24920,24921],{"class":5722},"    setCount",[5705,24923,9039],{"class":5726},[5705,24925,8330],{"class":5741},[5705,24927,8337],{"class":5726},[5705,24929,5955],{"class":5718},[5705,24931,21451],{"class":5741},[5705,24933,10886],{"class":5726},[5705,24935,21456],{"class":9489},[5705,24937,6028],{"class":5726},[5705,24939,24940,24942],{"class":5707,"line":6129},[5705,24941,6476],{"class":5726},[5705,24943,24944],{"class":5711},"\u002F\u002F Стабільне посилання\n",[5705,24946,24947],{"class":5707,"line":6141},[5705,24948,6895],{"class":5726},[5705,24950,24951,24953,24955,24957,24959,24961],{"class":5707,"line":6389},[5705,24952,6132],{"class":6060},[5705,24954,5958],{"class":5726},[5705,24956,16460],{"class":5741},[5705,24958,5580],{"class":5726},[5705,24960,24850],{"class":5741},[5705,24962,7793],{"class":5726},[5705,24964,24965],{"class":5707,"line":6408},[5705,24966,6144],{"class":5726},[5567,24968],{},[5685,24970,24972],{"id":24971},"помилка-3-повернення-нестабільних-обєктів","Помилка 3: Повернення нестабільних об'єктів",[5696,24974,24976],{"className":5698,"code":24975,"language":5700,"meta":5701,"style":5701},"\u002F\u002F ❌ ПОГАНО: новий об'єкт при кожному рендері\nfunction useBadReturn() {\n  const [count, setCount] = useState(0);\n  \n  return {\n    count,\n    increment: () => setCount(count + 1),\n  }; \u002F\u002F Новий об'єкт щоразу — порушує референсну рівність\n}\n\n\u002F\u002F ✅ ДОБРЕ: мемоізований об'єкт\nfunction useGoodReturn() {\n  const [count, setCount] = useState(0);\n  \n  const increment = useCallback(() => {\n    setCount((prev) => prev + 1);\n  }, []);\n  \n  return useMemo(() => ({\n    count,\n    increment,\n  }), [count, increment]);\n}\n",[5535,24977,24978,24983,24992,25014,25018,25024,25031,25054,25062,25066,25070,25075,25084,25106,25110,25126,25146,25150,25154,25167,25173,25179,25192],{"__ignoreMap":5701},[5705,24979,24980],{"class":5707,"line":5708},[5705,24981,24982],{"class":5711},"\u002F\u002F ❌ ПОГАНО: новий об'єкт при кожному рендері\n",[5705,24984,24985,24987,24990],{"class":5707,"line":5715},[5705,24986,5719],{"class":5718},[5705,24988,24989],{"class":5722}," useBadReturn",[5705,24991,5902],{"class":5726},[5705,24993,24994,24996,24998,25000,25002,25004,25006,25008,25010,25012],{"class":5707,"line":5730},[5705,24995,5907],{"class":5718},[5705,24997,5910],{"class":5726},[5705,24999,16460],{"class":5913},[5705,25001,5580],{"class":5726},[5705,25003,16465],{"class":5913},[5705,25005,5922],{"class":5726},[5705,25007,5579],{"class":5722},[5705,25009,5738],{"class":5726},[5705,25011,16483],{"class":9489},[5705,25013,6028],{"class":5726},[5705,25015,25016],{"class":5707,"line":5755},[5705,25017,6895],{"class":5726},[5705,25019,25020,25022],{"class":5707,"line":5791},[5705,25021,6132],{"class":6060},[5705,25023,6069],{"class":5726},[5705,25025,25026,25029],{"class":5707,"line":5798},[5705,25027,25028],{"class":5741},"    count",[5705,25030,8298],{"class":5726},[5705,25032,25033,25036,25038,25040,25042,25044,25046,25048,25050,25052],{"class":5707,"line":5804},[5705,25034,25035],{"class":5722},"    increment",[5705,25037,5600],{"class":5741},[5705,25039,6064],{"class":5726},[5705,25041,5955],{"class":5718},[5705,25043,16741],{"class":5722},[5705,25045,5738],{"class":5726},[5705,25047,16460],{"class":5741},[5705,25049,10886],{"class":5726},[5705,25051,21456],{"class":9489},[5705,25053,14420],{"class":5726},[5705,25055,25056,25059],{"class":5707,"line":5818},[5705,25057,25058],{"class":5726},"  }; ",[5705,25060,25061],{"class":5711},"\u002F\u002F Новий об'єкт щоразу — порушує референсну рівність\n",[5705,25063,25064],{"class":5707,"line":6031},[5705,25065,6144],{"class":5726},[5705,25067,25068],{"class":5707,"line":6052},[5705,25069,5795],{"emptyLinePlaceholder":5794},[5705,25071,25072],{"class":5707,"line":6057},[5705,25073,25074],{"class":5711},"\u002F\u002F ✅ ДОБРЕ: мемоізований об'єкт\n",[5705,25076,25077,25079,25082],{"class":5707,"line":6072},[5705,25078,5719],{"class":5718},[5705,25080,25081],{"class":5722}," useGoodReturn",[5705,25083,5902],{"class":5726},[5705,25085,25086,25088,25090,25092,25094,25096,25098,25100,25102,25104],{"class":5707,"line":6093},[5705,25087,5907],{"class":5718},[5705,25089,5910],{"class":5726},[5705,25091,16460],{"class":5913},[5705,25093,5580],{"class":5726},[5705,25095,16465],{"class":5913},[5705,25097,5922],{"class":5726},[5705,25099,5579],{"class":5722},[5705,25101,5738],{"class":5726},[5705,25103,16483],{"class":9489},[5705,25105,6028],{"class":5726},[5705,25107,25108],{"class":5707,"line":6112},[5705,25109,6895],{"class":5726},[5705,25111,25112,25114,25116,25118,25120,25122,25124],{"class":5707,"line":6118},[5705,25113,5907],{"class":5718},[5705,25115,24817],{"class":5913},[5705,25117,6525],{"class":5726},[5705,25119,5873],{"class":5722},[5705,25121,5952],{"class":5726},[5705,25123,5955],{"class":5718},[5705,25125,6069],{"class":5726},[5705,25127,25128,25130,25132,25134,25136,25138,25140,25142,25144],{"class":5707,"line":6124},[5705,25129,24921],{"class":5722},[5705,25131,9039],{"class":5726},[5705,25133,8330],{"class":5741},[5705,25135,8337],{"class":5726},[5705,25137,5955],{"class":5718},[5705,25139,21451],{"class":5741},[5705,25141,10886],{"class":5726},[5705,25143,21456],{"class":9489},[5705,25145,6028],{"class":5726},[5705,25147,25148],{"class":5707,"line":6129},[5705,25149,6121],{"class":5726},[5705,25151,25152],{"class":5707,"line":6141},[5705,25153,6895],{"class":5726},[5705,25155,25156,25158,25161,25163,25165],{"class":5707,"line":6389},[5705,25157,6132],{"class":6060},[5705,25159,25160],{"class":5722}," useMemo",[5705,25162,5952],{"class":5726},[5705,25164,5955],{"class":5718},[5705,25166,23048],{"class":5726},[5705,25168,25169,25171],{"class":5707,"line":6408},[5705,25170,25028],{"class":5741},[5705,25172,8298],{"class":5726},[5705,25174,25175,25177],{"class":5707,"line":6413},[5705,25176,25035],{"class":5741},[5705,25178,8298],{"class":5726},[5705,25180,25181,25184,25186,25188,25190],{"class":5707,"line":6419},[5705,25182,25183],{"class":5726},"  }), [",[5705,25185,16460],{"class":5741},[5705,25187,5580],{"class":5726},[5705,25189,24850],{"class":5741},[5705,25191,8935],{"class":5726},[5705,25193,25194],{"class":5707,"line":6430},[5705,25195,6144],{"class":5726},[5644,25197,25198,25203,25206,25223],{},[5479,25199,25200],{},[5483,25201,25202],{},"Коли мемоізація справді потрібна:",[5479,25204,25205],{},"У більшості випадків повернення нового об'єкта не є проблемою — React ефективно обробляє зміни. Мемоізація важлива лише коли:",[6642,25207,25208,25214,25220],{},[5506,25209,25210,25211,25213],{},"Хук використовується у залежностях ",[5535,25212,5583],{}," іншого компонента.",[5506,25215,25216,25217,5622],{},"Об'єкт передається як пропс у компонент, обгорнутий у ",[5535,25218,25219],{},"React.memo",[5506,25221,25222],{},"Виклик функції є дорогою операцією (складні обчислення).",[5479,25224,25225,25226,13813,25228,25230],{},"Не оптимізуйте передчасно — додавайте ",[5535,25227,5870],{},[5535,25229,5873],{}," лише за наявності реальних проблем продуктивності.",[5567,25232],{},[5570,25234,25236],{"id":25235},"резюме-переваги-кастомних-хуків","Резюме: переваги кастомних хуків",[5495,25238,25239,25244,25248,25253,25266,25274],{},[5498,25240,25243],{"icon":25241,"title":25242},"i-lucide-recycle","🎯 Повторне використання","Витягуйте повторювану реактивну логіку (стан + ефекти) в окремі функції. Один хук може використовуватися у десятках компонентів без дублювання коду.",[5498,25245,25247],{"icon":4348,"title":25246},"🔒 Інкапсуляція","Компоненти не знають деталей реалізації — вони отримують лише простий API. Зміна логіки хука не впливає на компоненти, що його використовують.",[5498,25249,25252],{"icon":25250,"title":25251},"i-lucide-flask-conical","🧪 Тестованість","Хуки можна тестувати ізольовано без рендерингу компонентів. Тести перевіряють логіку поведінки, а не UI-взаємодію.",[5498,25254,25257,25258,25260,25261,10886,25263,25265],{"icon":25255,"title":25256},"i-lucide-boxes","🧩 Композиційність","Складні хуки будуються з простих через композицію. ",[5535,25259,10108],{}," комбінує ",[5535,25262,9200],{},[5535,25264,5885],{}," без дублювання логіки.",[5498,25267,25269,25270,25273],{"icon":15,"title":25268},"📖 Читабельність","Компоненти виражають намір на високому рівні абстракції: ",[5535,25271,25272],{},"const isOnline = useOnlineStatus()"," замість 20 рядків коду підписок.",[5498,25275,25277],{"icon":92,"title":25276},"⚡ Продуктивність","Правильно написані хуки оптимізують рендеринг через мемоізацію, уникають зайвих ефектів та автоматично очищають ресурси.",[5567,25279],{},[5570,25281,25283],{"id":25282},"підсумок-лекції","Підсумок лекції",[5495,25285,25286,25321],{},[5498,25287,25290],{"icon":25288,"title":25289},"i-lucide-check-circle-2","✅ Ви навчилися",[5503,25291,25292,25298,25301,25312,25315,25318],{},[5506,25293,25294,25295,25297],{},"Створювати кастомні хуки за правилами React (префікс ",[5535,25296,5537],{},", виклик на верхньому рівні).",[5506,25299,25300],{},"Розуміти ізоляцію стану: кожен виклик хука має власний незалежний стан.",[5506,25302,25303,25304,5580,25306,5580,25308,5580,25310,5622],{},"Будувати типізовані хуки для типових сценаріїв: ",[5535,25305,5885],{},[5535,25307,5888],{},[5535,25309,9200],{},[5535,25311,5882],{},[5506,25313,25314],{},"Застосовувати композицію хуків для побудови складних абстракцій із простих.",[5506,25316,25317],{},"Організовувати хуки у великих проєктах через модульну структуру папок.",[5506,25319,25320],{},"Тестувати кастомні хуки ізольовано без рендерингу компонентів.",[5498,25322,25325,25326,25329,25330,25332],{"icon":25323,"title":25324},"i-lucide-arrow-right","🔮 Наступні кроки","У наступній лекції ми вийдемо за межі ядра React та почнемо вивчати ",[5483,25327,25328],{},"екосистему React"," — бібліотеки та інструменти, які використовуються у реальних продакшн-застосунках. Першою темою буде ",[5483,25331,2389],{}," — стандартна бібліотека маршрутизації для створення односторінкових застосунків (SPA) із вкладеними маршрутами, параметрами URL, захищеними роутами та обробкою помилок.",[25334,25335,25336],"style",{},"html pre.shiki code .spJ8K, html code.shiki .spJ8K{--shiki-light:#008000;--shiki-default:#6A9955;--shiki-dark:#6A9955}html pre.shiki code .su1O8, html code.shiki .su1O8{--shiki-light:#0000FF;--shiki-default:#569CD6;--shiki-dark:#569CD6}html pre.shiki code .s8Opu, html code.shiki .s8Opu{--shiki-light:#795E26;--shiki-default:#DCDCAA;--shiki-dark:#DCDCAA}html pre.shiki code .sHH4Y, html code.shiki .sHH4Y{--shiki-light:#000000;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .siwwj, html code.shiki .siwwj{--shiki-light:#001080;--shiki-default:#9CDCFE;--shiki-dark:#9CDCFE}html pre.shiki code .sN1BT, html code.shiki .sN1BT{--shiki-light:#267F99;--shiki-default:#4EC9B0;--shiki-dark:#4EC9B0}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-QsJ, html code.shiki .s-QsJ{--shiki-light:#0070C1;--shiki-default:#4FC1FF;--shiki-dark:#4FC1FF}html pre.shiki code .sbdoH, html code.shiki .sbdoH{--shiki-light:#A31515;--shiki-default:#CE9178;--shiki-dark:#CE9178}html pre.shiki code .s8xlr, html code.shiki .s8xlr{--shiki-light:#AF00DB;--shiki-default:#C586C0;--shiki-dark:#C586C0}html pre.shiki code .s0P7L, html code.shiki .s0P7L{--shiki-light:#800000;--shiki-default:#808080;--shiki-dark:#808080}html pre.shiki code .sKtos, html code.shiki .sKtos{--shiki-light:#800000;--shiki-default:#569CD6;--shiki-dark:#569CD6}html pre.shiki code .sa4r_, html code.shiki .sa4r_{--shiki-light:#E50000;--shiki-default:#9CDCFE;--shiki-dark:#9CDCFE}html pre.shiki code .sD7JJ, html code.shiki .sD7JJ{--shiki-light:#000000FF;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .sJj4R, html code.shiki .sJj4R{--shiki-light:#098658;--shiki-default:#B5CEA8;--shiki-dark:#B5CEA8}html pre.shiki code .sDUd3, html code.shiki .sDUd3{--shiki-light:#0451A5;--shiki-default:#CE9178;--shiki-dark:#CE9178}html pre.shiki code .sqdDX, html code.shiki .sqdDX{--shiki-light:#800000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}html pre.shiki code .shsrj, html code.shiki .shsrj{--shiki-light:#811F3F;--shiki-default:#D16969;--shiki-dark:#D16969}html pre.shiki code .siofk, html code.shiki .siofk{--shiki-light:#EE0000;--shiki-default:#DCDCAA;--shiki-dark:#DCDCAA}html pre.shiki code .sAV2Q, html code.shiki .sAV2Q{--shiki-light:#D16969;--shiki-default:#CE9178;--shiki-dark:#CE9178}html pre.shiki code .sYsli, html code.shiki .sYsli{--shiki-light:#000000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}html pre.shiki code .sjcCO, html code.shiki .sjcCO{--shiki-light:#EE0000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}",{"title":5701,"searchDepth":5715,"depth":5715,"links":25338},[25339,25340,25345,25350,25351,25358,25365,25372,25377,25383,25384,25387,25391,25392,25397,25404,25409,25410],{"id":5572,"depth":5715,"text":5573},{"id":5676,"depth":5715,"text":5677,"children":25341},[25342,25344],{"id":5687,"depth":5730,"text":25343},"Правило 1: Ім'я функції завжди починається з префікса use",{"id":5852,"depth":5730,"text":5853},{"id":6185,"depth":5715,"text":25346,"children":25347},"Базовий приклад: useOnlineStatus — відстеження мережевого з'єднання",[25348,25349],{"id":6203,"depth":5730,"text":6204},{"id":6501,"depth":5730,"text":6502},{"id":6679,"depth":5715,"text":6680},{"id":7078,"depth":5715,"text":25352,"children":25353},"Типізований хук завантаження даних: useFetch",[25354,25356],{"id":7094,"depth":5730,"text":25355},"Реалізація useFetch з повною типізацією",{"id":7801,"depth":5730,"text":25357},"Використання useFetch у компоненті",{"id":8228,"depth":5715,"text":25359,"children":25360},"Хук синхронізації з localStorage: useLocalStorage",[25361,25363],{"id":8240,"depth":5730,"text":25362},"Реалізація useLocalStorage",{"id":8962,"depth":5730,"text":25364},"Використання useLocalStorage",{"id":9196,"depth":5715,"text":25366,"children":25367},"Хук відкладеного виклику: useDebounce",[25368,25370],{"id":9210,"depth":5730,"text":25369},"Реалізація useDebounce",{"id":9427,"depth":5730,"text":25371},"Використання useDebounce для пошуку",{"id":10090,"depth":5715,"text":10091,"children":25373},[25374,25376],{"id":10104,"depth":5730,"text":25375},"Приклад: useSearchWithDebounce — композиція useDebounce та useFetch",{"id":10447,"depth":5730,"text":10448},{"id":10908,"depth":5715,"text":25378,"children":25379},"Хук відстеження розміру вікна: useWindowSize",[25380,25382],{"id":10918,"depth":5730,"text":25381},"Реалізація useWindowSize",{"id":11217,"depth":5730,"text":11218},{"id":11602,"depth":5715,"text":11603},{"id":13844,"depth":5715,"text":13845,"children":25385},[25386],{"id":13851,"depth":5730,"text":13852},{"id":14135,"depth":5715,"text":14136,"children":25388},[25389],{"id":14150,"depth":5730,"text":25390},"Приклад тесту для useDebounce",{"id":14884,"depth":5715,"text":14885},{"id":20256,"depth":5715,"text":20257,"children":25393},[25394,25396],{"id":20266,"depth":5730,"text":25395},"Приклад: useFetchWithConfig",{"id":21496,"depth":5730,"text":21497},{"id":22155,"depth":5715,"text":25398,"children":25399},"Хук для роботи з формами: useForm",[25400,25402],{"id":22165,"depth":5730,"text":25401},"Реалізація useForm",{"id":23682,"depth":5730,"text":25403},"Використання useForm",{"id":24569,"depth":5715,"text":24570,"children":25405},[25406,25407,25408],{"id":24573,"depth":5730,"text":24574},{"id":24759,"depth":5730,"text":24760},{"id":24971,"depth":5730,"text":24972},{"id":25235,"depth":5715,"text":25236},{"id":25282,"depth":5715,"text":25283},"Створення власних хуків для витягування повторюваної логіки: useOnlineStatus, useFetch, useLocalStorage, useDebounce. Правила композиції хуків, типізація TypeScript та архітектурні патерни для масштабованих застосунків.","md",null,{},{"title":5409,"description":25411},"RzM71DNPQPiIWHrLKnQ4pejifotk7k9PhnUD7_aQ86k",[25418,25420],{"title":5405,"path":5406,"stem":5407,"description":25419,"children":-1},"Чотири стратегії усунення непотрібних залежностей: винесення статичного коду, переміщення всередину ефекту, функціональні оновлення стану та розділення ефектів. Практичні рецепти для правильної роботи з exhaustive-deps.",{"title":5413,"path":5414,"stem":5415,"description":25421,"children":-1},"Повний курс клієнтської маршрутизації через React Router v7 у режимі бібліотеки: від базової конфігурації до складних вкладених маршрутів, динамічних параметрів, програмної навігації та обробки помилок.",1794237376093]