This commit is contained in:
Daniel Vinci 2021-04-16 10:07:57 -06:00
commit 2a8386e144
No known key found for this signature in database
GPG key ID: 5237E95295431664
361 changed files with 4842 additions and 0 deletions

39
src/ambient.d.ts vendored Normal file
View file

@ -0,0 +1,39 @@
/**
* These declarations tell TypeScript that we allow import of images, e.g.
* ```
<script lang='ts'>
import successkid from 'images/successkid.jpg';
</script>
<img src="{successkid}">
```
*/
declare module "*.gif" {
const value: string;
export = value;
}
declare module "*.jpg" {
const value: string;
export = value;
}
declare module "*.jpeg" {
const value: string;
export = value;
}
declare module "*.png" {
const value: string;
export = value;
}
declare module "*.svg" {
const value: string;
export = value;
}
declare module "*.webp" {
const value: string;
export = value;
}

5
src/client.js Normal file
View file

@ -0,0 +1,5 @@
import * as sapper from '@sapper/app';
sapper.start({
target: document.querySelector('#sapper')
});

View file

@ -0,0 +1,49 @@
<div>
<svg
width="96"
height="75"
viewBox="0 0 32 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 0H14.6453V4.5H5.05011V10.0714H14.2846V14.3571H5.05011V25H0V0Z"
fill="#FFFFFF"
/>
<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="#FFFFFF"
/>
</svg>
<h1>FemtoStar</h1>
<h2>Satellite communications, done differently.</h2>
</div>
<style>
div {
padding-top: 3em;
padding-bottom: 3em;
display: flex;
width: 100%;
background-color: #00111d;
color: #ffffff;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
svg {
padding-top: 1em;
}
h1 {
margin-top: 0.5em;
font-weight: bold;
}
h2 {
margin-top: -0.25em;
}
</style>

View file

@ -0,0 +1,19 @@
<div class="globeContainer">
<img alt="placeholder for globe" src="https://via.placeholder.com/225" />
</div>
<style>
.globeContainer {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
background-color: #00111d;
color: #ffffff;
}
img {
padding-right: 3em;
}
</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>

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

@ -0,0 +1,71 @@
<script>
export let segment;
</script>
<nav>
<ul>
<li>
<a
rel="prefetch"
aria-current={segment === undefined ? "page" : undefined}
href=".">home</a
>
</li>
<li>
<a
rel="prefetch"
aria-current={segment === "about-contact" ? "page" : undefined}
href="./about-contact">about & contact</a
>
</li>
</ul>
</nav>
<style>
nav {
font-weight: 300;
background-color: #00111d;
color: white;
}
ul {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
/* clearfix */
ul::after {
content: "";
display: block;
clear: both;
}
li {
display: block;
}
[aria-current] {
position: relative;
display: inline-block;
font-weight: bold;
}
[aria-current]::after {
position: absolute;
content: "";
width: calc(100% - 1em);
height: 3px;
background-color: white;
display: block;
bottom: -1px;
}
a {
text-decoration: none;
padding: 1em 0.5em;
display: block;
line-height: 1em;
}
</style>

View file

@ -0,0 +1,12 @@
<div class="talkingPointContainer">
<slot />
</div>
<style>
.talkingPointContainer {
background-color: aquamarine;
display: grid;
grid-template-columns: 30% auto;
grid-template-rows: 1;
}
</style>

View file

@ -0,0 +1,28 @@
<div class="talkingPointContentContainer">
<div class="talkingPointContent">
<slot />
</div>
</div>
<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;
}
</style>

View file

@ -0,0 +1,26 @@
<script>
export let text = "replace this";
</script>
<div class="talkingPointNameContainer">
<h2 class="talkingPointName">{text}</h2>
</div>
<style>
.talkingPointNameContainer {
width: 100%;
height: 100%;
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;
}
</style>

BIN
src/node_modules/images/successkid.jpg generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 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}

15
src/routes/_layout.svelte Normal file
View file

@ -0,0 +1,15 @@
<script>
import Nav from "../components/Nav.svelte";
export let segment;
</script>
<Nav {segment} />
<slot />
<style>
:global(body) {
background-color: #00111d;
}
</style>

View file

@ -0,0 +1,100 @@
<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 #femtostar:matrix.org. Alternatively, email us at [the name of this
site/our satellite] at tutanota.com.
</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: 1em;
padding-bottom: 3em;
max-width: 1500px;
}
</style>

View file

@ -0,0 +1,59 @@
<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: 1em;
padding-bottom: 3em;
max-width: 1500px;
margin-left: auto;
margin-right: auto;
}
</style>

89
src/routes/index.svelte Normal file
View file

