initial commit

This commit is contained in:
John Doe 2024-03-13 23:07:03 -04:00
parent 9f782ce3d0
commit f57d0c9c22
50 changed files with 5010 additions and 2 deletions

12
.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
.vercel
.output
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

1
.npmrc Normal file
View file

@ -0,0 +1 @@
engine-strict=true

View file

@ -1,3 +1,38 @@
# www-sveltekit
# create-svelte
A port of the FemtoStar website (www-new) from Sapper to SvelteKit.
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

18
jsconfig.json Normal file
View file

@ -0,0 +1,18 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

2426
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

29
package.json Normal file
View file

@ -0,0 +1,29 @@
{
"name": "www-sveltekit3",
"version": "0.0.1",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch"
},
"devDependencies": {
"@fontsource/fira-mono": "^4.5.10",
"@neoconfetti/svelte": "^1.0.0",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"typescript": "^5.0.0",
"vite": "^5.0.3"
},
"type": "module",
"dependencies": {
"d3": "^7.9.0",
"satellite.js": "^5.0.0",
"svelte-media-query": "^1.1.2",
"topojson": "^3.0.2"
}
}

13
src/app.d.ts vendored Normal file
View file

@ -0,0 +1,13 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}
export {};

13
src/app.html Normal file
View file

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="global.css">
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View file

@ -0,0 +1,44 @@
<script>
import { onMount } from "svelte";
export let title;
let hidden = false;
onMount(async () => {
hidden = true;
});
</script>
<div class="collapsedFAQ">
<div class="title" on:click={ ()=> {hidden = !hidden} }>
<div class="symbol">{hidden ? '+' : ''}</div> {title}
</div>
<div class="faqPoint" style="display: {hidden ? 'none' : 'block'}">
<slot />
</div>
</div>
<style>
.collapsedFAQ{
margin-top: 10px;
margin-bottom: 10px;
}
.symbol{
display: inline-block;
width: 1.0em;
}
.title{
color: #72bbd9;
cursor: pointer;
font-weight: bold;
user-select: none;
margin-bottom: 1em;
}
.faqPoint{
margin-bottom: 2.0em;
}
:global(.faqPoint p:first-child) {
margin-top: 0;
}
</style>

View file

@ -0,0 +1,61 @@
<script>
import FemtoStarLogo from "./FemtoStarLogo.svelte";
</script>
<div class="femtoHeader">
<div class="femtoLogotypeContainer"><FemtoStarLogo /><span class="femtoLogotype">FemtoStar</span></div>
<h2>Satellite communications, done differently.</h2>
<div class="introText">
<p>
The FemtoStar Project is a global community developing a satellite
constellation for secure, open, and private communications - anywhere on
planet Earth.
</p>
</div>
</div>
<style>
@font-face {
font-family: Jost;
src: url(../../Jost.ttf);
}
div {
display: flex;
width: 100%;
background-color: #00111d;
color: #ffffff;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.femtoLogotypeContainer{
}
.femtoLogotype{
font-weight: 500;
font-family: Jost, sans-serif;
font-size: 3.0em;
}
svg {
padding-top: 1em;
}
h2 {
margin-top: 0.5em;
}
.introText {
width: 100%;
color: #ffffff;
}
p {
max-width: 512px;
}
</style>

View file

@ -0,0 +1,25 @@
<script>
export let width = 128;
export let height = 100;
export let color = "#FFFFFF";
export let css_class = "femtostarLogo"
</script>
<svg
{width}
{height}
viewBox="0 0 32 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class={css_class}
>
<path
d="M0 0H14.6453V4.5H5.05011V10.0714H14.2846V14.3571H5.05011V25H0V0Z"
fill={color}
/>
<path
d="M20.7094 15.6786L17.2104 13.1786L21.3587 8.75L15.4068 7.5L16.7054 3.5L22.2605 6.03572L21.5751 0H25.8317L25.1463 6.03572L30.7014 3.5L32 7.5L26.0481 8.75L30.1964 13.1786L26.6974 15.6786L23.7034 10.4286L20.7094 15.6786Z"
fill={color}
/>
<slot />
</svg>

View file

@ -0,0 +1,32 @@
<script>
import FemtoStarLogo from "./FemtoStarLogo.svelte";
</script>
<div class="footer-container">
<FemtoStarLogo height={42} width={33} color="#FFFFFF75" />
<div class="footer-text">
Copyright 2024 - <a href="https://matrix.to/#/!COEHOXujBzfAHAVzPG:matrix.org">Matrix</a> / <a href="https://git.femtostar.com">GitLab</a> / <a href="https://twitter.com/FemtoStar">X</a>
</div>
</div>
<style>
.footer-text{
display: inline-block;
margin-left: 1.0em;
}
.footer-container {
font-weight: 300;
background-color: #00111d;
color: white;
width: 100%;
font-size: 0.7em;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin-top: auto;
text-align: center;
margin-bottom: 10px;
}
</style>

574
src/components/Globe.svelte Normal file
View file

