@networkpro/web 1.12.9 โ†’ 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +65 -1
  2. package/README.md +26 -18
  3. package/cspell.json +1 -0
  4. package/eslint.config.mjs +48 -48
  5. package/netlify/edge-functions/csp-report.js +31 -31
  6. package/package.json +3 -3
  7. package/playwright.config.js +14 -14
  8. package/postcss.config.mjs +1 -1
  9. package/scripts/auditScripts.js +16 -16
  10. package/scripts/bundleCss.js +5 -5
  11. package/scripts/checkEnv.js +6 -6
  12. package/scripts/checkNode.js +10 -10
  13. package/scripts/checkVersions.js +6 -6
  14. package/scripts/flattenHeaders.js +13 -13
  15. package/scripts/generateTest.js +5 -5
  16. package/scripts/openReport.js +3 -3
  17. package/scripts/validateHeaders.js +13 -13
  18. package/src/app.html +0 -9
  19. package/src/hooks.client.ts +1 -1
  20. package/src/hooks.server.js +31 -32
  21. package/src/lib/components/Badges.svelte +10 -10
  22. package/src/lib/components/CodeBlock.svelte +1 -1
  23. package/src/lib/components/ContainerSection.svelte +1 -1
  24. package/src/lib/components/FullWidthSection.svelte +3 -3
  25. package/src/lib/components/LegalNav.svelte +7 -7
  26. package/src/lib/components/Logo.svelte +9 -9
  27. package/src/lib/components/MetaTags.svelte +4 -4
  28. package/src/lib/components/PWAInstallButton.svelte +4 -4
  29. package/src/lib/components/RedirectPage.svelte +4 -4
  30. package/src/lib/components/SocialMedia.svelte +16 -16
  31. package/src/lib/components/foss/FossItemContent.svelte +27 -58
  32. package/src/lib/components/foss/ObtainiumBlock.svelte +64 -0
  33. package/src/lib/components/layout/Footer.svelte +18 -18
  34. package/src/lib/components/layout/HeaderDefault.svelte +16 -16
  35. package/src/lib/components/layout/HeaderHome.svelte +14 -14
  36. package/src/lib/data/fossData.js +22 -10
  37. package/src/lib/images.js +34 -34
  38. package/src/lib/img/obtainium.png +0 -0
  39. package/src/lib/img/obtainium.webp +0 -0
  40. package/src/lib/index.js +15 -15
  41. package/src/lib/meta.js +29 -29
  42. package/src/lib/pages/AboutContent.svelte +24 -24
  43. package/src/lib/pages/FossContent.svelte +13 -13
  44. package/src/lib/pages/HomeContent.svelte +7 -7
  45. package/src/lib/pages/LicenseContent.svelte +39 -39
  46. package/src/lib/pages/PGPContent.svelte +23 -23
  47. package/src/lib/pages/PrivacyContent.svelte +39 -39
  48. package/src/lib/pages/PrivacyDashboard.svelte +12 -12
  49. package/src/lib/pages/TermsConditionsContent.svelte +29 -29
  50. package/src/lib/pages/TermsUseContent.svelte +26 -26
  51. package/src/lib/registerServiceWorker.js +25 -25
  52. package/src/lib/stores/posthog.js +13 -13
  53. package/src/lib/stores/trackingPreferences.js +19 -19
  54. package/src/lib/styles/css/default.css +30 -0
  55. package/src/lib/styles/global.min.css +1 -1
  56. package/src/lib/types/fossTypes.js +9 -2
  57. package/src/lib/unregisterServiceWorker.js +1 -1
  58. package/src/lib/utils/purify.js +4 -4
  59. package/src/lib/utils/utm.js +2 -2
  60. package/src/routes/+error.svelte +4 -4
  61. package/src/routes/+layout.js +6 -6
  62. package/src/routes/+layout.svelte +29 -29
  63. package/src/routes/+page.server.js +2 -2
  64. package/src/routes/+page.svelte +9 -9
  65. package/src/routes/about/+page.server.js +2 -2
  66. package/src/routes/about/+page.svelte +7 -7
  67. package/src/routes/api/mock-csp/+server.js +3 -3
  68. package/src/routes/consultation/+page.svelte +5 -5
  69. package/src/routes/contact/+page.svelte +5 -5
  70. package/src/routes/foss-spotlight/+page.server.js +2 -2
  71. package/src/routes/foss-spotlight/+page.svelte +7 -7
  72. package/src/routes/license/+page.server.js +2 -2
  73. package/src/routes/license/+page.svelte +7 -7
  74. package/src/routes/pgp/+page.server.js +2 -2
  75. package/src/routes/pgp/+page.svelte +7 -7
  76. package/src/routes/pgp/[key]/+server.js +9 -9
  77. package/src/routes/privacy/+page.server.js +2 -2
  78. package/src/routes/privacy/+page.svelte +7 -7
  79. package/src/routes/privacy-dashboard/+page.server.js +2 -2
  80. package/src/routes/privacy-dashboard/+page.svelte +8 -8
  81. package/src/routes/privacy-rights/+page.svelte +5 -5
  82. package/src/routes/status/+page.server.js +2 -2
  83. package/src/routes/terms-conditions/+page.server.js +2 -2
  84. package/src/routes/terms-conditions/+page.svelte +7 -7
  85. package/src/routes/terms-of-use/+page.server.js +2 -2
  86. package/src/routes/terms-of-use/+page.svelte +7 -7
  87. package/src/service-worker.js +86 -86
  88. package/static/bin/heliboard.json +8 -0
  89. package/static/disableSw.js +2 -2
  90. package/static/offline.html +7 -7
  91. package/stylelint.config.js +56 -56
  92. package/svelte.config.js +6 -6
  93. package/tests/e2e/app.spec.js +27 -27
  94. package/tests/e2e/mobile.spec.js +18 -18
  95. package/tests/e2e/shared/helpers.js +4 -4
  96. package/tests/internal/auditCoverage.test.js +24 -24
  97. package/tests/unit/checkEnv.test.js +10 -10
  98. package/tests/unit/checkVersions.test.js +4 -4
  99. package/tests/unit/csp-report.test.js +24 -24
  100. package/tests/unit/demo.test.js +3 -3
  101. package/tests/unit/lib/utils/purify.test.js +12 -12
  102. package/tests/unit/routes/page.svelte.test.js +10 -10
  103. package/tests/unit/unregisterServiceWorker.test.js +5 -5
  104. package/tests/unit/utm.test.js +13 -13
  105. package/vite.config.js +5 -5
  106. package/vitest-setup-client.js +4 -4
  107. package/vitest.config.client.js +15 -15
  108. package/vitest.config.server.js +13 -13
