@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
@@ -3,4 +3,4 @@ Copyright © 2025 Network Pro Strategies (Network Pro™)
3
3
  SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
4
4
  This file is part of Network Pro.
5
5
  ========================================================================== */
6
- html{-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{margin:.67em 0;font-size:2em}hr{box-sizing:content-box}pre{font-family:monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:100%;line-height:1.15}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted buttontext}fieldset{padding:.35em .75em .625em}legend{color:inherit;box-sizing:border-box;white-space:normal;max-width:100%;padding:0;display:table}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}details{display:block}summary{display:list-item}template{display:none}html{color:#222;scroll-behavior:smooth;font-size:1em;line-height:1.4}::-moz-selection{text-shadow:none;background:#191919}::selection{text-shadow:none;background:#191919}hr{border:0;border-top:1px solid #ccc;height:1px;margin:1em 0;padding:0;display:block;overflow:visible}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}body{color:#fafafa;background-color:#191919;margin:10px;font-family:Arial,Helvetica,sans-serif}a{text-decoration:none}a:link{color:#ffc627}a:hover,a:active{color:#ffc627;text-decoration:underline}a:visited{color:#7f6227}a:focus-visible{color:#191919;outline-offset:4px;background-color:#ffc627;outline:2px solid #ffc627}a:focus:not(:focus-visible){color:inherit;background-color:#0000;outline:none}a:visited:hover{color:#7f6227}.hidden,[hidden]{display:none!important}.visually-hidden{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.visually-hidden.focusable:active,.visually-hidden.focusable:focus{clip:auto;width:auto;height:auto;white-space:inherit;margin:0;position:static;overflow:visible}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}@media print{*,:before,:after{color:#000!important;box-shadow:none!important;text-shadow:none!important;background:#fff!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href)")"}abbr[title]:after{content:" (" attr(title)")"}a[href^=\#]:after,a[href^=javascript\:]:after{content:""}pre{white-space:pre-wrap!important}pre,blockquote{page-break-inside:avoid;border:1px solid #999}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.full-width-section{background-position:50%;background-size:cover;width:100%;max-width:1920px;margin:0 auto}.container{max-width:1200px;margin:0 auto;padding:0 12px}.readable{max-width:900px;margin:0 auto}header,footer{width:100%}header .container,footer .container{max-width:1200px;margin:0 auto;padding:20px 12px}.gh{border-collapse:collapse;border-spacing:0;margin:0 auto}.gh td,.gh th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.gh .gh-tcell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.gh,.gh col{width:auto!important}.gh-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.soc{border-collapse:collapse;border-spacing:0;margin:0 auto}.soc td,.soc th{border-collapse:collapse;word-break:normal;padding:8px;overflow:hidden}.soc .soc-fa{text-align:center;vertical-align:middle}@media screen and (width<=767px){.soc,.soc col{width:auto!important}.soc-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.foss{border-collapse:collapse;border-spacing:0}.foss td,.foss th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.foss .foss-cell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.foss,.foss col{width:auto!important}.foss-wrap{-webkit-overflow-scrolling:touch;overflow-x:auto}}.bnav{text-align:center;border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav td,.bnav th{text-align:center;vertical-align:middle;word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav .bnav-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav,.bnav col{width:auto!important}.bnav-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.bnav2{border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav2 td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav2 th{word-break:normal;border-style:none;padding:12px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.bnav2 .bnav2-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav2,.bnav2 col{width:auto!important}.bnav2-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.pgp{border-collapse:collapse;border-spacing:0;margin:0 auto}.pgp td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp th{word-break:normal;border:1px solid #000;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp .pgp-col1{text-align:right;vertical-align:middle;padding-right:1rem}.pgp .pgp-col2{text-align:left;vertical-align:middle;padding-left:1rem}@media screen and (width<=767px){.pgp,.pgp col{width:auto!important}.pgp-wrap{-webkit-overflow-scrolling:touch;margin:2rem 0 auto;overflow-x:auto}}.logo{margin-left:auto;margin-right:auto;display:block}.index-title1{text-align:center;font-style:italic;font-weight:700}.index-title2{letter-spacing:-.015em;text-align:center;font-variant:small-caps;font-size:1.25rem;line-height:1.625rem}.index1{letter-spacing:-.035em;text-align:center;font-style:italic;font-weight:700;line-height:2.125rem}.index2{letter-spacing:-.035em;text-align:center;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.index3{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem}.index4{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem;text-decoration:underline}.subhead{letter-spacing:-.035em;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.bold{font-weight:700}.emphasis{font-style:italic}.uline{text-decoration:underline}.bolditalic{font-style:italic;font-weight:700}.bquote{border-left:3px solid #9e9e9e;margin-left:30px;padding-left:10px;font-style:italic}.small-text{font-size:.75rem;line-height:1.125rem}.large-text-center{text-align:center;font-size:1.25rem;line-height:1.75rem}.prewrap{white-space:pre-wrap;display:block}.hr-styled{width:75%;margin:auto}.center-text{text-align:center}.copyright{text-align:center;font-size:.75rem;line-height:1.125rem}.gold{color:#ffc627}.visited{color:#7f6227}.goldseparator{color:#ffc627;margin:0 .5rem}.center-nav{text-align:center;padding:5px;font-size:1rem;line-height:1.5rem}.block{overflow-wrap:break-word;resize:none;white-space:normal;word-break:normal;background:0 0;border:none;border-radius:0;outline:none;width:100%;font-family:monospace;font-size:.875rem;line-height:1.125rem}.fingerprint{white-space:pre-line;font-weight:700;display:block}.pgp-image{width:150px;height:150px}.spacer{margin:2rem 0}.separator{margin:0 .5rem}.emoji{margin-right:8px}.headline{margin-bottom:4px;font-style:italic;font-weight:700;display:block}.label{font-family:inherit;font-weight:700}.description{font-family:inherit;font-style:normal;font-weight:400;display:inline}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.pgp-entry{flex-wrap:wrap;align-items:center;gap:2rem;margin-bottom:2rem;display:flex}.pgp-text{flex:2;min-width:250px}.pgp-qr{flex:1;min-width:150px}
6
+ html{-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{margin:.67em 0;font-size:2em}hr{box-sizing:content-box}pre{font-family:monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:100%;line-height:1.15}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted buttontext}fieldset{padding:.35em .75em .625em}legend{color:inherit;box-sizing:border-box;white-space:normal;max-width:100%;padding:0;display:table}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}details{display:block}summary{display:list-item}template{display:none}html{color:#222;scroll-behavior:smooth;font-size:1em;line-height:1.4}::-moz-selection{text-shadow:none;background:#191919}::selection{text-shadow:none;background:#191919}hr{border:0;border-top:1px solid #ccc;height:1px;margin:1em 0;padding:0;display:block;overflow:visible}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}body{color:#fafafa;background-color:#191919;margin:10px;font-family:Arial,Helvetica,sans-serif}a{text-decoration:none}a:link{color:#ffc627}a:hover,a:active{color:#ffc627;text-decoration:underline}a:visited{color:#7f6227}a:focus-visible{color:#191919;outline-offset:4px;background-color:#ffc627;outline:2px solid #ffc627}a:focus:not(:focus-visible){color:inherit;background-color:#0000;outline:none}a:visited:hover{color:#7f6227}.hidden,[hidden]{display:none!important}.visually-hidden{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.visually-hidden.focusable:active,.visually-hidden.focusable:focus{clip:auto;width:auto;height:auto;white-space:inherit;margin:0;position:static;overflow:visible}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}@media print{*,:before,:after{color:#000!important;box-shadow:none!important;text-shadow:none!important;background:#fff!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href)")"}abbr[title]:after{content:" (" attr(title)")"}a[href^=\#]:after,a[href^=javascript\:]:after{content:""}pre{white-space:pre-wrap!important}pre,blockquote{page-break-inside:avoid;border:1px solid #999}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.full-width-section{background-position:50%;background-size:cover;width:100%;max-width:1920px;margin:0 auto}.container{max-width:1200px;margin:0 auto;padding:0 12px}.readable{max-width:900px;margin:0 auto}header,footer{width:100%}header .container,footer .container{max-width:1200px;margin:0 auto;padding:20px 12px}.gh{border-collapse:collapse;border-spacing:0;margin:0 auto}.gh td,.gh th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.gh .gh-tcell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.gh,.gh col{width:auto!important}.gh-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.soc{border-collapse:collapse;border-spacing:0;margin:0 auto}.soc td,.soc th{border-collapse:collapse;word-break:normal;padding:8px;overflow:hidden}.soc .soc-fa{text-align:center;vertical-align:middle}@media screen and (width<=767px){.soc,.soc col{width:auto!important}.soc-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.foss{border-collapse:collapse;border-spacing:0}.foss td,.foss th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.foss .foss-cell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.foss,.foss col{width:auto!important}.foss-wrap{-webkit-overflow-scrolling:touch;overflow-x:auto}}.bnav{text-align:center;border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav td,.bnav th{text-align:center;vertical-align:middle;word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav .bnav-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav,.bnav col{width:auto!important}.bnav-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.bnav2{border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav2 td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav2 th{word-break:normal;border-style:none;padding:12px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.bnav2 .bnav2-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav2,.bnav2 col{width:auto!important}.bnav2-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.pgp{border-collapse:collapse;border-spacing:0;margin:0 auto}.pgp td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp th{word-break:normal;border:1px solid #000;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp .pgp-col1{text-align:right;vertical-align:middle;padding-right:1rem}.pgp .pgp-col2{text-align:left;vertical-align:middle;padding-left:1rem}@media screen and (width<=767px){.pgp,.pgp col{width:auto!important}.pgp-wrap{-webkit-overflow-scrolling:touch;margin:2rem 0 auto;overflow-x:auto}}.logo{margin-left:auto;margin-right:auto;display:block}.index-title1{text-align:center;font-style:italic;font-weight:700}.index-title2{letter-spacing:-.015em;text-align:center;font-variant:small-caps;font-size:1.25rem;line-height:1.625rem}.index1{letter-spacing:-.035em;text-align:center;font-style:italic;font-weight:700;line-height:2.125rem}.index2{letter-spacing:-.035em;text-align:center;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.index3{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem}.index4{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem;text-decoration:underline}.subhead{letter-spacing:-.035em;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.bold{font-weight:700}.emphasis{font-style:italic}.uline{text-decoration:underline}.bolditalic{font-style:italic;font-weight:700}.bquote{border-left:3px solid #9e9e9e;margin-left:30px;padding-left:10px;font-style:italic}.small-text{font-size:.75rem;line-height:1.125rem}.large-text-center{text-align:center;font-size:1.25rem;line-height:1.75rem}.prewrap{white-space:pre-wrap;display:block}.hr-styled{width:75%;margin:auto}.center-text{text-align:center}.copyright{text-align:center;font-size:.75rem;line-height:1.125rem}.gold{color:#ffc627}.visited{color:#7f6227}.goldseparator{color:#ffc627;margin:0 .5rem}.center-nav{text-align:center;padding:5px;font-size:1rem;line-height:1.5rem}.block{overflow-wrap:break-word;resize:none;white-space:normal;word-break:normal;background:0 0;border:none;border-radius:0;outline:none;width:100%;font-family:monospace;font-size:.875rem;line-height:1.125rem}.fingerprint{white-space:pre-line;font-weight:700;display:block}.pgp-image{width:150px;height:150px}.spacer{margin:2rem 0}.separator{margin:0 .5rem}.emoji{margin-right:8px}.headline{margin-bottom:4px;font-style:italic;font-weight:700;display:block}.label{font-family:inherit;font-weight:700}.description{font-family:inherit;font-style:normal;font-weight:400;display:inline}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.pgp-entry{flex-wrap:wrap;align-items:center;gap:2rem;margin-bottom:2rem;display:flex}.pgp-text{flex:2;min-width:250px}.pgp-qr{flex:1;min-width:150px}.obtainium-direct-label{margin:.25rem 0 .75rem;font-weight:700}.obtainium-manual-label{margin-top:.75rem;font-weight:700}.obtainium-img{width:201px;height:60px;margin-bottom:.25rem}.obtainium-margin{margin-left:4px}.obtainium-fa-down{color:#ffc627;margin-left:4px}.obtainium-icon{width:50px;height:50px}
@@ -12,7 +12,7 @@ This file is part of Network Pro.
12
12
  * src/lib/components/foss/FossItemContent.svelte
13
13
  * @module src/lib/types
14
14
  * @author SunDevil311
15
- * @updated 2025-06-03
15
+ * @updated 2025-06-12
16
16
  */
17
17
 
18
18
  /**
@@ -22,7 +22,13 @@ This file is part of Network Pro.
22
22
  * @property {string} [imgAlt]
23
23
  * @property {string} [downloadText]
24
24
  * @property {string} [downloadHref]
25
- * @property {boolean} [hideLabels]
25
+ */
26
+
27
+ /**
28
+ * @typedef {object} FossObtainium
29
+ * @property {string} href // Link for Obtainium intent
30
+ * @property {string} label // Text for the manual config download link
31
+ * @property {string} download // Filename for the downloaded config
26
32
  */
27
33
 
28
34
  /**
@@ -37,4 +43,5 @@ This file is part of Network Pro.
37
43
  * @property {Array<any>} features
38
44
  * @property {Array<string>} notes
39
45
  * @property {Array<FossLink>} links
46
+ * @property {FossObtainium} [obtainium]
40
47
  */
@@ -13,7 +13,7 @@ export function unregisterServiceWorker() {
13
13
  if ('serviceWorker' in navigator) {
14
14
  navigator.serviceWorker.getRegistrations().then((registrations) => {
15
15
  registrations.forEach((reg) => reg.unregister());
16
- console.log("🧹 All service workers unregistered.");
16
+ console.log('🧹 All service workers unregistered.');
17
17
  });
18
18
  }
19
19
  }
@@ -15,7 +15,7 @@ This file is part of Network Pro.
15
15
  * @updated 2025-06-01
16
16
  */
17
17
 
18
- import createDOMPurify from "dompurify";
18
+ import createDOMPurify from 'dompurify';
19
19
 
20
20
  /**
21
21
  * @typedef {ReturnType<import('dompurify').default>} DOMPurifyInstance
@@ -37,13 +37,13 @@ let jsdomWindow = null;
37
37
  export async function getDOMPurify() {
38
38
  if (DOMPurifyInstance) return DOMPurifyInstance;
39
39
 
40
- if (typeof window !== "undefined") {
40
+ if (typeof window !== 'undefined') {
41
41
  // ✅ Client-side: use native window
42
42
  DOMPurifyInstance = createDOMPurify(window);
43
43
  } else {
44
44
  // ✅ SSR: dynamically import jsdom to avoid bundling
45
- const { JSDOM } = await import("jsdom");
46
- jsdomWindow = jsdomWindow || new JSDOM("").window;
45
+ const { JSDOM } = await import('jsdom');
46
+ jsdomWindow = jsdomWindow || new JSDOM('').window;
47
47
  DOMPurifyInstance = createDOMPurify(jsdomWindow);
48
48
  }
49
49
 
@@ -20,8 +20,8 @@ This file is part of Network Pro.
20
20
  * @returns {string | null}
21
21
  */
22
22
  export function appendUTM(url) {
23
- if (typeof window === "undefined") return null;
23
+ if (typeof window === 'undefined') return null;
24
24
 
25
- const utm = new URLSearchParams(window.location.search).get("utm_source");
25
+ const utm = new URLSearchParams(window.location.search).get('utm_source');
26
26
  return utm ? `${url}?utm_source=${encodeURIComponent(utm)}` : url;
27
27
  }
@@ -24,21 +24,21 @@ This file is part of Network Pro.
24
24
  */
25
25
  export let error;
26
26
 
27
- const centerText = "center-text";
27
+ const centerText = 'center-text';
28
28
 
29
29
  // Get the pathname from the URL if available
30
30
  const pathname =
31
- typeof window !== "undefined" ? window.location.pathname : "/";
31
+ typeof window !== 'undefined' ? window.location.pathname : '/';
32
32
  </script>
33
33
 
34
34
  <main>
35
35
  <h1 class={centerText}
36
- >{status} - {status === 404 ? "Page Not Found" : "Error"}</h1>
36
+ >{status} - {status === 404 ? 'Page Not Found' : 'Error'}</h1>
37
37
  <p class={centerText}>
38
38
  {#if status === 404}
39
39
  The page "{pathname}" does not exist.
40
40
  {:else}
41
- {error?.message || "An error occurred"}
41
+ {error?.message || 'An error occurred'}
42
42
  {/if}
43
43
  </p>
44
44
  </main>
@@ -12,27 +12,27 @@ This file is part of Network Pro.
12
12
  * @property {string} description - The description of the page
13
13
  */
14
14
 
15
- import { meta as routeMeta } from "$lib/meta.js"; // Import meta from $lib/meta.js and alias it
15
+ import { meta as routeMeta } from '$lib/meta.js'; // Import meta from $lib/meta.js and alias it
16
16
 
17
17
  /**
18
18
  * Fallback metadata to satisfy typing in +layout.svelte and +page.svelte.
19
19
  * Actual meta content is provided per-route via +page.server.js.
20
20
  */
21
21
  const fallbackMeta = {
22
- title: "Security, Networking, Privacy — Network Pro™",
22
+ title: 'Security, Networking, Privacy — Network Pro™',
23
23
  description:
24
- "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro™",
24
+ 'Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro™',
25
25
  };
26
26
 
27
- export const prerender = "auto";
28
- export const trailingSlash = "never";
27
+ export const prerender = 'auto';
28
+ export const trailingSlash = 'never';
29
29
 
30
30
  /**
31
31
  * @param {{ url: URL }} param0
32
32
  * @returns {{ pathname: string, meta: MetaData }}
33
33
  */
34
34
  export function load({ url }) {
35
- const normalizedPathname = url.pathname.replace(/\/+$/, "") || "/";
35
+ const normalizedPathname = url.pathname.replace(/\/+$/, '') || '/';
36
36
 
37
37
  // Check if meta data for the route exists in `meta.js`, otherwise use the fallback
38
38
  const currentMeta = routeMeta[normalizedPathname] || fallbackMeta;
@@ -9,50 +9,50 @@ This file is part of Network Pro.
9
9
  <script>
10
10
  export let data;
11
11
 
12
- import { onMount } from "svelte";
13
- import { afterNavigate } from "$app/navigation";
14
- import { initPostHog, showReminder, capture } from "$lib/stores/posthog";
15
- import { registerServiceWorker } from "$lib/registerServiceWorker.js";
16
- import { browser } from "$app/environment";
17
-
18
- import ContainerSection from "$lib/components/ContainerSection.svelte";
19
- import Footer from "$lib/components/layout/Footer.svelte";
20
- import HeaderDefault from "$lib/components/layout/HeaderDefault.svelte";
21
- import HeaderHome from "$lib/components/layout/HeaderHome.svelte";
22
- import PWAInstallButton from "$lib/components/PWAInstallButton.svelte";
23
-
24
- import "$lib/styles/global.min.css";
25
- import "$lib/styles/fa-global.css";
26
-
27
- import logoPng from "$lib/img/logo-web.png";
28
- import logoWbp from "$lib/img/logo-web.webp";
29
- import faviconSvg from "$lib/img/favicon.svg";
30
- import appleTouchIcon from "$lib/img/icon-180x180.png";
12
+ import { onMount } from 'svelte';
13
+ import { afterNavigate } from '$app/navigation';
14
+ import { initPostHog, showReminder, capture } from '$lib/stores/posthog';
15
+ import { registerServiceWorker } from '$lib/registerServiceWorker.js';
16
+ import { browser } from '$app/environment';
17
+
18
+ import ContainerSection from '$lib/components/ContainerSection.svelte';
19
+ import Footer from '$lib/components/layout/Footer.svelte';
20
+ import HeaderDefault from '$lib/components/layout/HeaderDefault.svelte';
21
+ import HeaderHome from '$lib/components/layout/HeaderHome.svelte';
22
+ import PWAInstallButton from '$lib/components/PWAInstallButton.svelte';
23
+
24
+ import '$lib/styles/global.min.css';
25
+ import '$lib/styles/fa-global.css';
26
+
27
+ import logoPng from '$lib/img/logo-web.png';
28
+ import logoWbp from '$lib/img/logo-web.webp';
29
+ import faviconSvg from '$lib/img/favicon.svg';
30
+ import appleTouchIcon from '$lib/img/icon-180x180.png';
31
31
 
32
32
  $: shouldShowReminder = $showReminder;
33
33
 
34
34
  onMount(() => {
35
- console.log("[APP] onMount triggered in +layout.svelte");
35
+ console.log('[APP] onMount triggered in +layout.svelte');
36
36
 
37
37
  registerServiceWorker();
38
38
  initPostHog();
39
39
 
40
40
  // Register navigation tracking only on client
41
41
  afterNavigate(() => {
42
- capture("$pageview");
42
+ capture('$pageview');
43
43
  });
44
44
 
45
45
  if (browser) {
46
- const isDev = import.meta.env.MODE === "development";
46
+ const isDev = import.meta.env.MODE === 'development';
47
47
 
48
48
  // Check for ?debug=true in URL (no persistence)
49
49
  const urlParams = new URLSearchParams(window.location.search);
50
- const debug = urlParams.get("debug") === "true";
50
+ const debug = urlParams.get('debug') === 'true';
51
51
 
52
52
  if (isDev || debug) {
53
- console.log("ENV MODE =", import.meta.env.MODE);
54
- console.log("isDev =", isDev);
55
- console.log("debug param =", debug);
53
+ console.log('ENV MODE =', import.meta.env.MODE);
54
+ console.log('isDev =', isDev);
55
+ console.log('debug param =', debug);
56
56
  }
57
57
 
58
58
  // Preload logo assets
@@ -65,10 +65,10 @@ This file is part of Network Pro.
65
65
 
66
66
  // fallback values if data.meta not set
67
67
  const metaTitle =
68
- data?.meta?.title || "Security, Networking, Privacy — Network Pro™";
68
+ data?.meta?.title || 'Security, Networking, Privacy — Network Pro™';
69
69
  const metaDescription =
70
70
  data?.meta?.description ||
71
- "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro™";
71
+ 'Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro™';
72
72
  </script>
73
73
 
74
74
  <svelte:head>
@@ -88,7 +88,7 @@ This file is part of Network Pro.
88
88
  <!-- BEGIN HEADER -->
89
89
  <header id="header-nav">
90
90
  <ContainerSection>
91
- {#if data.pathname === "/"}
91
+ {#if data.pathname === '/'}
92
92
  <!-- Render the Home Header for the root route -->
93
93
  <HeaderHome />
94
94
  <PWAInstallButton />
@@ -6,7 +6,7 @@ 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
 
@@ -23,6 +23,6 @@ export const prerender = false;
23
23
  */
24
24
  export function load() {
25
25
  return {
26
- meta: meta["/"] || defaultMeta,
26
+ meta: meta['/'] || defaultMeta,
27
27
  };
28
28
  }
@@ -7,25 +7,25 @@ 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 HomeContent from "$lib/pages/HomeContent.svelte";
13
- import LegalNav from "$lib/components/LegalNav.svelte";
14
- import Logo from "$lib/components/Logo.svelte";
15
- import SocialMedia from "$lib/components/SocialMedia.svelte";
16
- 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 HomeContent from '$lib/pages/HomeContent.svelte';
13
+ import LegalNav from '$lib/components/LegalNav.svelte';
14
+ import Logo from '$lib/components/Logo.svelte';
15
+ import SocialMedia from '$lib/components/SocialMedia.svelte';
16
+ import MetaTags from '$lib/components/MetaTags.svelte';
17
17
 
18
18
  /**
19
19
  * @type {string}
20
20
  * Style class for the horizontal rule element.
21
21
  */
22
- const hrStyle = "hr-styled";
22
+ const hrStyle = 'hr-styled';
23
23
 
24
24
  /**
25
25
  * @type {string}
26
26
  * Style class for the div element.
27
27
  */
28
- const spaceStyle = "spacer";
28
+ const spaceStyle = 'spacer';
29
29
 
30
30
  export let data;
31
31
  </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["/about"] || defaultMeta,
16
+ meta: meta['/about'] || 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 AboutContent from "$lib/pages/AboutContent.svelte";
11
- import Badges from "$lib/components/Badges.svelte";
12
- import FullWidthSection from "$lib/components/FullWidthSection.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 AboutContent from '$lib/pages/AboutContent.svelte';
11
+ import Badges from '$lib/components/Badges.svelte';
12
+ import FullWidthSection from '$lib/components/FullWidthSection.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>
@@ -8,14 +8,14 @@ This file is part of Network Pro.
8
8
 
9
9
  /** @type {import('@sveltejs/kit').RequestHandler} */
10
10
  export async function POST({ request }) {
11
- console.log("🔶 [Mock CSP] Report received during dev/CI");
11
+ console.log('🔶 [Mock CSP] Report received during dev/CI');
12
12
 
13
13
  // Optional: read/validate body for debugging
14
14
  try {
15
15
  const data = await request.json();
16
- console.log("🔶 [Mock CSP] Payload:", data);
16
+ console.log('🔶 [Mock CSP] Payload:', data);
17
17
  } catch {
18
- console.warn("⚠️ [Mock CSP] No JSON body provided.");
18
+ console.warn('⚠️ [Mock CSP] No JSON body provided.');
19
19
  }
20
20
 
21
21
  return new Response(null, { status: 204 });
@@ -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/appointments/pub/8clCqQrt3AtGbNrr/form",
25
+ 'https://cloud.neteng.pro/index.php/apps/appointments/pub/8clCqQrt3AtGbNrr/form',
26
26
  );
27
27
  show = true;
28
28
  });
@@ -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/nyWEq9fdE7kWAjqMtMySLqJc",
25
+ 'https://cloud.neteng.pro/index.php/apps/forms/s/nyWEq9fdE7kWAjqMtMySLqJc',
26
26
  );
27
27
  show = true;
28
28
  });
@@ -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["/foss-spotlight"] || defaultMeta,
16
+ meta: meta['/foss-spotlight'] || 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 FossContent from "$lib/pages/FossContent.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 FossContent from '$lib/pages/FossContent.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["/license"] || defaultMeta,
16
+ meta: meta['/license'] || 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 LicenseContent from "$lib/pages/LicenseContent.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 LicenseContent from '$lib/pages/LicenseContent.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["/pgp"] || defaultMeta,
16
+ meta: meta['/pgp'] || 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 PGPContent from "$lib/pages/PGPContent.svelte";
11
- import Badges from "$lib/components/Badges.svelte";
12
- import FullWidthSection from "$lib/components/FullWidthSection.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 PGPContent from '$lib/pages/PGPContent.svelte';
11
+ import Badges from '$lib/components/Badges.svelte';
12
+ import FullWidthSection from '$lib/components/FullWidthSection.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,9 +6,9 @@ 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 { error } from "@sveltejs/kit";
10
- import fs from "fs/promises";
11
- import path from "path";
9
+ import { error } from '@sveltejs/kit';
10
+ import fs from 'fs/promises';
11
+ import path from 'path';
12
12
 
13
13
  /**
14
14
  * @type {import('@sveltejs/kit').RequestHandler}
@@ -16,20 +16,20 @@ import path from "path";
16
16
  export async function GET({ params, setHeaders }) {
17
17
  const key = params.key;
18
18
 
19
- if (!key || !key.endsWith(".asc")) {
20
- throw error(400, "Invalid or missing file name");
19
+ if (!key || !key.endsWith('.asc')) {
20
+ throw error(400, 'Invalid or missing file name');
21
21
  }
22
22
 
23
- const filePath = path.resolve("static/pgp", key);
23
+ const filePath = path.resolve('static/pgp', key);
24
24
 
25
25
  try {
26
26
  const file = await fs.readFile(filePath);
27
27
  setHeaders({
28
- "Content-Type": "application/pgp-keys",
29
- "Content-Disposition": `attachment; filename="${key}"`,
28
+ 'Content-Type': 'application/pgp-keys',
29
+ 'Content-Disposition': `attachment; filename="${key}"`,
30
30
  });
31
31
  return new Response(file);
32
32
  } catch {
33
- return new Response("File not found", { status: 404 });
33
+ return new Response('File not found', { status: 404 });
34
34
  }
35
35
  }