@ -0,0 +1,89 @@
<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 TalkingPointContent from "../components/TalkingPointContent.svelte";
import TalkingPointName from "../components/TalkingPointName.svelte";
</script>
<svelte:head>
<title>FemtoStar</title>
</svelte:head>
<div class="site">
<div class="hero">
<div class="container">
<Globe />
<FemtoHeader />
<IntroText />
</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="./open-source">Learn more →</a></p>
</TalkingPointContent>
</TalkingPointContainer>
</div>
<style>
:global(.site a) {
color: #72bbd9;
}
.site {
margin-left: auto;
margin-right: auto;
max-width: 1500px;
}
.hero {
background-color: aqua;
}
.hero .container {
background-color: aquamarine;
display: grid;
grid-template-columns: 30% auto 30%;
grid-template-rows: auto;
}
</style>

View file

@ -0,0 +1,65 @@
<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 [LINK TO ABOUT US] collaborating online. If you're interested
in helping out, don't hesitate to contact us [LINK TO CONTACT US].
</p>
</TalkingPointContent>
</TalkingPointContainer>
</div>
<style>
.site {
margin-left: auto;
margin-right: auto;
padding-top: 1em;
padding-bottom: 3em;
max-width: 1500px;
}
</style>

View file

@ -0,0 +1,79 @@
<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 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: 1em;
padding-bottom: 3em;
max-width: 1500px;
}
</style>

17
src/server.js Normal file
View file

@ -0,0 +1,17 @@
import sirv from 'sirv';
import polka from 'polka';
import compression from 'compression';
import * as sapper from '@sapper/server';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
polka() // You can also use Express
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
sapper.middleware()
)
.listen(PORT, err => {
if (err) console.log('error', err);
});

86
src/service-worker.js Normal file
View file

@ -0,0 +1,86 @@
import { timestamp, files, shell } from '@sapper/service-worker';
const ASSETS = `cache${timestamp}`;
// `shell` is an array of all the files generated by the bundler,
// `files` is an array of everything in the `static` directory
const to_cache = shell.concat(files);
const staticAssets = new Set(to_cache);
self.addEventListener('install', event => {
event.waitUntil(
caches
.open(ASSETS)
.then(cache => cache.addAll(to_cache))
.then(() => {
self.skipWaiting();
})
);
});
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(async keys => {
// delete old caches
for (const key of keys) {
if (key !== ASSETS) await caches.delete(key);
}
self.clients.claim();
})
);
});
/**
* Fetch the asset from the network and store it in the cache.
* Fall back to the cache if the user is offline.
*/
async function fetchAndCache(request) {
const cache = await caches.open(`offline${timestamp}`)
try {
const response = await fetch(request);
cache.put(request, response.clone());
return response;
} catch (err) {
const response = await cache.match(request);
if (response) return response;
throw err;
}
}
self.addEventListener('fetch', event => {
if (event.request.method !== 'GET' || event.request.headers.has('range')) return;
const url = new URL(event.request.url);
// don't try to handle e.g. data: URIs
const isHttp = url.protocol.startsWith('http');
const isDevServerRequest = url.hostname === self.location.hostname && url.port !== self.location.port;
const isStaticAsset = url.host === self.location.host && staticAssets.has(url.pathname);
const skipBecauseUncached = event.request.cache === 'only-if-cached' && !isStaticAsset;
if (isHttp && !isDevServerRequest && !skipBecauseUncached) {
event.respondWith(
(async () => {
// always serve static files and bundler-generated assets from cache.
// if your application has other URLs with data that will never change,
// set this variable to true for them and they will only be fetched once.
const cachedAsset = isStaticAsset && await caches.match(event.request);
// for pages, you might want to serve a shell `service-worker-index.html` file,
// which Sapper has generated for you. It's not right for every
// app, but if it's right for yours then uncomment this section
/*
if (!cachedAsset && url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
return caches.match('/service-worker-index.html');
}
*/
return cachedAsset || fetchAndCache(event.request);
})()
);
}
});

33
src/template.html Normal file
View file

@ -0,0 +1,33 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="theme-color" content="#333333">
%sapper.base%
<link rel="stylesheet" href="global.css">
<link rel="manifest" href="manifest.json" crossorigin="use-credentials">
<link rel="icon" type="image/png" href="favicon.png">
<!-- Sapper creates a <script> tag containing `src/client.js`
and anything else it needs to hydrate the app and
initialise the router -->
%sapper.scripts%
<!-- Sapper generates a <style> tag containing critical CSS
for the current page. CSS for the rest of the app is
lazily loaded when it precaches secondary pages -->
%sapper.styles%
<!-- This contains the contents of the <svelte:head> component, if
the current page has one -->
%sapper.head%
</head>
<body>
<!-- The application will be rendered inside this element,
because `src/client.js` references it -->
<div id="sapper">%sapper.html%</div>
</body>
</html>