@@ -6,13 +6,13 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ========================================================================== */
8
8
 
9
- import { defaultMeta, meta } from "$lib/meta.js";
9
+ import { defaultMeta, meta } from '$lib/meta.js';
10
10
 
11
11
  export const prerender = false;
12
12
 
13
13
  /** @type {import('./$types').PageServerLoad} */
14
14
  export function load() {
15
15
  return {
16
- meta: meta["/privacy"] || defaultMeta,
16
+ meta: meta['/privacy'] || defaultMeta,
17
17
  };
18
18
  }
@@ -7,18 +7,18 @@ This file is part of Network Pro.
7
7
  ========================================================================== -->
8
8
 
9
9
  <script>
10
- import Badges from "$lib/components/Badges.svelte";
11
- import FullWidthSection from "$lib/components/FullWidthSection.svelte";
12
- import PrivacyContent from "$lib/pages/PrivacyContent.svelte";
13
- import LegalNav from "$lib/components/LegalNav.svelte";
14
- import SocialMedia from "$lib/components/SocialMedia.svelte";
15
- import MetaTags from "$lib/components/MetaTags.svelte";
10
+ import Badges from '$lib/components/Badges.svelte';
11
+ import FullWidthSection from '$lib/components/FullWidthSection.svelte';
12
+ import PrivacyContent from '$lib/pages/PrivacyContent.svelte';
13
+ import LegalNav from '$lib/components/LegalNav.svelte';
14
+ import SocialMedia from '$lib/components/SocialMedia.svelte';
15
+ import MetaTags from '$lib/components/MetaTags.svelte';
16
16
 
17
17
  /**
18
18
  * @type {string}
19
19
  * Style class for the div element.
20
20
  */
