[{"data":1,"prerenderedAt":60},["Reactive",2],{"blog-post-markdown-progressive-web-app-documentation-complete-guide":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":34,"related":35},"markdown-progressive-web-app-documentation-complete-guide","Markdown Progressive Web App Documentation: Complete Guide for Interactive Documentation and Offline-First Content Systems","Master Progressive Web App documentation using Markdown for offline-first content delivery, interactive documentation systems, and service worker-powered content management. Learn PWA integration, caching strategies, and offline content optimization.","Progressive Web App documentation using Markdown creates powerful offline-first content delivery systems that provide native app-like experiences while maintaining the simplicity and flexibility…","2025-09-26","Tutorial","Matthew Rathbone","markdown pwa documentation, progressive web app markdown, offline markdown docs, service worker markdown, pwa documentation guide, interactive markdown docs, offline-first documentation, markdown app development",22,"\u003Cp>Progressive Web App documentation using Markdown creates powerful offline-first content delivery systems that provide native app-like experiences while maintaining the simplicity and flexibility of Markdown content creation. By combining service worker caching strategies, responsive design principles, and interactive documentation features, technical teams can build sophisticated documentation platforms that function seamlessly across devices and network conditions while delivering rich, engaging user experiences.\u003C/p>\n\u003Ch2 id=\"why-master-pwa-powered-markdown-documentation\">Why Master PWA-Powered Markdown Documentation?\u003C/h2>\n\u003Cp>Progressive Web App integration provides transformative documentation capabilities:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Offline Accessibility\u003C/strong>: Access complete documentation without internet connectivity through intelligent caching\u003C/li>\n\u003Cli>\u003Cstrong>Native App Experience\u003C/strong>: Install documentation as standalone applications with app-like navigation and performance\u003C/li>\n\u003Cli>\u003Cstrong>Cross-Platform Consistency\u003C/strong>: Deliver identical experiences across desktop, mobile, and tablet devices\u003C/li>\n\u003Cli>\u003Cstrong>Performance Optimization\u003C/strong>: Achieve instant loading through preloading and background sync capabilities\u003C/li>\n\u003Cli>\u003Cstrong>Interactive Features\u003C/strong>: Integrate dynamic search, filtering, and personalization while maintaining Markdown simplicity\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"foundation-pwa-documentation-architecture\">Foundation PWA Documentation Architecture\u003C/h2>\n\u003Ch3 id=\"service-worker-implementation-for-markdown-content\">Service Worker Implementation for Markdown Content\u003C/h3>\n\u003Cp>Setting up intelligent caching and offline functionality for Markdown-based documentation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// sw.js - Service Worker for Markdown PWA Documentation\u003C/span>\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> \u003Cspan class=\"hljs-variable constant_\">CACHE_NAME\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;markdown-docs-v1.2.3&#x27;\u003C/span>;\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> \u003Cspan class=\"hljs-variable constant_\">STATIC_CACHE\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;static-assets-v1&#x27;\u003C/span>;\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> \u003Cspan class=\"hljs-variable constant_\">DYNAMIC_CACHE\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;dynamic-content-v1&#x27;\u003C/span>;\n\n\u003Cspan class=\"hljs-comment\">// Assets to cache immediately\u003C/span>\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> \u003Cspan class=\"hljs-variable constant_\">STATIC_ASSETS\u003C/span> = [\n  \u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>,\n  \u003Cspan class=\"hljs-string\">&#x27;/manifest.json&#x27;\u003C/span>,\n  \u003Cspan class=\"hljs-string\">&#x27;/assets/css/app.css&#x27;\u003C/span>,\n  \u003Cspan class=\"hljs-string\">&#x27;/assets/js/app.js&#x27;\u003C/span>,\n  \u003Cspan class=\"hljs-string\">&#x27;/assets/js/markdown-parser.js&#x27;\u003C/span>,\n  \u003Cspan class=\"hljs-string\">&#x27;/assets/fonts/inter-var.woff2&#x27;\u003C/span>,\n  \u003Cspan class=\"hljs-string\">&#x27;/assets/icons/icon-192.png&#x27;\u003C/span>,\n  \u003Cspan class=\"hljs-string\">&#x27;/assets/icons/icon-512.png&#x27;\u003C/span>,\n  \u003Cspan class=\"hljs-string\">&#x27;/offline.html&#x27;\u003C/span>\n];\n\n\u003Cspan class=\"hljs-comment\">// Markdown content patterns to cache\u003C/span>\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> \u003Cspan class=\"hljs-variable constant_\">CONTENT_PATTERNS\u003C/span> = [\n  \u003Cspan class=\"hljs-regexp\">/^\\/docs\\//\u003C/span>,\n  \u003Cspan class=\"hljs-regexp\">/^\\/guides\\//\u003C/span>,\n  \u003Cspan class=\"hljs-regexp\">/^\\/api\\//\u003C/span>,\n  \u003Cspan class=\"hljs-regexp\">/\\.md$/\u003C/span>\n];\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownPWAServiceWorker\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupEventListeners\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">contentCache\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Map\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">lastSync\u003C/span> = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupEventListeners\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    self.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;install&#x27;\u003C/span>, \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">handleInstall\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>));\n    self.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;activate&#x27;\u003C/span>, \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">handleActivate\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>));\n    self.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;fetch&#x27;\u003C/span>, \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">handleFetch\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>));\n    self.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;sync&#x27;\u003C/span>, \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">handleBackgroundSync\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>));\n    self.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;push&#x27;\u003C/span>, \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">handlePushNotification\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>));\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handleInstall\u003C/span>(\u003Cspan class=\"hljs-params\">event\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Installing Markdown PWA Service Worker...&#x27;\u003C/span>);\n    \n    event.\u003Cspan class=\"hljs-title function_\">waitUntil\u003C/span>(\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">preloadEssentialContent\u003C/span>()\n    );\n    \n    \u003Cspan class=\"hljs-comment\">// Skip waiting to activate immediately\u003C/span>\n    self.\u003Cspan class=\"hljs-title function_\">skipWaiting\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">preloadEssentialContent\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-comment\">// Cache static assets\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> staticCache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">STATIC_CACHE\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">await\u003C/span> staticCache.\u003Cspan class=\"hljs-title function_\">addAll\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">STATIC_ASSETS\u003C/span>);\n      \n      \u003Cspan class=\"hljs-comment\">// Cache critical documentation pages\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> criticalPages = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">getCriticalDocumentationPages\u003C/span>();\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> dynamicCache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">DYNAMIC_CACHE\u003C/span>);\n      \n      \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> page \u003Cspan class=\"hljs-keyword\">of\u003C/span> criticalPages) {\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n          \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(page);\n          \u003Cspan class=\"hljs-keyword\">if\u003C/span> (response.\u003Cspan class=\"hljs-property\">ok\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">await\u003C/span> dynamicCache.\u003Cspan class=\"hljs-title function_\">put\u003C/span>(page, response.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>());\n          }\n        } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n          \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">`Failed to preload \u003Cspan class=\"hljs-subst\">${page}\u003C/span>:`\u003C/span>, error);\n        }\n      }\n      \n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Essential content preloaded successfully&#x27;\u003C/span>);\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Failed to preload content:&#x27;\u003C/span>, error);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">getCriticalDocumentationPages\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Define critical pages for offline access\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> [\n      \u003Cspan class=\"hljs-string\">&#x27;/docs/getting-started/&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-string\">&#x27;/docs/installation/&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-string\">&#x27;/docs/quick-reference/&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-string\">&#x27;/docs/troubleshooting/&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-string\">&#x27;/api/reference/&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-string\">&#x27;/guides/best-practices/&#x27;\u003C/span>\n    ];\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handleActivate\u003C/span>(\u003Cspan class=\"hljs-params\">event\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Activating Markdown PWA Service Worker...&#x27;\u003C/span>);\n    \n    event.\u003Cspan class=\"hljs-title function_\">waitUntil\u003C/span>(\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">cleanupOldCaches\u003C/span>()\n    );\n    \n    \u003Cspan class=\"hljs-comment\">// Take control of all pages immediately\u003C/span>\n    self.\u003Cspan class=\"hljs-property\">clients\u003C/span>.\u003Cspan class=\"hljs-title function_\">claim\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">cleanupOldCaches\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> cacheNames = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">keys\u003C/span>();\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> validCaches = [\u003Cspan class=\"hljs-variable constant_\">STATIC_CACHE\u003C/span>, \u003Cspan class=\"hljs-variable constant_\">DYNAMIC_CACHE\u003C/span>, \u003Cspan class=\"hljs-variable constant_\">CACHE_NAME\u003C/span>];\n    \n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> cleanupPromises = cacheNames\n      .\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">cacheName\u003C/span> =&gt;\u003C/span> !validCaches.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(cacheName))\n      .\u003Cspan class=\"hljs-title function_\">map\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">cacheName\u003C/span> =&gt;\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">delete\u003C/span>(cacheName));\n    \n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>.\u003Cspan class=\"hljs-title function_\">all\u003C/span>(cleanupPromises);\n    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Old caches cleaned up&#x27;\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handleFetch\u003C/span>(\u003Cspan class=\"hljs-params\">event\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> { request } = event;\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> url = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title function_\">URL\u003C/span>(request.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n    \n    \u003Cspan class=\"hljs-comment\">// Handle different types of requests\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isStaticAsset\u003C/span>(url)) {\n      event.\u003Cspan class=\"hljs-title function_\">respondWith\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleStaticAssetRequest\u003C/span>(request));\n    } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isMarkdownContent\u003C/span>(url)) {\n      event.\u003Cspan class=\"hljs-title function_\">respondWith\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleMarkdownContentRequest\u003C/span>(request));\n    } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isAPIRequest\u003C/span>(url)) {\n      event.\u003Cspan class=\"hljs-title function_\">respondWith\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleAPIRequest\u003C/span>(request));\n    } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n      event.\u003Cspan class=\"hljs-title function_\">respondWith\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleGenericRequest\u003C/span>(request));\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">isStaticAsset\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> url.\u003Cspan class=\"hljs-property\">pathname\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\.(css|js|png|jpg|jpeg|svg|woff2|ico)$/\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">isMarkdownContent\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-variable constant_\">CONTENT_PATTERNS\u003C/span>.\u003Cspan class=\"hljs-title function_\">some\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">pattern\u003C/span> =&gt;\u003C/span> pattern.\u003Cspan class=\"hljs-title function_\">test\u003C/span>(url.\u003Cspan class=\"hljs-property\">pathname\u003C/span>)) ||\n           url.\u003Cspan class=\"hljs-property\">pathname\u003C/span>.\u003Cspan class=\"hljs-title function_\">endsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.md&#x27;\u003C/span>) ||\n           url.\u003Cspan class=\"hljs-property\">pathname\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/docs/&#x27;\u003C/span>) ||\n           url.\u003Cspan class=\"hljs-property\">pathname\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/guides/&#x27;\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">isAPIRequest\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> url.\u003Cspan class=\"hljs-property\">pathname\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/api/&#x27;\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handleStaticAssetRequest\u003C/span>(\u003Cspan class=\"hljs-params\">request\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Cache-first strategy for static assets\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">STATIC_CACHE\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cachedResponse = \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(request);\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (cachedResponse) {\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> cachedResponse;\n      }\n      \n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> networkResponse = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(request);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (networkResponse.\u003Cspan class=\"hljs-property\">ok\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">put\u003C/span>(request, networkResponse.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>());\n      }\n      \n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> networkResponse;\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Static asset fetch failed:&#x27;\u003C/span>, error);\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createErrorResponse\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Static asset unavailable offline&#x27;\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handleMarkdownContentRequest\u003C/span>(\u003Cspan class=\"hljs-params\">request\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Stale-while-revalidate strategy for content\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">DYNAMIC_CACHE\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cachedResponse = \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(request);\n      \n      \u003Cspan class=\"hljs-comment\">// Return cached version immediately if available\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (cachedResponse) {\n        \u003Cspan class=\"hljs-comment\">// Update in background\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">updateContentInBackground\u003C/span>(request, cache);\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> cachedResponse;\n      }\n      \n      \u003Cspan class=\"hljs-comment\">// Fetch from network if not cached\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> networkResponse = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(request);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (networkResponse.\u003Cspan class=\"hljs-property\">ok\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">put\u003C/span>(request, networkResponse.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>());\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> networkResponse;\n      }\n      \n      \u003Cspan class=\"hljs-keyword\">throw\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Network request failed&#x27;\u003C/span>);\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Content fetch failed:&#x27;\u003C/span>, error);\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createOfflineContentResponse\u003C/span>(request);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">updateContentInBackground\u003C/span>(\u003Cspan class=\"hljs-params\">request, cache\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> networkResponse = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(request);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (networkResponse.\u003Cspan class=\"hljs-property\">ok\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">put\u003C/span>(request, networkResponse.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>());\n        \n        \u003Cspan class=\"hljs-comment\">// Notify clients of updated content\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">notifyClientsOfUpdate\u003C/span>(request.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n      }\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Background update failed:&#x27;\u003C/span>, error);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handleAPIRequest\u003C/span>(\u003Cspan class=\"hljs-params\">request\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Network-first strategy for API requests\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> networkResponse = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(request);\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (networkResponse.\u003Cspan class=\"hljs-property\">ok\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Cache successful API responses\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">DYNAMIC_CACHE\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">put\u003C/span>(request, networkResponse.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>());\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> networkResponse;\n      }\n      \n      \u003Cspan class=\"hljs-keyword\">throw\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;API request failed&#x27;\u003C/span>);\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-comment\">// Fallback to cached API response\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">DYNAMIC_CACHE\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cachedResponse = \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(request);\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (cachedResponse) {\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> cachedResponse;\n      }\n      \n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createErrorResponse\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;API unavailable offline&#x27;\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handleGenericRequest\u003C/span>(\u003Cspan class=\"hljs-params\">request\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Default strategy for other requests\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(request);\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-comment\">// Fallback to offline page for navigation requests\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (request.\u003Cspan class=\"hljs-property\">mode\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;navigate&#x27;\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">STATIC_CACHE\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/offline.html&#x27;\u003C/span>);\n      }\n      \n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createErrorResponse\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Content unavailable offline&#x27;\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">createOfflineContentResponse\u003C/span>(\u003Cspan class=\"hljs-params\">request\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> offlineContent = \u003Cspan class=\"hljs-string\">`\n      &lt;!DOCTYPE html&gt;\n      &lt;html lang=&quot;en&quot;&gt;\n      &lt;head&gt;\n        &lt;meta charset=&quot;UTF-8&quot;&gt;\n        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;\n        &lt;title&gt;Offline Content&lt;/title&gt;\n        &lt;style&gt;\n          body { font-family: system-ui, sans-serif; margin: 2rem; }\n          .offline-notice { background: #fef3cd; padding: 1rem; border-radius: 4px; }\n        &lt;/style&gt;\n      &lt;/head&gt;\n      &lt;body&gt;\n        &lt;div class=&quot;offline-notice&quot;&gt;\n          &lt;h1&gt;Content Temporarily Unavailable&lt;/h1&gt;\n          &lt;p&gt;This page is not available offline. Please check your connection and try again.&lt;/p&gt;\n          &lt;p&gt;&lt;strong&gt;Requested:&lt;/strong&gt; \u003Cspan class=\"hljs-subst\">${request.url}\u003C/span>&lt;/p&gt;\n          &lt;button onclick=&quot;location.reload()&quot;&gt;Try Again&lt;/button&gt;\n        &lt;/div&gt;\n      &lt;/body&gt;\n      &lt;/html&gt;\n    `\u003C/span>;\n    \n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Response\u003C/span>(offlineContent, {\n      \u003Cspan class=\"hljs-attr\">headers\u003C/span>: { \u003Cspan class=\"hljs-string\">&#x27;Content-Type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;text/html&#x27;\u003C/span> }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">createErrorResponse\u003C/span>(\u003Cspan class=\"hljs-params\">message\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Response\u003C/span>(\u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">stringify\u003C/span>({ \u003Cspan class=\"hljs-attr\">error\u003C/span>: message }), {\n      \u003Cspan class=\"hljs-attr\">status\u003C/span>: \u003Cspan class=\"hljs-number\">503\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">headers\u003C/span>: { \u003Cspan class=\"hljs-string\">&#x27;Content-Type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;application/json&#x27;\u003C/span> }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">notifyClientsOfUpdate\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    self.\u003Cspan class=\"hljs-property\">clients\u003C/span>.\u003Cspan class=\"hljs-title function_\">matchAll\u003C/span>().\u003Cspan class=\"hljs-title function_\">then\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">clients\u003C/span> =&gt;\u003C/span> {\n      clients.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">client\u003C/span> =&gt;\u003C/span> {\n        client.\u003Cspan class=\"hljs-title function_\">postMessage\u003C/span>({\n          \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;CONTENT_UPDATED&#x27;\u003C/span>,\n          \u003Cspan class=\"hljs-attr\">url\u003C/span>: url,\n          \u003Cspan class=\"hljs-attr\">timestamp\u003C/span>: \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>()\n        });\n      });\n    });\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handleBackgroundSync\u003C/span>(\u003Cspan class=\"hljs-params\">event\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (event.\u003Cspan class=\"hljs-property\">tag\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;content-sync&#x27;\u003C/span>) {\n      event.\u003Cspan class=\"hljs-title function_\">waitUntil\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">syncContent\u003C/span>());\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">syncContent\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Syncing content in background...&#x27;\u003C/span>);\n      \n      \u003Cspan class=\"hljs-comment\">// Get list of content that needs updating\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-variable constant_\">DYNAMIC_CACHE\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cachedRequests = \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">keys\u003C/span>();\n      \n      \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> request \u003Cspan class=\"hljs-keyword\">of\u003C/span> cachedRequests) {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isMarkdownContent\u003C/span>(\u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title function_\">URL\u003C/span>(request.\u003Cspan class=\"hljs-property\">url\u003C/span>))) {\n          \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">updateContentInBackground\u003C/span>(request, cache);\n        }\n      }\n      \n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">lastSync\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Date\u003C/span>();\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Content sync completed&#x27;\u003C/span>);\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Content sync failed:&#x27;\u003C/span>, error);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">handlePushNotification\u003C/span>(\u003Cspan class=\"hljs-params\">event\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> data = event.\u003Cspan class=\"hljs-property\">data\u003C/span>.\u003Cspan class=\"hljs-title function_\">json\u003C/span>();\n    \n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> options = {\n      \u003Cspan class=\"hljs-attr\">body\u003C/span>: data.\u003Cspan class=\"hljs-property\">body\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;New documentation update available&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">icon\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;/assets/icons/icon-192.png&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">badge\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;/assets/icons/badge.png&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">data\u003C/span>: data,\n      \u003Cspan class=\"hljs-attr\">actions\u003C/span>: [\n        {\n          \u003Cspan class=\"hljs-attr\">action\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;view&#x27;\u003C/span>,\n          \u003Cspan class=\"hljs-attr\">title\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;View Update&#x27;\u003C/span>,\n          \u003Cspan class=\"hljs-attr\">icon\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;/assets/icons/view.png&#x27;\u003C/span>\n        },\n        {\n          \u003Cspan class=\"hljs-attr\">action\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;dismiss&#x27;\u003C/span>,\n          \u003Cspan class=\"hljs-attr\">title\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Dismiss&#x27;\u003C/span>\n        }\n      ]\n    };\n    \n    event.\u003Cspan class=\"hljs-title function_\">waitUntil\u003C/span>(\n      self.\u003Cspan class=\"hljs-property\">registration\u003C/span>.\u003Cspan class=\"hljs-title function_\">showNotification\u003C/span>(data.\u003Cspan class=\"hljs-property\">title\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;Documentation Update&#x27;\u003C/span>, options)\n    );\n  }\n}\n\n\u003Cspan class=\"hljs-comment\">// Initialize service worker\u003C/span>\n\u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownPWAServiceWorker\u003C/span>();\n\n\u003Cspan class=\"hljs-comment\">// Handle notification clicks\u003C/span>\nself.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;notificationclick&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">event\u003C/span> =&gt;\u003C/span> {\n  event.\u003Cspan class=\"hljs-property\">notification\u003C/span>.\u003Cspan class=\"hljs-title function_\">close\u003C/span>();\n  \n  \u003Cspan class=\"hljs-keyword\">if\u003C/span> (event.\u003Cspan class=\"hljs-property\">action\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;view&#x27;\u003C/span>) {\n    event.\u003Cspan class=\"hljs-title function_\">waitUntil\u003C/span>(\n      clients.\u003Cspan class=\"hljs-title function_\">openWindow\u003C/span>(event.\u003Cspan class=\"hljs-property\">notification\u003C/span>.\u003Cspan class=\"hljs-property\">data\u003C/span>.\u003Cspan class=\"hljs-property\">url\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>)\n    );\n  }\n});\n\n\u003Cspan class=\"hljs-comment\">// Handle service worker updates\u003C/span>\nself.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">event\u003C/span> =&gt;\u003C/span> {\n  \u003Cspan class=\"hljs-keyword\">if\u003C/span> (event.\u003Cspan class=\"hljs-property\">data\u003C/span> &amp;&amp; event.\u003Cspan class=\"hljs-property\">data\u003C/span>.\u003Cspan class=\"hljs-property\">type\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;SKIP_WAITING&#x27;\u003C/span>) {\n    self.\u003Cspan class=\"hljs-title function_\">skipWaiting\u003C/span>();\n  }\n});\n\u003C/code>\u003C/pre>\u003Ch3 id=\"pwa-manifest-configuration\">PWA Manifest Configuration\u003C/h3>\n\u003Cp>Creating a comprehensive app manifest for documentation PWA:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-json\">\u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;name&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Markdown Documentation Hub&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;short_name&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;MarkdownDocs&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;description&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Comprehensive documentation platform with offline access and interactive features&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;start_url&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/?utm_source=pwa_install&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;display&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;standalone&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;orientation&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;theme_color&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;#2563eb&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;background_color&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;#ffffff&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;scope&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;lang&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;en&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \u003Cspan class=\"hljs-attr\">&quot;dir&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;ltr&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \n  \u003Cspan class=\"hljs-attr\">&quot;icons&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">[\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/icon-72.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;72x72&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/icon-96.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;96x96&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/icon-128.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;128x128&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/icon-144.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;144x144&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/icon-152.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;152x152&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/icon-192.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;192x192&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/icon-384.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;384x384&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/icon-512.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;512x512&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;any&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/maskable-icon-192.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;192x192&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;maskable&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/maskable-icon-512.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;512x512&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;purpose&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;maskable&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n  \u003Cspan class=\"hljs-punctuation\">]\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \n  \u003Cspan class=\"hljs-attr\">&quot;categories&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">[\u003C/span>\u003Cspan class=\"hljs-string\">&quot;productivity&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span> \u003Cspan class=\"hljs-string\">&quot;developer&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span> \u003Cspan class=\"hljs-string\">&quot;education&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">]\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \n  \u003Cspan class=\"hljs-attr\">&quot;shortcuts&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">[\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;name&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Quick Reference&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;short_name&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Reference&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;description&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Access quick reference guide&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;url&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/docs/quick-reference/?utm_source=pwa_shortcut&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;icons&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">[\u003C/span>\n        \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/reference-96.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;96x96&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\n        \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n      \u003Cspan class=\"hljs-punctuation\">]\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;name&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Search Documentation&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;short_name&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Search&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;description&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Search through all documentation&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;url&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/search/?utm_source=pwa_shortcut&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;icons&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">[\u003C/span>\n        \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/search-96.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;96x96&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\n        \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n      \u003Cspan class=\"hljs-punctuation\">]\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;name&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Getting Started&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;short_name&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Start&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;description&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Begin with getting started guide&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;url&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/docs/getting-started/?utm_source=pwa_shortcut&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;icons&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">[\u003C/span>\n        \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/icons/start-96.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;96x96&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n          \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\n        \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n      \u003Cspan class=\"hljs-punctuation\">]\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n  \u003Cspan class=\"hljs-punctuation\">]\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \n  \u003Cspan class=\"hljs-attr\">&quot;screenshots&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">[\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/screenshots/desktop-wide.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;1280x720&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;form_factor&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;wide&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;label&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Documentation interface on desktop&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;src&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/assets/screenshots/mobile-narrow.png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;sizes&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;375x812&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;type&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;image/png&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;form_factor&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;narrow&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;label&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Mobile documentation experience&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n  \u003Cspan class=\"hljs-punctuation\">]\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \n  \u003Cspan class=\"hljs-attr\">&quot;prefer_related_applications&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-literal\">\u003Cspan class=\"hljs-keyword\">false\u003C/span>\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \n  \u003Cspan class=\"hljs-attr\">&quot;protocol_handlers&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">[\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;protocol&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;web+markdowndocs&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;url&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/open?url=%s&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n  \u003Cspan class=\"hljs-punctuation\">]\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n  \n  \u003Cspan class=\"hljs-attr\">&quot;share_target&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n    \u003Cspan class=\"hljs-attr\">&quot;action&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;/share/&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-attr\">&quot;method&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;POST&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-attr\">&quot;enctype&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;multipart/form-data&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n    \u003Cspan class=\"hljs-attr\">&quot;params&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-punctuation\">{\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;title&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;title&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;text&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;text&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">,\u003C/span>\n      \u003Cspan class=\"hljs-attr\">&quot;url&quot;\u003C/span>\u003Cspan class=\"hljs-punctuation\">:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;url&quot;\u003C/span>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n  \u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n\u003Cspan class=\"hljs-punctuation\">}\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"progressive-enhancement-for-markdown-content\">Progressive Enhancement for Markdown Content\u003C/h3>\n\u003Cp>Building responsive, interactive documentation interfaces:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// assets/js/pwa-markdown-app.js - Main PWA application logic\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownPWAApp\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">markdownParser\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownParser\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">searchIndex\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">SearchIndex\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">offlineManager\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">OfflineManager\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">updateManager\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">UpdateManager\u003C/span>();\n    \n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">init\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">init\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Initializing Markdown PWA App...&#x27;\u003C/span>);\n    \n    \u003Cspan class=\"hljs-comment\">// Initialize components\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>.\u003Cspan class=\"hljs-title function_\">all\u003C/span>([\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">registerServiceWorker\u003C/span>(),\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeSearch\u003C/span>(),\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupNavigationHandlers\u003C/span>(),\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeOfflineSupport\u003C/span>(),\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupUpdateNotifications\u003C/span>(),\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeShareSupport\u003C/span>()\n    ]);\n    \n    \u003Cspan class=\"hljs-comment\">// Setup responsive features\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupResponsiveFeatures\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Initialize page-specific functionality\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeCurrentPage\u003C/span>();\n    \n    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Markdown PWA App initialized successfully&#x27;\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">registerServiceWorker\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-string\">&#x27;serviceWorker&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> navigator) {\n      \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> registration = \u003Cspan class=\"hljs-keyword\">await\u003C/span> navigator.\u003Cspan class=\"hljs-property\">serviceWorker\u003C/span>.\u003Cspan class=\"hljs-title function_\">register\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/sw.js&#x27;\u003C/span>, {\n          \u003Cspan class=\"hljs-attr\">scope\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>\n        });\n        \n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Service Worker registered:&#x27;\u003C/span>, registration.\u003Cspan class=\"hljs-property\">scope\u003C/span>);\n        \n        \u003Cspan class=\"hljs-comment\">// Listen for service worker updates\u003C/span>\n        registration.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;updatefound&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n          \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleServiceWorkerUpdate\u003C/span>(registration);\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Listen for messages from service worker\u003C/span>\n        navigator.\u003Cspan class=\"hljs-property\">serviceWorker\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">event\u003C/span> =&gt;\u003C/span> {\n          \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleServiceWorkerMessage\u003C/span>(event);\n        });\n        \n      } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Service Worker registration failed:&#x27;\u003C/span>, error);\n      }\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">handleServiceWorkerUpdate\u003C/span>(\u003Cspan class=\"hljs-params\">registration\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> newWorker = registration.\u003Cspan class=\"hljs-property\">installing\u003C/span>;\n    \n    newWorker.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;statechange&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (newWorker.\u003Cspan class=\"hljs-property\">state\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;installed&#x27;\u003C/span> &amp;&amp; navigator.\u003Cspan class=\"hljs-property\">serviceWorker\u003C/span>.\u003Cspan class=\"hljs-property\">controller\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Show update available notification\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">showUpdateNotification\u003C/span>();\n      }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">handleServiceWorkerMessage\u003C/span>(\u003Cspan class=\"hljs-params\">event\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> { type, url, timestamp } = event.\u003Cspan class=\"hljs-property\">data\u003C/span>;\n    \n    \u003Cspan class=\"hljs-keyword\">switch\u003C/span> (type) {\n      \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;CONTENT_UPDATED&#x27;\u003C/span>:\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleContentUpdate\u003C/span>(url, timestamp);\n        \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n      \u003Cspan class=\"hljs-attr\">default\u003C/span>:\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Unknown service worker message:&#x27;\u003C/span>, event.\u003Cspan class=\"hljs-property\">data\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">handleContentUpdate\u003C/span>(\u003Cspan class=\"hljs-params\">url, timestamp\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Show subtle notification that content has been updated\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> notification = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createUpdateNotification\u003C/span>(url);\n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">body\u003C/span>.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(notification);\n    \n    \u003Cspan class=\"hljs-comment\">// Auto-hide after 5 seconds\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">setTimeout\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      notification.\u003Cspan class=\"hljs-title function_\">remove\u003C/span>();\n    }, \u003Cspan class=\"hljs-number\">5000\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">createUpdateNotification\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> notification = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n    notification.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;update-notification&#x27;\u003C/span>;\n    notification.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = \u003Cspan class=\"hljs-string\">`\n      &lt;div class=&quot;update-content&quot;&gt;\n        &lt;span class=&quot;update-icon&quot;&gt;🔄&lt;/span&gt;\n        &lt;span class=&quot;update-message&quot;&gt;Content updated&lt;/span&gt;\n        &lt;button class=&quot;update-refresh&quot; onclick=&quot;location.reload()&quot;&gt;Refresh&lt;/button&gt;\n        &lt;button class=&quot;update-dismiss&quot; onclick=&quot;this.parentElement.parentElement.remove()&quot;&gt;✕&lt;/button&gt;\n      &lt;/div&gt;\n    `\u003C/span>;\n    \n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> notification;\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">initializeSearch\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-comment\">// Load search index\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">searchIndex\u003C/span>.\u003Cspan class=\"hljs-title function_\">initialize\u003C/span>();\n      \n      \u003Cspan class=\"hljs-comment\">// Setup search functionality\u003C/span>\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupSearchInterface\u003C/span>();\n      \n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Search initialized&#x27;\u003C/span>);\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Search initialization failed:&#x27;\u003C/span>, error);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupSearchInterface\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> searchInput = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;search-input&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> searchResults = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;search-results&#x27;\u003C/span>);\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!searchInput || !searchResults) \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n    \n    \u003Cspan class=\"hljs-keyword\">let\u003C/span> searchTimeout;\n    \n    searchInput.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;input&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-built_in\">clearTimeout\u003C/span>(searchTimeout);\n      \n      searchTimeout = \u003Cspan class=\"hljs-built_in\">setTimeout\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> query = event.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-property\">value\u003C/span>.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>();\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (query.\u003Cspan class=\"hljs-property\">length\u003C/span> &gt;= \u003Cspan class=\"hljs-number\">2\u003C/span>) {\n          \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">performSearch\u003C/span>(query, searchResults);\n        } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n          searchResults.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>;\n          searchResults.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">display\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;none&#x27;\u003C/span>;\n        }\n      }, \u003Cspan class=\"hljs-number\">300\u003C/span>);\n    });\n    \n    \u003Cspan class=\"hljs-comment\">// Setup keyboard navigation\u003C/span>\n    searchInput.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;keydown&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleSearchKeyNavigation\u003C/span>(event, searchResults);\n    });\n    \n    \u003Cspan class=\"hljs-comment\">// Setup search shortcuts\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;keydown&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> ((event.\u003Cspan class=\"hljs-property\">ctrlKey\u003C/span> || event.\u003Cspan class=\"hljs-property\">metaKey\u003C/span>) &amp;&amp; event.\u003Cspan class=\"hljs-property\">key\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;k&#x27;\u003C/span>) {\n        event.\u003Cspan class=\"hljs-title function_\">preventDefault\u003C/span>();\n        searchInput.\u003Cspan class=\"hljs-title function_\">focus\u003C/span>();\n      }\n    });\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">performSearch\u003C/span>(\u003Cspan class=\"hljs-params\">query, resultsContainer\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> results = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">searchIndex\u003C/span>.\u003Cspan class=\"hljs-title function_\">search\u003C/span>(query);\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (results.\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n        resultsContainer.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&lt;div class=&quot;no-results&quot;&gt;No results found&lt;/div&gt;&#x27;\u003C/span>;\n      } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n        resultsContainer.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = results\n          .\u003Cspan class=\"hljs-title function_\">slice\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-number\">10\u003C/span>)\n          .\u003Cspan class=\"hljs-title function_\">map\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">result\u003C/span> =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createSearchResult\u003C/span>(result))\n          .\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>);\n      }\n      \n      resultsContainer.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">display\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;block&#x27;\u003C/span>;\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Search failed:&#x27;\u003C/span>, error);\n      resultsContainer.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&lt;div class=&quot;search-error&quot;&gt;Search temporarily unavailable&lt;/div&gt;&#x27;\u003C/span>;\n      resultsContainer.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">display\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;block&#x27;\u003C/span>;\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">createSearchResult\u003C/span>(\u003Cspan class=\"hljs-params\">result\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">`\n      &lt;div class=&quot;search-result&quot; data-url=&quot;\u003Cspan class=\"hljs-subst\">${result.url}\u003C/span>&quot;&gt;\n        &lt;div class=&quot;result-title&quot;&gt;\n          &lt;a href=&quot;\u003Cspan class=\"hljs-subst\">${result.url}\u003C/span>&quot;&gt;\u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.highlightSearchTerms(result.title, result.highlights)}\u003C/span>&lt;/a&gt;\n        &lt;/div&gt;\n        &lt;div class=&quot;result-excerpt&quot;&gt;\n          \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.highlightSearchTerms(result.excerpt, result.highlights)}\u003C/span>\n        &lt;/div&gt;\n        &lt;div class=&quot;result-meta&quot;&gt;\n          &lt;span class=&quot;result-category&quot;&gt;\u003Cspan class=\"hljs-subst\">${result.category}\u003C/span>&lt;/span&gt;\n          &lt;span class=&quot;result-date&quot;&gt;\u003Cspan class=\"hljs-subst\">${result.lastModified}\u003C/span>&lt;/span&gt;\n        &lt;/div&gt;\n      &lt;/div&gt;\n    `\u003C/span>;\n  }\n\n  \u003Cspan class=\"hljs-title function_\">highlightSearchTerms\u003C/span>(\u003Cspan class=\"hljs-params\">text, highlights\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!highlights || highlights.\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>) \u003Cspan class=\"hljs-keyword\">return\u003C/span> text;\n    \n    \u003Cspan class=\"hljs-keyword\">let\u003C/span> highlightedText = text;\n    highlights.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">term\u003C/span> =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> regex = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">RegExp\u003C/span>(\u003Cspan class=\"hljs-string\">`(\u003Cspan class=\"hljs-subst\">${term}\u003C/span>)`\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;gi&#x27;\u003C/span>);\n      highlightedText = highlightedText.\u003Cspan class=\"hljs-title function_\">replace\u003C/span>(regex, \u003Cspan class=\"hljs-string\">&#x27;&lt;mark&gt;$1&lt;/mark&gt;&#x27;\u003C/span>);\n    });\n    \n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> highlightedText;\n  }\n\n  \u003Cspan class=\"hljs-title function_\">handleSearchKeyNavigation\u003C/span>(\u003Cspan class=\"hljs-params\">event, resultsContainer\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> results = resultsContainer.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.search-result&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> currentlySelected = resultsContainer.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.search-result.selected&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">let\u003C/span> newSelection;\n    \n    \u003Cspan class=\"hljs-keyword\">switch\u003C/span> (event.\u003Cspan class=\"hljs-property\">key\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;ArrowDown&#x27;\u003C/span>:\n        event.\u003Cspan class=\"hljs-title function_\">preventDefault\u003C/span>();\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (currentlySelected) {\n          newSelection = currentlySelected.\u003Cspan class=\"hljs-property\">nextElementSibling\u003C/span> || results[\u003Cspan class=\"hljs-number\">0\u003C/span>];\n        } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n          newSelection = results[\u003Cspan class=\"hljs-number\">0\u003C/span>];\n        }\n        \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n        \n      \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;ArrowUp&#x27;\u003C/span>:\n        event.\u003Cspan class=\"hljs-title function_\">preventDefault\u003C/span>();\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (currentlySelected) {\n          newSelection = currentlySelected.\u003Cspan class=\"hljs-property\">previousElementSibling\u003C/span> || results[results.\u003Cspan class=\"hljs-property\">length\u003C/span> - \u003Cspan class=\"hljs-number\">1\u003C/span>];\n        } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n          newSelection = results[results.\u003Cspan class=\"hljs-property\">length\u003C/span> - \u003Cspan class=\"hljs-number\">1\u003C/span>];\n        }\n        \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n        \n      \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Enter&#x27;\u003C/span>:\n        event.\u003Cspan class=\"hljs-title function_\">preventDefault\u003C/span>();\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (currentlySelected) {\n          \u003Cspan class=\"hljs-keyword\">const\u003C/span> link = currentlySelected.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;a&#x27;\u003C/span>);\n          \u003Cspan class=\"hljs-keyword\">if\u003C/span> (link) link.\u003Cspan class=\"hljs-title function_\">click\u003C/span>();\n        }\n        \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n        \n      \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Escape&#x27;\u003C/span>:\n        event.\u003Cspan class=\"hljs-title function_\">preventDefault\u003C/span>();\n        resultsContainer.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">display\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;none&#x27;\u003C/span>;\n        event.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-title function_\">blur\u003C/span>();\n        \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (newSelection) {\n      results.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">result\u003C/span> =&gt;\u003C/span> result.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">remove\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;selected&#x27;\u003C/span>));\n      newSelection.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">add\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;selected&#x27;\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupNavigationHandlers\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Setup single-page navigation for better performance\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> link = event.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-title function_\">closest\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;a&#x27;\u003C/span>);\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (link &amp;&amp; \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isInternalLink\u003C/span>(link)) {\n        event.\u003Cspan class=\"hljs-title function_\">preventDefault\u003C/span>();\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">navigateToPage\u003C/span>(link.\u003Cspan class=\"hljs-property\">href\u003C/span>);\n      }\n    });\n    \n    \u003Cspan class=\"hljs-comment\">// Handle browser back/forward\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;popstate&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (event.\u003Cspan class=\"hljs-property\">state\u003C/span> &amp;&amp; event.\u003Cspan class=\"hljs-property\">state\u003C/span>.\u003Cspan class=\"hljs-property\">page\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadPage\u003C/span>(event.\u003Cspan class=\"hljs-property\">state\u003C/span>.\u003Cspan class=\"hljs-property\">page\u003C/span>, \u003Cspan class=\"hljs-literal\">false\u003C/span>);\n      }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">isInternalLink\u003C/span>(\u003Cspan class=\"hljs-params\">link\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> link.\u003Cspan class=\"hljs-property\">origin\u003C/span> === \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">origin\u003C/span> &amp;&amp;\n           !link.\u003Cspan class=\"hljs-title function_\">hasAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;download&#x27;\u003C/span>) &amp;&amp;\n           !link.\u003Cspan class=\"hljs-property\">href\u003C/span>.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;#&#x27;\u003C/span>) &amp;&amp;\n           link.\u003Cspan class=\"hljs-title function_\">getAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;target&#x27;\u003C/span>) !== \u003Cspan class=\"hljs-string\">&#x27;_blank&#x27;\u003C/span>;\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">navigateToPage\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-comment\">// Show loading indicator\u003C/span>\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">showLoadingIndicator\u003C/span>();\n      \n      \u003Cspan class=\"hljs-comment\">// Load new page content\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> content = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadPage\u003C/span>(url, \u003Cspan class=\"hljs-literal\">true\u003C/span>);\n      \n      \u003Cspan class=\"hljs-comment\">// Update URL\u003C/span>\n      history.\u003Cspan class=\"hljs-title function_\">pushState\u003C/span>({ \u003Cspan class=\"hljs-attr\">page\u003C/span>: url }, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>, url);\n      \n      \u003Cspan class=\"hljs-comment\">// Hide loading indicator\u003C/span>\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">hideLoadingIndicator\u003C/span>();\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Navigation failed:&#x27;\u003C/span>, error);\n      \u003Cspan class=\"hljs-comment\">// Fallback to regular navigation\u003C/span>\n      \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">href\u003C/span> = url;\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">loadPage\u003C/span>(\u003Cspan class=\"hljs-params\">url, updateHistory = \u003Cspan class=\"hljs-literal\">false\u003C/span>\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(url);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!response.\u003Cspan class=\"hljs-property\">ok\u003C/span>) \u003Cspan class=\"hljs-keyword\">throw\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Page load failed&#x27;\u003C/span>);\n      \n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> html = \u003Cspan class=\"hljs-keyword\">await\u003C/span> response.\u003Cspan class=\"hljs-title function_\">text\u003C/span>();\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> parser = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">DOMParser\u003C/span>();\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> doc = parser.\u003Cspan class=\"hljs-title function_\">parseFromString\u003C/span>(html, \u003Cspan class=\"hljs-string\">&#x27;text/html&#x27;\u003C/span>);\n      \n      \u003Cspan class=\"hljs-comment\">// Extract main content\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> newContent = doc.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;main&#x27;\u003C/span>) || doc.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.content&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> currentContent = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;main&#x27;\u003C/span>) || \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.content&#x27;\u003C/span>);\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (newContent &amp;&amp; currentContent) {\n        currentContent.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = newContent.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span>;\n        \n        \u003Cspan class=\"hljs-comment\">// Update page title\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">title\u003C/span> = doc.\u003Cspan class=\"hljs-property\">title\u003C/span>;\n        \n        \u003Cspan class=\"hljs-comment\">// Re-initialize page-specific features\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeCurrentPage\u003C/span>();\n        \n        \u003Cspan class=\"hljs-comment\">// Scroll to top\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">scrollTo\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-number\">0\u003C/span>);\n      }\n      \n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> html;\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-keyword\">throw\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Error\u003C/span>(\u003Cspan class=\"hljs-string\">`Failed to load page: \u003Cspan class=\"hljs-subst\">${error.message}\u003C/span>`\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">showLoadingIndicator\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> indicator = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;loading-indicator&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (indicator) {\n      indicator.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">display\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;block&#x27;\u003C/span>;\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">hideLoadingIndicator\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> indicator = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;loading-indicator&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (indicator) {\n      indicator.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">display\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;none&#x27;\u003C/span>;\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">initializeOfflineSupport\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Check online/offline status\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">updateOnlineStatus\u003C/span>();\n    \n    \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;online&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">updateOnlineStatus\u003C/span>());\n    \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;offline&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">updateOnlineStatus\u003C/span>());\n    \n    \u003Cspan class=\"hljs-comment\">// Initialize offline content management\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">offlineManager\u003C/span>.\u003Cspan class=\"hljs-title function_\">initialize\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-title function_\">updateOnlineStatus\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> isOnline = navigator.\u003Cspan class=\"hljs-property\">onLine\u003C/span>;\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> statusIndicator = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;online-status&#x27;\u003C/span>);\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (statusIndicator) {\n      statusIndicator.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = isOnline ? \u003Cspan class=\"hljs-string\">&#x27;Online&#x27;\u003C/span> : \u003Cspan class=\"hljs-string\">&#x27;Offline&#x27;\u003C/span>;\n      statusIndicator.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">`online-status \u003Cspan class=\"hljs-subst\">${isOnline ? \u003Cspan class=\"hljs-string\">&#x27;online&#x27;\u003C/span> : \u003Cspan class=\"hljs-string\">&#x27;offline&#x27;\u003C/span>}\u003C/span>`\u003C/span>;\n    }\n    \n    \u003Cspan class=\"hljs-comment\">// Update UI elements based on connectivity\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> offlineOnlyElements = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.offline-only&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> onlineOnlyElements = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.online-only&#x27;\u003C/span>);\n    \n    offlineOnlyElements.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">element\u003C/span> =&gt;\u003C/span> {\n      element.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">display\u003C/span> = isOnline ? \u003Cspan class=\"hljs-string\">&#x27;none&#x27;\u003C/span> : \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>;\n    });\n    \n    onlineOnlyElements.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">element\u003C/span> =&gt;\u003C/span> {\n      element.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">display\u003C/span> = isOnline ? \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span> : \u003Cspan class=\"hljs-string\">&#x27;none&#x27;\u003C/span>;\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupUpdateNotifications\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">updateManager\u003C/span>.\u003Cspan class=\"hljs-title function_\">onUpdateAvailable\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">showUpdateAvailableNotification\u003C/span>();\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">showUpdateAvailableNotification\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> notification = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n    notification.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;app-update-notification&#x27;\u003C/span>;\n    notification.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = \u003Cspan class=\"hljs-string\">`\n      &lt;div class=&quot;update-banner&quot;&gt;\n        &lt;div class=&quot;update-message&quot;&gt;\n          &lt;strong&gt;App Update Available&lt;/strong&gt;\n          &lt;p&gt;A new version of the documentation is ready to install.&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;div class=&quot;update-actions&quot;&gt;\n          &lt;button class=&quot;btn-primary&quot; onclick=&quot;this.updateApp()&quot;&gt;Update Now&lt;/button&gt;\n          &lt;button class=&quot;btn-secondary&quot; onclick=&quot;this.parentElement.parentElement.remove()&quot;&gt;Later&lt;/button&gt;\n        &lt;/div&gt;\n      &lt;/div&gt;\n    `\u003C/span>;\n    \n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">body\u003C/span>.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(notification);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">updateApp\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Send message to service worker to skip waiting\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (navigator.\u003Cspan class=\"hljs-property\">serviceWorker\u003C/span>.\u003Cspan class=\"hljs-property\">controller\u003C/span>) {\n      navigator.\u003Cspan class=\"hljs-property\">serviceWorker\u003C/span>.\u003Cspan class=\"hljs-property\">controller\u003C/span>.\u003Cspan class=\"hljs-title function_\">postMessage\u003C/span>({ \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;SKIP_WAITING&#x27;\u003C/span> });\n    }\n    \n    \u003Cspan class=\"hljs-comment\">// Reload the page\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-title function_\">reload\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupResponsiveFeatures\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Setup responsive navigation\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupMobileNavigation\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Setup responsive tables\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupResponsiveTables\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Setup touch gestures\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupTouchGestures\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupMobileNavigation\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> navToggle = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;nav-toggle&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> navigation = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;navigation&#x27;\u003C/span>);\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (navToggle &amp;&amp; navigation) {\n      navToggle.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n        navigation.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">toggle\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;open&#x27;\u003C/span>);\n        navToggle.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">toggle\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;active&#x27;\u003C/span>);\n      });\n      \n      \u003Cspan class=\"hljs-comment\">// Close navigation when clicking outside\u003C/span>\n      \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!navigation.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(event.\u003Cspan class=\"hljs-property\">target\u003C/span>) &amp;&amp; !navToggle.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(event.\u003Cspan class=\"hljs-property\">target\u003C/span>)) {\n          navigation.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">remove\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;open&#x27;\u003C/span>);\n          navToggle.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">remove\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;active&#x27;\u003C/span>);\n        }\n      });\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupResponsiveTables\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> tables = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;table&#x27;\u003C/span>);\n    \n    tables.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">table\u003C/span> =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-comment\">// Wrap tables for horizontal scrolling on mobile\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!table.\u003Cspan class=\"hljs-property\">parentElement\u003C/span>.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;table-wrapper&#x27;\u003C/span>)) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> wrapper = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n        wrapper.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;table-wrapper&#x27;\u003C/span>;\n        table.\u003Cspan class=\"hljs-property\">parentNode\u003C/span>.\u003Cspan class=\"hljs-title function_\">insertBefore\u003C/span>(wrapper, table);\n        wrapper.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(table);\n      }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupTouchGestures\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">let\u003C/span> startX, startY;\n    \n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;touchstart&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      startX = event.\u003Cspan class=\"hljs-property\">touches\u003C/span>[\u003Cspan class=\"hljs-number\">0\u003C/span>].\u003Cspan class=\"hljs-property\">clientX\u003C/span>;\n      startY = event.\u003Cspan class=\"hljs-property\">touches\u003C/span>[\u003Cspan class=\"hljs-number\">0\u003C/span>].\u003Cspan class=\"hljs-property\">clientY\u003C/span>;\n    }, { \u003Cspan class=\"hljs-attr\">passive\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span> });\n    \n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;touchend&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!startX || !startY) \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n      \n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> endX = event.\u003Cspan class=\"hljs-property\">changedTouches\u003C/span>[\u003Cspan class=\"hljs-number\">0\u003C/span>].\u003Cspan class=\"hljs-property\">clientX\u003C/span>;\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> endY = event.\u003Cspan class=\"hljs-property\">changedTouches\u003C/span>[\u003Cspan class=\"hljs-number\">0\u003C/span>].\u003Cspan class=\"hljs-property\">clientY\u003C/span>;\n      \n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> deltaX = endX - startX;\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> deltaY = endY - startY;\n      \n      \u003Cspan class=\"hljs-comment\">// Detect swipe gestures\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">abs\u003C/span>(deltaX) &gt; \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">abs\u003C/span>(deltaY) &amp;&amp; \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">abs\u003C/span>(deltaX) &gt; \u003Cspan class=\"hljs-number\">50\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (deltaX &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n          \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleSwipeRight\u003C/span>();\n        } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n          \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleSwipeLeft\u003C/span>();\n        }\n      }\n      \n      startX = startY = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n    }, { \u003Cspan class=\"hljs-attr\">passive\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span> });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">handleSwipeRight\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Navigate to previous page or open navigation\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> prevLink = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.pagination .prev&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (prevLink) {\n      prevLink.\u003Cspan class=\"hljs-title function_\">click\u003C/span>();\n    } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> navigation = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;navigation&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (navigation) {\n        navigation.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">add\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;open&#x27;\u003C/span>);\n      }\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">handleSwipeLeft\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Navigate to next page or close navigation\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> nextLink = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.pagination .next&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (nextLink) {\n      nextLink.\u003Cspan class=\"hljs-title function_\">click\u003C/span>();\n    } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> navigation = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;navigation&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (navigation) {\n        navigation.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">remove\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;open&#x27;\u003C/span>);\n      }\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">initializeShareSupport\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (navigator.\u003Cspan class=\"hljs-property\">share\u003C/span>) {\n      \u003Cspan class=\"hljs-comment\">// Add share buttons to content\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> shareButtons = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.share-button&#x27;\u003C/span>);\n      \n      shareButtons.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">button\u003C/span> =&gt;\u003C/span> {\n        button.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n          \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">shareContent\u003C/span>();\n        });\n      });\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">shareContent\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">await\u003C/span> navigator.\u003Cspan class=\"hljs-title function_\">share\u003C/span>({\n        \u003Cspan class=\"hljs-attr\">title\u003C/span>: \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">title\u003C/span>,\n        \u003Cspan class=\"hljs-attr\">text\u003C/span>: \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;meta[name=&quot;description&quot;]&#x27;\u003C/span>)?.\u003Cspan class=\"hljs-property\">content\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>,\n        \u003Cspan class=\"hljs-attr\">url\u003C/span>: \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">href\u003C/span>\n      });\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Sharing failed:&#x27;\u003C/span>, error);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">initializeCurrentPage\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Initialize syntax highlighting\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeSyntaxHighlighting\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Initialize interactive code blocks\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeInteractiveCode\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Initialize table of contents\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeTableOfContents\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Initialize copy code buttons\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeCopyButtons\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-title function_\">initializeSyntaxHighlighting\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-keyword\">typeof\u003C/span> \u003Cspan class=\"hljs-title class_\">Prism\u003C/span> !== \u003Cspan class=\"hljs-string\">&#x27;undefined&#x27;\u003C/span>) {\n      \u003Cspan class=\"hljs-title class_\">Prism\u003C/span>.\u003Cspan class=\"hljs-title function_\">highlightAll\u003C/span>();\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">initializeInteractiveCode\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> codeBlocks = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;pre code&#x27;\u003C/span>);\n    \n    codeBlocks.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">block\u003C/span> =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-comment\">// Add copy button\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> button = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;button&#x27;\u003C/span>);\n      button.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;copy-code-button&#x27;\u003C/span>;\n      button.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Copy&#x27;\u003C/span>;\n      button.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n        navigator.\u003Cspan class=\"hljs-property\">clipboard\u003C/span>.\u003Cspan class=\"hljs-title function_\">writeText\u003C/span>(block.\u003Cspan class=\"hljs-property\">textContent\u003C/span>);\n        button.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Copied!&#x27;\u003C/span>;\n        \u003Cspan class=\"hljs-built_in\">setTimeout\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> button.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Copy&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">2000\u003C/span>);\n      });\n      \n      block.\u003Cspan class=\"hljs-property\">parentElement\u003C/span>.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(button);\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">initializeTableOfContents\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> headings = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;h1, h2, h3, h4, h5, h6&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> tocContainer = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;table-of-contents&#x27;\u003C/span>);\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (headings.\u003Cspan class=\"hljs-property\">length\u003C/span> &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> &amp;&amp; tocContainer) {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> tocList = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;ul&#x27;\u003C/span>);\n      tocList.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;toc-list&#x27;\u003C/span>;\n      \n      headings.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">heading, index\u003C/span>) =&gt;\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> id = heading.\u003Cspan class=\"hljs-property\">id\u003C/span> || \u003Cspan class=\"hljs-string\">`heading-\u003Cspan class=\"hljs-subst\">${index}\u003C/span>`\u003C/span>;\n        heading.\u003Cspan class=\"hljs-property\">id\u003C/span> = id;\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> listItem = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;li&#x27;\u003C/span>);\n        listItem.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">`toc-item toc-\u003Cspan class=\"hljs-subst\">${heading.tagName.toLowerCase()}\u003C/span>`\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> link = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;a&#x27;\u003C/span>);\n        link.\u003Cspan class=\"hljs-property\">href\u003C/span> = \u003Cspan class=\"hljs-string\">`#\u003Cspan class=\"hljs-subst\">${id}\u003C/span>`\u003C/span>;\n        link.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = heading.\u003Cspan class=\"hljs-property\">textContent\u003C/span>;\n        link.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n          event.\u003Cspan class=\"hljs-title function_\">preventDefault\u003C/span>();\n          heading.\u003Cspan class=\"hljs-title function_\">scrollIntoView\u003C/span>({ \u003Cspan class=\"hljs-attr\">behavior\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;smooth&#x27;\u003C/span> });\n        });\n        \n        listItem.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(link);\n        tocList.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(listItem);\n      });\n      \n      tocContainer.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(tocList);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">initializeCopyButtons\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> copyButtons = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.copy-button&#x27;\u003C/span>);\n    \n    copyButtons.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">button\u003C/span> =&gt;\u003C/span> {\n      button.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> targetId = button.\u003Cspan class=\"hljs-title function_\">getAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;data-target&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> target = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C/span>(targetId);\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (target) {\n          navigator.\u003Cspan class=\"hljs-property\">clipboard\u003C/span>.\u003Cspan class=\"hljs-title function_\">writeText\u003C/span>(target.\u003Cspan class=\"hljs-property\">textContent\u003C/span>);\n          button.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Copied!&#x27;\u003C/span>;\n          \u003Cspan class=\"hljs-built_in\">setTimeout\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> button.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Copy&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">2000\u003C/span>);\n        }\n      });\n    });\n  }\n}\n\n\u003Cspan class=\"hljs-comment\">// Supporting classes for PWA functionality\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">SearchIndex\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">index\u003C/span> = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">documents\u003C/span> = [];\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">initialize\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-comment\">// Load search index from cache or network\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/search-index.json&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> data = \u003Cspan class=\"hljs-keyword\">await\u003C/span> response.\u003Cspan class=\"hljs-title function_\">json\u003C/span>();\n      \n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">index\u003C/span> = data.\u003Cspan class=\"hljs-property\">index\u003C/span>;\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">documents\u003C/span> = data.\u003Cspan class=\"hljs-property\">documents\u003C/span>;\n      \n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Search index loaded&#x27;\u003C/span>);\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Failed to load search index:&#x27;\u003C/span>, error);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">search\u003C/span>(\u003Cspan class=\"hljs-params\">query\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">index\u003C/span> || !\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">documents\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> [];\n    }\n\n    \u003Cspan class=\"hljs-comment\">// Simple search implementation\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> results = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">documents\u003C/span>.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">doc\u003C/span> =&gt;\u003C/span> \n      doc.\u003Cspan class=\"hljs-property\">title\u003C/span>.\u003Cspan class=\"hljs-title function_\">toLowerCase\u003C/span>().\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(query.\u003Cspan class=\"hljs-title function_\">toLowerCase\u003C/span>()) ||\n      doc.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">toLowerCase\u003C/span>().\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(query.\u003Cspan class=\"hljs-title function_\">toLowerCase\u003C/span>())\n    );\n\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> results.\u003Cspan class=\"hljs-title function_\">map\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">doc\u003C/span> =&gt;\u003C/span> ({\n      ...doc,\n      \u003Cspan class=\"hljs-attr\">highlights\u003C/span>: [query]\n    }));\n  }\n}\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">OfflineManager\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">cachedPages\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Set\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">initialize\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Load list of cached pages\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-string\">&#x27;caches&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-variable language_\">window\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;dynamic-content-v1&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> cachedRequests = \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">keys\u003C/span>();\n        \n        cachedRequests.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">request\u003C/span> =&gt;\u003C/span> {\n          \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">cachedPages\u003C/span>.\u003Cspan class=\"hljs-title function_\">add\u003C/span>(request.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n        });\n        \n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.cachedPages.size}\u003C/span> pages available offline`\u003C/span>);\n      } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Failed to initialize offline manager:&#x27;\u003C/span>, error);\n      }\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">isPageCached\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">cachedPages\u003C/span>.\u003Cspan class=\"hljs-title function_\">has\u003C/span>(url);\n  }\n}\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">UpdateManager\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">updateCallbacks\u003C/span> = [];\n  }\n\n  \u003Cspan class=\"hljs-title function_\">onUpdateAvailable\u003C/span>(\u003Cspan class=\"hljs-params\">callback\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">updateCallbacks\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(callback);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">notifyUpdateAvailable\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">updateCallbacks\u003C/span>.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">callback\u003C/span> =&gt;\u003C/span> \u003Cspan class=\"hljs-title function_\">callback\u003C/span>());\n  }\n}\n\n\u003Cspan class=\"hljs-comment\">// Initialize the PWA when DOM is ready\u003C/span>\n\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;DOMContentLoaded&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n  \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">markdownPWA\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownPWAApp\u003C/span>();\n});\n\u003C/code>\u003C/pre>\u003Ch2 id=\"advanced-pwa-features-for-documentation\">Advanced PWA Features for Documentation\u003C/h2>\n\u003Ch3 id=\"background-sync-and-content-updates\">Background Sync and Content Updates\u003C/h3>\n\u003Cp>Implementing intelligent background synchronization for documentation content:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// Background sync worker for content updates\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">BackgroundContentSync\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span> = [];\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">lastSyncTime\u003C/span> = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncInterval\u003C/span> = \u003Cspan class=\"hljs-number\">60\u003C/span> * \u003Cspan class=\"hljs-number\">60\u003C/span> * \u003Cspan class=\"hljs-number\">1000\u003C/span>; \u003Cspan class=\"hljs-comment\">// 1 hour\u003C/span>\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">registerBackgroundSync\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-string\">&#x27;serviceWorker&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> navigator &amp;&amp; \u003Cspan class=\"hljs-string\">&#x27;sync&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">ServiceWorkerRegistration\u003C/span>.\u003Cspan class=\"hljs-property\">\u003Cspan class=\"hljs-keyword\">prototype\u003C/span>\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> registration = \u003Cspan class=\"hljs-keyword\">await\u003C/span> navigator.\u003Cspan class=\"hljs-property\">serviceWorker\u003C/span>.\u003Cspan class=\"hljs-property\">ready\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> registration.\u003Cspan class=\"hljs-property\">sync\u003C/span>.\u003Cspan class=\"hljs-title function_\">register\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;content-sync&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Background sync registered&#x27;\u003C/span>);\n      } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Background sync registration failed:&#x27;\u003C/span>, error);\n      }\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">queueContentUpdate\u003C/span>(\u003Cspan class=\"hljs-params\">url, priority = \u003Cspan class=\"hljs-string\">&#x27;normal&#x27;\u003C/span>\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> updateItem = {\n      url,\n      priority,\n      \u003Cspan class=\"hljs-attr\">timestamp\u003C/span>: \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>(),\n      \u003Cspan class=\"hljs-attr\">retryCount\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>\n    };\n\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(updateItem);\n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">saveQueueToStorage\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Try immediate sync if online\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (navigator.\u003Cspan class=\"hljs-property\">onLine\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">processQueue\u003C/span>();\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">processQueue\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>) \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> highPriorityItems = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">item\u003C/span> =&gt;\u003C/span> item.\u003Cspan class=\"hljs-property\">priority\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> normalItems = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">item\u003C/span> =&gt;\u003C/span> item.\u003Cspan class=\"hljs-property\">priority\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;normal&#x27;\u003C/span>);\n    \n    \u003Cspan class=\"hljs-comment\">// Process high priority items first\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> item \u003Cspan class=\"hljs-keyword\">of\u003C/span> [...highPriorityItems, ...normalItems]) {\n      \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">syncContent\u003C/span>(item.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">removeFromQueue\u003C/span>(item);\n      } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">`Sync failed for \u003Cspan class=\"hljs-subst\">${item.url}\u003C/span>:`\u003C/span>, error);\n        item.\u003Cspan class=\"hljs-property\">retryCount\u003C/span>++;\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (item.\u003Cspan class=\"hljs-property\">retryCount\u003C/span> &gt;= \u003Cspan class=\"hljs-number\">3\u003C/span>) {\n          \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">removeFromQueue\u003C/span>(item);\n        }\n      }\n    }\n\n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">saveQueueToStorage\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">syncContent\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(url);\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!response.\u003Cspan class=\"hljs-property\">ok\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">throw\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Error\u003C/span>(\u003Cspan class=\"hljs-string\">`HTTP \u003Cspan class=\"hljs-subst\">${response.status}\u003C/span>: \u003Cspan class=\"hljs-subst\">${response.statusText}\u003C/span>`\u003C/span>);\n    }\n\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;dynamic-content-v1&#x27;\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">put\u003C/span>(url, response.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>());\n    \n    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`Content synced: \u003Cspan class=\"hljs-subst\">${url}\u003C/span>`\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> response;\n  }\n\n  \u003Cspan class=\"hljs-title function_\">removeFromQueue\u003C/span>(\u003Cspan class=\"hljs-params\">item\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> index = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">findIndex\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">qItem\u003C/span> =&gt;\u003C/span> \n      qItem.\u003Cspan class=\"hljs-property\">url\u003C/span> === item.\u003Cspan class=\"hljs-property\">url\u003C/span> &amp;&amp; qItem.\u003Cspan class=\"hljs-property\">timestamp\u003C/span> === item.\u003Cspan class=\"hljs-property\">timestamp\u003C/span>\n    );\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (index &gt; -\u003Cspan class=\"hljs-number\">1\u003C/span>) {\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">splice\u003C/span>(index, \u003Cspan class=\"hljs-number\">1\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">saveQueueToStorage\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-variable language_\">localStorage\u003C/span>.\u003Cspan class=\"hljs-title function_\">setItem\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;sync-queue&#x27;\u003C/span>, \u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">stringify\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span>));\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Failed to save sync queue:&#x27;\u003C/span>, error);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">loadQueueFromStorage\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> stored = \u003Cspan class=\"hljs-variable language_\">localStorage\u003C/span>.\u003Cspan class=\"hljs-title function_\">getItem\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;sync-queue&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (stored) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">syncQueue\u003C/span> = \u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">parse\u003C/span>(stored);\n      }\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Failed to load sync queue:&#x27;\u003C/span>, error);\n    }\n  }\n}\n\u003C/code>\u003C/pre>\u003Ch3 id=\"push-notifications-for-documentation-updates\">Push Notifications for Documentation Updates\u003C/h3>\n\u003Cp>Implementing push notifications for content updates and announcements:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// Push notification manager for documentation updates\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">DocumentationNotificationManager\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">subscription\u003C/span> = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">vapidPublicKey\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;YOUR_VAPID_PUBLIC_KEY&#x27;\u003C/span>; \u003Cspan class=\"hljs-comment\">// Replace with actual key\u003C/span>\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">requestNotificationPermission\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!(\u003Cspan class=\"hljs-string\">&#x27;Notification&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-variable language_\">window\u003C/span>)) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Notifications not supported&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-title class_\">Notification\u003C/span>.\u003Cspan class=\"hljs-property\">permission\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;granted&#x27;\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-title class_\">Notification\u003C/span>.\u003Cspan class=\"hljs-property\">permission\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;denied&#x27;\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> permission = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title class_\">Notification\u003C/span>.\u003Cspan class=\"hljs-title function_\">requestPermission\u003C/span>();\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> permission === \u003Cspan class=\"hljs-string\">&#x27;granted&#x27;\u003C/span>;\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">subscribeToPushNotifications\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> hasPermission = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">requestNotificationPermission\u003C/span>();\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!hasPermission) {\n        \u003Cspan class=\"hljs-keyword\">throw\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Notification permission denied&#x27;\u003C/span>);\n      }\n\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> registration = \u003Cspan class=\"hljs-keyword\">await\u003C/span> navigator.\u003Cspan class=\"hljs-property\">serviceWorker\u003C/span>.\u003Cspan class=\"hljs-property\">ready\u003C/span>;\n      \n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">subscription\u003C/span> = \u003Cspan class=\"hljs-keyword\">await\u003C/span> registration.\u003Cspan class=\"hljs-property\">pushManager\u003C/span>.\u003Cspan class=\"hljs-title function_\">subscribe\u003C/span>({\n        \u003Cspan class=\"hljs-attr\">userVisibleOnly\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n        \u003Cspan class=\"hljs-attr\">applicationServerKey\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">urlBase64ToUint8Array\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">vapidPublicKey\u003C/span>)\n      });\n\n      \u003Cspan class=\"hljs-comment\">// Send subscription to server\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">sendSubscriptionToServer\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">subscription\u003C/span>);\n      \n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Push notification subscription successful&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">subscription\u003C/span>;\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Push notification subscription failed:&#x27;\u003C/span>, error);\n      \u003Cspan class=\"hljs-keyword\">throw\u003C/span> error;\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">unsubscribeFromPushNotifications\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">subscription\u003C/span>) \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">subscription\u003C/span>.\u003Cspan class=\"hljs-title function_\">unsubscribe\u003C/span>();\n      \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">removeSubscriptionFromServer\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">subscription\u003C/span>);\n      \n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">subscription\u003C/span> = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Push notification unsubscription successful&#x27;\u003C/span>);\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Push notification unsubscription failed:&#x27;\u003C/span>, error);\n      \u003Cspan class=\"hljs-keyword\">throw\u003C/span> error;\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">sendSubscriptionToServer\u003C/span>(\u003Cspan class=\"hljs-params\">subscription\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/api/notifications/subscribe&#x27;\u003C/span>, {\n      \u003Cspan class=\"hljs-attr\">method\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;POST&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">headers\u003C/span>: {\n        \u003Cspan class=\"hljs-string\">&#x27;Content-Type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;application/json&#x27;\u003C/span>\n      },\n      \u003Cspan class=\"hljs-attr\">body\u003C/span>: \u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">stringify\u003C/span>({\n        subscription,\n        \u003Cspan class=\"hljs-attr\">preferences\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">getNotificationPreferences\u003C/span>()\n      })\n    });\n\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!response.\u003Cspan class=\"hljs-property\">ok\u003C/span>) {\n      \u003Cspan class=\"hljs-keyword\">throw\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Failed to save subscription on server&#x27;\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">removeSubscriptionFromServer\u003C/span>(\u003Cspan class=\"hljs-params\">subscription\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/api/notifications/unsubscribe&#x27;\u003C/span>, {\n      \u003Cspan class=\"hljs-attr\">method\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;POST&#x27;\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">headers\u003C/span>: {\n        \u003Cspan class=\"hljs-string\">&#x27;Content-Type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;application/json&#x27;\u003C/span>\n      },\n      \u003Cspan class=\"hljs-attr\">body\u003C/span>: \u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">stringify\u003C/span>({ subscription })\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">getNotificationPreferences\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n      \u003Cspan class=\"hljs-attr\">contentUpdates\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">newReleases\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">criticalUpdates\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n      \u003Cspan class=\"hljs-attr\">weeklyDigest\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>\n    };\n  }\n\n  \u003Cspan class=\"hljs-title function_\">urlBase64ToUint8Array\u003C/span>(\u003Cspan class=\"hljs-params\">base64String\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> padding = \u003Cspan class=\"hljs-string\">&#x27;=&#x27;\u003C/span>.\u003Cspan class=\"hljs-title function_\">repeat\u003C/span>((\u003Cspan class=\"hljs-number\">4\u003C/span> - base64String.\u003Cspan class=\"hljs-property\">length\u003C/span> % \u003Cspan class=\"hljs-number\">4\u003C/span>) % \u003Cspan class=\"hljs-number\">4\u003C/span>);\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> base64 = (base64String + padding)\n      .\u003Cspan class=\"hljs-title function_\">replace\u003C/span>(\u003Cspan class=\"hljs-regexp\">/-/g\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;+&#x27;\u003C/span>)\n      .\u003Cspan class=\"hljs-title function_\">replace\u003C/span>(\u003Cspan class=\"hljs-regexp\">/_/g\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>);\n\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> rawData = \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">atob\u003C/span>(base64);\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> outputArray = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Uint8Array\u003C/span>(rawData.\u003Cspan class=\"hljs-property\">length\u003C/span>);\n\n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">let\u003C/span> i = \u003Cspan class=\"hljs-number\">0\u003C/span>; i &lt; rawData.\u003Cspan class=\"hljs-property\">length\u003C/span>; ++i) {\n      outputArray[i] = rawData.\u003Cspan class=\"hljs-title function_\">charCodeAt\u003C/span>(i);\n    }\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> outputArray;\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">setupNotificationHandlers\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Handle notification clicks in main thread\u003C/span>\n    navigator.\u003Cspan class=\"hljs-property\">serviceWorker\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">event\u003C/span> =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (event.\u003Cspan class=\"hljs-property\">data\u003C/span>.\u003Cspan class=\"hljs-property\">type\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;NOTIFICATION_CLICK&#x27;\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleNotificationClick\u003C/span>(event.\u003Cspan class=\"hljs-property\">data\u003C/span>.\u003Cspan class=\"hljs-property\">notification\u003C/span>);\n      }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">handleNotificationClick\u003C/span>(\u003Cspan class=\"hljs-params\">notificationData\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Navigate to relevant documentation page\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (notificationData.\u003Cspan class=\"hljs-property\">url\u003C/span>) {\n      \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">focus\u003C/span>();\n      \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">href\u003C/span> = notificationData.\u003Cspan class=\"hljs-property\">url\u003C/span>;\n    }\n  }\n}\n\u003C/code>\u003C/pre>\u003Ch2 id=\"performance-optimization-and-caching-strategies\">Performance Optimization and Caching Strategies\u003C/h2>\n\u003Cp>Progressive Web App documentation systems require sophisticated performance optimization to deliver native-app experiences. When combined with \u003Ca href=\"/blog/markdown-image-optimization-compression-complete-guide\">image optimization techniques\u003C/a>, PWA documentation platforms can achieve exceptional loading performance through intelligent preloading, compression, and caching strategies that minimize bandwidth usage while maximizing content availability.\u003C/p>\n\u003Cp>For comprehensive content management, PWA documentation complements \u003Ca href=\"/blog/markdown-automation-workflows-complete-guide\">automation workflow systems\u003C/a> by providing client-side caching and offline functionality that ensures documentation remains accessible even when automated update processes are running or network connectivity is limited, creating resilient content delivery systems that support continuous integration and deployment practices.\u003C/p>\n\u003Cp>When building sophisticated user experiences, PWA documentation integrates effectively with \u003Ca href=\"/blog/markdown-table-sorting-filtering-interactive-guide\">interactive table features\u003C/a> and advanced formatting options by implementing service worker caching for dynamic content while maintaining the responsiveness and interactivity that users expect from modern web applications.\u003C/p>\n\u003Ch2 id=\"advanced-caching-and-storage-strategies\">Advanced Caching and Storage Strategies\u003C/h2>\n\u003Ch3 id=\"intelligent-content-prefetching\">Intelligent Content Prefetching\u003C/h3>\n\u003Cp>Implementing predictive content loading based on user behavior:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// Intelligent prefetching system for documentation content\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ContentPrefetcher\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Map\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">userBehaviorTracker\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">UserBehaviorTracker\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchStrategy\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;intelligent&#x27;\u003C/span>; \u003Cspan class=\"hljs-comment\">// &#x27;aggressive&#x27;, &#x27;conservative&#x27;, &#x27;intelligent&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">maxPrefetchItems\u003C/span> = \u003Cspan class=\"hljs-number\">10\u003C/span>;\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchDelay\u003C/span> = \u003Cspan class=\"hljs-number\">2000\u003C/span>; \u003Cspan class=\"hljs-comment\">// ms\u003C/span>\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">initialize\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">userBehaviorTracker\u003C/span>.\u003Cspan class=\"hljs-title function_\">initialize\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupPrefetchTriggers\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">startPrefetchWorker\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupPrefetchTriggers\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Prefetch on hover (desktop)\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;mouseover&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> link = event.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-title function_\">closest\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;a&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (link &amp;&amp; \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isDocumentationLink\u003C/span>(link)) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">schedulePrefetch\u003C/span>(link.\u003Cspan class=\"hljs-property\">href\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;hover&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">1000\u003C/span>);\n      }\n    });\n\n    \u003Cspan class=\"hljs-comment\">// Prefetch on viewport entry (mobile)\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> observer = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">IntersectionObserver\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">entries\u003C/span>) =&gt;\u003C/span> {\n      entries.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">entry\u003C/span> =&gt;\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (entry.\u003Cspan class=\"hljs-property\">isIntersecting\u003C/span>) {\n          \u003Cspan class=\"hljs-keyword\">const\u003C/span> links = entry.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;a&#x27;\u003C/span>);\n          links.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">link\u003C/span> =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isDocumentationLink\u003C/span>(link)) {\n              \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">schedulePrefetch\u003C/span>(link.\u003Cspan class=\"hljs-property\">href\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;viewport&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">2000\u003C/span>);\n            }\n          });\n        }\n      });\n    }, {\n      \u003Cspan class=\"hljs-attr\">rootMargin\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;100px&#x27;\u003C/span>\n    });\n\n    \u003Cspan class=\"hljs-comment\">// Observe sections for viewport prefetching\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;section, article&#x27;\u003C/span>).\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">section\u003C/span> =&gt;\u003C/span> {\n      observer.\u003Cspan class=\"hljs-title function_\">observe\u003C/span>(section);\n    });\n\n    \u003Cspan class=\"hljs-comment\">// Prefetch based on user behavior patterns\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupBehaviorBasedPrefetching\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">setupBehaviorBasedPrefetching\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> patterns = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">userBehaviorTracker\u003C/span>.\u003Cspan class=\"hljs-title function_\">getNavigationPatterns\u003C/span>();\n    \n    patterns.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">pattern\u003C/span> =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (pattern.\u003Cspan class=\"hljs-property\">confidence\u003C/span> &gt; \u003Cspan class=\"hljs-number\">0.7\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">schedulePrefetch\u003C/span>(pattern.\u003Cspan class=\"hljs-property\">nextUrl\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;behavior&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">500\u003C/span>);\n      }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">schedulePrefetch\u003C/span>(\u003Cspan class=\"hljs-params\">url, trigger, delay\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">has\u003C/span>(url)) \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> prefetchItem = {\n      url,\n      trigger,\n      \u003Cspan class=\"hljs-attr\">scheduled\u003C/span>: \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>(),\n      \u003Cspan class=\"hljs-attr\">priority\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">calculatePrefetchPriority\u003C/span>(url, trigger)\n    };\n\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(url, prefetchItem);\n\n    \u003Cspan class=\"hljs-built_in\">setTimeout\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">executePrefetch\u003C/span>(prefetchItem);\n    }, delay);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">calculatePrefetchPriority\u003C/span>(\u003Cspan class=\"hljs-params\">url, trigger\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">let\u003C/span> priority = \u003Cspan class=\"hljs-number\">0\u003C/span>;\n\n    \u003Cspan class=\"hljs-comment\">// Base priority by trigger type\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> triggerPriorities = {\n      \u003Cspan class=\"hljs-string\">&#x27;hover&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">3\u003C/span>,\n      \u003Cspan class=\"hljs-string\">&#x27;viewport&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">2\u003C/span>,\n      \u003Cspan class=\"hljs-string\">&#x27;behavior&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">4\u003C/span>,\n      \u003Cspan class=\"hljs-string\">&#x27;manual&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">5\u003C/span>\n    };\n\n    priority += triggerPriorities[trigger] || \u003Cspan class=\"hljs-number\">1\u003C/span>;\n\n    \u003Cspan class=\"hljs-comment\">// Boost priority for frequently accessed content\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> accessCount = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">userBehaviorTracker\u003C/span>.\u003Cspan class=\"hljs-title function_\">getAccessCount\u003C/span>(url);\n    priority += \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">min\u003C/span>(accessCount * \u003Cspan class=\"hljs-number\">0.5\u003C/span>, \u003Cspan class=\"hljs-number\">3\u003C/span>);\n\n    \u003Cspan class=\"hljs-comment\">// Reduce priority for recently cached content\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isRecentlyCached\u003C/span>(url)) {\n      priority -= \u003Cspan class=\"hljs-number\">1\u003C/span>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">max\u003C/span>(priority, \u003Cspan class=\"hljs-number\">1\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">executePrefetch\u003C/span>(\u003Cspan class=\"hljs-params\">prefetchItem\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-property\">size\u003C/span> &gt; \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">maxPrefetchItems\u003C/span>) {\n      \u003Cspan class=\"hljs-comment\">// Remove lowest priority items\u003C/span>\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">cleanupPrefetchQueue\u003C/span>();\n    }\n\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-comment\">// Check if already cached\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isContentCached\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>)) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">delete\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n      }\n\n      \u003Cspan class=\"hljs-comment\">// Respect user&#x27;s data preferences\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">shouldRespectDataUsage\u003C/span>()) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">delete\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n      }\n\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`Prefetching: \u003Cspan class=\"hljs-subst\">${prefetchItem.url}\u003C/span> (\u003Cspan class=\"hljs-subst\">${prefetchItem.trigger}\u003C/span>)`\u003C/span>);\n      \n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">fetch\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>, {\n        \u003Cspan class=\"hljs-attr\">priority\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;low&#x27;\u003C/span> \u003Cspan class=\"hljs-comment\">// Use low priority to avoid blocking critical requests\u003C/span>\n      });\n\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (response.\u003Cspan class=\"hljs-property\">ok\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;dynamic-content-v1&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">put\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>, response.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>());\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">userBehaviorTracker\u003C/span>.\u003Cspan class=\"hljs-title function_\">recordPrefetch\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>, \u003Cspan class=\"hljs-literal\">true\u003C/span>);\n      }\n\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">delete\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n      \n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">`Prefetch failed for \u003Cspan class=\"hljs-subst\">${prefetchItem.url}\u003C/span>:`\u003C/span>, error);\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">userBehaviorTracker\u003C/span>.\u003Cspan class=\"hljs-title function_\">recordPrefetch\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>, \u003Cspan class=\"hljs-literal\">false\u003C/span>);\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">delete\u003C/span>(prefetchItem.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">cleanupPrefetchQueue\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Sort by priority and keep only highest priority items\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> items = \u003Cspan class=\"hljs-title class_\">Array\u003C/span>.\u003Cspan class=\"hljs-title function_\">from\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">entries\u003C/span>());\n    items.\u003Cspan class=\"hljs-title function_\">sort\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">a, b\u003C/span>) =&gt;\u003C/span> b[\u003Cspan class=\"hljs-number\">1\u003C/span>].\u003Cspan class=\"hljs-property\">priority\u003C/span> - a[\u003Cspan class=\"hljs-number\">1\u003C/span>].\u003Cspan class=\"hljs-property\">priority\u003C/span>);\n    \n    \u003Cspan class=\"hljs-comment\">// Remove lowest priority items\u003C/span>\n    items.\u003Cspan class=\"hljs-title function_\">slice\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">maxPrefetchItems\u003C/span>).\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">[url]\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">delete\u003C/span>(url);\n    });\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">isContentCached\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> cache = \u003Cspan class=\"hljs-keyword\">await\u003C/span> caches.\u003Cspan class=\"hljs-title function_\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;dynamic-content-v1&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> cache.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(url);\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> !!response;\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">isRecentlyCached\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Implementation would check cache timestamps\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>; \u003Cspan class=\"hljs-comment\">// Simplified for example\u003C/span>\n  }\n\n  \u003Cspan class=\"hljs-title function_\">shouldRespectDataUsage\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Check connection type and user preferences\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-string\">&#x27;connection&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> navigator) {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> connection = navigator.\u003Cspan class=\"hljs-property\">connection\u003C/span>;\n      \n      \u003Cspan class=\"hljs-comment\">// Avoid prefetching on slow or expensive connections\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (connection.\u003Cspan class=\"hljs-property\">saveData\u003C/span> || \n          connection.\u003Cspan class=\"hljs-property\">effectiveType\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;slow-2g&#x27;\u003C/span> ||\n          connection.\u003Cspan class=\"hljs-property\">effectiveType\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;2g&#x27;\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>;\n      }\n    }\n\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n  }\n\n  \u003Cspan class=\"hljs-title function_\">isDocumentationLink\u003C/span>(\u003Cspan class=\"hljs-params\">link\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> link.\u003Cspan class=\"hljs-property\">origin\u003C/span> === \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">origin\u003C/span> &amp;&amp;\n           (link.\u003Cspan class=\"hljs-property\">pathname\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/docs/&#x27;\u003C/span>) ||\n            link.\u003Cspan class=\"hljs-property\">pathname\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/guides/&#x27;\u003C/span>) ||\n            link.\u003Cspan class=\"hljs-property\">pathname\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;/api/&#x27;\u003C/span>));\n  }\n\n  \u003Cspan class=\"hljs-title function_\">startPrefetchWorker\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Process prefetch queue periodically\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">setInterval\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-property\">size\u003C/span> &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> &amp;&amp; navigator.\u003Cspan class=\"hljs-property\">onLine\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">processPrefetchQueue\u003C/span>();\n      }\n    }, \u003Cspan class=\"hljs-number\">5000\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">processPrefetchQueue\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> items = \u003Cspan class=\"hljs-title class_\">Array\u003C/span>.\u003Cspan class=\"hljs-title function_\">from\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">prefetchQueue\u003C/span>.\u003Cspan class=\"hljs-title function_\">values\u003C/span>());\n    items.\u003Cspan class=\"hljs-title function_\">sort\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">a, b\u003C/span>) =&gt;\u003C/span> b.\u003Cspan class=\"hljs-property\">priority\u003C/span> - a.\u003Cspan class=\"hljs-property\">priority\u003C/span>);\n    \n    \u003Cspan class=\"hljs-comment\">// Process up to 2 items per cycle to avoid overwhelming the network\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> itemsToProcess = items.\u003Cspan class=\"hljs-title function_\">slice\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-number\">2\u003C/span>);\n    \n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> item \u003Cspan class=\"hljs-keyword\">of\u003C/span> itemsToProcess) {\n      \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">executePrefetch\u003C/span>(item);\n    }\n  }\n}\n\n\u003Cspan class=\"hljs-comment\">// User behavior tracking for intelligent prefetching\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">UserBehaviorTracker\u003C/span> {\n  \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span> = {\n      \u003Cspan class=\"hljs-attr\">pageViews\u003C/span>: [],\n      \u003Cspan class=\"hljs-attr\">navigationPatterns\u003C/span>: \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Map\u003C/span>(),\n      \u003Cspan class=\"hljs-attr\">timeSpent\u003C/span>: \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Map\u003C/span>(),\n      \u003Cspan class=\"hljs-attr\">scrollDepth\u003C/span>: \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Map\u003C/span>()\n    };\n    \n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">storageKey\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;user-behavior-data&#x27;\u003C/span>;\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">initialize\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadStoredData\u003C/span>();\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupTracking\u003C/span>();\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">loadStoredData\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> stored = \u003Cspan class=\"hljs-variable language_\">localStorage\u003C/span>.\u003Cspan class=\"hljs-title function_\">getItem\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">storageKey\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (stored) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> data = \u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">parse\u003C/span>(stored);\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span> = { ...\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>, ...data };\n      }\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Failed to load behavior data:&#x27;\u003C/span>, error);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupTracking\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Track page views\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">recordPageView\u003C/span>(\u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">pathname\u003C/span>);\n    \n    \u003Cspan class=\"hljs-comment\">// Track time spent on page\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">startTimeTracking\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Track scroll depth\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupScrollTracking\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Track navigation patterns\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupNavigationTracking\u003C/span>();\n    \n    \u003Cspan class=\"hljs-comment\">// Save data periodically\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">setInterval\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">saveData\u003C/span>();\n    }, \u003Cspan class=\"hljs-number\">30000\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">recordPageView\u003C/span>(\u003Cspan class=\"hljs-params\">path\u003C/span>) {\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">pageViews\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n      path,\n      \u003Cspan class=\"hljs-attr\">timestamp\u003C/span>: \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>(),\n      \u003Cspan class=\"hljs-attr\">referrer\u003C/span>: \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">referrer\u003C/span>\n    });\n\n    \u003Cspan class=\"hljs-comment\">// Update navigation patterns\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> previousPage = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">pageViews\u003C/span>[\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">pageViews\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span> - \u003Cspan class=\"hljs-number\">2\u003C/span>];\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (previousPage) {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> pattern = \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${previousPage.path}\u003C/span>-&gt;\u003Cspan class=\"hljs-subst\">${path}\u003C/span>`\u003C/span>;\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> count = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">navigationPatterns\u003C/span>.\u003Cspan class=\"hljs-title function_\">get\u003C/span>(pattern) || \u003Cspan class=\"hljs-number\">0\u003C/span>;\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">navigationPatterns\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(pattern, count + \u003Cspan class=\"hljs-number\">1\u003C/span>);\n    }\n  }\n\n  \u003Cspan class=\"hljs-title function_\">startTimeTracking\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> startTime = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>();\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> currentPath = \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">pathname\u003C/span>;\n    \n    \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;beforeunload&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> timeSpent = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>() - startTime;\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">recordTimeSpent\u003C/span>(currentPath, timeSpent);\n    });\n    \n    \u003Cspan class=\"hljs-comment\">// Also track when page becomes hidden\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;visibilitychange&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">hidden\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> timeSpent = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>() - startTime;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">recordTimeSpent\u003C/span>(currentPath, timeSpent);\n      }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">recordTimeSpent\u003C/span>(\u003Cspan class=\"hljs-params\">path, duration\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> existing = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">timeSpent\u003C/span>.\u003Cspan class=\"hljs-title function_\">get\u003C/span>(path) || { \u003Cspan class=\"hljs-attr\">total\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-attr\">sessions\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span> };\n    existing.\u003Cspan class=\"hljs-property\">total\u003C/span> += duration;\n    existing.\u003Cspan class=\"hljs-property\">sessions\u003C/span> += \u003Cspan class=\"hljs-number\">1\u003C/span>;\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">timeSpent\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(path, existing);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupScrollTracking\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">let\u003C/span> maxScrollDepth = \u003Cspan class=\"hljs-number\">0\u003C/span>;\n    \n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> \u003Cspan class=\"hljs-title function_\">trackScroll\u003C/span> = (\u003Cspan class=\"hljs-params\">\u003C/span>) =&gt; {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> scrollDepth = \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">round\u003C/span>(\n        (\u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">scrollY\u003C/span> / (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">documentElement\u003C/span>.\u003Cspan class=\"hljs-property\">scrollHeight\u003C/span> - \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">innerHeight\u003C/span>)) * \u003Cspan class=\"hljs-number\">100\u003C/span>\n      );\n      \n      maxScrollDepth = \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">max\u003C/span>(maxScrollDepth, scrollDepth);\n    };\n    \n    \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;scroll&#x27;\u003C/span>, trackScroll, { \u003Cspan class=\"hljs-attr\">passive\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span> });\n    \n    \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;beforeunload&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">recordScrollDepth\u003C/span>(\u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">pathname\u003C/span>, maxScrollDepth);\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">recordScrollDepth\u003C/span>(\u003Cspan class=\"hljs-params\">path, depth\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> existing = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">scrollDepth\u003C/span>.\u003Cspan class=\"hljs-title function_\">get\u003C/span>(path) || { \u003Cspan class=\"hljs-attr\">max\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-attr\">average\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-attr\">count\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span> };\n    existing.\u003Cspan class=\"hljs-property\">max\u003C/span> = \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">max\u003C/span>(existing.\u003Cspan class=\"hljs-property\">max\u003C/span>, depth);\n    existing.\u003Cspan class=\"hljs-property\">average\u003C/span> = (existing.\u003Cspan class=\"hljs-property\">average\u003C/span> * existing.\u003Cspan class=\"hljs-property\">count\u003C/span> + depth) / (existing.\u003Cspan class=\"hljs-property\">count\u003C/span> + \u003Cspan class=\"hljs-number\">1\u003C/span>);\n    existing.\u003Cspan class=\"hljs-property\">count\u003C/span> += \u003Cspan class=\"hljs-number\">1\u003C/span>;\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">scrollDepth\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(path, existing);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">setupNavigationTracking\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Track internal link clicks\u003C/span>\n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> link = event.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-title function_\">closest\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;a&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (link &amp;&amp; \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isInternalLink\u003C/span>(link)) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">recordLinkClick\u003C/span>(link.\u003Cspan class=\"hljs-property\">href\u003C/span>, \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">pathname\u003C/span>);\n      }\n    });\n  }\n\n  \u003Cspan class=\"hljs-title function_\">recordLinkClick\u003C/span>(\u003Cspan class=\"hljs-params\">targetUrl, sourcePage\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// This helps build navigation patterns\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> pattern = \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${sourcePage}\u003C/span>-&gt;\u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-keyword\">new\u003C/span> URL(targetUrl).pathname}\u003C/span>`\u003C/span>;\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> count = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">navigationPatterns\u003C/span>.\u003Cspan class=\"hljs-title function_\">get\u003C/span>(pattern) || \u003Cspan class=\"hljs-number\">0\u003C/span>;\n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">navigationPatterns\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(pattern, count + \u003Cspan class=\"hljs-number\">1\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">getNavigationPatterns\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> patterns = [];\n    \n    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">navigationPatterns\u003C/span>.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">count, pattern\u003C/span>) =&gt;\u003C/span> {\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> [\u003Cspan class=\"hljs-keyword\">from\u003C/span>, to] = pattern.\u003Cspan class=\"hljs-title function_\">split\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;-&gt;&#x27;\u003C/span>);\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> confidence = \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">min\u003C/span>(count / \u003Cspan class=\"hljs-number\">10\u003C/span>, \u003Cspan class=\"hljs-number\">1\u003C/span>); \u003Cspan class=\"hljs-comment\">// Normalize to 0-1\u003C/span>\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-keyword\">from\u003C/span> === \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">pathname\u003C/span> &amp;&amp; confidence &gt; \u003Cspan class=\"hljs-number\">0.3\u003C/span>) {\n        patterns.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n          \u003Cspan class=\"hljs-attr\">nextUrl\u003C/span>: to,\n          confidence,\n          count\n        });\n      }\n    });\n    \n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> patterns.\u003Cspan class=\"hljs-title function_\">sort\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">a, b\u003C/span>) =&gt;\u003C/span> b.\u003Cspan class=\"hljs-property\">confidence\u003C/span> - a.\u003Cspan class=\"hljs-property\">confidence\u003C/span>);\n  }\n\n  \u003Cspan class=\"hljs-title function_\">getAccessCount\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> path = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title function_\">URL\u003C/span>(url).\u003Cspan class=\"hljs-property\">pathname\u003C/span>;\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">pageViews\u003C/span>.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">view\u003C/span> =&gt;\u003C/span> view.\u003Cspan class=\"hljs-property\">path\u003C/span> === path).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n  }\n\n  \u003Cspan class=\"hljs-title function_\">recordPrefetch\u003C/span>(\u003Cspan class=\"hljs-params\">url, success\u003C/span>) {\n    \u003Cspan class=\"hljs-comment\">// Track prefetch success/failure for learning\u003C/span>\n    \u003Cspan class=\"hljs-comment\">// Implementation would update ML models or heuristics\u003C/span>\n  }\n\n  \u003Cspan class=\"hljs-title function_\">isInternalLink\u003C/span>(\u003Cspan class=\"hljs-params\">link\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> link.\u003Cspan class=\"hljs-property\">origin\u003C/span> === \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">location\u003C/span>.\u003Cspan class=\"hljs-property\">origin\u003C/span>;\n  }\n\n  \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">saveData\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n      \u003Cspan class=\"hljs-comment\">// Convert Maps to objects for storage\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">const\u003C/span> dataToSave = {\n        \u003Cspan class=\"hljs-attr\">pageViews\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">pageViews\u003C/span>,\n        \u003Cspan class=\"hljs-attr\">navigationPatterns\u003C/span>: \u003Cspan class=\"hljs-title class_\">Object\u003C/span>.\u003Cspan class=\"hljs-title function_\">fromEntries\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">navigationPatterns\u003C/span>),\n        \u003Cspan class=\"hljs-attr\">timeSpent\u003C/span>: \u003Cspan class=\"hljs-title class_\">Object\u003C/span>.\u003Cspan class=\"hljs-title function_\">fromEntries\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">timeSpent\u003C/span>),\n        \u003Cspan class=\"hljs-attr\">scrollDepth\u003C/span>: \u003Cspan class=\"hljs-title class_\">Object\u003C/span>.\u003Cspan class=\"hljs-title function_\">fromEntries\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sessionData\u003C/span>.\u003Cspan class=\"hljs-property\">scrollDepth\u003C/span>)\n      };\n      \n      \u003Cspan class=\"hljs-variable language_\">localStorage\u003C/span>.\u003Cspan class=\"hljs-title function_\">setItem\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">storageKey\u003C/span>, \u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">stringify\u003C/span>(dataToSave));\n    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n      \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Failed to save behavior data:&#x27;\u003C/span>, error);\n    }\n  }\n}\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Progressive Web App documentation using Markdown represents a powerful convergence of content simplicity and application sophistication, enabling organizations to deliver native app-like documentation experiences while maintaining the editorial flexibility and version control benefits that make Markdown an ideal content creation format. Through intelligent caching strategies, offline-first design principles, and progressive enhancement techniques, PWA documentation platforms can provide consistent, high-performance user experiences across all devices and network conditions.\u003C/p>\n\u003Cp>The key to successful PWA implementation lies in balancing comprehensive functionality with performance optimization, ensuring that advanced features enhance rather than complicate the user experience. Whether you&#39;re building internal documentation systems, customer-facing help centers, or comprehensive developer platforms, the PWA techniques covered in this guide provide the foundation for creating resilient, scalable documentation solutions that meet modern user expectations while supporting efficient content management workflows.\u003C/p>\n\u003Cp>Remember to prioritize core functionality for the initial load, implement intelligent prefetching to improve perceived performance, and continuously monitor real-world usage patterns to optimize caching strategies and user experience. With proper implementation of PWA principles, your Markdown documentation platform can deliver exceptional user experiences that rival native applications while maintaining the simplicity and maintainability that makes Markdown documentation so valuable for technical teams.\u003C/p>\n",[15,19,22,25,28,31],{"id":16,"text":17,"level":18},"why-master-pwa-powered-markdown-documentation","Why Master PWA-Powered Markdown Documentation?",2,{"id":20,"text":21,"level":18},"foundation-pwa-documentation-architecture","Foundation PWA Documentation Architecture",{"id":23,"text":24,"level":18},"advanced-pwa-features-for-documentation","Advanced PWA Features for Documentation",{"id":26,"text":27,"level":18},"performance-optimization-and-caching-strategies","Performance Optimization and Caching Strategies",{"id":29,"text":30,"level":18},"advanced-caching-and-storage-strategies","Advanced Caching and Storage Strategies",{"id":32,"text":33,"level":18},"conclusion","Conclusion",[],[36,44,52],{"slug":37,"title":38,"description":39,"excerpt":40,"date":41,"category":9,"author":10,"keywords":42,"readingMinutes":43},"markdown-content-organization-project-structure-complete-guide","Markdown Content Organization and Project Structure: Complete Guide for Scalable Documentation Systems","Master advanced Markdown content organization strategies for large-scale documentation projects, including hierarchical structures, content categorization, automated organization systems, and scalable project architectures that grow with your needs.","Effective Markdown content organization and project structure design enables scalable documentation systems that maintain clarity, findability, and maintainability across large content…","2025-10-19","markdown content organization, documentation structure, content management markdown, project structure documentation, scalable markdown, content categorization, documentation architecture, markdown organization systems",18,{"slug":45,"title":46,"description":47,"excerpt":48,"date":49,"category":9,"author":10,"keywords":50,"readingMinutes":51},"markdown-form-validation-input-handling-complete-guide","Markdown Form Validation and Input Handling: Complete Guide for Interactive Documentation with Dynamic Validation Systems","Master advanced Markdown form validation and input handling techniques for creating interactive documentation with comprehensive validation systems, real-time feedback, and user-friendly error handling that ensures data quality and user experience.","Advanced Markdown form validation and input handling systems enable interactive documentation with robust data validation, real-time user feedback, and comprehensive error handling mechanisms. By…","2025-10-23","markdown form validation, input validation markdown, form handling markdown, interactive forms markdown, markdown input validation, form validation systems, dynamic form validation, markdown user input",34,{"slug":53,"title":54,"description":55,"excerpt":56,"date":57,"category":9,"author":10,"keywords":58,"readingMinutes":59},"markdown-form-creation-input-validation-complete-guide","Markdown Form Creation and Input Validation: Complete Guide for Interactive Documentation and User Input Systems","Master advanced Markdown form creation techniques for interactive documentation, user input validation, and dynamic content generation. Learn to build accessible forms, implement client-side validation, and create sophisticated input systems within Markdown-based platforms.","Advanced Markdown form creation and input validation capabilities enable sophisticated interactive documentation systems that combine the simplicity of Markdown with powerful user input…","2025-10-10","markdown forms, markdown input validation, interactive markdown, markdown user input, form creation markdown, markdown form validation, dynamic markdown forms, markdown form processing",23,1792184942360]