web: Snap Store badge, served from here
CodeQL Analysis / Analyze CodeQL (push) Canceled after 0s
Deploy Application / deploy (push) Canceled after 0s
Mirror to Codeberg / mirror (push) Canceled after 0s
Mirror to PrivacyGuides / mirror (push) Canceled after 0s

The badge image is vendored rather than hotlinked from snapcraft.io. The CSP
is img-src 'self' data: and would block it anyway, but the reason to leave the
CSP alone is the page's own claim: fetching a badge from someone else's server
hands them the address of every visitor to a page that says no servers are
involved.

The README badge stays dynamic — it reports the published version, and GitHub
proxies images, so no reader is exposed by it.
This commit is contained in:
SecureBitChatVolodymyr committed 2026-09-02 19:12:15 -04:00
1 parent 30e335f9e9
commit 0691ce618c
21 files changed
+392 -323

No files matched your search

+3
View File
@@ -21,3 +21,6 @@ assets/screenshots
# full-size marketing captures stay out of the image, which is what the rule
# above was for.
!assets/screenshots/desktop-*.png
# The Snap Store badge is served from this origin so the page makes no
# third-party request; it has to actually ship for that to be true.
!assets/badges/*.svg
+1
View File
@@ -10,6 +10,7 @@ No accounts. No servers storing your messages. No installation required.
[![License: MIT](https://img.shields.io/badge/License-MIT-f0892a.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-6.7.2-3ecf8e.svg)](CHANGELOG.md)
[![Get it from the Snap Store](https://snapcraft.io/securebit-chat/badge.svg)](https://snapcraft.io/securebit-chat)
[![PWA](https://img.shields.io/badge/PWA-installable-3ecf8e.svg)](#install-as-an-app)
[![Encryption](https://img.shields.io/badge/crypto-ECDH%20P--384%20%C2%B7%20AES--256--GCM-blue.svg)](#security-model)
[![Forward secrecy](https://img.shields.io/badge/forward%20secrecy-Double%20Ratchet-3ecf8e.svg)](#forward-secrecy)
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/ar/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+1
View File
@@ -0,0 +1 @@
<svg width="182" height="56" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect stroke="#CDCDCD" fill="#252525" width="182" height="56" rx="2"/><g fill-rule="nonzero"><path d="M26.99 28.8V18.33l7.22 3.22-7.22 7.25zM13.2 42.64l8.85-16.67 3.88 3.88-12.73 12.8zm-5.05-31.4l18.22 6.6v11.58L8.16 11.23z" fill="#82BEA0"/><path fill="#FA6441" d="M37.9 17.85H27.4l13.5 6.02z"/></g><path d="M56.1 13.9h1.17v3.9l-.41.1a12.68 12.68 0 01-2.25.27c-.59 0-1.12-.1-1.6-.29a3.4 3.4 0 01-1.23-.84 3.8 3.8 0 01-.8-1.36 5.57 5.57 0 01-.28-1.84c0-.7.1-1.32.31-1.86.22-.54.5-1 .86-1.36.36-.37.78-.65 1.27-.84.48-.2 1-.29 1.55-.29a6.23 6.23 0 011.75.24 3.67 3.67 0 01.78.34l-.37.97a3.14 3.14 0 00-.92-.38c-.39-.1-.78-.15-1.18-.15-.42 0-.8.08-1.16.23-.34.15-.64.37-.88.66-.25.29-.44.64-.57 1.05a4.95 4.95 0 00-.03 2.74c.11.41.29.76.52 1.05.24.3.53.52.88.68.35.16.76.24 1.23.24a5.8 5.8 0 001.37-.16v-3.1zm2.58 1c0-.56.08-1.04.24-1.45.16-.42.37-.76.63-1.03.27-.27.57-.48.91-.61.35-.14.7-.2 1.06-.2.84 0 1.48.26 1.93.78.45.52.67 1.32.67 2.4v.39h-4.28c.05.65.24 1.14.56 1.48.33.33.84.5 1.54.5a4.1 4.1 0 001.6-.3l.15.94a5.08 5.08 0 01-1.87.35c-.54 0-1.01-.09-1.41-.25a2.63 2.63 0 01-1.55-1.7c-.12-.4-.18-.84-.18-1.3zm4.28-.62c0-.5-.12-.92-.38-1.24a1.3 1.3 0 00-1.07-.49 1.47 1.47 0 00-1.18.54 1.8 1.8 0 00-.32.55c-.07.21-.12.42-.15.64h3.1zm3.82-2.52h2.36v.94h-2.36v2.88c0 .3.02.57.07.77.05.2.12.36.21.48.1.12.22.2.36.25a2.37 2.37 0 001.31-.04l.43-.17.22.93a4.14 4.14 0 01-1.55.33c-.42 0-.77-.05-1.05-.16-.27-.1-.5-.27-.66-.49a1.95 1.95 0 01-.36-.8c-.07-.31-.1-.68-.1-1.1v-5.56l1.12-.2v1.94zM74.44 18h-1.11v-6.24h1.11V18zm-.56-7.37a.7.7 0 01-.72-.73.7.7 0 01.72-.73.7.7 0 01.72.73.7.7 0 01-.72.73zm3.53 1.13h2.36v.94h-2.36v2.88c0 .3.02.57.07.77.05.2.12.36.22.48s.21.2.36.25a2.37 2.37 0 001.31-.04l.43-.17.21.93a4.14 4.14 0 01-1.55.33c-.42 0-.77-.05-1.05-.16-.27-.1-.5-.27-.66-.49a1.95 1.95 0 01-.36-.8c-.06-.31-.1-.68-.1-1.1v-5.56l1.12-.2v1.94zm8.99-3.07a4.3 4.3 0 011.34.2l-.2.96a2.72 2.72 0 00-1.06-.2c-.52 0-.88.14-1.1.42-.2.29-.3.67-.3 1.15v.54h2.4v.94h-2.4V18h-1.12v-6.8c0-.8.2-1.42.59-1.86.39-.43 1-.65 1.85-.65zm4.5 2.94a3.47 3.47 0 01.7.06 10.46 10.46 0 01.54.12l-.19.97a3.74 3.74 0 00-2.24-.02V18h-1.12v-5.98a7.59 7.59 0 012.3-.4zm7.83 3.25c0 .5-.07.94-.21 1.34-.15.4-.35.75-.61 1.04-.26.28-.57.5-.93.66-.36.16-.75.24-1.18.24-.42 0-.81-.08-1.17-.24a2.67 2.67 0 01-.93-.66 3.07 3.07 0 01-.6-1.04c-.15-.4-.22-.84-.22-1.34 0-.49.07-.93.21-1.34.15-.4.35-.75.6-1.04a2.93 2.93 0 012.1-.9c.44 0 .83.08 1.19.24.36.15.67.38.93.66.26.3.46.64.6 1.04.15.4.22.85.22 1.34zm-1.16 0c0-.7-.16-1.26-.48-1.67a1.54 1.54 0 00-1.29-.62c-.54 0-.97.2-1.29.62-.31.4-.47.97-.47 1.67s.16 1.26.47 1.67c.32.42.75.62 1.3.62.54 0 .97-.2 1.28-.62.32-.4.48-.97.48-1.67zm2.73-2.94a8.71 8.71 0 012.47-.31c.4 0 .74.05 1.01.16.28.1.5.27.69.47a4.3 4.3 0 01.7-.37c.18-.07.38-.13.6-.18.21-.06.44-.08.69-.08.48 0 .87.07 1.18.2.3.15.54.35.71.6.17.26.29.56.35.91.06.36.09.74.09 1.16V18h-1.12v-3.26c0-.37-.02-.69-.05-.95-.04-.27-.1-.49-.2-.66a.93.93 0 00-.41-.4 2.47 2.47 0 00-1.6.02c-.24.11-.41.2-.5.28a6.1 6.1 0 01.2 1.46V18h-1.12v-3.26c0-.37-.02-.69-.06-.95a1.91 1.91 0 00-.21-.66.93.93 0 00-.41-.4 1.49 1.49 0 00-.65-.12 5.79 5.79 0 00-1.24.12V18h-1.12v-6.06zm14.15-.18h2.37v.94h-2.37v2.88c0 .3.03.57.07.77.05.2.12.36.22.48s.22.2.36.25a2.37 2.37 0 001.31-.04l.43-.17.22.93a4.14 4.14 0 01-1.55.33c-.43 0-.78-.05-1.05-.16-.28-.1-.5-.27-.67-.49a1.95 1.95 0 01-.35-.8c-.07-.31-.1-.68-.1-1.1v-5.56l1.11-.2v1.94zm3.78 6.24V8.88l1.12-.2v3.2a3.78 3.78 0 011.37-.25c.5 0 .9.07 1.23.2.33.15.6.34.79.6.2.25.33.55.41.9.08.35.12.74.12 1.17V18h-1.11v-3.26c0-.39-.03-.72-.08-.99s-.14-.49-.26-.66a1.02 1.02 0 00-.48-.36 2.1 2.1 0 00-.74-.12 7.99 7.99 0 00-1.25.2V18h-1.12zm6.5-3.1c0-.56.09-1.04.25-1.45.16-.42.37-.76.63-1.03.27-.27.57-.48.91-.61.35-.14.7-.2 1.06-.2.84 0 1.48.26 1.93.78.45.52.67 1.32.67 2.4v.39h-4.28c.05.65.24 1.14.56 1.48.33.33.84.5 1.54.5a4.1 4.1 0 001.6-.3l.15.94a5.08 5.08 0 01-1.87.35c-.54 0-1.01-.09-1.41-.25a2.63 2.63 0 01-1.55-1.7c-.12-.4-.18-.84-.18-1.3zm4.29-.62c0-.5-.12-.92-.38-1.24a1.3 1.3 0 00-1.07-.49 1.47 1.47 0 00-1.18.54 1.8 1.8 0 00-.32.55c-.07.21-.12.42-.15.64h3.1zM55.93 39.34c2.43 0 3.65-.83 3.65-2.5 0-.5-.11-.94-.33-1.3-.21-.36-.5-.67-.87-.94-.37-.26-.8-.49-1.26-.68-.48-.2-.98-.38-1.5-.58-.61-.2-1.19-.44-1.73-.7a6.05 6.05 0 01-1.42-.94c-.4-.36-.71-.79-.95-1.28-.23-.5-.34-1.1-.34-1.8 0-1.46.5-2.6 1.48-3.41 1-.82 2.36-1.23 4.1-1.23 1.02 0 1.93.11 2.76.33.82.21 1.42.45 1.8.7l-.74 1.9a8.05 8.05 0 00-3.82-.91c-.44 0-.86.05-1.24.14-.38.1-.72.24-1 .44-.3.19-.52.43-.7.73-.16.3-.24.64-.24 1.04 0 .45.08.83.26 1.13.18.3.42.57.74.8.32.24.7.45 1.12.64.42.2.9.38 1.4.58.72.28 1.38.57 1.98.86.6.29 1.12.63 1.56 1.03.44.4.78.88 1.02 1.43.24.55.36 1.22.36 2 0 1.46-.53 2.58-1.6 3.36-1.06.79-2.56 1.18-4.5 1.18a11.54 11.54 0 01-5.13-1.18l.7-1.92a8.63 8.63 0 004.44 1.08zm8.76-10.46c.51-.13 1.19-.26 2.04-.4.85-.15 1.82-.22 2.93-.22.99 0 1.81.14 2.47.42.65.28 1.18.67 1.57 1.17.4.5.67 1.11.83 1.81.16.7.24 1.48.24 2.33VLine truncated

After

Width:  |  Height:  |  Size: 8.4 KiB

+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/de/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+35 -1
View File
@@ -34078,7 +34078,41 @@ var CommunityCTA = () => {
React.createElement("div", {
key: "btns",
style: { display: "flex", gap: "14px", justifyContent: "center", flexWrap: "wrap" }
}, [githubBtn, feedbackBtn])
}, [githubBtn, feedbackBtn]),
// Snap Store, bottom right.
//
// Served from this origin, not snapcraft.io. The site's CSP is
// `img-src 'self' data:` and would block a hotlink anyway, but the
// reason to keep it that way is the product's own claim: fetching a
// badge from someone else's server hands them the address of every
// visitor to a page that promises no servers are involved.
React.createElement("div", {
key: "snap",
style: {
display: "flex",
justifyContent: isMobile ? "center" : "flex-end",
marginTop: "28px"
}
}, React.createElement("a", {
href: "https://snapcraft.io/securebit-chat",
target: "_blank",
rel: "noopener noreferrer",
"aria-label": "Get it from the Snap Store",
style: { display: "inline-flex", opacity: 0.9, transition: "opacity .2s" },
onMouseEnter: (e) => {
e.currentTarget.style.opacity = 1;
},
onMouseLeave: (e) => {
e.currentTarget.style.opacity = 0.9;
}
}, React.createElement("img", {
src: "/assets/badges/snap-store.svg",
alt: "Get it from the Snap Store",
width: 182,
height: 56,
loading: "lazy",
style: { display: "block" }
})))
]);
return React.createElement("section", {
style: {
+2 -2
View File
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../src/notifications/SecureNotificationManager.js", "../src/notifications/NotificationIntegration.js", "../node_modules/dompurify/src/utils.ts", "../node_modules/dompurify/src/tags.ts", "../node_modules/dompurify/src/attrs.ts", "../node_modules/dompurify/src/regexp.ts", "../node_modules/dompurify/src/purify.ts", "../src/crypto/EnhancedSecureCryptoUtils.js", "../src/i18n/generated.js", "../src/i18n/index.js", "../src/transfer/EnhancedSecureFileTransfer.js", "../src/network/webrtc/config.js", "../src/network/webrtc/sdp.js", "../src/network/webrtc/audio.js", "../src/network/webrtc/video.js", "../src/network/webrtc/adaptation/metrics.js", "../src/network/webrtc/adaptation/controller.js", "../src/crypto/DoubleRatchet.js", "../src/network/descriptor/sbq2.js", "../src/network/descriptor/keyexchange.js", "../src/network/EnhancedSecureWebRTCManager.js", "../src/scripts/app-boot.js", "../package.json", "../src/components/ui/LanguageSwitcher.jsx", "../src/components/ui/Header.jsx", "../src/components/ui/DownloadApps.jsx", "../src/components/ui/BecomePartner.jsx", "../src/components/ui/UniqueFeatureSlider.jsx", "../src/components/ui/Roadmap.jsx", "../src/components/ui/CommunityCTA.jsx", "../src/components/ui/FileTransfer.jsx", "../src/network/iceServers.js", "../src/components/ui/IceServerSettings.jsx", "../src/components/ui/CallUI.jsx"],
"sourcesContent": ["/**\n * Secure and Reliable Notification Manager for P2P WebRTC Chat\n * Follows best practices: OWASP, MDN, Chrome DevRel\n * \n * @version 1.0.0\n * @author SecureBit Team\n * @license MIT\n */\n\nclass SecureChatNotificationManager {\n constructor(config = {}) {\n // Safely read Notification permission (iOS Safari may not define Notification)\n this.permission = (typeof Notification !== 'undefined' && Notification && typeof Notification.permission === 'string')\n ? Notification.permission\n : 'denied';\n this.isTabActive = this.checkTabActive(); // Initialize with proper check\n this.unreadCount = 0;\n this.originalTitle = document.title;\n this.notificationQueue = [];\n this.maxQueueSize = config.maxQueueSize || 5;\n this.rateLimitMs = config.rateLimitMs || 2000; // Spam protection\n this.lastNotificationTime = 0;\n this.trustedOrigins = config.trustedOrigins || [];\n \n // Secure context flag\n this.isSecureContext = window.isSecureContext;\n \n // Cross-browser compatibility for Page Visibility API\n this.hidden = this.getHiddenProperty();\n this.visibilityChange = this.getVisibilityChangeEvent();\n \n this.initVisibilityTracking();\n this.initSecurityChecks();\n }\n\n /**\n * Initialize security checks and validation\n * @private\n */\n initSecurityChecks() {\n // Security checks are performed silently\n }\n\n /**\n * Get hidden property name for cross-browser compatibility\n * @returns {string} Hidden property name\n * @private\n */\n getHiddenProperty() {\n if (typeof document.hidden !== \"undefined\") {\n return \"hidden\";\n } else if (typeof document.msHidden !== \"undefined\") {\n return \"msHidden\";\n } else if (typeof document.webkitHidden !== \"undefined\") {\n return \"webkitHidden\";\n }\n return \"hidden\"; // fallback\n }\n\n /**\n * Get visibility change event name for cross-browser compatibility\n * @returns {string} Visibility change event name\n * @private\n */\n getVisibilityChangeEvent() {\n if (typeof document.hidden !== \"undefined\") {\n return \"visibilitychange\";\n } else if (typeof document.msHidden !== \"undefined\") {\n return \"msvisibilitychange\";\n } else if (typeof document.webkitHidden !== \"undefined\") {\n return \"webkitvisibilitychange\";\n }\n return \"visibilitychange\"; // fallback\n }\n\n /**\n * Check if tab is currently active using multiple methods\n * @returns {boolean} True if tab is active\n * @private\n */\n checkTabActive() {\n // Primary method: Page Visibility API\n if (this.hidden && typeof document[this.hidden] !== \"undefined\") {\n return !document[this.hidden];\n }\n \n // Fallback method: document.hasFocus()\n if (typeof document.hasFocus === \"function\") {\n return document.hasFocus();\n }\n \n // Ultimate fallback: assume active\n return true;\n }\n\n /**\n * Initialize page visibility tracking (Page Visibility API)\n * @private\n */\n initVisibilityTracking() {\n // Primary method: Page Visibility API with cross-browser support\n if (typeof document.addEventListener !== \"undefined\" && typeof document[this.hidden] !== \"undefined\") {\n document.addEventListener(this.visibilityChange, () => {\n this.isTabActive = this.checkTabActive();\n \n if (this.isTabActive) {\n this.resetUnreadCount();\n this.clearNotificationQueue();\n }\n });\n }\n\n // Fallback method: Window focus/blur events\n window.addEventListener('focus', () => {\n this.isTabActive = this.checkTabActive();\n if (this.isTabActive) {\n this.resetUnreadCount();\n }\n });\n\n window.addEventListener('blur', () => {\n this.isTabActive = this.checkTabActive();\n });\n\n // Page unload cleanup\n window.addEventListener('beforeunload', () => {\n this.clearNotificationQueue();\n });\n }\n\n /**\n * Request notification permission (BEST PRACTICE: Only call in response to user action)\n * Never call on page load!\n * @returns {Promise<boolean>} Permission granted status\n */\n async requestPermission() {\n // Secure context check\n if (!this.isSecureContext || !('Notification' in window)) {\n return false;\n }\n\n if (this.permission === 'granted') {\n return true;\n }\n\n if (this.permission === 'denied') {\n return false;\n }\n\n try {\n this.permission = await Notification.requestPermission();\n return this.permission === 'granted';\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Update page title with unread count\n * @private\n */\n updateTitle() {\n if (this.unreadCount > 0) {\n document.title = `(${this.unreadCount}) ${this.originalTitle}`;\n } else {\n document.title = this.originalTitle;\n }\n }\n\n /**\n Line truncated
"mappings": "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 truncated
"sourcesContent": ["/**\n * Secure and Reliable Notification Manager for P2P WebRTC Chat\n * Follows best practices: OWASP, MDN, Chrome DevRel\n * \n * @version 1.0.0\n * @author SecureBit Team\n * @license MIT\n */\n\nclass SecureChatNotificationManager {\n constructor(config = {}) {\n // Safely read Notification permission (iOS Safari may not define Notification)\n this.permission = (typeof Notification !== 'undefined' && Notification && typeof Notification.permission === 'string')\n ? Notification.permission\n : 'denied';\n this.isTabActive = this.checkTabActive(); // Initialize with proper check\n this.unreadCount = 0;\n this.originalTitle = document.title;\n this.notificationQueue = [];\n this.maxQueueSize = config.maxQueueSize || 5;\n this.rateLimitMs = config.rateLimitMs || 2000; // Spam protection\n this.lastNotificationTime = 0;\n this.trustedOrigins = config.trustedOrigins || [];\n \n // Secure context flag\n this.isSecureContext = window.isSecureContext;\n \n // Cross-browser compatibility for Page Visibility API\n this.hidden = this.getHiddenProperty();\n this.visibilityChange = this.getVisibilityChangeEvent();\n \n this.initVisibilityTracking();\n this.initSecurityChecks();\n }\n\n /**\n * Initialize security checks and validation\n * @private\n */\n initSecurityChecks() {\n // Security checks are performed silently\n }\n\n /**\n * Get hidden property name for cross-browser compatibility\n * @returns {string} Hidden property name\n * @private\n */\n getHiddenProperty() {\n if (typeof document.hidden !== \"undefined\") {\n return \"hidden\";\n } else if (typeof document.msHidden !== \"undefined\") {\n return \"msHidden\";\n } else if (typeof document.webkitHidden !== \"undefined\") {\n return \"webkitHidden\";\n }\n return \"hidden\"; // fallback\n }\n\n /**\n * Get visibility change event name for cross-browser compatibility\n * @returns {string} Visibility change event name\n * @private\n */\n getVisibilityChangeEvent() {\n if (typeof document.hidden !== \"undefined\") {\n return \"visibilitychange\";\n } else if (typeof document.msHidden !== \"undefined\") {\n return \"msvisibilitychange\";\n } else if (typeof document.webkitHidden !== \"undefined\") {\n return \"webkitvisibilitychange\";\n }\n return \"visibilitychange\"; // fallback\n }\n\n /**\n * Check if tab is currently active using multiple methods\n * @returns {boolean} True if tab is active\n * @private\n */\n checkTabActive() {\n // Primary method: Page Visibility API\n if (this.hidden && typeof document[this.hidden] !== \"undefined\") {\n return !document[this.hidden];\n }\n \n // Fallback method: document.hasFocus()\n if (typeof document.hasFocus === \"function\") {\n return document.hasFocus();\n }\n \n // Ultimate fallback: assume active\n return true;\n }\n\n /**\n * Initialize page visibility tracking (Page Visibility API)\n * @private\n */\n initVisibilityTracking() {\n // Primary method: Page Visibility API with cross-browser support\n if (typeof document.addEventListener !== \"undefined\" && typeof document[this.hidden] !== \"undefined\") {\n document.addEventListener(this.visibilityChange, () => {\n this.isTabActive = this.checkTabActive();\n \n if (this.isTabActive) {\n this.resetUnreadCount();\n this.clearNotificationQueue();\n }\n });\n }\n\n // Fallback method: Window focus/blur events\n window.addEventListener('focus', () => {\n this.isTabActive = this.checkTabActive();\n if (this.isTabActive) {\n this.resetUnreadCount();\n }\n });\n\n window.addEventListener('blur', () => {\n this.isTabActive = this.checkTabActive();\n });\n\n // Page unload cleanup\n window.addEventListener('beforeunload', () => {\n this.clearNotificationQueue();\n });\n }\n\n /**\n * Request notification permission (BEST PRACTICE: Only call in response to user action)\n * Never call on page load!\n * @returns {Promise<boolean>} Permission granted status\n */\n async requestPermission() {\n // Secure context check\n if (!this.isSecureContext || !('Notification' in window)) {\n return false;\n }\n\n if (this.permission === 'granted') {\n return true;\n }\n\n if (this.permission === 'denied') {\n return false;\n }\n\n try {\n this.permission = await Notification.requestPermission();\n return this.permission === 'granted';\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Update page title with unread count\n * @private\n */\n updateTitle() {\n if (this.unreadCount > 0) {\n document.title = `(${this.unreadCount}) ${this.originalTitle}`;\n } else {\n document.title = this.originalTitle;\n }\n }\n\n /**\n Line truncated
"mappings": "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 truncated
"names": ["text", "NotificationIntegration", "entries", "Object", "setPrototypeOf", "isFrozen", "getPrototypeOf", "getOwnPropertyDescriptor", "freeze", "seal", "create", "_ref", "Reflect", "apply", "construct", "x", "func", "thisArg", "_len", "arguments", "length", "args", "Array", "_key", "Func", "_len2", "_key2", "arrayForEach", "unapply", "prototype", "forEach", "arrayLastIndexOf", "lastIndexOf", "arrayPop", "pop", "arrayPush", "push", "arraySplice", "splice", "arrayIsArray", "isArray", "stringToLowerCase", "String", "toLowerCase", "stringToString", "toString", "stringMatch", "match", "stringReplace", "replace", "stringIndexOf", "indexOf", "stringTrim", "trim", "numberToString", "Number", "booleanToString", "Boolean", "bigintToString", "BigInt", "symbolToString", "Symbol", "objectHasOwnProperty", "hasOwnProperty", "objectToString", "regExpTest", "RegExp", "test", "typeErrorCreate", "unconstruct", "TypeError", "lastIndex", "_len3", "_key3", "_len4", "_key4", "addToSet", "set", "array", "transformCaseFunc", "l", "element", "lcElement", "cleanArray", "index", "isPropertyExist", "clone", "object", "newObject", "_ref2", "_ref3", "_slicedToArray", "property", "value", "constructor", "stringifyValue", "valueAsRecord", "valueToString", "lookupGetter", "stringified", "prop", "desc", "get", "fallbackValue", "isRegex", "_unused", "html", "svg", "svgFilters", "svgDisallowed", "mathMl", "mathMlDisallowed", "text", "xml", "MUSTACHE_EXPR", "ERB_EXPR", "TMPLIT_EXPR", "DATA_ATTR", "ARIA_ATTR", "IS_ALLOWED_URI", "IS_SCRIPT_OR_DATA", "ATTR_WHITESPACE", "DOCTYPE_NAME", "CUSTOM_ELEMENT", "ELEMENT_MARKUP_PROBE", "COMMENT_MARKUP_PROBE", "FALLBACK_TAG_CLOSE", "SELF_CLOSING_TAG", "NODE_TYPE", "attribute", "cdataSection", "entityReference", "entityNode", "processingInstruction", "comment", "document", "documentType", "documentFragment", "notation", "getGlobal", "window", "_createTrustedTypesPolicy", "trustedTypes", "purifyHostElement", "createPolicy", "suffix", "ATTR_NAME", "hasAttribute", "getAttribute", "policyName", "createHTML", "createScriptURL", "scriptUrl", "_", "console", "warn", "_createHooksMap", "afterSanitizeAttributes", "afterSanitizeElements", "afterSanitizeShadowDOM", "beforeSanitizeAttributes", "beforeSanitizeElements", "beforeSanitizeShadowDOM", "uponSanitizeAttribute", "uponSanitizeElement", "uponSanitizeShadowNode", "_resolveSetOption", "cfg", "key", "fallback", "options", "base", "transform", "createDOMPurify", "undefined", "DOMPurify", "root", "version", "VERSION", "removed", "nodeType", "Element", "isSupported", "originalDocument", "currentScript", "DocumentFragment", "HTMLTemplateElement", "Node", "NodeFilter", "_window$NamedNodeMap", "NamedNodeMap", "MozNamedAttrMap", "HTMLFormElement", "DOMParser", "ElementPrototype", "cloneNode", "remove", "getNextSibling", "getChildNodes", "getParentNode", "getShadowRoot", "getAttributes", "getNodeType", "getNodeName", "template", "createElement", "content", "ownerDocument", "trustedTypesPolicy", "emptyHTML", "defaultTrustedTypesPolicy", "defaultTrustedTypesPolicyResolved", "IN_TRUSTED_TYPES_POLICY", "_assertNotInTrustedTypesPolicy", "_createTrustedHTML", "_createTrustedScriptURL", "_getDefaultTrustedTypesPolicy", "_document", "implementation", "createNodeIterator", "createDocumentFragment", "getElementsByTagName", "importNode", "hooks", "createHTMLDocument", "EXPRESSIONS", "ALLOWED_TAGS", "DEFAULT_ALLOWED_TAGS", "TAGS", "ALLOWED_ATTR", "DEFAULT_ALLOWED_ATTR", "ATTRS", "CUSTOM_ELEMENT_HANDLING", "tagNameCheck", "writable", "configurable", "enumerable", "attributeNameCheck", "allowCustomizedBuiltInElements", "FORBID_TAGS", "FORBID_ATTR", "EXTRA_ELEMENT_HANDLING", "tagCheck", "attributeCheck", "ALLOW_ARIA_ATTR", "ALLOW_DATA_ATTR", "ALLOW_UNKNOWN_PROTOCOLS", "ALLOW_SELF_CLOSE_IN_ATTR", "SAFE_FOR_TEMPLATES", "SAFE_FOR_XML", "WHOLE_DOCUMENT", "SET_CONFIG", "FORCE_BODY", "RETURN_DOM", "RETURN_DOM_FRAGMENT", "RETURN_TRUSTED_TYPE", "SANITIZE_DOM", "SANITIZE_NAMED_PROPS", "SANITIZE_NAMED_PROPS_PREFIX", "KEEP_CONTENT", "IN_PLACE", "USE_PROFILES", "FORBID_CONTENTS", "DEFAULT_FORBID_CONTENTS", "DATA_URI_TAGS", "DEFAULT_DATA_URI_TAGS", "URI_SAFE_ATTRIBUTES", "DEFAULT_URI_SAFE_ATTRIBUTES", "MATHML_NAMESPACE", "SVG_NAMESPACE", "HTML_NAMESPACE", "NAMESPACE", "IS_EMPTY_INPUT", "ALLOWED_NAMESPACES", "DEFAULT_ALLOWED_NAMESPACES", "DEFAULT_MATHML_TEXT_INTEGRATION_POINTS", "MATHML_TEXT_INTEGRATION_POINTS", "DEFAULT_HTML_INTEGRATION_POINTS", "HTML_INTEGRATION_POINTS", "COMMON_SVG_AND_HTML_ELEMENTS", "PARSER_MEDIA_TYPE", "SUPPORTED_PARSER_MEDIA_TYPES", "DEFAULT_PARSER_MEDIA_TYPE", "CONFIG", "formElement", "isRegexOrFunction", "testValue", "Function", "_parseConfig", "ALLOWED_URI_REGEXP", "customElementHandling", "ADD_TAGS", "ADD_ATTR", "ADD_URI_SAFE_ATTR", "ADD_FORBID_CONTENTS", "table", "tbody", "TRUSTED_TYPES_POLICY", "previousTrustedTypesPolicy", "error", "ALL_SVG_TAGS", "ALL_MATHML_TAGS", "_checkSvgNamespace", "tagName", "parent", "parentTagName", "namespaceURI", "_checkMathMlNamespaceLine truncated
}
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/es/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/fa/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/fr/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/he/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/hi/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/ko/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+6 -6
View File
@@ -1,10 +1,10 @@
{
"version": "1788382788139",
"buildVersion": "1788382788139",
"version": "1788390440675",
"buildVersion": "1788390440675",
"appVersion": "6.7.2",
"buildTime": "2026-09-02T20:59:48.213Z",
"buildId": "1788382788139-2294e38",
"gitHash": "2294e38",
"buildTime": "2026-09-02T23:07:20.764Z",
"buildId": "1788390440675-30e335f",
"gitHash": "30e335f",
"generated": true,
"generatedAt": "2026-09-02T20:59:48.215Z"
"generatedAt": "2026-09-02T23:07:20.766Z"
}
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/ru/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+31 -1
View File
@@ -104,7 +104,37 @@ const CommunityCTA = () => {
React.createElement('div', {
key: 'btns',
style: { display: 'flex', gap: '14px', justifyContent: 'center', flexWrap: 'wrap' }
}, [githubBtn, feedbackBtn])
}, [githubBtn, feedbackBtn]),
// Snap Store, bottom right.
//
// Served from this origin, not snapcraft.io. The site's CSP is
// `img-src 'self' data:` and would block a hotlink anyway, but the
// reason to keep it that way is the product's own claim: fetching a
// badge from someone else's server hands them the address of every
// visitor to a page that promises no servers are involved.
React.createElement('div', {
key: 'snap',
style: {
display: 'flex',
justifyContent: isMobile ? 'center' : 'flex-end',
marginTop: '28px'
}
}, React.createElement('a', {
href: 'https://snapcraft.io/securebit-chat',
target: '_blank',
rel: 'noopener noreferrer',
'aria-label': 'Get it from the Snap Store',
style: { display: 'inline-flex', opacity: 0.9, transition: 'opacity .2s' },
onMouseEnter: (e) => { e.currentTarget.style.opacity = 1; },
onMouseLeave: (e) => { e.currentTarget.style.opacity = 0.9; }
}, React.createElement('img', {
src: '/assets/badges/snap-store.svg',
alt: 'Get it from the Snap Store',
width: 182,
height: 56,
loading: 'lazy',
style: { display: 'block' }
})))
]);
return React.createElement('section', {
+1 -1
View File
@@ -11,7 +11,7 @@ let DYNAMIC_CACHE = 'securebit-pwa-dynamic-v4.7.56';
// Build stamp — rewritten by scripts/post-build.js on every release so this file's
// bytes change each deploy. That is what makes the browser detect a new Service Worker,
// reinstall it, drop stale caches and (via controllerchange) prompt the page to update.
const SW_BUILD_VERSION = '1788382788139';
const SW_BUILD_VERSION = '1788390440675';
// Locale subdirectories, rewritten by scripts/build-i18n.js. Each localized page is a
// separate document at its own URL, so the shell has to be cached and served per
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/uk/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/ur/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>
+24 -24
View File
@@ -30,7 +30,7 @@
<!-- PWA Manifest -->
<link rel="manifest" href="/zh/manifest.json">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
@@ -96,7 +96,7 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1788390440675">
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
@@ -105,7 +105,7 @@
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788382788139">
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1788390440675">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#ff6b35">
@@ -222,7 +222,7 @@
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
both execute in document order after parsing, so React still runs before the
app modules below, but the parser / first paint is no longer blocked. -->
<script defer src="/config/ice-servers.js?v=1788382788139"></script>
<script defer src="/config/ice-servers.js?v=1788390440675"></script>
<script defer src="/libs/react/react.production.min.js"></script>
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
@@ -230,8 +230,8 @@
Its CSS is loaded async via load-async-css.js (not paint-critical). -->
<script defer src="/libs/prism/prism.js"></script>
<!-- Critical, paint-defining CSS stays render-blocking (avoids FOUC / layout shift). -->
<link rel="stylesheet" href="/assets/tailwind.css?v=1788382788139">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788382788139">
<link rel="stylesheet" href="/assets/tailwind.css?v=1788390440675">
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1788390440675">
<!-- Preload only the fonts needed for first paint. fa-solid covers the bulk of UI
icons; fa-regular/fa-brands are loaded on demand by their CSS (rarely on the
first screen). Inter latin 400/700 cover body text and headings/buttons. -->
@@ -239,38 +239,38 @@
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/inter/files/inter-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/src/styles/main.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/components.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/main.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/animations.css?v=1788390440675">
<link rel="stylesheet" href="/src/styles/components.css?v=1788390440675">
<!-- Loads after components.css on purpose: press feedback, material weight,
size-specific tracking and the reduced-motion / -transparency / -contrast
answers all need to settle arguments with the sheets above on source order. -->
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/apple-motion.css?v=1788390440675">
<!-- Last of the hand-written sheets: the mirroring rules must win over anything
above them, and they only ever apply under [dir="rtl"]. -->
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788382788139">
<link rel="stylesheet" href="/src/styles/rtl.css?v=1788390440675">
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
<script defer src="/src/scripts/load-async-css.js?v=1788382788139"></script>
<script defer src="/src/scripts/load-async-css.js?v=1788390440675"></script>
<noscript>
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/libs/prism/prism.css">
</noscript>
<script defer src="/src/scripts/fa-check.js?v=1788382788139"></script>
<script defer src="/src/scripts/fa-check.js?v=1788390440675"></script>
<!-- Update Manager - система принудительного обновления -->
<script defer src="/src/utils/updateManager.js?v=1788382788139"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788382788139"></script>
<script type="module" src="/dist/qr-local.js?v=1788382788139"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788382788139"></script>
<script defer src="/src/utils/updateManager.js?v=1788390440675"></script>
<script type="module" src="/src/components/UpdateChecker.jsx?v=1788390440675"></script>
<script type="module" src="/dist/qr-local.js?v=1788390440675"></script>
<script type="module" src="/src/components/QRScanner.js?v=1788390440675"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/app-boot.js?v=1788382788139"></script>
<script type="module" src="/dist/app.js?v=1788382788139"></script>
<script type="module" src="/dist/app-boot.js?v=1788390440675"></script>
<script type="module" src="/dist/app.js?v=1788390440675"></script>
<script defer src="/src/scripts/pwa-register.js?v=1788382788139"></script>
<script src="/src/pwa/install-prompt.js?v=1788382788139" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788382788139" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788382788139"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788382788139">
<script defer src="/src/scripts/pwa-register.js?v=1788390440675"></script>
<script src="/src/pwa/install-prompt.js?v=1788390440675" type="module"></script>
<script src="/src/pwa/pwa-manager.js?v=1788390440675" type="module"></script>
<script defer src="/src/scripts/pwa-offline-test.js?v=1788390440675"></script>
<link rel="stylesheet" href="/src/styles/pwa.css?v=1788390440675">
</body>
</html>