21
- const spaceStyle = "spacer";
21
+ const spaceStyle = 'spacer';
22
22
 
23
23
  export let data;
24
24
  </script>
@@ -6,13 +6,13 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ========================================================================== */
8
8
 
9
- import { defaultMeta, meta } from "$lib/meta.js";
9
+ import { defaultMeta, meta } from '$lib/meta.js';
10
10
 
11
11
  export const prerender = false;
12
12
 
13
13
  /** @type {import('./$types').PageServerLoad} */
14
14
  export function load() {
15
15
  return {
16
- meta: meta["/privacy-dashboard"] || defaultMeta,
16
+ meta: meta['/privacy-dashboard'] || defaultMeta,
17
17
  };
18
18
  }
@@ -7,24 +7,24 @@ This file is part of Network Pro.
7
7
  ========================================================================== -->
8
8
 
9
9
  <script>
10
- import Badges from "$lib/components/Badges.svelte";
11
- import FullWidthSection from "$lib/components/FullWidthSection.svelte";
12
- import PrivacyDashboard from "$lib/pages/PrivacyDashboard.svelte";
13
- import LegalNav from "$lib/components/LegalNav.svelte";
14
- import SocialMedia from "$lib/components/SocialMedia.svelte";
15
- import MetaTags from "$lib/components/MetaTags.svelte";
10
+ import Badges from '$lib/components/Badges.svelte';
11
+ import FullWidthSection from '$lib/components/FullWidthSection.svelte';
12
+ import PrivacyDashboard from '$lib/pages/PrivacyDashboard.svelte';
13
+ import LegalNav from '$lib/components/LegalNav.svelte';
14
+ import SocialMedia from '$lib/components/SocialMedia.svelte';
15
+ import MetaTags from '$lib/components/MetaTags.svelte';
16
16
 
17
17
  /**
18
18
  * @type {string}
19
19
  * Style class for the horizontal rule element.
20
20
  */
21
- const hrStyle = "hr-styled";
21
+ const hrStyle = 'hr-styled';
22
22
 
23
23
  /**
24
24
  * @type {string}
25
25
  * Style class for the div element.
26
26
  */
27
- const spaceStyle = "spacer";
27
+ const spaceStyle = 'spacer';
28
28
 
29
29
  export let data;
30
30
  </script>
@@ -7,10 +7,10 @@ This file is part of Network Pro.
7
7
  ========================================================================== -->
8
8
 
9
9
  <script>
10
- import RedirectPage from "$lib/components/RedirectPage.svelte";
11
- import { appendUTM } from "$lib/utils/utm.js";
12
- import { onMount } from "svelte";
13
- import { browser } from "$app/environment";
10
+ import RedirectPage from '$lib/components/RedirectPage.svelte';
11
+ import { appendUTM } from '$lib/utils/utm.js';
12
+ import { onMount } from 'svelte';
13
+ import { browser } from '$app/environment';
14
14
 
15
15
  /** @type {string | null} */
16
16
  let target = null;
@@ -22,7 +22,7 @@ This file is part of Network Pro.
22
22
  if (!browser) return;
23
23
 
24
24
  target = appendUTM(
25
- "https://cloud.neteng.pro/index.php/apps/forms/s/6HpZKZCaLwb6TXYL99nLQM8t",
25
+ 'https://cloud.neteng.pro/index.php/apps/forms/s/6HpZKZCaLwb6TXYL99nLQM8t',
26
26
  );
27
27
  show = true;
28
28
  });
@@ -26,7 +26,7 @@ export const prerender = false;
26
26
  * @returns {{ ok: boolean }} Response indicating successful execution
27
27
  */
28
28
  export function load() {
29
- console.log("[Status Debug] ENV_MODE:", process.env.ENV_MODE);
30
- console.log("[Status Debug] NODE_ENV:", process.env.NODE_ENV);
29
+ console.log('[Status Debug] ENV_MODE:', process.env.ENV_MODE);
30
+ console.log('[Status Debug] NODE_ENV:', process.env.NODE_ENV);
31
31
  return { ok: true };
32
32
  }
@@ -6,13 +6,13 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ========================================================================== */
8
8
 