@ -0,0 +1,574 @@
<script>
import * as d3 from "d3";
import MediaQuery from "svelte-media-query";
import * as sjs from "satellite.js";
import { onDestroy, onMount } from "svelte";
import tles from "../../static/tle.js";
import world110m from "../../static/world-110m.js";
import * as topojson from "topojson";
let shouldLoop = true;
let tta;
async function doThing() {
let satelliteJs = sjs;
var RADIANS = Math.PI / 180;
var DEGREES = 180 / Math.PI;
var R_EARTH = 6378.137; // equatorial radius (km)
var disablescroll = false;
/* =============================================== */
/* =============== CLOCK ========================= */
/* =============================================== */
/**
* Factory function for keeping track of elapsed time and rates.
*/
class Clock {
constructor() {
this._rate = 60; // 1ms elapsed : 60sec simulated
this._date = d3.now();
this._elapsed = 0;
}
async date(timeInMs) {
if (!arguments.length) return this._date + this._elapsed * this._rate;
this._date = timeInMs;
return this;
}
async elapsed(ms) {
if (!arguments.length) return this._date - d3.now(); // calculates elapsed
this._elapsed = ms;
return this;
}
async rate(secondsPerMsElapsed) {
if (!arguments.length) return this._rate;
this._rate = secondsPerMsElapsed;
return this;
}
}
/* ==================================================== */
/* =============== CONVERSION ========================= */
/* ==================================================== */
async function satrecToFeature(satrec, date, props) {
var properties = props || {};
var positionAndVelocity = satelliteJs.propagate(satrec, date);
var gmst = satelliteJs.gstime(date);
var positionGd = satelliteJs.eciToGeodetic(
positionAndVelocity.position,
gmst
);
properties.height = positionGd.height;
return {
type: "Feature",
properties: properties,
geometry: {
type: "Point",
coordinates: [
positionGd.longitude * DEGREES,
positionGd.latitude * DEGREES,
],
},
};
}
/* ==================================================== */
/* =============== TLE ================================ */
/* ==================================================== */
/**
* Factory function for working with TLE.
*/
class TLE {
constructor() {
this._properties;
this._date;
}
async _lines(arry) {
return arry.slice(0, 2);
}
async satrecs(tles) {
return tles.map(function (d) {
return satelliteJs.twoline2satrec.apply(null, this._lines(d));
});
}
async features(tles) {
var date = this._date || d3.now();
return tles.map(function (d) {
var satrec = satelliteJs.twoline2satrec.apply(null, this._lines(d));
return satrecToFeature(satrec, date, this._properties(d));
});
}
async lines(func) {
if (!arguments.length) return this._lines;
this._lines = func;
return this;
}
async properties(func) {
if (!arguments.length) return this._properties;
this._properties = func;
return this;
}
async date(ms) {
if (!arguments.length) return this._date;
this._date = ms;
return this;
}
}
/* ==================================================== */
/* =============== PARSE ============================== */
/* ==================================================== */
/**
* Parses text file string of tle into groups.
* @return {string[][]} Like [['tle line 1', 'tle line 2'], ...]
*/
async function parseTle(tleString) {
// remove last newline so that we can properly split all the lines
var lines = tleString.replace(/\r?\n$/g, "").split(/\r?\n/);
return lines.reduce(function (acc, cur, index) {
if (index % 2 === 0) acc.push([]);
acc[acc.length - 1].push(cur);
return acc;
}, []);
}
/* ==================================================== */
/* =============== SATELLITE ========================== */
/* ==================================================== */
/**
* Satellite factory function that wraps satellitejs functionality
* and can compute footprints based on TLE and date
*
* @param {string[][]} tle two-line element
* @param {Date} date date to propagate with TLE
*/
function Satellite(tle, date) {
this._satrec = satelliteJs.twoline2satrec(tle[0], tle[1]);
this._satNum = this._satrec.satnum; // NORAD Catalog Number
this._altitude; // km
this._position = {
lat: null,
lng: null,
};
this._halfAngle; // degrees
this._date;
this._gmst;
this.setDate(date);
this.update();
this._orbitType = this.orbitTypeFromAlt(this._altitude); // LEO, MEO, or GEO
}
/**
* Updates satellite position and altitude based on current TLE and date
*/
Satellite.prototype.update = async function () {
var positionAndVelocity = satelliteJs.propagate(this._satrec, this._date);
var positionGd = satelliteJs.eciToGeodetic(
positionAndVelocity.position,
this._gmst
);
this._position = {
lat: positionGd.latitude * DEGREES,
lng: positionGd.longitude * DEGREES,
};
this._altitude = positionGd.height;
return this;
};
/**
* @returns {GeoJSON.Polygon} GeoJSON describing the satellite's current footprint on the Earth
*/
Satellite.prototype.getFootprint = function () {
var theta = this._halfAngle * RADIANS;
let coreAngle = this._coreAngle(theta, this._altitude, R_EARTH) * DEGREES;
return d3
.geoCircle()
.center([this._position.lng, this._position.lat])
.radius(coreAngle)();
};
/**
* A conical satellite with half angle casts a circle on the Earth. Find the angle
* from the center of the earth to the radius of this circle
* @param {number} theta: Satellite half angle in radians
* @param {number} altitude Satellite altitude
* @param {number} r Earth radius
* @returns {number} core angle in radians
*/
Satellite.prototype._coreAngle = function (theta, altitude, r) {
// if FOV is larger than Earth, assume it goes to the tangential point
if (Math.sin(theta) > r / (altitude + r)) {
return Math.acos(r / (r + altitude));
}
return (
Math.abs(Math.asin(((r + altitude) * Math.sin(theta)) / r)) - theta
);
};
Satellite.prototype.halfAngle = function (halfAngle) {
if (!arguments.length) return this._halfAngle;
this._halfAngle = halfAngle;
return this;
};
Satellite.prototype.satNum = function (satNum) {
if (!arguments.length) return this._satNum;
this._satNum = satNum;
return this;
};
Satellite.prototype.altitude = function (altitude) {
if (!arguments.length) return this._altitude;
this._altitude = altitude;
return this;
};
Satellite.prototype.position = function (position) {
if (!arguments.length) return this._position;
this._position = position;
return this;
};
Satellite.prototype.getOrbitType = function () {
return this._orbitType;
};
/**
* sets both the date and the Greenwich Mean Sidereal Time
* @param {Date} date
*/
Satellite.prototype.setDate = function (date) {
this._date = date;
this._gmst = satelliteJs.gstime(date);
return this;
};
/**
* Maps an altitude to a type of satellite
* @param {number} altitude (in KM)
* @returns {'LEO' | 'MEO' | 'GEO'}
*/
Satellite.prototype.orbitTypeFromAlt = function (altitude) {
this._altitude = altitude || this._altitude;
return this._altitude < 1200
? "LEO"
: this._altitude > 22000
? "GEO"
: "MEO";
};
/* =============================================== */
/* =================== GLOBE ===================== */
/* =============================================== */
// Approximate date the tle data was aquired from https://www.space-track.org/#recent
var TLE_DATA_DATE = new Date(2015, 11, 3, 17, 36).getTime();
var activeClock;
var sats;
var svg = d3.select("#globe");
var width = svg.attr("width");
var height = svg.attr("height");
var projection = d3
.geoOrthographic()
.scale((height - 10) / 2)
.translate([width / 2, height / 2])
.rotate([45, -30]);
var geoPath = d3.geoPath().projection(projection);
function initGlobe() {
let worldData = world110m;
svg
.append("path")
.datum({
type: "Sphere",
})
.style("cursor", "grab")
.attr("fill", "#2E86AB")
.attr("d", geoPath);
svg
.selectAll(".segment")
.data([topojson.feature(worldData, worldData.objects.land)])
.enter()
.append("path")
.style("cursor", "grab")
.attr("class", "segment")
.attr("d", geoPath)
.style("stroke", "#88888800")
.style("stroke-width", "0px")
.style("fill", "#ffffff")
.style("opacity", "1");
}
async function updateSats(date) {
sats.forEach(async function (sat) {
return sat.setDate(date).update();
});
return sats;
}
/**
* Create satellite objects for each record in the TLEs and begin animation
* @param {string[][]} parsedTles
*/
async function initSats(parsedTles) {
activeClock = new Clock();
await activeClock.rate(100);
await activeClock.date(TLE_DATA_DATE);
sats = await Promise.all(
parsedTles.map(async function (tle) {
var sat = new Satellite(tle, new Date(2015, 11, 3, 17, 36));
sat.halfAngle(61.73);
return sat;
})
);
if (shouldLoop) window.requestAnimationFrame(animateSats);
return sats;
}
async function draw() {
// redrawGlobe();
let allFootprints = svg.selectAll(".footprint");
let allFootprintsData = allFootprints.data(sats, async function (sat) {
return sat.satNum();
});
let allFootprintsDataJoin = allFootprintsData.join(function (enter) {
return enter
.append("path")
.attr("class", function (sat) {
return "footprint footprint--" + sat.getOrbitType();
})
.style("cursor", "grab");
});
allFootprintsDataJoin.attr("d", function (sat) {
return geoPath(sat.getFootprint());
});
if(svg.attr("width") != width){
svg.selectAll("*").remove();
width = svg.attr("width");
height = svg.attr("height");
projection.scale((height - 10) / 2);
projection.translate([width / 2, height / 2]);
projection.rotate([45, -30]);
initGlobe();
redrawGlobe();
}
}
async function redrawGlobe() {
let allSelectedSegment = svg.selectAll(".segment");
allSelectedSegment.attr("d", geoPath);
}
var m0;
var o0;
var preventScroll = function(e){
//This function doesn't have to do anything, it just has to exist
/*if(disablescroll){
e.preventDefault();
}*/
};
async function mousedown(e) {
m0 = [e.pageX, e.pageY];
o0 = projection.rotate();
e.preventDefault();
}
async function mousemove(e) {
if (m0) {
var m1 = [e.pageX, e.pageY];
const o1 = [
o0[0] + (m1[0] - m0[0]) / 2.5,
o0[1] + (m0[1] - m1[1]) / 2.5,
];
projection.rotate(o1);
redrawGlobe();
}
}
async function mouseup(e) {
if (m0) {
mousemove(e);
m0 = null;
}
}
function touchstart(e){
m0 = [e.touches[0].pageX, e.touches[0].pageY];;
o0 = projection.rotate();
e.preventDefault();
return false;
}
function touchmove(e){
if (m0) {
var m1 = [e.touches[0].pageX, e.touches[0].pageY];
const o1 = [
o0[0] + (m1[0] - m0[0]) / 2.5,
o0[1] + (m0[1] - m1[1]) / 2.5,
];
projection.rotate(o1);
redrawGlobe();
}
e.preventDefault();
return false;
}
function touchend(e){
if (m0) {
m0 = null;
}
e.preventDefault();
return false;
}
//Stop Chrome from messing up the scroll by adding an event listener on touch events
document.addEventListener('touchstart', function(){}, {passive: false});
document.addEventListener('touchmove', function(){}, {passive: false});
svg.on("mousedown", mousedown);
d3.select(window).on("mousemove", mousemove)
d3.select(window).on("mouseup", mouseup);
tta.addEventListener("mousedown", mousedown);
tta.addEventListener("mousemove", mousemove);
tta.addEventListener("mouseup", mouseup);
tta.addEventListener("touchstart", touchstart);
tta.addEventListener("touchmove", touchmove);
tta.addEventListener("touchend", touchend);
async function animateSats(elapsed) {
var dateInMsI1 = await activeClock.elapsed(elapsed);
var dateInMs = dateInMsI1.date();
var date = new Date(await dateInMs);
updateSats(date);
draw();
if (shouldLoop) window.requestAnimationFrame(animateSats);
}
initGlobe();
await initSats(await parseTle(tles));
}
onMount(async () => {
doThing();
});
onDestroy(() => {
shouldLoop = false;
});
</script>
<div class="globeContainer">
<MediaQuery query="only screen and (max-device-width: 900px) and (orientation: portrait)" let:matches>
<div class="touch-sensor {matches ? "touch-sensor-small":"touch-sensor-large"}" bind:this={tta} />
<span id="no-js"><noscript>This interactive widget requires JavaScript.</noscript></span>
<svg id="globe" class={matches ? "globe globe-small":"globe globe-large"} width={matches ? 250:400} height={matches ? 250:400}/>
</MediaQuery>
<!--<svg id="globe" {width} height={width}/>-->
<div class="globeText">click and drag</div>
</div>
<style>
#no-js{
z-index: 0;
position: absolute;
opacity: 30%;
}
.globeContainer {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: #00111d;
color: #ffffff;
}
.touch-sensor{
position: absolute;
opacity: 0;
padding-top: 0.6em;
cursor: pointer;
}
.touch-sensor-small{
width: 250px;
height: 250px;
border-radius: 125px;
}
.touch-sensor-large{
width: 400px;
height: 400px;
border-radius: 200px;
}
:global(.footprint--LEO) {
fill: rgba(255, 177, 64, 0.08);
stroke: rgba(255, 177, 64, 0.5);
}
.globeText {
text-align: center;
font-size: 0.6em;
color: #aaaaaa;
}
.globe {
z-index: 100;
display: block;
}
.globe-small {
width: 250px;
height: 250px;
}
.globe-large {
width: 400px;
height: 400px;
}
</style>