9
- import { defaultMeta, meta } from "$lib/meta.js";
9
+ import { defaultMeta, meta } from '$lib/meta.js';
10
10
 
11
11
  export const prerender = false;
12
12
 
13
13
  /** @type {import('./$types').PageServerLoad} */
14
14
  export function load() {
15
15
  return {
16
- meta: meta["/terms-conditions"] || defaultMeta,
16
+ meta: meta['/terms-conditions'] || defaultMeta,
17
17
  };
18
18
  }
@@ -7,18 +7,18 @@ This file is part of Network Pro.
7
7
  ========================================================================== -->
8
8
 
9
9
  <script>
10
- import Badges from "$lib/components/Badges.svelte";
11
- import FullWidthSection from "$lib/components/FullWidthSection.svelte";
12
- import TermsConditionsContent from "$lib/pages/TermsConditionsContent.svelte";
13
- import LegalNav from "$lib/components/LegalNav.svelte";
14
- import SocialMedia from "$lib/components/SocialMedia.svelte";
15
- import MetaTags from "$lib/components/MetaTags.svelte";
10
+ import Badges from '$lib/components/Badges.svelte';
11
+ import FullWidthSection from '$lib/components/FullWidthSection.svelte';
12
+ import TermsConditionsContent from '$lib/pages/TermsConditionsContent.svelte';
13
+ import LegalNav from '$lib/components/LegalNav.svelte';
14
+ import SocialMedia from '$lib/components/SocialMedia.svelte';
15
+ import MetaTags from '$lib/components/MetaTags.svelte';
16
16
 
17
17
  /**
18
18
  * @type {string}
19
19
  * Style class for the div element.
20
20
  */
21
- const spaceStyle = "spacer";
21
+ const spaceStyle = 'spacer';
22
22
 
23
23
  export let data;
24
24
  </script>
@@ -6,13 +6,13 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ========================================================================== */
8
8
 
9
- import { defaultMeta, meta } from "$lib/meta.js";
9
+ import { defaultMeta, meta } from '$lib/meta.js';
10
10
 
11
11
  export const prerender = false;
12
12
 
13
13
  /** @type {import('./$types').PageServerLoad} */
14
14
  export function load() {
15
15
  return {
16
- meta: meta["/terms-of-use"] || defaultMeta,
16
+ meta: meta['/terms-of-use'] || defaultMeta,
17
17
  };
18
18
  }
@@ -7,18 +7,18 @@ This file is part of Network Pro.
7
7
  ========================================================================== -->
8
8
 
9
9
  <script>
10
- import Badges from "$lib/components/Badges.svelte";
11
- import FullWidthSection from "$lib/components/FullWidthSection.svelte";
12
- import TermsUseContent from "$lib/pages/TermsUseContent.svelte";
13
- import LegalNav from "$lib/components/LegalNav.svelte";
14
- import SocialMedia from "$lib/components/SocialMedia.svelte";
15
- import MetaTags from "$lib/components/MetaTags.svelte";
10
+ import Badges from '$lib/components/Badges.svelte';
11
+ import FullWidthSection from '$lib/components/FullWidthSection.svelte';
12
+ import TermsUseContent from '$lib/pages/TermsUseContent.svelte';
13
+ import LegalNav from '$lib/components/LegalNav.svelte';
14
+ import SocialMedia from '$lib/components/SocialMedia.svelte';
15
+ import MetaTags from '$lib/components/MetaTags.svelte';
16
16
 
17
17
  /**
18
18
  * @type {string}
19
19
  * Style class for the div element.
20
20
  */
21
- const spaceStyle = "spacer";
21
+ const spaceStyle = 'spacer';
22
22
 
23
23
  export let data;
24
24
  </script>
@@ -13,13 +13,13 @@ const sw = /** @type {ServiceWorkerGlobalScope} */ (
13
13
 
14
14
  /// <reference types="vite/client" />
15
15
 
16
- const isDev = location.hostname === "localhost";
16
+ const isDev = location.hostname === 'localhost';
17
17
  const disallowedHosts = [
18
- "us.i.posthog.com", // Add PostHog to disallowed hosts
19
- "posthog.com", // Add PostHog to disallowed hosts
18
+ 'us.i.posthog.com', // Add PostHog to disallowed hosts
19
+ 'posthog.com', // Add PostHog to disallowed hosts
20
20
  ];
21
21
 
22
- import { build, files, version } from "$service-worker";
22
+ import { build, files, version } from '$service-worker';
23
23
 
24
24
  /** @type {string} */
25
25
  const CACHE = `cache-${version}`;
@@ -28,38 +28,38 @@ const CACHE = `cache-${version}`;
28
28
  const excludedAssets = [];
29
29
 
30
30
  const IGNORE_PATHS = new Set([
31
- "/.well-known/security.txt.asc",
32
- "/img/banner-1280x640.png",
33
- "/img/logo-transparent.png",
34
- "/img/logo.png",
35
- "/img/svelte.png",
36
- "/pgp/pgp-github.png",
37
- "/pgp/pgp-github.webp",
38
- "/pgp/contact@s.neteng.pro.asc",
39
- "/pgp/github@sl.neteng.cc.asc",
40
- "/pgp/security@s.neteng.pro.asc",
41
- "/pgp/support@neteng.pro.asc",
42
- "/pgp/vcard.png",
43
- "/pgp/vcard.webp",
44
- "/screenshots/desktop-foss.png",
45
- "/webfonts/fa-brands-400.ttf",
46
- "/webfonts/fa-solid-900.ttf",
47
- "/robots.txt",
48
- "/sitemap.xml",
49
- "/CNAME",
31
+ '/.well-known/security.txt.asc',
32
+ '/img/banner-1280x640.png',
33
+ '/img/logo-transparent.png',
34
+ '/img/logo.png',
35
+ '/img/svelte.png',
36
+ '/pgp/pgp-github.png',
37
+ '/pgp/pgp-github.webp',
38
+ '/pgp/contact@s.neteng.pro.asc',
39
+ '/pgp/github@sl.neteng.cc.asc',
40
+ '/pgp/security@s.neteng.pro.asc',
41
+ '/pgp/support@neteng.pro.asc',
42
+ '/pgp/vcard.png',
43
+ '/pgp/vcard.webp',
44
+ '/screenshots/desktop-foss.png',
45
+ '/webfonts/fa-brands-400.ttf',
46
+ '/webfonts/fa-solid-900.ttf',
47
+ '/robots.txt',
48
+ '/sitemap.xml',
49
+ '/CNAME',
50
50
  ]);
51
51
 
52
52
  /** @type {string[]} */
53
53
  const ASSETS = [
54
54
  ...new Set(
55
- [...build, ...files, "/offline.html"].filter((path) => {
55
+ [...build, ...files, '/offline.html'].filter((path) => {
56
56
  try {
57
57
  const url = new URL(path, location.origin);
58
58
  const hostname = url.hostname;
59
59
 
60
60
  const shouldExclude =
61
- path.startsWith("http") ||
62
- path.startsWith("/bin/") ||
61
+ path.startsWith('http') ||
62
+ path.startsWith('/bin/') ||
63
63
  disallowedHosts.some(
64
64
  (host) => hostname === host || hostname.endsWith(`.${host}`),
65
65
  ) ||
@@ -69,7 +69,7 @@ const ASSETS = [
69
69
  return !shouldExclude;
70
70
  } catch (err) {
71
71
  if (isDev)
72
- console.warn("[SW] URL parse failed, skipping path:", path, err);
72
+ console.warn('[SW] URL parse failed, skipping path:', path, err);
73
73
  excludedAssets.push(path);
74
74
  return true;
75
75
  }
@@ -81,41 +81,41 @@ const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
81
81
 
82
82
  /** @type {string[]} */
83
83
  const REQUIRED_ASSETS = [
84
- "/disableSw.js",
85
- "/favicon.ico",
86
- "/icon-192x192.png",
87
- "/icon-512x512-maskable.png",
88
- "/icon-512x512.png",
89
- "/icon-contact.png",
90
- "/icon-services.png",
91
- "/icon-splash.png",
92
- "/img/banner-og-1200x630.png",
93
- "/pgp/pgp-contact.png",
94
- "/pgp/pgp-contact.webp",
95
- "/pgp/pgp-security.png",
96
- "/pgp/pgp-security.webp",
97
- "/pgp/pgp-support.png",
98
- "/pgp/pgp-support.webp",
99
- "/manifest.json",
100
- "/offline.html",
101
- "/offline.min.css",
102
- "/screenshots/desktop-about.png",
103
- "/screenshots/desktop-home.png",
104
- "/screenshots/mobile-foss.png",
105
- "/screenshots/mobile-home.png",
106
- "/styles/brands.min.css",
107
- "/styles/fontawesome.min.css",
108
- "/styles/global.min.css",
109
- "/styles/solid.min.css",
110
- "/webfonts/fa-brands-400.woff2",
111
- "/webfonts/fa-solid-900.woff2",
112
- "/.well-known/dnt-policy.txt",
113
- "/.well-known/gpc.json",
84
+ '/disableSw.js',
85
+ '/favicon.ico',
86
+ '/icon-192x192.png',
87
+ '/icon-512x512-maskable.png',
88
+ '/icon-512x512.png',
89
+ '/icon-contact.png',
90
+ '/icon-services.png',
91
+ '/icon-splash.png',
92
+ '/img/banner-og-1200x630.png',
93
+ '/pgp/pgp-contact.png',
94
+ '/pgp/pgp-contact.webp',
95
+ '/pgp/pgp-security.png',
96
+ '/pgp/pgp-security.webp',
97
+ '/pgp/pgp-support.png',
98
+ '/pgp/pgp-support.webp',
99
+ '/manifest.json',
100
+ '/offline.html',
101
+ '/offline.min.css',
102
+ '/screenshots/desktop-about.png',
103
+ '/screenshots/desktop-home.png',
104
+ '/screenshots/mobile-foss.png',
105
+ '/screenshots/mobile-home.png',
106
+ '/styles/brands.min.css',
107
+ '/styles/fontawesome.min.css',
108
+ '/styles/global.min.css',
109
+ '/styles/solid.min.css',
110
+ '/webfonts/fa-brands-400.woff2',
111
+ '/webfonts/fa-solid-900.woff2',
112
+ '/.well-known/dnt-policy.txt',
113
+ '/.well-known/gpc.json',
114
114
  ];
115
115
 
116
116
  if (isDev) {
117
- console.log("[SW] Assets to precache:", ASSETS);
118
- console.log("[SW] Excluded assets:", uniqueExcludedAssets);
117
+ console.log('[SW] Assets to precache:', ASSETS);
118
+ console.log('[SW] Excluded assets:', uniqueExcludedAssets);
119
119
  }
120
120
 
121
121
  /**
@@ -152,7 +152,7 @@ async function cacheAssetsSafely(cache, assets, required = []) {
152
152
 
153
153
  const missing = required.filter((req) => !cachedPaths.includes(req));
154
154
  if (missing.length > 0) {
155
- const errorMsg = `[SW] โš ๏ธ Missing required assets: ${missing.join(", ")}`;
155
+ const errorMsg = `[SW] โš ๏ธ Missing required assets: ${missing.join(', ')}`;
156
156
  if (isDev) throw new Error(errorMsg);
157
157
  console.error(errorMsg);
158
158
  }
@@ -161,8 +161,8 @@ async function cacheAssetsSafely(cache, assets, required = []) {
161
161
  }
162
162
 
163
163
  // ๐Ÿ”น Install event
164
- sw.addEventListener("install", (event) => {
165
- if (isDev) console.log("[SW] Install event");
164
+ sw.addEventListener('install', (event) => {
165
+ if (isDev) console.log('[SW] Install event');
166
166
 
167
167
  event.waitUntil(
168
168
  (async () => {
@@ -172,29 +172,29 @@ sw.addEventListener("install", (event) => {
172
172
  try {
173
173
  cachedPaths = await cacheAssetsSafely(cache, ASSETS, REQUIRED_ASSETS);
174
174
  if (isDev) {
175
- console.log("[SW] Cached assets:", cachedPaths);
175
+ console.log('[SW] Cached assets:', cachedPaths);
176
176
  }
177
177
  } catch (err) {
178
178
  if (isDev) throw err;
179
- console.warn("[SW] Error while precaching (non-fatal in prod):", err);
179
+ console.warn('[SW] Error while precaching (non-fatal in prod):', err);
180
180
  }
181
181
 
182
182
  await sw.skipWaiting();
183
- if (isDev) console.log("[SW] skipWaiting() called");
183
+ if (isDev) console.log('[SW] skipWaiting() called');
184
184
  })(),
185
185
  );
186
186
  });
187
187
 
188
188
  // ๐Ÿ”น Activate event
189
- sw.addEventListener("activate", (event) => {
190
- if (isDev) console.log("[SW] Activate event");
189
+ sw.addEventListener('activate', (event) => {
190
+ if (isDev) console.log('[SW] Activate event');
191
191
  event.waitUntil(
192
192
  (async () => {
193
193
  const tasks = [];
194
194
 
195
195
  if (sw.registration.navigationPreload) {
196
196
  tasks.push(sw.registration.navigationPreload.enable());
197
- if (isDev) console.log("[SW] Navigation preload enabled");
197
+ if (isDev) console.log('[SW] Navigation preload enabled');
198
198
  }
199
199
 
200
200
  tasks.push(
@@ -203,7 +203,7 @@ sw.addEventListener("activate", (event) => {
203
203
  keys
204
204
  .filter((key) => key !== CACHE)
205
205
  .map((key) => {
206
- if (isDev) console.log("[SW] Deleting old cache:", key);
206
+ if (isDev) console.log('[SW] Deleting old cache:', key);
207
207
  return caches.delete(key);
208
208
  }),
209
209
  ),
@@ -213,8 +213,8 @@ sw.addEventListener("activate", (event) => {
213
213
  await Promise.all(tasks);
214
214
  await sw.clients.claim();
215
215
  if (isDev) {
216
- console.log("[SW] clients.claim() called");
217
- console.log("[SW] Scope:", sw.registration.scope);
216
+ console.log('[SW] clients.claim() called');
217
+ console.log('[SW] Scope:', sw.registration.scope);
218
218
  }
219
219
  })(),
220
220
  );
@@ -232,16 +232,16 @@ function shouldSkipDevModule(url) {
232
232
  if (!isDev) return false;
233
233
 
234
234
  return (
235
- url.pathname.startsWith("/@fs") ||
236
- url.pathname.startsWith("/node_modules") ||
237
- url.pathname.includes(".vite") ||
238
- url.pathname.includes(".svelte-kit") ||
235
+ url.pathname.startsWith('/@fs') ||
236
+ url.pathname.startsWith('/node_modules') ||
237
+ url.pathname.includes('.vite') ||
238
+ url.pathname.includes('.svelte-kit') ||
239
239
  !!url.pathname.match(/\.(js|ts|svelte)$/)
240
240
  );
241
241
  }
242
242
 
243
243
  // ๐Ÿ”น Fetch event
244
- sw.addEventListener("fetch", (event) => {
244
+ sw.addEventListener('fetch', (event) => {
245
245
  const requestUrl = new URL(event.request.url);
246
246
 
247
247
  // โœ… Skip cross-origin requests
@@ -250,23 +250,23 @@ sw.addEventListener("fetch", (event) => {
250
250
  // โœ… Skip internal dev/module files (only in dev)
251
251
  if (shouldSkipDevModule(requestUrl)) return;
252
252
 
253
- if (isDev) console.log("[SW] Fetch intercepted:", event.request.url);
253
+ if (isDev) console.log('[SW] Fetch intercepted:', event.request.url);
254
254
 
255
255
  event.respondWith(
256
256
  (async () => {
257
257
  const cached = await caches.match(event.request);
258
258
  if (cached) {
259
- if (isDev) console.log("[SW] Serving from cache:", event.request.url);
259
+ if (isDev) console.log('[SW] Serving from cache:', event.request.url);
260
260
  return cached;
261
261
  }
262
262
 
263
263
  try {
264
- if (event.request.mode === "navigate") {
264
+ if (event.request.mode === 'navigate') {
265
265
  const preloadResponse = await event.preloadResponse;
266
266
  if (preloadResponse) {
267
267
  if (isDev) {
268
268
  console.log(
269
- "[SW] Using preload response for:",
269
+ '[SW] Using preload response for:',
270
270
  event.request.url,
271
271
  );
272
272
  }
@@ -275,23 +275,23 @@ sw.addEventListener("fetch", (event) => {
275
275
  }
276
276
 
277
277
  if (isDev)
278
- console.log("[SW] Fetching from network:", event.request.url);
278
+ console.log('[SW] Fetching from network:', event.request.url);
279
279
 
280
280
  return await fetch(event.request);
281
281
  } catch (err) {
282
282
  if (isDev) {
283
283
  console.warn(
284
- "[SW] Fetch failed; offline fallback used:",
284
+ '[SW] Fetch failed; offline fallback used:',
285
285
  event.request.url,
286
286
  err,
287
287
  );
288
288
  }
289
289
 
290
- if (event.request.mode === "navigate") {
291
- const offline = await caches.match("/offline.html");
290
+ if (event.request.mode === 'navigate') {
291
+ const offline = await caches.match('/offline.html');
292
292
  if (offline) return offline;
293
- return new Response("<h1>Offline</h1>", {
294
- headers: { "Content-Type": "text/html" },
293
+ return new Response('<h1>Offline</h1>', {
294
+ headers: { 'Content-Type': 'text/html' },
295
295
  });
296
296
  }
297
297
 
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "helium314.keyboard",
3
+ "url": "https://github.com/Helium314/HeliBoard",
4
+ "author": "Helium314",
5
+ "name": "HeliBoard",
6
+ "preferredApkIndex": 0,
7
+ "additionalSettings": "{\"includePrereleases\":false,\"fallbackToOlderReleases\":true,\"filterReleaseTitlesByRegEx\":\"\",\"filterReleaseNotesByRegEx\":\"\",\"verifyLatestTag\":false,\"dontSortReleasesList\":false,\"useLatestAssetDateAsReleaseDate\":false,\"trackOnly\":false,\"versionExtractionRegEx\":\"\",\"matchGroupToUse\":\"\",\"versionDetection\":true,\"releaseDateAsVersion\":false,\"useVersionCodeAsOSVersion\":false,\"apkFilterRegEx\":\"release\",\"invertAPKFilter\":false,\"autoApkFilterByArch\":true,\"appName\":\"HeliBoard\",\"shizukuPretendToBeGooglePlay\":false,\"exemptFromBackgroundUpdates\":false,\"skipUpdateNotifications\":false,\"about\":\"HeliBoard is a privacy-conscious and customizable open-source keyboard, based on AOSP / OpenBoard. Does not use internet permission, and thus is 100% offline.\",\"appAuthor\":\"Helium314\"}"
8
+ }
@@ -14,7 +14,7 @@ This file is part of Network Pro.
14
14
  * @updated 2025-05-29
15
15
  */
16
16
 
17
- if (location.search.includes("nosw")) {
17
+ if (location.search.includes('nosw')) {
18
18
  window.__DISABLE_SW__ = true;
19
- console.warn("๐Ÿงช Service worker disabled via ?nosw flag in URL.");
19
+ console.warn('๐Ÿงช Service worker disabled via ?nosw flag in URL.');
20
20
  }
@@ -43,10 +43,10 @@
43
43
  function updateTimestamp() {
44
44
  const now = new Date();
45
45
  const timeStr = now.toLocaleTimeString([], {
46
- hour: "2-digit",
47
- minute: "2-digit",
46
+ hour: '2-digit',
47
+ minute: '2-digit',
48
48
  });
49
- document.getElementById("timestamp").textContent = timeStr;
49
+ document.getElementById('timestamp').textContent = timeStr;
50
50
  }
51
51
 
52
52
  // Check connection status periodically
@@ -64,17 +64,17 @@
64
64
  setInterval(updateTimestamp, 60000);
65
65
 
66
66
  // Also listen for online event
67
- window.addEventListener("online", () => {
67
+ window.addEventListener('online', () => {
68
68
  window.location.reload();
69
69
  });
70
70
 
71
71
  // Prevent default action for offline links
72
72
  document
73
- .getElementById("contact-link")
74
- .addEventListener("click", function (e) {
73
+ .getElementById('contact-link')
74
+ .addEventListener('click', function (e) {
75
75
  if (!navigator.onLine) {
76
76
  e.preventDefault();
77
- alert("This link will be available when you are back online.");
77
+ alert('This link will be available when you are back online.');
78
78
  }
79
79
  });
80
80
  </script>