View file

@ -0,0 +1,24 @@
<div class="introText">
<p>
The FemtoStar Project is a global community developing a satellite
constellation for secure, open, and private communications - anywhere on
planet Earth.
</p>
</div>
<style>
.introText {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
background-color: #00111d;
color: #ffffff;
}
p {
padding-left: 2em;
max-width: 225px;
}
</style>

114
src/components/Nav.svelte Normal file
View file

@ -0,0 +1,114 @@
<script>
import NavItem from "./NavItem.svelte";
import FemtoStarLogo from "./FemtoStarLogo.svelte"
export let segment;
import { page } from '$app/stores';
</script>
<nav>
<NavItem {segment} href="." matchingSegment="/" humanName="home">
<FemtoStarLogo css_class="navlogo" height={42} width={33} color={$page.url.pathname == "/" ? "#FFFFFF" : "#FFFFFF75"}>home</FemtoStarLogo>
</NavItem>
<NavItem {segment} href="./faq" matchingSegment="/faq" humanName="faq" />
<NavItem
{segment}
href="./about-contact"
matchingSegment="/about-contact"
humanName="about & contact"
/>
<NavItem {segment} href="./donate" matchingSegment="/donate" humanName="donate" />
<div class="dropdown">
<div
class="dropdown-name"
class:bold={segment === "global-open-infrastructure" ||
segment === "privacy-by-design" ||
segment === "free-open-source"}
>
more
</div>
<div class="dropdown-content">
<NavItem
{segment}
href="./global-open-infrastructure"
matchingSegment="/global-open-infrastructure"
humanName="global open infrastructure"
/>
<NavItem
{segment}
href="./privacy-by-design"
matchingSegment="/privacy-by-design"
humanName="privacy by design"
/>
<NavItem
{segment}
href="./free-open-source"
matchingSegment="/free-open-source"
humanName="free and open-source"
/>
</div>
</div>
</nav>
<style>
nav {
font-weight: 300;
background-color: #00111d;
color: white;
width: 100%;
height: 48px;
display: flex;
justify-content: center;
align-items: center;
vertical-align: center;
padding-top: 8px;
}
.dropdown {
height: 100%;
width: 49px;
}
.dropdown-name {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: default;
}
.bold {
font-weight: bold;
}
.dropdown-content {
display: none;
position: relative;
right: 201px;
box-sizing: border-box;
background-color: #33414a;
color: white;
width: 250px;
box-shadow: 0 2px 6px -0.25px #00000035;
z-index: 1;
padding-left: 1em;
padding-right: 1em;
padding-top: 1em;
padding-bottom: 1em;
}
.dropdown:hover {
background-color: #33414a;
}
.dropdown:hover .dropdown-content {
display: block;
box-sizing: border-box;
}
</style>

View file

@ -0,0 +1,42 @@
<script>
export let segment;
export let humanName;
export let href;
export let matchingSegment;
import { page } from '$app/stores';
</script>
<div
class="navItem"
aria-current={$page.url.pathname === matchingSegment ? "page" : undefined}
>
<div class="width-placeholder">{humanName}</div>
<a rel="prefetch" {href}>{humanName == "home" ? "" : humanName}<slot /></a>
</div>
<style>
.navItem {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-left: 0.5em;
padding-right: 0.5em;
}
.width-placeholder{
height: 0;
font-weight: bold;
overflow: hidden;
}
a {
text-decoration: none;
}
.navItem[aria-current] {
font-weight: bold;
}
</style>

View file

@ -0,0 +1,34 @@
<script>
import Faq from "../routes/faq/+page.svelte";
import FaqItem from "./FAQItem.svelte";
import FemtoHeader from "./FemtoHeader.svelte";
import FemtoStarLogo from "./FemtoStarLogo.svelte";
import PartnerItem from "./PartnerItem.svelte"
</script>
<style>
.partner-container{
padding-top: 3em;
width: 100%;
color: white;
text-align: center;
}
.partner-text{
padding-bottom: 1em;
}
h2{
margin-bottom: 0.1em;
}
</style>
<div class="partner-container">
<div class="partner-text">
<h2>Our Partners</h2>
The FemtoStar Project is working with an ever-growing community of partners to make FemtoStar a reality.<br>
</div>
<PartnerItem link="https://appliedionsystems.com" alt="Logo of Applied Ion Systems" image="../../ais-logo.png" />
<PartnerItem link="https://fossa.systems" alt="Logo of Fossa Systems" image="../../fossa-logo.png" />
<PartnerItem link="https://nlnet.nl" alt="Logo of NLNet" image="../../nlnet-logo.png" />
<PartnerItem link="https://pine64.org" alt="Logo of Pine64" image="../../pine-logo.png" />
</div>

View file

@ -0,0 +1,13 @@
<script>
export let image, alt, link;
</script>
<a href={link}><img alt={alt} src={image} /></a>
<style>
img{
margin: 15px;
height: 64px;
width: auto;
}
</style>

View file

@ -0,0 +1,21 @@
<div class="talkingPointContainer">
<slot />
</div>
<style>
.talkingPointContainer {
background-color: transparent;
display: grid;
grid-template-columns: 30% auto;
grid-template-rows: auto;
}
@media only screen
and (max-device-width: 900px)
and (orientation: portrait) {
.talkingPointContainer {
grid-template-columns: auto;
grid-template-rows: 115px auto;
}
}
</style>

View file

@ -0,0 +1,40 @@
<style>
.talkingPointContentContainer {
width: 100%;
height: 100%;
display: flex;
align-items: flex-start;
justify-content: flex-start;
background-color: #00111d;
color: #ffffff;
}
.talkingPointContentContainer .talkingPointContent {
padding-top: 1em;
padding-left: 2em;
font-size: 1em;
max-width: 850px;
}
:global(.talkingPointContent li:not(:last-child)) {
margin-bottom: 1em;
}
@media only screen and (max-device-width: 900px) and (orientation: portrait) {
.talkingPointContentContainer {
padding-bottom: 1em;
}
.talkingPointContentContainer .talkingPointContent {
padding-top: 0;
padding-left: 0;
max-width: 100%;
}
}
</style>
<div class="talkingPointContentContainer">
<div class="talkingPointContent">
<slot />
</div>
</div>

View file

@ -0,0 +1,38 @@
<script>
export let text = "replace this";
</script>
<div class="talkingPointNameContainer">
<h2 class="talkingPointName">{text}</h2>
</div>
<style>
.talkingPointNameContainer {
width: 100%;
height: 115px;
display: flex;
align-items: flex-start;
justify-content: flex-end;
background-color: #00111d;
color: #ffffff;
}
.talkingPointNameContainer .talkingPointName {
padding-top: 1.25em;
padding-right: 2em;
max-width: 250px;
text-align: right;
}
@media only screen and (max-device-width: 900px) and (orientation: portrait) {
.talkingPointNameContainer {
align-items: center;
justify-content: center;
}
.talkingPointNameContainer .talkingPointName {
padding-top: 0;
padding-right: 0;
text-align: center;
}
}
</style>

16
src/lib/images/github.svg Normal file
View file

@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 30 30">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5229 6.47715 22 12 22C17.5229 22 22 17.5229 22 12C22 6.47715 17.5229 2 12 2ZM0 12C0 5.3726 5.3726 0 12 0C18.6274 0 24 5.3726 24 12C24 18.6274 18.6274 24 12 24C5.3726 24 0 18.6274 0 12Z"
fill="rgba(0,0,0,0.7)"
stroke="none"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M9.59162 22.7357C9.49492 22.6109 9.49492 21.4986 9.59162 19.399C8.55572 19.4347 7.90122 19.3628 7.62812 19.1833C7.21852 18.9139 6.80842 18.0833 6.44457 17.4979C6.08072 16.9125 5.27312 16.8199 4.94702 16.6891C4.62091 16.5582 4.53905 16.0247 5.84562 16.4282C7.15222 16.8316 7.21592 17.9303 7.62812 18.1872C8.04032 18.4441 9.02572 18.3317 9.47242 18.1259C9.91907 17.9201 9.88622 17.1538 9.96587 16.8503C10.0666 16.5669 9.71162 16.5041 9.70382 16.5018C9.26777 16.5018 6.97697 16.0036 6.34772 13.7852C5.71852 11.5669 6.52907 10.117 6.96147 9.49369C7.24972 9.07814 7.22422 8.19254 6.88497 6.83679C8.11677 6.67939 9.06732 7.06709 9.73672 7.99999C9.73737 8.00534 10.6143 7.47854 12.0001 7.47854C13.386 7.47854 13.8777 7.90764 14.2571 7.99999C14.6365 8.09234 14.94 6.36699 17.2834 6.83679C16.7942 7.79839 16.3844 8.99999 16.6972 9.49369C17.0099 9.98739 18.2372 11.5573 17.4833 13.7852C16.9807 15.2706 15.9927 16.1761 14.5192 16.5018C14.3502 16.5557 14.2658 16.6427 14.2658 16.7627C14.2658 16.9427 14.4942 16.9624 14.8233 17.8058C15.0426 18.368 15.0585 19.9739 14.8708 22.6234C14.3953 22.7445 14.0254 22.8257 13.7611 22.8673C13.2924 22.9409 12.7835 22.9822 12.2834 22.9982C11.7834 23.0141 11.6098 23.0123 10.9185 22.948C10.4577 22.9051 10.0154 22.8343 9.59162 22.7357Z"
fill="rgba(0,0,0,0.7)"
stroke="none"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157" style="fill:#ff3e00"/><path d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287" style="fill:#fff"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

18
src/routes/+error.svelte Normal file
View file

@ -0,0 +1,18 @@
<script>
export let status;
export let error;
const dev = process.env.NODE_ENV === "development";
</script>
<svelte:head>
<title>{status}</title>
</svelte:head>
<h1>{status}</h1>
<p>{error.message}</p>
{#if dev && error.stack}
<pre>{error.stack}</pre>
{/if}

26
src/routes/+layout.svelte Normal file
View file

@ -0,0 +1,26 @@
<script>
import Footer from "../components/Footer.svelte";
import Nav from "../components/Nav.svelte";
export let segment;
</script>
<div class="wrapper">
<Nav {segment} />
<slot />
<Footer />
</div>
<style>
:global(body) {
background-color: #00111d;
}
.wrapper {
min-height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto;
}
</style>

121
src/routes/+page.svelte Normal file
View file

@ -0,0 +1,121 @@
<script>
import FemtoHeader from "../components/FemtoHeader.svelte";
import Globe from "../components/Globe.svelte";
import IntroText from "../components/IntroText.svelte";
import TalkingPointContainer from "../components/TalkingPointContainer.svelte";
import MediaQuery from "svelte-media-query";
import TalkingPointContent from "../components/TalkingPointContent.svelte";
import TalkingPointName from "../components/TalkingPointName.svelte";
import PartnerContainer from "../components/PartnerContainer.svelte";
</script>
<svelte:head>
<title>FemtoStar</title>
</svelte:head>
<div class="site">
<div class="hero">
<div class="container">
<MediaQuery query="only screen and (max-device-width: 900px) and (orientation: portrait)" let:matches>
{#if matches}
<FemtoHeader />
<Globe/>
{:else}
<Globe/>
<FemtoHeader />
{/if}
</MediaQuery>
</div>
</div>
<TalkingPointContainer>
<TalkingPointName text="Global Open Infrastructure" />
<TalkingPointContent>
<p>
Our satellites are open infrastructure - that means anyone can use them
without needing to go through an official gateway. This makes FemtoStar
a flexible, open, and inherently net-neutral network, able not just to
connect users to the services we provide, but to serve as a platform for
what others build on top of it.
</p>
<p>
<a rel="prefetch" href="./global-open-infrastructure">Learn more →</a>
</p>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName text="Privacy by design, not just by promise" />
<TalkingPointContent>
<p>
Many products only promise privacy. FemtoStar is different. Privacy and
security are verifiably baked into every part of the system, all the way
down to the lowest level details. We couldn't violate your privacy even
if we wanted to.
</p>
<p>
<a rel="prefetch" href="./privacy-by-design">Learn more →</a>
</p>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName
text="Free and open-source technology, built by a global community"
/>
<TalkingPointContent>
<p>
FemtoStar is free and open-source technology. This goes for software and
hardware alike, and, yes, even for the satellites themselves. You have
access to the source files, and if you want to make sure the software on
your terminal lives up to its privacy and security claims, the source is
freely available to use, read, or modify.
</p>
<p>
<a rel="prefetch" href="./free-open-source">Learn more →</a>
</p>
</TalkingPointContent>
</TalkingPointContainer>
<PartnerContainer />
</div>
<style>
:global(.site a) {
color: #72bbd9;
}
.site {
margin-left: auto;
margin-right: auto;
max-width: 1024px;
padding-left: 2em;
padding-right: 2em;
padding-bottom: 1em;
}
.hero {
margin-top: 3em;
margin-bottom: 3em;
background-color: aqua;
}
.hero .container {
background-color: aquamarine;
display: grid;
grid-template-columns: 400px auto;
grid-template-rows: auto;
}
@media only screen and (max-device-width: 900px) and (orientation: portrait) {
.hero {
margin-top: 1em;
margin-bottom: 1em;
}
.hero .container {
grid-template-columns: auto;
grid-template-rows: 480px auto;
}
}
</style>

View file

@ -0,0 +1,126 @@
<script>
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
import TalkingPointName from "../../components/TalkingPointName.svelte";
</script>
<svelte:head>
<title>FemtoStar - About & Contact</title>
</svelte:head>
<div class="site">
<TalkingPointContainer>
<TalkingPointName text="Who We Are" />
<TalkingPointContent>
<p>
The FemtoStar Project is a global community of developers working
towards one common goal - better, more open, and more private
communications, anywhere on earth. At the core of the FemtoStar Project
is FemtoStar Inc., a Canadian corporation wholly owned by FemtoStar
Project members and tasked with ownership and operation of the FemtoStar
satellite constellation. However, development of the hardware and
software that make FemtoStar possible is undertaken by a global
community of volunteer developers with experience ranging from embedded
hardware, to secure telecommunications, to software development, to
aerospace.
</p>
<p>
The FemtoStar Project is a global endeavour. All of our members joined
the project online, many after coming across the project on their own
and contacting us. If you've found us, and you want to help, don't
hesitate to contact us.
</p>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName text="Contact" />
<TalkingPointContent>
<p>
Questions? Comments? Want to chat about satellites? Visit us on Matrix
at <a
href="https://matrix.to/#/!COEHOXujBzfAHAVzPG:matrix.org?via=matrix.org&via=lighthouse.cx&via=nordgedanken.dev"
>#femtostar:matrix.org</a
>. Alternatively, email us at
<span class="j">This address has been hidden to prevent spam being received. If you are reading this website as plain text or through a screen reader, the correct address is the word hello, then the symbol spelled with the letter before B and then the letter after S, then the name of this
website or of our satellite, then dot com. </span>h<span class="c">
</span>e<span class="c">Lorem</span>l<span class="j">ipsum</span>l<span class="c">dolor</span>o<span class="c">sit</span> а<span class="c">amet</span>t
f<span class="c">consectetur</span>e<span class="j">adipiscing</span>m<span class="c">elit</span>t<span class="c">Sed</span>o<span class="j">dolor</span>s<span class="c">sem</span>t<span class="c">lacinia</span>a<span class="c">ac</span>r
d<span class="c">euismod</span>о<span class="j">vitae</span>t c<span class="c">hendrerit</span>o<span class="j">sit</span>m (if you have Tutanota, you can send end-to-end encrypted mail here too).
</p>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName text="History" />
<TalkingPointContent>
<p>
Development of what is now FemtoStar began with a project named Private
Mobile Data Protocol (PMDP). While PMDP was intended to be a terrestrial
network, many of the design elements now used in the FemtoStar Protocol
were initially designed for this project. A series of tests in
real-world urban and suburban environments throughout 2019 led to the
conclusion that, without a dense network and an impractically large
number of towers, reasonable coverage, even only at low speeds and only
within city centers, was impractical with a license-free terrestrial
network.
</p>
<p>
In early 2020, the decision was made to research the implementation of a
PMDP-like network in a Mobile Satellite Service (MSS) system. While
Mobile Satellite Service hardware (such as satellite phones, portable
satellite internet terminals, and machine-to-machine/IoT satellite data
terminals) is likely less familiar to the typical consumer than hardware
for terrestrial mobile networks, the possibility of a satellite-based
network offered an opportunity both to solve the coverage problem, and
to improve the geolocation-resistance of the system (due to the
inherently large footprint of communications satellites).
</p>
<p>
Within a month, a basic plan had been developed, and many of the
remaining problems of the PMDP protocol (such as its lack of any
mechanism for payment for service) had been solved. The core of the
proposed network was a constellation of very small communications
satellites - a design we named FemtoStar.
</p>
<p>
As the FemtoStar Project grew, development continued throughout 2020. In
2021, FemtoStar Inc. was incorporated in Canada as an entity to own and
operate the FemtoStar satellite constellation on behalf of the FemtoStar
Project.
</p>
</TalkingPointContent>
</TalkingPointContainer>
</div>
<style>
.site {
margin-left: auto;
margin-right: auto;
padding-top: 0;
padding-bottom: 3em;
max-width: 1024px;
padding-left: 2em;
padding-right: 2em;
}
.c{
overflow: hidden;
height: 0px;
width: 0px;
position: absolute;
}
.j{
overflow: hidden;
height: 0px;
width: 0px;
position: absolute;
}
:global(.site a) {
color: #72bbd9;
}
</style>

View file

@ -0,0 +1,111 @@
<script>
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
import TalkingPointName from "../../components/TalkingPointName.svelte";
</script>
<svelte:head>
<title>FemtoStar - Donate</title>
</svelte:head>
<div class="site">
<TalkingPointContainer>
<TalkingPointName text="Donations" />
<TalkingPointContent>
<p>
The FemtoStar Project is a community of volunteers funded by a grant from our partner NLnet,
out-of-pocket by some of our members, and from donations by our community. Nobody is required
to donate, and we currently don't have much in terms of perks for donors, but if you'd like to see
this project succeed and are able to, consider throwing a few dollars our way or setting up
a recurring donation through Liberapay.
</p>
<p>
Donations go directly into buying hardware for the project. All of our members are volunteers, and our
operating costs apart from hardware are low enough to cover out of pocket. Everything donated here will
be spent on hardware to make this project possible.
</p>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName text="Donate via PayPal" />
<TalkingPointContent>
<p>
Via PayPal, we accept both one-time donations directly via PayPal, and recurring donations via Liberapay
(processed using PayPal).
</p>
<p>
<b>PayPal (one-time donation):</b> <a href="https://www.paypal.com/donate/?hosted_button_id=M2N5N2B624CNQ&source=url">Click Here</a>
</p>
<p>
<b>Liberapay (recurring donation):</b> <a href="https://liberapay.com/FemtoStar/donate">Click Here</a>
</p>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName text="Donate Cryptocurrency" />
<TalkingPointContent>
<p>
If you would like to make a donation in cryptocurrency, please send any amount of Bitcoin or Monero to
one of the following addresses.
</p>
<p>
<b>Bitcoin:</b> <span class="crypto-address">bc1qnytm8arpuz247622yef070nvxx56qp6dqwl80s</span>
</p>
<p>
<b>Monero:</b> <span class="crypto-address">83YcY9dsxARYkS4AaKVNkEJTLMQnuvuzSSij9vC7SqU7eriCpHHBsrs2ijKE6MQjobUShY4D2kjQTZ3XXp7WMtR7PdjKrx9</span>
</p>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName text="Want to donate another way?" />
<TalkingPointContent>
<p>
If you would like to donate via a method not listed above (such as via
a different payment processor or in a different cryptocurrency), please
<a href="about-contact/">contact us</a> and we'd be glad to help set something up.
</p>
</TalkingPointContent>
</TalkingPointContainer>
</div>
<style>
.site {
margin-left: auto;
margin-right: auto;
padding-top: 0;
padding-bottom: 3em;
max-width: 1024px;
padding-left: 2em;
padding-right: 2em;
}
.c{
overflow: hidden;
height: 0px;
width: 0px;
position: absolute;
}
.j{
overflow: hidden;
height: 0px;
width: 0px;
position: absolute;
}
.crypto-address{
overflow-wrap: break-word;
word-break: break-all;
}
talkingPointContainer{
overflow-wrap: normal;
}
:global(.site a) {
color: #72bbd9;
}
</style>

575
src/routes/faq/+page.svelte Normal file
View file

@ -0,0 +1,575 @@
<script>
import FAQItem from "../../components/FAQItem.svelte";
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
import TalkingPointName from "../../components/TalkingPointName.svelte";
</script>
<svelte:head>
<title>FemtoStar - FAQ</title>
</svelte:head>
<div class="site">
<TalkingPointContainer>
<TalkingPointName text="Products and Services" />
<TalkingPointContent>
<FAQItem
title="Do you plan to offer bandwidth tiers? Will there be a data cap?"
>
<p>
All FemtoStar services are delivered on a best-effort basis, at the
highest speed technically feasible with the user's hardware and with
network traffic at that time. We do not impose artificial restrictions
on bandwidth. The flipside of this is that, while we do not limit you
to a maximum speed, we cannot guarantee you will always get one
particular speed either - getting the maximum possible at all times
means that, unlike a service where you are constantly limited to a
certain bandwidth even when more is possible, FemtoStar performance
will vary. Performance at some times being lower than at some others
should be expected.
</p>
<p>
FemtoStar service is paid for in terms of the amount of beam time a
session consumes - that is, how long the satellite needs to spend
using one of its beams to transmit data for that session. This is not
the same as the amount of time a user stays connected to the network -
because the beam must also serve other users and any particular user's
terminal is unlikely to be consuming the full throughput of its link
at all times, a connected terminal consumes much less beam time than
the amount of time it remains connected, especially when usage is
light. What all of this means is that there is no data cap - we don't
care about how many bytes you send through the satellite, only how
long the satellite must spend handling your traffic.
</p>
<p>
This means that users with larger, higher-speed terminals (see the
above point) able to transfer the same amount of data in a shorter
period of time will pay less for the same amount of data transferred,
as they will consume less beam time in doing so. Because beam time is
the network's most important resource, and is the limiting factor in
terms of network performance, we believe that charging for service in
terms of the actual resource - beam time - being consumed is the most
fair model for service pricing.
</p>
</FAQItem>
<FAQItem title="Who makes FemtoStar terminals?">
FemtoStar plans to take a hybrid approach to manufacturing and selling
terminals. FemtoStar's higher-sales-volume "core" user terminals will be
manufactured and sold primarily by hardware partners, allowing us to
leverage existing manufacturing and sales infrastructure. Meanwhile,
development and reference hardware, as well as more specialized
terminals will be made in Canada by FemtoStar, at the same facility
where we build our satellites. Every FemtoStar terminal is based on
FemtoStar-developed reference designs.
</FAQItem>
<FAQItem title="What speeds do you anticipate being available?">
<p>
FemtoStar is a midband Mobile Satellite Service network, designed for
speeds in line with other midband Mobile Satellite Service offerings.
Here, the term "midband" refers to the level of bandwidth between
narrowband services, designed to provide a low-speed connection to
small, usually IoT/embedded terminals, and broadband services,
designed to provide a high-speed connection to large, expensive, fixed
terminals.
</p>
<p>
While this middle category of service may be unfamiliar to those more
used to terrestrial services, it's common in the in Mobile Satellite
Service landscape, and is what's offered by services such as Inmarsat
BGAN, Iridium Certus, or Thuraya IP. In these services, as in
FemtoStar, designing for this middle category means that users can
expect performance much better than a narrowband system, while still
having a portable terminal much smaller than those needed for
broadband systems. Like the aforementioned MSS options, a typical
FemtoStar terminal should provide in the mid-hundreds of kbps, using a
terminal roughly the size of a tablet or small laptop.
</p>
<p>
Of course, FemtoStar's design still allows for flexibility on the size
and speed of terminals - users should be able to choose their own
balance between speed, cost, and portability. As such, depending on
the size of the terminal, FemtoStar should be able to accomodate
larger terminals in the megabits-per-second range, or smaller
terminals with reduced (if still better than typical narrowband
offerings) speeds in a pocket-sized form factor.
</p>
</FAQItem>
<FAQItem title="Is the FemtoStar Credit Token a cryptocurrency?">
<p>
No, at least not by any usual definition of the term. While they are a
digital system used to pay for service, and while they do make use of
cryptographic signatures for security, FemtoStar Credit Tokens are not
transacted on a blockchain, cannot be mined, and are not intended for
use as anything other than payment for FemtoStar service. While
third-party users are free to buy and sell Credit Tokens at any price
they are able to, their value in FemtoStar service is fixed.
</p>
</FAQItem>
<FAQItem title="How do I buy FemtoStar tokens? Are they available yet?">
<p>
Once our network is operational, you will be able to purchase
FemtoStar tokens from FemtoStar via a retail token sales portal, from
a third-party reseller, in bulk from FemtoStar via a wholesale
agreement, or from anyone else willing to sell them to you. While the
FemtoStar Project is capable of pre-issuing tokens that will be usable
once the network is operational, we do not currently offer pre-issued
retail tokens to the general public, due to the inherent risk to
consumers of purchasing a service before it is available. If you are
interested in working with us to purchase wholesale tokens, for resale
as a token reseller or for a large deployment of FemtoStar hardware as
an enterprise user, please <a href="./about-contact">contact us</a>.
</p>
</FAQItem>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName text="Network Architecture and Other Projects" />
<TalkingPointContent>
<FAQItem title="What about Starlink?">
<p>
<a href="https://starlink.com">Starlink</a> is a low-earth-orbit communications
constellation developed by SpaceX. While we have a tremendous amount of
respect for the engineering accomplishments of the Starlink network, its
goals and those of FemtoStar are almost entirely separate. While both intend
to provide satellite communications service using low-earth orbit constellations,
Starlink is designed to provide consumer broadband services to large, fixed
terminals (in the satellite industry, this is known as Fixed Satellite
Service). FemtoStar, on the other hand, is designed for midband services
to small and medium, portable or in-motion terminals (also known as Mobile
Satellite Service).
</p>
<p>
While the Starlink network is large, its architecture is traditional -
it is designed to connect users to official ground stations providing
official services. While there has been talk of limited use of
Starlink for point-to-point connectivity, such as for high-speed
securities trading, SpaceX holds complete control over use of this
feature, and it is not a part of their consumer-facing services, nor
is it known to be possible with their consumer hardware. FemtoStar's
open-infrastructure architecture ensures an inherently net-neutral
network, wherein all hardware is usable as a ground station, and even
our own services are simply one of many a satellite is able to connect
users to.
</p>
<p>
Starlink terminals are uniquely identified on the network, and can be
easily geolocated by the network (whether they report their GPS
location is currently unknown, but the network is certainly able to
geolocate them accurately, as they are disallowed from accessing the
network outside of the small region, or "cell", where their user's
address is registered). Starlink users are required to provide a
substantial amount of personal information in order to purchase
service. Payments are handled on ground infrastructure, based on user
accounts. FemtoStar does not require any user account whatsoever, is
not restricted to use in a small cell, and handles payments on the
satellite itself using FemtoStar Credit Tokens.
</p>
</FAQItem>
<FAQItem title="What about Blockstream or Othernet?">
<p>
<a href="https://blockstream.com">Blockstream</a> is a cryptocurrency
company which offers a service named
<a href="https://blockstream.com/satellite">Blockstream Satellite</a>.
<a href="https://othernet.is">Othernet</a> is a company which broadcasts
data, primarily news and other text content, via satellite.
</p>
<p>
Blockstream Satellite broadcasts the Bitcoin blockchain, one-way, over
six geostationary broadcasting satellites, and offers an API to
transmit your own short pieces of data over the network, with payment
in Bitcoin. While Blockstream does allow for remote access to the
Bitcoin blockchain, it is a one-way system - it cannot be used for
two-way communications, or to make online cryptocurrency transactions,
unless you already have an internet connection and can connect to its
API.
</p>
<p>
Othernet provides one-way, broadcast data service via two
geostationary satellites. This data typically consists of news,
Wikipedia articles, and other low-data-rate content which can be
delivered one-way.
</p>
<p>
Both of these companies purchase time on existing geostationary
broadcasting satellites, of the type typically used for consumer
satellite television. These services do not support, nor is the
hardware provided for them capable of, any form of uplink from the
user terminal. While both services are useful as tools for broadcast
data distribution, they are one-way, Broadcasting Satellite Service
systems, distinct from two-way communications systems in the Fixed
Satellite Service (such as Starlink) and Mobile Satellite Service
(such as FemtoStar).
</p>
</FAQItem>
<FAQItem
title="Are you sure satellites are the right way to do this? Surely a terrestrial network would be easier?"
>
<p>
We're big fans of a number of the terrestrial privacy-respecting
communications projects currently in development - in fact, FemtoStar <a
href="./about-contact">began as a terrestrial network</a
>, named Private Mobile Data Protocol (PMDP).
</p>
<p>
The fundamental issue of terrestrial networks is the amount of
hardware necessary to provide adequate coverage. It has taken decades
of development, thousands of licenses to thousands of companies in
hundreds of countries, hundreds of billions of dollars at least, and <a
href="https://www.mobileworldlive.com/blog/blog-global-base-station-count-7m-or-4-times-higher"
>more than 7 million cell towers</a
> to build mainstream cellular networks out to their current coverage,
and even with this it's likely you still sometimes have problems getting
cellular service. We began with the assumption that a terrestrial network
would be the only practical solution, and extensively tested PMDP hardware
in real-world urban and suburban environments. Eventually, even we - the
developers of the technology - were forced to admit that it was impractical
without an impractically dense network, even for a small, urban implementation
- letalone regional or global coverage.
</p>
<p>
As a thought experiment in community-run terrestrial networks, next
time you leave home, ask yourself if you are ever more than 1
kilometer (3200 feet) away from somewhere a mesh node or base station
in a community-run terrestrial network could be installed without
being removed, stolen, or tampered with, and if anyone nearby would be
willing to pay for, install, and maintain such a device. We tried
this, with real hardware, in a real city, in 2019, and came to the
conclusion that that, in contrast to being an easier solution, it was
likely outright impossible in most circumstances.
</p>
<p>
Where such networks can exist, they genuinely do have some advantages
over satellite-based networks - however, in most places, it is simply
not realistic to build them. We found this out the hard way. It's also
worth noting that FemtoStar can coexist with these networks
symbiotically - where these networks can be built, given that this is
likely to occur in clusters of nodes or base stations (such as in a
city center) separated by a substantial distance, we believe FemtoStar
could be extremely useful to link these sections together into larger,
more resillient networks.
</p>
</FAQItem>
<FAQItem title="What about mesh networks?">
<p>
See the above point. While mesh networks are able to partially solve
the problem of base station range by allowing every user device to
extend coverage, this still does not allow for coverage where there
are no nodes. The same thought experiment applies - are you always
within a kilometer of someone else who might have a node in the mesh?
If you have your own node in the mesh, is there ever another node
nearby for it to mesh with? If not, a mesh network may not be
practical in your situation. Even where mesh networks are practical,
FemtoStar could still be used to interconnect regions where the mesh
is available, even when they are separated by large regions with no
nodes.
</p>
</FAQItem>
<FAQItem
title="I've used satellite internet, and the latency is pretty bad - is this true of FemtoStar too?"
>
<p>
Not to nearly the same degree. While the distance to the satellite
does add some amount of latency due to the time taken for the signal
to reach the satellite, the round-trip propagation time to a low-earth
orbit satellite is a handful of milliseconds, not the hundreds of
milliseconds familiar to users of geostationary satellite networks.
Ping time on FemtoStar should be less than a tenth of that which a
geostationary satellite user would experience, if even that.
</p>
</FAQItem>
<FAQItem title="How do you plan to mitigate orbital debris?">
<p>
In contrast to the vast majority of small satellites, FemtoStar plans
to include electric propulsion onboard our satellites, allowing them
to be repositioned as needed and cleanly deorbited at end-of-life. The
FemtoStar Project is working closely with Applied Ion Systems, a
leading developer of open-hardware smallsat propulsion hardware, to
develop a specialized implementation of their technology for use
onboard the FemtoStar space vehicle. Even in the event of a thruster
failure, the solar panel can be positioned to drastically increase
atmospheric drag on the satellite, rapidly increasing orbital decay
and deorbiting the satellite.
</p>
</FAQItem>
<FAQItem
title="Is this a megaconstellation? How many satellites do you need?"
>
<p>
The network can theoretically work with as little as a single
satellite, however of course this configuration does not allow for
continuous coverage. Practical constellation layouts begin at around
48 satellites (and include the layout shown on our <a href="./"
>homepage</a
>. We have also considered the possibility of starting with a larger
constellation of up to 96 satellites, however we believe the most
reasonable approach would be to begin with the minimum practical
number of satellites (likely 48) and then scale up the constellation
with new satellites as needed.
</p>
</FAQItem>
<FAQItem
title="What if a satellite fails? Will the network become unreliable?"
>
<p>
The FemtoStar network provides multiple levels of protection against
failure of spacecraft, and against failure of the network due to
failure of a spacecraft, resulting in a resilient network able to
mitigate and work around hardware failures onboard satellites. Each
satellite incorporates a degree of redundancy previously seen only on
far larger satellites, and is designed with longevity in mind. The
network as a whole also protects against network-wide failure as a
result of the failure of a single satellite - most regions, especially
those with a latitude near the inclination of the satellites such as
North America Europe, and Oceania, and much of Asia and South America
- are covered redundantly, and even elsewhere, the "gap" caused when
the only satellite visible to a user has failed is short - lasting
only minutes or less before working satellites come into view.
</p>
<p>
For most users, a satellite failure would likely be noticeable only as
a decrease in the network's coverage angle, while for those in the
aforementioned near-inclination regions, it might not be noticeable at
all. Finally, FemtoStar would be able to rapidly and inexpensively
replenish its network with new satellites, either newly-launched or
simply moved into place if already available in a storage orbit.
</p>
</FAQItem>
</TalkingPointContent>
</TalkingPointContainer>
<TalkingPointContainer>
<TalkingPointName text="Privacy and Security" />
<TalkingPointContent>
<FAQItem
title="How is using FemtoStar private when using it indicates that you are looking for privacy?"
>
<p>
FemtoStar is not purely a "privacy" system - we believe it to be
competitive with other mobile satellite options, and in all likelihood
there will be plenty of FemtoStar users who aren't even aware of, much
less interested in, its privacy features. We also believe there will
be a number of FemtoStar terminals installed as a part of
machine-to-machine data installations, as backup connections for
enterprise networks, or as backhaul to community-run terrestrial
networks. A user using it for privacy reasons is indistinguishable
from any of these users.
</p>
<p>
Additionally, by this rationale, any privacy-respecting product,
service, or system is bad for your privacy, as its use demonstrates
that you are looking for privacy. Even if your threat model truly does
require that you obscure even the fact that someone is using a system
that could be used for privacy-respecting communications, FemtoStar
still does substantially better than just about any other
privacy-respecting communications network. For one thing, it uses a
substantially more directional antenna than any terrestrial mobile,
which means its transmitted signal is very weak in any direction but
that of the satellite.
</p>
<p>
Its connection to the satellite is also is encrypted, and even to the
satellite, it does not contain a location, terminal identifier, user
account, or any other identifying details. The terminal never
transmits when it has no session open with the satellite, and, unlike
mesh network nodes, it cannot be made to transmit by the traffic of
another user unless the terminal's owner has chosen to operate their
own service over the network.
</p>
</FAQItem>
<FAQItem
title="Don't FemtoStar's satellites have to know where I am, based on which beam I use?"
>
<p>
In theory, to some extent, but in practice, not meaningfully. In
contrast to traditional communications satellites, a FemtoStar
satellite, at least for transmit, does not have a consistent beam
pattern. Instead, electronic beamforming is used to point each of only
a handful of beams, rapidly switching beam patterns as the satellite
jumps between active sessions. The footprints within which these beams
are usable are hundreds of kilometers across, even at their narrowest,
and more than 2000 kilometers long. In addition, knowing where "you"
are, as opposed to just knowing the rough area in which one of the
network's users is located, requires knowing who you are. As such, the
satellite could determine that an anonymous session is within, for
example, northern Europe, western North America, or eastern Asia, but
not that it is in a particular country or city, and certainly not who
that session belongs to.
</p>
</FAQItem>
<FAQItem title="You say geolocation-resistant - is it geolocation-proof?">
<p>
We do not feel that we can promise that there is any two-way wireless
communications system where it is truly impossible for an adversary to
locate a transmitter given enough time to search for it on the ground.
In particular, it is extremely difficult to prevent just about any
transmitter from being detectable by a high-gain antenna at short
range, no matter how directional or low-power the transmitter may be.
However, we also believe that such a search would need to begin
relatively close to any terminal it wanted to have a chance of
finding, and that it would likely be complicated by the presence of
more than one FemtoStar terminal in an area.
</p>
<p>
Additionally, there's the question of why finding terminals would be
worthwhile to an attacker to begin with. Given that such an attack
would almost certainly involve the rather labor-intensive task of
traveling around an area of interest with a vehicle full of equipment
looking for terminals that you cannot identify and cannot monitor the
activity of, while also being unable to tell the difference between
two intermittently-used terminals and one terminal which has moved, we
do feel we can say that this attack is unlikely to fit into many
threat models.
</p>
<p>
A FemtoStar terminal can even be used as a receive-only device if this
is acceptable for the user's use case - in this configuration, it
would likely be nearly impossible to geolocate, even with this sort of
attack.
</p>
<p>
In short, we don't believe any transmitting device is truly
geolocation-proof, but we do believe that geolocation of users can be
made impractical for to perform at a large scale, and that its value
to an attacker can be substantially diminished. On top of this, we do
feel we can safely say that FemtoStar is substantially more
geolocation-resistant than any currently-available two-way wireless
communications system, and that it is likely that its
geolocation-resistance could only be matched or exceeded by another
satellite-based system including most or all of the same
geolocation-resistance features.
</p>
</FAQItem>
<FAQItem
title="What if the FemtoStar project is taken over by someone I don't trust?"
>
<p>
The FemtoStar architecture does not require that you trust the
FemtoStar Project, even to begin with. Because the user is not
required to trust the FemtoStar network, in order for the FemtoStar
Project, or or an entity who had taken it over, to meaningfully
compromise the security of FemtoStar users, many core design elements
of the network would need to be changed, necessitating, at minimum, a
firmware update to user terminals to accomodate substantial protocol
changes. A new update published without
<a href="./free-open-source">source code</a> would be immediately suspicious,
as would a new update where the newly-released source code disabled privacy
features.
</p>
</FAQItem>
<FAQItem
title="FemtoStar Inc. is Canadian - what if I don't trust Canada?"
>
<p>
See the above point. Even if a malicious government were to take over
the FemtoStar Project and attempt to surveil its users, they would be
incapable of doing so without making changes that would be immediately
obvious to users, and to our own developers in other countries.
Additionally FemtoStar Inc. in Canada is only one part of the
overarching FemtoStar Project - we have developers all over the world.
</p>
</FAQItem>
<FAQItem title="What if the satellites themselves are attacked?">
<p>
While we would never claim that it is impossible that a FemtoStar
satellite could be compromised, either remotely or through physical
attack, we believe the likelihood of this to be low for a number of
reasons.
</p>
<p>
The most important point here is that FemtoStar satellites are not
especially useful targets to an attacker. Due to not being a trusted
part of the network, even if they themselves are fully compromised,
they cannot be used to compromise FemtoStar users, nor would they be
much use as part of a botnet, nor would they provide an attacker with
any additional utility in their intended purpose (communications) than
is available officially.
</p>
<p>
With regards to compromising the satellites from the ground, the
satellite's onboard software is subject to intense scrutiny, including
through formal proofs, makes extensive use of sandboxing, and, given
the relative simplicity of the FemtoStar protocol, presents a small
attack surface.
</p>
<p>
In terms of physical security, while FemtoStar's placement of its
infrastructure in orbit certainly grants it a degree of
inaccessibility compared to terrestrial infrastructure, there are of
course spacecraft which could conceivably reach a FemtoStar satellite,
and could hypothetically either tamper with or replace it. However,
tampering would require physical capture and substantial disassembly
of the satellite, which is detectable and would result in the deletion
of onboard keys, resulting in a tampered-with satellite being easily
detectable from the ground (even if new software attempted to obscure
this tampering), while a replacement satellite would lack the
cryptographic keys of the satellite it replaced entirely.
</p>
<p>
An attacker could opt to attempt to disable, capture, or destroy a
satellite altogether - after all, if you want to assume that truly no
adversary is off the table, you could choose to consider even the use
of anti-satellite weapons. However, an attacker trying to make the
network truly unusable would need to destroy or disable not just one
satellite, but the entire constellation, and any replacement
satellites, and to do so in a way which obscured their involvement, a
daunting task even for the largest possible adversaries. This type of
attack is also immediately obvious (especially if the satellite is
physically destroyed, resulting in the generation of orbital debris),
and even this still does not result in an actual compromise
(geolocation, identification, etc.) of FemtoStar users.
</p>
</FAQItem>
</TalkingPointContent>
</TalkingPointContainer>
</div>
<style>
.site {
padding-top: 0;
padding-bottom: 3em;
max-width: 1024px;
margin-left: auto;
margin-right: auto;
padding-left: 2em;
padding-right: 2em;
}
</style>

View file

@ -0,0 +1,73 @@
<script>
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
import TalkingPointName from "../../components/TalkingPointName.svelte";
</script>
<svelte:head>
<title>FemtoStar - Free & Open Source</title>
</svelte:head>
<div class="site">
<TalkingPointContainer>
<TalkingPointName
text="Free and open-source technology, built by a global community"
/>
<TalkingPointContent>
<p>
From the user terminal, to the spacecraft, to the ground station,
FemtoStar is powered by free and open-source hardware and software, and
we don't just mean the high-level stuff. Notably, in a world first for
wide-area communications networks, even the FemtoStar air interface and
the low-level radio firmware implementing it will be free and
open-source software.
</p>
<p>
This isn't just a technical decision. FOSS is common in the software
world, but in the telecommunications and aerospace industries, this
approach is highly unusual. However, for FemtoStar to succeed, we
believe it to be critical.
</p>
<p>
Releasing our designs as free and open-source allows for FemtoStar to be
effective as a piece of open infrastructure - you can build on top of
it, or integrate it into your own products and services. It's what gives
FemtoStar the flexibility to work just as well as an internal backup
network for a business as it does as a portable mobile internet
terminal.
</p>
<p>
It also allows our users to verify our claims about privacy and
security. We do not believe that simply promising the user that their
privacy will be preserved is adequate. Free and open-source software
allows users to inspect and verify that features such as end-to-end
encryption and low-level geolocation mitigations are operating as
intended, allowing users to be sure that FemtoStar meets its privacy
claims without the need to simply trust its developers.
</p>
<p>
FemtoStar is developed and maintained by a global community of
developers collaborating online. If you're interested in helping out,
don't hesitate to <a rel="prefetch" href="./about-contact"
>contact us →</a
>.
</p>
</TalkingPointContent>
</TalkingPointContainer>
</div>
<style>
.site {
margin-left: auto;
margin-right: auto;
padding-top: 0;
padding-bottom: 3em;
max-width: 1024px;
padding-left: 2em;
padding-right: 2em;
}
:global(.site a) {
color: #72bbd9;
}
</style>

View file

@ -0,0 +1,61 @@
<script>
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
import TalkingPointName from "../../components/TalkingPointName.svelte";
</script>
<svelte:head>
<title>FemtoStar - Global Open Infrastructure</title>
</svelte:head>
<div class="site">
<TalkingPointContainer>
<TalkingPointName text="Global Open Infrastructure" />
<TalkingPointContent>
<p>
Like any satellite communications system, FemtoStar uses a network of
satellites to allow communications between terminals on earth.
Traditional communications satellites - both those that act as simple
repeaters, and those with onboard routing - fundamentally work by
shuffling data to and from user terminals via a separate,
non-user-accessible feeder link connecting them to a large, official
ground station.
</p>
<p>
FemtoStar breaks this distinction. All user hardware can be used both to
connect to and to operate services, directly via the satellites. There
are no special "feeder" links, and no prior arrangement with FemtoStar
is required to operate a service. Credit processing takes place
on-satellite, and works even when no official ground station is
available.
</p>
<p>
FemtoStar is also developing FemtoStar Real-Time Core Services (RTCS),
an open standard for basic communications services such as internet
access over the FemtoStar network. RTCS is intended to provide a global
baseline in FemtoStar-based service, and will be supported by all of our
own ground stations. We encourage RTCS adoption at third-party ground
stations
</p>
<p>
It's not just services either - the FemtoStar terminal will be released
as an open standard, with an open-hardware reference design, and
FemtoStar will work with third-party terminal manufacturers to license
third-party terminals for use on the FemtoStar network.
</p>
</TalkingPointContent>
</TalkingPointContainer>
</div>
<style>
.site {
padding-top: 0;
padding-bottom: 3em;
max-width: 1024px;
margin-left: auto;
margin-right: auto;
padding-left: 2em;
padding-right: 2em;
}
</style>

View file

@ -0,0 +1,81 @@
<script>
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
import TalkingPointName from "../../components/TalkingPointName.svelte";
</script>
<svelte:head>
<title>FemtoStar - Privacy by Design, not promise</title>
</svelte:head>
<div class="site">
<TalkingPointContainer>
<TalkingPointName text="Privacy by design, not just by promise" />
<TalkingPointContent>
<p>
Today, many products and services advertise user privacy as a selling
point. Very few can be proven to live up to their claims. At FemtoStar,
privacy isn't just a marketing promise the user is required to trust we
will keep. It's baked into the network at every level - from
physical-layer mitigations of low-level attacks, to end-to-end
encryption on all connections, to anonymous payment via our credit token
system. Don't believe us? FemtoStar's hardware and software are
completely free and open-source, and therefore completely open to
third-party inspection and testing.
</p>
<ul>
<li>
<b>Verifiable anonymity</b> - In the FemtoStar network, neither users nor
their hardware are identifiable to the network. When a user terminal connects
to a FemtoStar satellite, it opens an anonymous, short-lived routing session,
which is not tied to any identity, location, or other user information.
Users don't need any form of user account to use FemtoStar - we don't even
offer them.
</li>
<li>
<b>Geolocation-resistant by design</b> - Traditional communications systems,
such as cellular networks or existing mobile satellite systems, rely on
tracking the user's location for basic network functions, such as setting
up the connection or handling a moving user. FemtoStar takes advantage
of a unique combination of cautious protocol design, low-level terminal-side
mitigations, and the inherent properties of satellites to ensure that the
location of terminals cannot be determined accurately.
</li>
<li>
<b>End-to-end encrypted</b> - While most modern communications systems
encrypt traffic over the air, FemtoStar goes a step further. FemtoStar
user traffic is end-to-end encrypted, meaning not even the satellite itself
can decrypt it. What's more, connections are direct - from user, to satellite,
to service. Unless you're connecting to a service we provide, our ground
infrastructure never handles your data even in an encrypted form. This
also makes FemtoStar inherently net-neutral - after all, if we can't even
decrypt your traffic, we can't selectively limit or throttle it either.
</li>
<li>
<b>Private payments</b> - An anonymous system isn't truly anonymous if
users must still provide identifying information in order to pay for service.
FemtoStar's payment system is simple, flexible, and above all, private.
User terminals provide service tokens as they consume service. These tokens
can be bought, stored, sold, used, or transferred freely by the user. They
are not tied to any account or identity, they do not need to be purchased
directly from FemtoStar, and they never expire. Service is priced by satellite
resources consumed, not by time or data usage, so you won't be charged
more for staying connected for longer or for connecting with a faster terminal.
</li>
</ul>
</TalkingPointContent>
</TalkingPointContainer>
</div>
<style>
.site {
margin-left: auto;
margin-right: auto;
padding-top: 0;
padding-bottom: 3em;
max-width: 1024px;
padding-left: 2em;
padding-right: 2em;
}
</style>

BIN
static/Jost.ttf Normal file

Binary file not shown.

BIN
static/ais-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
static/femtostar_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
static/fossa-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

40
static/global.css Normal file
View file

@ -0,0 +1,40 @@
body {
margin: 0;
font-family: Roboto, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-size: 14px;
line-height: 1.5;
color: #333;
}
h1, h2, h3, h4, h5, h6 {
margin: 0 0 0.5em 0;
font-weight: 400;
line-height: 1.2;
}
h1 {
font-size: 2em;
}
a {
color: inherit;
}
code {
font-family: menlo, inconsolata, monospace;
font-size: calc(1em - 2px);
color: #555;
background-color: #f0f0f0;
padding: 0.2em 0.4em;
border-radius: 2px;
}
.navlogo{
height: 100%;
}
@media (min-width: 400px) {
body {
font-size: 16px;
}
}

BIN
static/logo-192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
static/logo-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

20
static/manifest.json Normal file
View file

@ -0,0 +1,20 @@
{
"background_color": "#ffffff",
"theme_color": "#333333",
"name": "TODO",
"short_name": "TODO",
"display": "minimal-ui",
"start_url": "/",
"icons": [
{
"src": "logo-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "logo-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

BIN
static/nlnet-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
static/pine-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

3
static/robots.txt Normal file
View file

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

96
static/tle.js Normal file
View file

@ -0,0 +1,96 @@
export default `1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 000.0000 0000000 000.0000 000.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 000.0000 0000000 000.0000 090.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 000.0000 0000000 000.0000 180.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 000.0000 0000000 000.0000 270.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 030.0000 0000000 000.0000 307.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 030.0000 0000000 000.0000 037.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 030.0000 0000000 000.0000 127.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 030.0000 0000000 000.0000 217.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 060.0000 0000000 000.0000 255.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 060.0000 0000000 000.0000 345.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 060.0000 0000000 000.0000 075.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 060.0000 0000000 000.0000 165.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 090.0000 0000000 000.0000 202.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 090.0000 0000000 000.0000 292.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 090.0000 0000000 000.0000 022.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 090.0000 0000000 000.0000 112.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 120.0000 0000000 000.0000 150.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 120.0000 0000000 000.0000 240.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 120.0000 0000000 000.0000 330.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 120.0000 0000000 000.0000 060.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 150.0000 0000000 000.0000 097.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 150.0000 0000000 000.0000 187.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 150.0000 0000000 000.0000 277.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 150.0000 0000000 000.0000 007.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 180.0000 0000000 000.0000 045.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 180.0000 0000000 000.0000 135.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 180.0000 0000000 000.0000 225.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 180.0000 0000000 000.0000 315.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 210.0000 0000000 000.0000 352.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 210.0000 0000000 000.0000 082.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 210.0000 0000000 000.0000 172.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 210.0000 0000000 000.0000 262.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 240.0000 0000000 000.0000 300.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 240.0000 0000000 000.0000 030.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 240.0000 0000000 000.0000 120.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 240.0000 0000000 000.0000 210.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 270.0000 0000000 000.0000 247.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 270.0000 0000000 000.0000 337.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 270.0000 0000000 000.0000 067.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 270.0000 0000000 000.0000 157.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 300.0000 0000000 000.0000 195.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 300.0000 0000000 000.0000 285.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 300.0000 0000000 000.0000 015.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 300.0000 0000000 000.0000 105.0000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 330.0000 0000000 000.0000 142.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 330.0000 0000000 000.0000 232.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 330.0000 0000000 000.0000 322.5000 14.12748000000000
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
2 00000 53.0000 330.0000 0000000 000.0000 052.5000 14.12748000000000`

1
static/world-110m.js Normal file

File diff suppressed because one or more lines are too long

13
svelte.config.js Normal file
View file

@ -0,0 +1,13 @@
import adapter from '@sveltejs/adapter-auto';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter()
}
};
export default config;

17
vite.config.js Normal file
View file

@ -0,0 +1,17 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig, searchForWorkspaceRoot } from 'vite';
export default defineConfig({
plugins: [sveltekit()],
server: {
fs: {
allow: [
// search up for workspace root
searchForWorkspaceRoot(process.cwd()),
// your custom rules
'static/',
],
},
},
});