Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6dbb3fbd3f | |||
| 95b6ac50be | |||
| 5f2247ab83 | |||
| 842bcfa782 | |||
| c2938e0672 | |||
| 278516ad11 | |||
| ce241339bf | |||
| 8d7428923a | |||
| 4a1a4b6415 | |||
| 65a45bc0a8 | |||
| 5932974108 | |||
| ce34e45afc | |||
| afcefa9432 | |||
| d346fdcff9 | |||
| a05a7e261a | |||
| ab9c892f8a | |||
| ca7bfef865 | |||
| f8c9397afd | |||
| 0c215efdb2 | |||
| e1efcda3dd | |||
| 59056a22c5 | |||
| 13841e813b | |||
| da775af00a | |||
| bd99474f26 | |||
| 9c70244157 | |||
| 736edcbe00 | |||
| 40e215473e | |||
| 6746514317 | |||
| 50a332eb2b | |||
| 08f1b176db | |||
| 00e2319be3 |
@@ -0,0 +1,43 @@
|
|||||||
|
name: Publish Nym binaries
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-nym:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform: [ubuntu-latest]
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Check the release tag starts with `nym-binaries-`
|
||||||
|
if: startsWith(github.ref, 'refs/tags/nym-binaries-') == false
|
||||||
|
uses: actions/github-script@v3
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
core.setFailed('Release tag did not start with nym-binaries-...')
|
||||||
|
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
|
||||||
|
- name: Build all binaries
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --workspace --release
|
||||||
|
|
||||||
|
- name: Upload to release based on tag name
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
target/release/nym-client
|
||||||
|
target/release/nym-gateway
|
||||||
|
target/release/nym-mixnode
|
||||||
|
target/release/nym-socks5-client
|
||||||
|
target/release/nym-validator-api
|
||||||
@@ -549,7 +549,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "client-core"
|
name = "client-core"
|
||||||
version = "0.12.0"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"config",
|
"config",
|
||||||
"crypto",
|
"crypto",
|
||||||
@@ -750,31 +750,31 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmwasm-crypto"
|
name = "cosmwasm-crypto"
|
||||||
version = "1.0.0-beta6"
|
version = "1.0.0-beta7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dddc1443004c6340e55ca66d98e9d2f1a44aadf4ce2bed2c4f29baa8a15e7b7"
|
checksum = "88c2565b1e73a816fb659ef4838fc356143fbd35f43c48a51d2d7d4e5d6679d3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest 0.9.0",
|
"digest 0.9.0",
|
||||||
"ed25519-zebra",
|
"ed25519-zebra",
|
||||||
"k256 0.9.6",
|
"k256 0.9.6",
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.6.3",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmwasm-derive"
|
name = "cosmwasm-derive"
|
||||||
version = "1.0.0-beta6"
|
version = "1.0.0-beta7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fe4f0f10f165b8bcc558a13cddb498140960544519aa0581532c766dd80b5598"
|
checksum = "fa89fcdf8dbbe0088e663d0a814aa7368e7ebe8fb045a3a150fb5fdc2ffe3b45"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmwasm-std"
|
name = "cosmwasm-std"
|
||||||
version = "1.0.0-beta6"
|
version = "1.0.0-beta7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f0f3145097b692b2d95fa5d2c7c6fdd60f193ccc709857e7e1987a608725300"
|
checksum = "bcb8f99a61d0b9069e1afc80a4ffea87dcc3523edd992080923870b13a677da0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"cosmwasm-crypto",
|
"cosmwasm-crypto",
|
||||||
@@ -1071,20 +1071,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cw-storage-plus"
|
name = "cw-storage-plus"
|
||||||
version = "0.11.1"
|
version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d7ee1963302b0ac2a9d42fe0faec826209c17452bfd36fbfd9d002a88929261"
|
checksum = "5e8b7f9a758c030d375520df947323c052704f784561fc28dcaab4f988c50a30"
|
||||||
dependencies = [
|
|
||||||
"cosmwasm-std",
|
|
||||||
"schemars",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cw-storage-plus"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c087ff98fb0475db4c2b5298a5fd12b2848d2854b39d1115d930ee6da24d1eed"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
"schemars",
|
"schemars",
|
||||||
@@ -1322,16 +1311,17 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ed25519-zebra"
|
name = "ed25519-zebra"
|
||||||
version = "2.2.0"
|
version = "3.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0a128b76af6dd4b427e34a6fd43dc78dbfe73672ec41ff615a2414c1a0ad0409"
|
checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
"hex",
|
"hex",
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.6.3",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1470,7 +1460,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "explorer-api"
|
name = "explorer-api"
|
||||||
version = "0.1.0"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"humantime-serde",
|
"humantime-serde",
|
||||||
@@ -2902,7 +2892,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "0.12.1"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.34.0",
|
"clap 2.34.0",
|
||||||
"client-core",
|
"client-core",
|
||||||
@@ -2936,7 +2926,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-gateway"
|
name = "nym-gateway"
|
||||||
version = "0.12.1"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -2982,7 +2972,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-mixnode"
|
name = "nym-mixnode"
|
||||||
version = "0.12.1"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bs58",
|
"bs58",
|
||||||
@@ -3020,7 +3010,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-network-requester"
|
name = "nym-network-requester"
|
||||||
version = "0.12.0"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.34.0",
|
"clap 2.34.0",
|
||||||
"dirs",
|
"dirs",
|
||||||
@@ -3041,7 +3031,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "0.12.1"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.34.0",
|
"clap 2.34.0",
|
||||||
"client-core",
|
"client-core",
|
||||||
@@ -3076,7 +3066,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-validator-api"
|
name = "nym-validator-api"
|
||||||
version = "0.12.0"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"attohttpc",
|
"attohttpc",
|
||||||
@@ -6062,11 +6052,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vesting-contract"
|
name = "vesting-contract"
|
||||||
version = "0.1.0"
|
version = "1.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"config",
|
"config",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
"cw-storage-plus 0.12.1",
|
"cw-storage-plus",
|
||||||
"mixnet-contract-common",
|
"mixnet-contract-common",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -6080,7 +6070,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"config",
|
"config",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
"cw-storage-plus 0.11.1",
|
"cw-storage-plus",
|
||||||
"mixnet-contract-common",
|
"mixnet-contract-common",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "client-core"
|
name = "client-core"
|
||||||
version = "0.12.0"
|
version = "1.0.0-rc.1"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "0.12.1"
|
version = "1.0.0-rc.1"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56"
|
rust-version = "1.56"
|
||||||
|
|||||||
@@ -18,14 +18,12 @@
|
|||||||
"author": "Dave Hrycyszyn",
|
"author": "Dave Hrycyszyn",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^10.2.6",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"clean-webpack-plugin": "^3.0.0",
|
"webpack": "^5.70.0",
|
||||||
"webpack": "^4.42.1",
|
"webpack-cli": "^4.9.2",
|
||||||
"webpack-cli": "^3.3.11",
|
"webpack-dev-server": "^4.7.4"
|
||||||
"webpack-dev-server": "^3.11.0"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.6.5",
|
"html-webpack-plugin": "^5.5.0"
|
||||||
"html-webpack-plugin": "^4.2.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
const autoprefixer = require('autoprefixer');
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
mode: 'production',
|
||||||
entry: './src/index.js',
|
entry: './src/index.js',
|
||||||
output: {
|
output: {
|
||||||
filename: 'bundle.js',
|
filename: 'bundle.js',
|
||||||
@@ -18,7 +18,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
],
|
],
|
||||||
devServer: {
|
devServer: {
|
||||||
contentBase: path.join(__dirname, 'dist'),
|
static: path.join(__dirname, 'dist'),
|
||||||
compress: true,
|
compress: true,
|
||||||
port: 8888
|
port: 8888
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "0.12.1"
|
version = "1.0.0-rc.1"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56"
|
rust-version = "1.56"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
.DS_Store
|
|
||||||
/node_modules/
|
|
||||||
/src/node_modules/@sapper/
|
|
||||||
yarn-error.log
|
|
||||||
/__sapper__/
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
## Prerequisites
|
|
||||||
|
|
||||||
On Ubuntu-ish systems (not tested on Debian but may work):
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo apt update && sudo apt install libwebkit2gtk-4.0-dev \
|
|
||||||
build-essential \
|
|
||||||
curl \
|
|
||||||
wget \
|
|
||||||
libssl-dev \
|
|
||||||
libgtk-3-dev \
|
|
||||||
libappindicator3-dev \
|
|
||||||
patchelf \
|
|
||||||
librsvg2-dev```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
1. Start Sapper([docs](https://sapper.svelte.dev/docs/)) -> `yarn run dev`
|
|
||||||
2. Start Tauri([docs](https://tauri.studio/en/)) in another terminal -> `yarn tauri dev`
|
|
||||||
3. Start validator-api locally, or override `validator-urls` in `index.svelte`
|
|
||||||
|
|
||||||
## Getting around
|
|
||||||
|
|
||||||
+ Frontend -> `tauri-client/`
|
|
||||||
+ logic -> `tauri-client/src/routes/index.svelte`
|
|
||||||
+ assets -> `tauri-client/static`
|
|
||||||
+ Backend -> `tauri-client/src/src-tauri`
|
|
||||||
|
|
||||||
## Build standalone app
|
|
||||||
|
|
||||||
+ yarn tauri build [--debug]
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "TODO",
|
|
||||||
"description": "TODO",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "sapper dev",
|
|
||||||
"build": "sapper build --legacy",
|
|
||||||
"export": "sapper export --legacy",
|
|
||||||
"start": "node __sapper__/build"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@tauri-apps/api": "^1.0.0-beta.4",
|
|
||||||
"compression": "^1.7.1",
|
|
||||||
"polka": "next",
|
|
||||||
"qrious": "^4.0.2",
|
|
||||||
"sirv": "^1.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@babel/core": "^7.0.0",
|
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-runtime": "^7.0.0",
|
|
||||||
"@babel/preset-env": "^7.0.0",
|
|
||||||
"@babel/runtime": "^7.0.0",
|
|
||||||
"@rollup/plugin-babel": "^5.0.0",
|
|
||||||
"@rollup/plugin-commonjs": "^14.0.0",
|
|
||||||
"@rollup/plugin-node-resolve": "^8.0.0",
|
|
||||||
"@rollup/plugin-replace": "^2.4.0",
|
|
||||||
"@rollup/plugin-url": "^5.0.0",
|
|
||||||
"@tauri-apps/cli": "^1.0.0-rc.5",
|
|
||||||
"rollup": "^2.3.4",
|
|
||||||
"rollup-plugin-svelte": "^7.0.0",
|
|
||||||
"rollup-plugin-terser": "^7.0.0",
|
|
||||||
"sapper": "^0.28.0",
|
|
||||||
"sass": "^1.35.2",
|
|
||||||
"svelte": "^3.17.3",
|
|
||||||
"svelte-preprocess": "^4.7.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
import path from "path";
|
|
||||||
import resolve from "@rollup/plugin-node-resolve";
|
|
||||||
import replace from "@rollup/plugin-replace";
|
|
||||||
import commonjs from "@rollup/plugin-commonjs";
|
|
||||||
import url from "@rollup/plugin-url";
|
|
||||||
import svelte from "rollup-plugin-svelte";
|
|
||||||
import babel from "@rollup/plugin-babel";
|
|
||||||
import { terser } from "rollup-plugin-terser";
|
|
||||||
import config from "sapper/config/rollup.js";
|
|
||||||
import pkg from "./package.json";
|
|
||||||
import sveltePreprocess from "svelte-preprocess";
|
|
||||||
|
|
||||||
const mode = process.env.NODE_ENV;
|
|
||||||
const dev = mode === "development";
|
|
||||||
const legacy = !!process.env.SAPPER_LEGACY_BUILD;
|
|
||||||
|
|
||||||
const onwarn = (warning, onwarn) =>
|
|
||||||
(warning.code === "MISSING_EXPORT" && /'preload'/.test(warning.message)) ||
|
|
||||||
(warning.code === "CIRCULAR_DEPENDENCY" &&
|
|
||||||
/[/\\]@sapper[/\\]/.test(warning.message)) ||
|
|
||||||
onwarn(warning);
|
|
||||||
|
|
||||||
export default {
|
|
||||||
client: {
|
|
||||||
input: config.client.input(),
|
|
||||||
output: config.client.output(),
|
|
||||||
plugins: [
|
|
||||||
replace({
|
|
||||||
preventAssignment: true,
|
|
||||||
values: {
|
|
||||||
"process.browser": true,
|
|
||||||
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
svelte({
|
|
||||||
compilerOptions: {
|
|
||||||
dev,
|
|
||||||
hydratable: true,
|
|
||||||
},
|
|
||||||
preprocess: sveltePreprocess(),
|
|
||||||
}),
|
|
||||||
url({
|
|
||||||
sourceDir: path.resolve(__dirname, "src/node_modules/images"),
|
|
||||||
publicPath: "/client/",
|
|
||||||
}),
|
|
||||||
resolve({
|
|
||||||
browser: true,
|
|
||||||
dedupe: ["svelte"],
|
|
||||||
}),
|
|
||||||
commonjs(),
|
|
||||||
|
|
||||||
legacy &&
|
|
||||||
babel({
|
|
||||||
extensions: [".js", ".mjs", ".html", ".svelte"],
|
|
||||||
babelHelpers: "runtime",
|
|
||||||
exclude: ["node_modules/@babel/**"],
|
|
||||||
presets: [
|
|
||||||
[
|
|
||||||
"@babel/preset-env",
|
|
||||||
{
|
|
||||||
targets: "> 0.25%, not dead",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
"@babel/plugin-syntax-dynamic-import",
|
|
||||||
[
|
|
||||||
"@babel/plugin-transform-runtime",
|
|
||||||
{
|
|
||||||
useESModules: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
|
|
||||||
!dev &&
|
|
||||||
terser({
|
|
||||||
module: true,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
|
|
||||||
preserveEntrySignatures: false,
|
|
||||||
onwarn,
|
|
||||||
},
|
|
||||||
|
|
||||||
server: {
|
|
||||||
input: config.server.input(),
|
|
||||||
output: config.server.output(),
|
|
||||||
plugins: [
|
|
||||||
replace({
|
|
||||||
preventAssignment: true,
|
|
||||||
values: {
|
|
||||||
"process.browser": false,
|
|
||||||
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
svelte({
|
|
||||||
compilerOptions: {
|
|
||||||
dev,
|
|
||||||
generate: "ssr",
|
|
||||||
hydratable: true,
|
|
||||||
},
|
|
||||||
emitCss: false,
|
|
||||||
}),
|
|
||||||
url({
|
|
||||||
sourceDir: path.resolve(__dirname, "src/node_modules/images"),
|
|
||||||
publicPath: "/client/",
|
|
||||||
emitFiles: false, // already emitted by client build
|
|
||||||
}),
|
|
||||||
resolve({
|
|
||||||
dedupe: ["svelte"],
|
|
||||||
}),
|
|
||||||
commonjs(),
|
|
||||||
],
|
|
||||||
external: Object.keys(pkg.dependencies).concat(
|
|
||||||
require("module").builtinModules
|
|
||||||
),
|
|
||||||
preserveEntrySignatures: "strict",
|
|
||||||
onwarn,
|
|
||||||
},
|
|
||||||
|
|
||||||
serviceworker: {
|
|
||||||
input: config.serviceworker.input(),
|
|
||||||
output: config.serviceworker.output(),
|
|
||||||
plugins: [
|
|
||||||
resolve(),
|
|
||||||
replace({
|
|
||||||
preventAssignment: true,
|
|
||||||
values: {
|
|
||||||
"process.browser": true,
|
|
||||||
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
commonjs(),
|
|
||||||
!dev && terser(),
|
|
||||||
],
|
|
||||||
preserveEntrySignatures: false,
|
|
||||||
onwarn,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,304 +0,0 @@
|
|||||||
/**
|
|
||||||
* Run this script to convert the project to TypeScript. This is only guaranteed to work
|
|
||||||
* on the unmodified default template; if you have done code changes you are likely need
|
|
||||||
* to touch up the generated project manually.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// @ts-check
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const { argv } = require('process');
|
|
||||||
|
|
||||||
const projectRoot = argv[2] || path.join(__dirname, '..');
|
|
||||||
|
|
||||||
const isRollup = fs.existsSync(path.join(projectRoot, "rollup.config.js"));
|
|
||||||
|
|
||||||
function warn(message) {
|
|
||||||
console.warn('Warning: ' + message);
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceInFile(fileName, replacements) {
|
|
||||||
if (fs.existsSync(fileName)) {
|
|
||||||
let contents = fs.readFileSync(fileName, 'utf8');
|
|
||||||
let hadUpdates = false;
|
|
||||||
|
|
||||||
replacements.forEach(([from, to]) => {
|
|
||||||
const newContents = contents.replace(from, to);
|
|
||||||
|
|
||||||
const isAlreadyApplied = typeof to !== 'string' || contents.includes(to);
|
|
||||||
|
|
||||||
if (newContents !== contents) {
|
|
||||||
contents = newContents;
|
|
||||||
hadUpdates = true;
|
|
||||||
} else if (!isAlreadyApplied) {
|
|
||||||
warn(`Wanted to update "${from}" in ${fileName}, but did not find it.`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hadUpdates) {
|
|
||||||
fs.writeFileSync(fileName, contents);
|
|
||||||
} else {
|
|
||||||
console.log(`${fileName} had already been updated.`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn(`Wanted to update ${fileName} but the file did not exist.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createFile(fileName, contents) {
|
|
||||||
if (fs.existsSync(fileName)) {
|
|
||||||
warn(`Wanted to create ${fileName}, but it already existed. Leaving existing file.`);
|
|
||||||
} else {
|
|
||||||
fs.writeFileSync(fileName, contents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addDepsToPackageJson() {
|
|
||||||
const pkgJSONPath = path.join(projectRoot, 'package.json');
|
|
||||||
const packageJSON = JSON.parse(fs.readFileSync(pkgJSONPath, 'utf8'));
|
|
||||||
packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, {
|
|
||||||
...(isRollup ? { '@rollup/plugin-typescript': '^6.0.0' } : { 'ts-loader': '^8.0.4' }),
|
|
||||||
'@tsconfig/svelte': '^1.0.10',
|
|
||||||
'@types/compression': '^1.7.0',
|
|
||||||
'@types/node': '^14.11.1',
|
|
||||||
'@types/polka': '^0.5.1',
|
|
||||||
'svelte-check': '^1.0.46',
|
|
||||||
'svelte-preprocess': '^4.3.0',
|
|
||||||
tslib: '^2.0.1',
|
|
||||||
typescript: '^4.0.3'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add script for checking
|
|
||||||
packageJSON.scripts = Object.assign(packageJSON.scripts, {
|
|
||||||
validate: 'svelte-check --ignore src/node_modules/@sapper'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Write the package JSON
|
|
||||||
fs.writeFileSync(pkgJSONPath, JSON.stringify(packageJSON, null, ' '));
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeJsExtensionToTs(dir) {
|
|
||||||
const elements = fs.readdirSync(dir, { withFileTypes: true });
|
|
||||||
|
|
||||||
for (let i = 0; i < elements.length; i++) {
|
|
||||||
if (elements[i].isDirectory()) {
|
|
||||||
changeJsExtensionToTs(path.join(dir, elements[i].name));
|
|
||||||
} else if (elements[i].name.match(/^[^_]((?!json).)*js$/)) {
|
|
||||||
fs.renameSync(path.join(dir, elements[i].name), path.join(dir, elements[i].name).replace('.js', '.ts'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSingleSvelteFile({ view, vars, contextModule }) {
|
|
||||||
replaceInFile(path.join(projectRoot, 'src', `${view}.svelte`), [
|
|
||||||
[/(?:<script)(( .*?)*?)>/gm, (m, attrs) => `<script${attrs}${!attrs.includes('lang="ts"') ? ' lang="ts"' : ''}>`],
|
|
||||||
...(vars ? vars.map(({ name, type }) => [`export let ${name};`, `export let ${name}: ${type};`]) : []),
|
|
||||||
...(contextModule ? contextModule.map(({ js, ts }) => [js, ts]) : [])
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch the *.svelte file to use TS
|
|
||||||
function updateSvelteFiles() {
|
|
||||||
[
|
|
||||||
{
|
|
||||||
view: 'components/Nav',
|
|
||||||
vars: [{ name: 'segment', type: 'string' }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
view: 'routes/_layout',
|
|
||||||
vars: [{ name: 'segment', type: 'string' }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
view: 'routes/_error',
|
|
||||||
vars: [
|
|
||||||
{ name: 'status', type: 'number' },
|
|
||||||
{ name: 'error', type: 'Error' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
view: 'routes/blog/index',
|
|
||||||
vars: [{ name: 'posts', type: '{ slug: string; title: string, html: any }[]' }],
|
|
||||||
contextModule: [
|
|
||||||
{
|
|
||||||
js: '.then(r => r.json())',
|
|
||||||
ts: '.then((r: { json: () => any; }) => r.json())'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
js: '.then(posts => {',
|
|
||||||
ts: '.then((posts: { slug: string; title: string, html: any }[]) => {'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
view: 'routes/blog/[slug]',
|
|
||||||
vars: [{ name: 'post', type: '{ slug: string; title: string, html: any }' }]
|
|
||||||
}
|
|
||||||
].forEach(updateSingleSvelteFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateRollupConfig() {
|
|
||||||
// Edit rollup config
|
|
||||||
replaceInFile(path.join(projectRoot, 'rollup.config.js'), [
|
|
||||||
// Edit imports
|
|
||||||
[
|
|
||||||
/'rollup-plugin-terser';\n(?!import sveltePreprocess)/,
|
|
||||||
`'rollup-plugin-terser';
|
|
||||||
import sveltePreprocess from 'svelte-preprocess';
|
|
||||||
import typescript from '@rollup/plugin-typescript';
|
|
||||||
`
|
|
||||||
],
|
|
||||||
// Edit inputs
|
|
||||||
[
|
|
||||||
/(?<!THIS_IS_UNDEFINED[^\n]*\n\s*)onwarn\(warning\);/,
|
|
||||||
`(warning.code === 'THIS_IS_UNDEFINED') ||\n\tonwarn(warning);`
|
|
||||||
],
|
|
||||||
[/input: config.client.input\(\)(?!\.replace)/, `input: config.client.input().replace(/\\.js$/, '.ts')`],
|
|
||||||
[
|
|
||||||
/input: config.server.input\(\)(?!\.replace)/,
|
|
||||||
`input: { server: config.server.input().server.replace(/\\.js$/, ".ts") }`
|
|
||||||
],
|
|
||||||
[
|
|
||||||
/input: config.serviceworker.input\(\)(?!\.replace)/,
|
|
||||||
`input: config.serviceworker.input().replace(/\\.js$/, '.ts')`
|
|
||||||
],
|
|
||||||
// Add preprocess
|
|
||||||
[/compilerOptions/g, 'preprocess: sveltePreprocess({ sourceMap: dev }),\n\t\t\t\tcompilerOptions'],
|
|
||||||
// Add TypeScript
|
|
||||||
[/commonjs\(\)(?!,\n\s*typescript)/g, 'commonjs(),\n\t\t\ttypescript({ sourceMap: dev })']
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateWebpackConfig() {
|
|
||||||
// Edit webpack config
|
|
||||||
replaceInFile(path.join(projectRoot, 'webpack.config.js'), [
|
|
||||||
// Edit imports
|
|
||||||
[
|
|
||||||
/require\('webpack-modules'\);\n(?!const sveltePreprocess)/,
|
|
||||||
`require('webpack-modules');\nconst sveltePreprocess = require('svelte-preprocess');\n`
|
|
||||||
],
|
|
||||||
// Edit extensions
|
|
||||||
[
|
|
||||||
/\['\.mjs', '\.js', '\.json', '\.svelte', '\.html'\]/,
|
|
||||||
`['.mjs', '.js', '.ts', '.json', '.svelte', '.html']`
|
|
||||||
],
|
|
||||||
// Edit entries
|
|
||||||
[
|
|
||||||
/entry: config\.client\.entry\(\)/,
|
|
||||||
`entry: { main: config.client.entry().main.replace(/\\.js$/, '.ts') }`
|
|
||||||
],
|
|
||||||
[
|
|
||||||
/entry: config\.server\.entry\(\)/,
|
|
||||||
`entry: { server: config.server.entry().server.replace(/\\.js$/, '.ts') }`
|
|
||||||
],
|
|
||||||
[
|
|
||||||
/entry: config\.serviceworker\.entry\(\)/,
|
|
||||||
`entry: { 'service-worker': config.serviceworker.entry()['service-worker'].replace(/\\.js$/, '.ts') }`
|
|
||||||
],
|
|
||||||
[
|
|
||||||
/loader: 'svelte-loader',\n\t\t\t\t\t\toptions: {/g,
|
|
||||||
'loader: \'svelte-loader\',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tpreprocess: sveltePreprocess({ sourceMap: dev }),'
|
|
||||||
],
|
|
||||||
// Add TypeScript rules for client and server
|
|
||||||
[
|
|
||||||
/module: {\n\s*rules: \[\n\s*(?!{\n\s*test: \/\\\.ts\$\/)/g,
|
|
||||||
`module: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.ts$/,\n\t\t\t\t\tloader: 'ts-loader'\n\t\t\t\t},\n\t\t\t\t`
|
|
||||||
],
|
|
||||||
// Add TypeScript rules for serviceworker
|
|
||||||
[
|
|
||||||
/output: config\.serviceworker\.output\(\),\n\s*(?!module)/,
|
|
||||||
`output: config.serviceworker.output(),\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.ts$/,\n\t\t\t\t\tloader: 'ts-loader'\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t`
|
|
||||||
],
|
|
||||||
// Edit outputs
|
|
||||||
[
|
|
||||||
/output: config\.serviceworker\.output\(\),\n\s*(?!resolve)/,
|
|
||||||
`output: config.serviceworker.output(),\n\t\tresolve: { extensions: ['.mjs', '.js', '.ts', '.json'] },\n\t\t`
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateServiceWorker() {
|
|
||||||
replaceInFile(path.join(projectRoot, 'src', 'service-worker.ts'), [
|
|
||||||
[`shell.concat(files);`, `(shell as string[]).concat(files as string[]);`],
|
|
||||||
[`self.skipWaiting();`, `((self as any) as ServiceWorkerGlobalScope).skipWaiting();`],
|
|
||||||
[`self.clients.claim();`, `((self as any) as ServiceWorkerGlobalScope).clients.claim();`],
|
|
||||||
[`fetchAndCache(request)`, `fetchAndCache(request: Request)`],
|
|
||||||
[`self.addEventListener('activate', event =>`, `self.addEventListener('activate', (event: ExtendableEvent) =>`],
|
|
||||||
[`self.addEventListener('install', event =>`, `self.addEventListener('install', (event: ExtendableEvent) =>`],
|
|
||||||
[`addEventListener('fetch', event =>`, `addEventListener('fetch', (event: FetchEvent) =>`],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createTsConfig() {
|
|
||||||
const tsconfig = `{
|
|
||||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["DOM", "ES2017", "WebWorker"]
|
|
||||||
},
|
|
||||||
"include": ["src/**/*", "src/node_modules/**/*"],
|
|
||||||
"exclude": ["node_modules/*", "__sapper__/*", "static/*"]
|
|
||||||
}`;
|
|
||||||
|
|
||||||
createFile(path.join(projectRoot, 'tsconfig.json'), tsconfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds the extension recommendation
|
|
||||||
function configureVsCode() {
|
|
||||||
const dir = path.join(projectRoot, '.vscode');
|
|
||||||
|
|
||||||
if (!fs.existsSync(dir)) {
|
|
||||||
fs.mkdirSync(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
createFile(path.join(projectRoot, '.vscode', 'extensions.json'), `{"recommendations": ["svelte.svelte-vscode"]}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteThisScript() {
|
|
||||||
fs.unlinkSync(path.join(__filename));
|
|
||||||
|
|
||||||
// Check for Mac's DS_store file, and if it's the only one left remove it
|
|
||||||
const remainingFiles = fs.readdirSync(path.join(__dirname));
|
|
||||||
if (remainingFiles.length === 1 && remainingFiles[0] === '.DS_store') {
|
|
||||||
fs.unlinkSync(path.join(__dirname, '.DS_store'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the scripts folder is empty
|
|
||||||
if (fs.readdirSync(path.join(__dirname)).length === 0) {
|
|
||||||
// Remove the scripts folder
|
|
||||||
fs.rmdirSync(path.join(__dirname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Adding TypeScript with ${isRollup ? "Rollup" : "webpack" }...`);
|
|
||||||
|
|
||||||
addDepsToPackageJson();
|
|
||||||
|
|
||||||
changeJsExtensionToTs(path.join(projectRoot, 'src'));
|
|
||||||
|
|
||||||
updateSvelteFiles();
|
|
||||||
|
|
||||||
if (isRollup) {
|
|
||||||
updateRollupConfig();
|
|
||||||
} else {
|
|
||||||
updateWebpackConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
updateServiceWorker();
|
|
||||||
|
|
||||||
createTsConfig();
|
|
||||||
|
|
||||||
configureVsCode();
|
|
||||||
|
|
||||||
// Delete this script, but not during testing
|
|
||||||
if (!argv[2]) {
|
|
||||||
deleteThisScript();
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Converted to TypeScript.');
|
|
||||||
|
|
||||||
if (fs.existsSync(path.join(projectRoot, 'node_modules'))) {
|
|
||||||
console.log(`
|
|
||||||
Next:
|
|
||||||
1. run 'npm install' again to install TypeScript dependencies
|
|
||||||
2. run 'npm run build' for the @sapper imports in your project to work
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Generated by Cargo
|
|
||||||
# will have compiled files and executables
|
|
||||||
/target/
|
|
||||||
WixTools
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "app"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = "A Tauri App"
|
|
||||||
authors = ["you"]
|
|
||||||
license = ""
|
|
||||||
repository = ""
|
|
||||||
default-run = "app"
|
|
||||||
edition = "2021"
|
|
||||||
build = "src/build.rs"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
tauri-build = { version = "=1.0.0-rc.2" }
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
serde_json = "1.0"
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
||||||
tauri = { version = "=1.0.0-rc.2", features = [] }
|
|
||||||
tokio = "1.4"
|
|
||||||
url = "2.2"
|
|
||||||
|
|
||||||
tauri-codegen = "=1.0.0-rc.1"
|
|
||||||
tauri-macros = "=1.0.0-rc.1"
|
|
||||||
core-graphics = "=0.22.2"
|
|
||||||
|
|
||||||
coconut-interface = { path = "../../../common/coconut-interface" }
|
|
||||||
credentials = { path = "../../../common/credentials" }
|
|
||||||
validator-client = {path = "../../../common/client-libs/validator-client"}
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["custom-protocol"]
|
|
||||||
custom-protocol = ["tauri/custom-protocol"]
|
|
||||||
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 88 KiB |
@@ -1,13 +0,0 @@
|
|||||||
max_width = 100
|
|
||||||
hard_tabs = false
|
|
||||||
tab_spaces = 2
|
|
||||||
newline_style = "Auto"
|
|
||||||
use_small_heuristics = "Default"
|
|
||||||
reorder_imports = true
|
|
||||||
reorder_modules = true
|
|
||||||
remove_nested_parens = true
|
|
||||||
edition = "2018"
|
|
||||||
merge_derives = true
|
|
||||||
use_try_shorthand = false
|
|
||||||
use_field_init_shorthand = false
|
|
||||||
force_explicit_abi = true
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
tauri_build::build()
|
|
||||||
}
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
#![cfg_attr(
|
|
||||||
all(not(debug_assertions), target_os = "windows"),
|
|
||||||
windows_subsystem = "windows"
|
|
||||||
)]
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use tokio::sync::RwLock;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
use coconut_interface::{
|
|
||||||
self, hash_to_scalar, Attribute, Credential, Parameters, Signature, Theta, VerificationKey,
|
|
||||||
};
|
|
||||||
use credentials::{obtain_aggregate_signature, obtain_aggregate_verification_key};
|
|
||||||
|
|
||||||
struct State {
|
|
||||||
signatures: Vec<Signature>,
|
|
||||||
n_attributes: u32,
|
|
||||||
params: Parameters,
|
|
||||||
serial_number: Attribute,
|
|
||||||
binding_number: Attribute,
|
|
||||||
voucher_value: Attribute,
|
|
||||||
voucher_info: Attribute,
|
|
||||||
aggregated_verification_key: Option<VerificationKey>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl State {
|
|
||||||
fn init(public_attributes_bytes: Vec<Vec<u8>>, private_attributes_bytes: Vec<Vec<u8>>) -> State {
|
|
||||||
let n_attributes = (public_attributes_bytes.len() + private_attributes_bytes.len()) as u32;
|
|
||||||
let params = Parameters::new(n_attributes).unwrap();
|
|
||||||
let public_attributes = public_attributes_bytes
|
|
||||||
.iter()
|
|
||||||
.map(hash_to_scalar)
|
|
||||||
.collect::<Vec<Attribute>>();
|
|
||||||
let private_attributes = private_attributes_bytes
|
|
||||||
.iter()
|
|
||||||
.map(hash_to_scalar)
|
|
||||||
.collect::<Vec<Attribute>>();
|
|
||||||
State {
|
|
||||||
signatures: Vec::new(),
|
|
||||||
n_attributes,
|
|
||||||
params,
|
|
||||||
serial_number: private_attributes[0],
|
|
||||||
binding_number: private_attributes[1],
|
|
||||||
voucher_value: public_attributes[0],
|
|
||||||
voucher_info: public_attributes[1],
|
|
||||||
aggregated_verification_key: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_url_validators(raw: &[String]) -> Result<Vec<Url>, String> {
|
|
||||||
let mut parsed_urls = Vec::with_capacity(raw.len());
|
|
||||||
for url in raw {
|
|
||||||
let parsed_url: Url = url
|
|
||||||
.parse()
|
|
||||||
.map_err(|err| format!("one of validator urls is malformed - {}", err))?;
|
|
||||||
parsed_urls.push(parsed_url)
|
|
||||||
}
|
|
||||||
Ok(parsed_urls)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn randomise_credential(
|
|
||||||
idx: usize,
|
|
||||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
|
||||||
) -> Result<Vec<Signature>, String> {
|
|
||||||
let mut state = state.write().await;
|
|
||||||
let signature = state.signatures.remove(idx);
|
|
||||||
let (new_signature, _) = signature.randomise(&state.params);
|
|
||||||
state.signatures.insert(idx, new_signature);
|
|
||||||
Ok(state.signatures.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn delete_credential(
|
|
||||||
idx: usize,
|
|
||||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
|
||||||
) -> Result<Vec<Signature>, String> {
|
|
||||||
let mut state = state.write().await;
|
|
||||||
state.signatures.remove(idx);
|
|
||||||
Ok(state.signatures.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn list_credentials(
|
|
||||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
|
||||||
) -> Result<Vec<Signature>, String> {
|
|
||||||
let state = state.read().await;
|
|
||||||
Ok(state.signatures.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_aggregated_verification_key(
|
|
||||||
validator_urls: Vec<String>,
|
|
||||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
|
||||||
) -> Result<VerificationKey, String> {
|
|
||||||
if let Some(verification_key) = &state.read().await.aggregated_verification_key {
|
|
||||||
return Ok(verification_key.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let parsed_urls = parse_url_validators(&validator_urls)?;
|
|
||||||
let key = obtain_aggregate_verification_key(&parsed_urls)
|
|
||||||
.await
|
|
||||||
.map_err(|err| format!("failed to obtain aggregate verification key - {:?}", err))?;
|
|
||||||
|
|
||||||
state
|
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.aggregated_verification_key
|
|
||||||
.replace(key.clone());
|
|
||||||
|
|
||||||
Ok(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn prove_credential(
|
|
||||||
idx: usize,
|
|
||||||
validator_urls: Vec<String>,
|
|
||||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
|
||||||
) -> Result<Theta, String> {
|
|
||||||
let verification_key = get_aggregated_verification_key(validator_urls, state.clone()).await?;
|
|
||||||
let state = state.read().await;
|
|
||||||
|
|
||||||
if let Some(signature) = state.signatures.get(idx) {
|
|
||||||
match coconut_interface::prove_bandwidth_credential(
|
|
||||||
&state.params,
|
|
||||||
&verification_key,
|
|
||||||
signature,
|
|
||||||
state.serial_number,
|
|
||||||
state.binding_number,
|
|
||||||
) {
|
|
||||||
Ok(theta) => Ok(theta),
|
|
||||||
Err(e) => Err(format!("{:?}", e)),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err("Got invalid Signature idx".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn verify_credential(
|
|
||||||
idx: usize,
|
|
||||||
validator_urls: Vec<String>,
|
|
||||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
|
||||||
) -> Result<bool, String> {
|
|
||||||
// the API needs to be improved but at least it should compile (in theory)
|
|
||||||
let verification_key =
|
|
||||||
get_aggregated_verification_key(validator_urls.clone(), state.clone()).await?;
|
|
||||||
let theta = prove_credential(idx, validator_urls, state.clone()).await?;
|
|
||||||
|
|
||||||
let state = state.read().await;
|
|
||||||
|
|
||||||
let public_attributes_bytes = vec![
|
|
||||||
state.voucher_value.to_bytes().to_vec(),
|
|
||||||
state.voucher_info.to_bytes().to_vec(),
|
|
||||||
];
|
|
||||||
|
|
||||||
let credential = Credential::new(
|
|
||||||
state.n_attributes,
|
|
||||||
theta,
|
|
||||||
public_attributes_bytes,
|
|
||||||
state
|
|
||||||
.signatures
|
|
||||||
.get(idx)
|
|
||||||
.ok_or("Got invalid signature idx")?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(credential.verify(&verification_key))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn get_credential(
|
|
||||||
validator_urls: Vec<String>,
|
|
||||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
|
||||||
) -> Result<Vec<Signature>, String> {
|
|
||||||
let guard = state.read().await;
|
|
||||||
let parsed_urls = parse_url_validators(&validator_urls)?;
|
|
||||||
let public_attributes = vec![guard.voucher_value, guard.voucher_info];
|
|
||||||
let private_attributes = vec![guard.serial_number, guard.binding_number];
|
|
||||||
|
|
||||||
let signature = obtain_aggregate_signature(
|
|
||||||
&guard.params,
|
|
||||||
&public_attributes,
|
|
||||||
&private_attributes,
|
|
||||||
&parsed_urls,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map_err(|err| format!("failed to obtain aggregate signature - {:?}", err))?;
|
|
||||||
|
|
||||||
let mut state = state.write().await;
|
|
||||||
state.signatures.push(signature);
|
|
||||||
Ok(state.signatures.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let public_attributes = vec![b"public_key".to_vec()];
|
|
||||||
let private_attributes = vec![b"private_key".to_vec()];
|
|
||||||
tauri::Builder::default()
|
|
||||||
.manage(Arc::new(RwLock::new(State::init(
|
|
||||||
public_attributes,
|
|
||||||
private_attributes,
|
|
||||||
))))
|
|
||||||
.invoke_handler(tauri::generate_handler![
|
|
||||||
get_credential,
|
|
||||||
randomise_credential,
|
|
||||||
delete_credential,
|
|
||||||
list_credentials,
|
|
||||||
verify_credential
|
|
||||||
])
|
|
||||||
.run(tauri::generate_context!())
|
|
||||||
.expect("error while running tauri application");
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
{
|
|
||||||
"package": {
|
|
||||||
"productName": "nym-tauri-client",
|
|
||||||
"version": "0.1.0"
|
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"distDir": "../__sapper__/export",
|
|
||||||
"devPath": "http://localhost:3000",
|
|
||||||
"beforeDevCommand": "",
|
|
||||||
"beforeBuildCommand": "yarn run export"
|
|
||||||
},
|
|
||||||
"tauri": {
|
|
||||||
"bundle": {
|
|
||||||
"active": true,
|
|
||||||
"targets": "all",
|
|
||||||
"identifier": "com.tauri.dev",
|
|
||||||
"icon": [
|
|
||||||
"icons/32x32.png",
|
|
||||||
"icons/128x128.png",
|
|
||||||
"icons/128x128@2x.png",
|
|
||||||
"icons/icon.icns",
|
|
||||||
"icons/icon.ico"
|
|
||||||
],
|
|
||||||
"resources": [],
|
|
||||||
"externalBin": [],
|
|
||||||
"copyright": "",
|
|
||||||
"category": "DeveloperTool",
|
|
||||||
"shortDescription": "",
|
|
||||||
"longDescription": "",
|
|
||||||
"deb": {
|
|
||||||
"depends": [],
|
|
||||||
"useBootstrapper": false
|
|
||||||
},
|
|
||||||
"macOS": {
|
|
||||||
"frameworks": [],
|
|
||||||
"minimumSystemVersion": "",
|
|
||||||
"useBootstrapper": false,
|
|
||||||
"exceptionDomain": "",
|
|
||||||
"signingIdentity": null,
|
|
||||||
"entitlements": null
|
|
||||||
},
|
|
||||||
"windows": {
|
|
||||||
"certificateThumbprint": null,
|
|
||||||
"digestAlgorithm": "sha256",
|
|
||||||
"timestampUrl": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"updater": {
|
|
||||||
"active": false
|
|
||||||
},
|
|
||||||
"allowlist": {},
|
|
||||||
"windows": [
|
|
||||||
{
|
|
||||||
"title": "Nym Client",
|
|
||||||
"width": 800,
|
|
||||||
"height": 1000,
|
|
||||||
"resizable": true,
|
|
||||||
"fullscreen": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"security": {
|
|
||||||
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 default value;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "*.jpg" {
|
|
||||||
const value: string;
|
|
||||||
export default value;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "*.jpeg" {
|
|
||||||
const value: string;
|
|
||||||
export default value;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "*.png" {
|
|
||||||
const value: string;
|
|
||||||
export default value;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "*.svg" {
|
|
||||||
const value: string;
|
|
||||||
export default value;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "*.webp" {
|
|
||||||
const value: string;
|
|
||||||
export default value;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import * as sapper from '@sapper/app';
|
|
||||||
|
|
||||||
sapper.start({
|
|
||||||
target: document.querySelector('#sapper')
|
|
||||||
});
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<nav>
|
|
||||||
<img src="coconut-120.png" style="width: 120px" alt=""/>
|
|
||||||
</nav>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let status;
|
|
||||||
export let error;
|
|
||||||
|
|
||||||
const dev = process.env.NODE_ENV === 'development';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
h1, p {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2.8em;
|
|
||||||
font-weight: 700;
|
|
||||||
margin: 0 0 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 1em auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 480px) {
|
|
||||||
h1 {
|
|
||||||
font-size: 4em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>{status}</title>
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<h1>{status}</h1>
|
|
||||||
|
|
||||||
<p>{error.message}</p>
|
|
||||||
|
|
||||||
{#if dev && error.stack}
|
|
||||||
<pre>{error.stack}</pre>
|
|
||||||
{/if}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Nav from '../components/Nav.svelte';
|
|
||||||
|
|
||||||
// export let segment;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
main {
|
|
||||||
position: relative;
|
|
||||||
max-width: 56em;
|
|
||||||
/* background-color: white; */
|
|
||||||
padding: 2em;
|
|
||||||
margin: 0 auto;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<Nav />
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<slot></slot>
|
|
||||||
</main>
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
<script>
|
|
||||||
import {invoke} from "@tauri-apps/api/tauri";
|
|
||||||
import {onMount} from "svelte";
|
|
||||||
import QRious from "qrious";
|
|
||||||
|
|
||||||
const validator_urls = ["http://localhost:8080"];
|
|
||||||
let signatures = [];
|
|
||||||
let qrVisible = false;
|
|
||||||
|
|
||||||
async function getCredential() {
|
|
||||||
signatures = await invoke("get_credential", {
|
|
||||||
validatorUrls: validator_urls,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function randomiseCredential(idx) {
|
|
||||||
signatures = await invoke("randomise_credential", {
|
|
||||||
idx: idx,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function verifyCredential(idx) {
|
|
||||||
const response = await invoke("verify_credential", {
|
|
||||||
idx: idx,
|
|
||||||
validatorUrls: validator_urls,
|
|
||||||
});
|
|
||||||
alert(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteCredential(idx) {
|
|
||||||
signatures = await invoke("delete_credential", {
|
|
||||||
idx: idx,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function listCredentials() {
|
|
||||||
signatures = await invoke("list_credentials");
|
|
||||||
}
|
|
||||||
|
|
||||||
function signatureQR(idx) {
|
|
||||||
qrVisible = true;
|
|
||||||
const signature = signatures[idx];
|
|
||||||
new QRious({
|
|
||||||
element: document.getElementById("qr"),
|
|
||||||
value: signature,
|
|
||||||
foreground: "white",
|
|
||||||
background: "black",
|
|
||||||
size: 148,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
listCredentials();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>Coconut</title>
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<button class="btn btn-success" on:click={getCredential}>Get Credential</button>
|
|
||||||
<hr />
|
|
||||||
<table class="table table-dark">
|
|
||||||
{#each signatures as signature, idx}
|
|
||||||
<tr>
|
|
||||||
<td><p>{signature.slice(0, 12)}</p></td>
|
|
||||||
<td>
|
|
||||||
<div class="btn-group" role="group" aria-label="Basic example">
|
|
||||||
<button
|
|
||||||
class="btn btn-primary"
|
|
||||||
on:click={() => {
|
|
||||||
randomiseCredential(idx);
|
|
||||||
}}>Randomize</button
|
|
||||||
><button
|
|
||||||
class="btn btn-danger"
|
|
||||||
on:click={() => {
|
|
||||||
deleteCredential(idx);
|
|
||||||
}}>Delete</button
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="btn btn-info"
|
|
||||||
on:click={() => {
|
|
||||||
signatureQR(idx);
|
|
||||||
}}>QR</button
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="btn btn-primary"
|
|
||||||
on:click={() => {
|
|
||||||
verifyCredential(idx);
|
|
||||||
}}>Verify</button
|
|
||||||
>
|
|
||||||
</div></td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="modal"
|
|
||||||
tabindex="-1"
|
|
||||||
style={qrVisible ? "display: block" : "display: none"}
|
|
||||||
>
|
|
||||||
<div class="modal-dialog modal-sm">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-body">
|
|
||||||
<canvas id="qr"></canvas>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="close"
|
|
||||||
on:click={() => (qrVisible = false)}
|
|
||||||
>
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div><br /></div> -->
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
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);
|
|
||||||
});
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
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);
|
|
||||||
})()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
||||||
|
|
||||||
%sapper.base%
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="stylesheets/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="stylesheets/bootstrap-grid.min.css">
|
|
||||||
<link rel="stylesheet" href="stylesheets/bootstrap-reboot.min.css">
|
|
||||||
<link rel="stylesheet" href="stylesheets/bundle.min.css">
|
|
||||||
<link rel="manifest" href="manifest.json" crossorigin="use-credentials">
|
|
||||||
<link rel="icon" type="image/png" href="favicon.png">
|
|
||||||
<link rel="apple-touch-icon" href="logo-192.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>
|
|
||||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 89 KiB |
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"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",
|
|
||||||
"purpose": "any maskable"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo-512.png",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/png",
|
|
||||||
"purpose": "any maskable"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
@import "viewports.css.scss";
|
|
||||||
@import "colors.css.scss";
|
|
||||||
@import "fonts.css.scss";
|
|
||||||
@import "typography.css.scss";
|
|
||||||
@import "mixins.css.scss";
|
|
||||||
|
|
||||||
// Sections
|
|
||||||
// Section: Mission
|
|
||||||
#mission-pull-quote {
|
|
||||||
@include cover-background-image("/images/backgrounds/mission.png")
|
|
||||||
color: $color-orange;
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
@import "viewports.css.scss";
|
|
||||||
@import "colors.css.scss";
|
|
||||||
@import "fonts.css.scss";
|
|
||||||
@import "typography.css.scss";
|
|
||||||
@import "mixins.css.scss";
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
input,
|
|
||||||
.btn {
|
|
||||||
@include font-mono();
|
|
||||||
@include text-form();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buttons: Danger
|
|
||||||
.btn-outline-danger {
|
|
||||||
color: $color-red;
|
|
||||||
border-color: $color-red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-danger {
|
|
||||||
color: $color-black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-danger:hover {
|
|
||||||
background-color: $color-black;
|
|
||||||
border-color: $color-white;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buttons: Warning
|
|
||||||
.btn-outline-warning {
|
|
||||||
color: $color-orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-warning:hover {
|
|
||||||
color: $color-white;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2019 The Bootstrap Authors
|
|
||||||
* Copyright 2011-2019 Twitter, Inc.
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
|
||||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
|
||||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
@font-face{font-family:'akkurat-mono';src:url("/fonts/akkurat-mono.woff2") format("woff2"),url("/fonts/akkurat-mono.woff") format("woff"),url("/fonts/akkurat-mono.otf") format("opentype");font-weight:normal;font-style:normal;font-display:swap}@font-face{font-family:'graphik';src:url("/fonts/graphik-light.woff2") format("woff2"),url("/fonts/graphik-light.woff") format("woff"),url("/fonts/graphik-light.otf") format("opentype");font-weight:100;font-style:normal;font-display:swap}@font-face{font-family:'graphik';src:url("/fonts/graphik-regular.woff2") format("woff2"),url("/fonts/graphik-regular.woff") format("woff"),url("/fonts/graphik-regular.otf") format("opentype");font-weight:300;font-style:normal;font-display:swap}@font-face{font-family:'graphik';src:url("/fonts/graphik-medium.woff2") format("woff2"),url("/fonts/graphik-medium.woff") format("woff"),url("/fonts/graphik-medium.otf") format("opentype");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:'graphik';src:url("/fonts/graphik-semibold.woff2") format("woff2"),url("/fonts/graphik-semibold.woff") format("woff"),url("/fonts/graphik-semibold.otf") format("opentype");font-weight:900;font-style:normal;font-display:swap}@font-face{font-family:'akkurat-mono';src:url("/fonts/akkurat-mono.woff2") format("woff2"),url("/fonts/akkurat-mono.woff") format("woff"),url("/fonts/akkurat-mono.otf") format("opentype");font-weight:normal;font-style:normal;font-display:swap}@font-face{font-family:'graphik';src:url("/fonts/graphik-light.woff2") format("woff2"),url("/fonts/graphik-light.woff") format("woff"),url("/fonts/graphik-light.otf") format("opentype");font-weight:100;font-style:normal;font-display:swap}@font-face{font-family:'graphik';src:url("/fonts/graphik-regular.woff2") format("woff2"),url("/fonts/graphik-regular.woff") format("woff"),url("/fonts/graphik-regular.otf") format("opentype");font-weight:300;font-style:normal;font-display:swap}@font-face{font-family:'graphik';src:url("/fonts/graphik-medium.woff2") format("woff2"),url("/fonts/graphik-medium.woff") format("woff"),url("/fonts/graphik-medium.otf") format("opentype");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:'graphik';src:url("/fonts/graphik-semibold.woff2") format("woff2"),url("/fonts/graphik-semibold.woff") format("woff"),url("/fonts/graphik-semibold.otf") format("opentype");font-weight:900;font-style:normal;font-display:swap}.font-mono{font-family:"akkurat-mono", "SF Mono", "Inconsolata-g", "Inconsolata-dz", Menlo, Consolas, Monaco, monospace, monospace;text-transform:uppercase;letter-spacing:.2em;font-size:12px}.font-sans-serif{font-family:graphik, system, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.text-note{font-family:"akkurat-mono", "SF Mono", "Inconsolata-g", "Inconsolata-dz", Menlo, Consolas, Monaco, monospace, monospace;text-transform:uppercase;letter-spacing:.2em;font-size:12px;color:#8C8C8C;font-weight:bold;font-size:11px}::placeholder{color:#646464 !important;opacity:.5 !important}.h1{font-size:40px;line-height:50px}@media (min-width: 720px){.h1{font-size:56px;line-height:70px}}.h2{font-size:40px;line-height:50px}.h3{font-size:18px;line-height:24px;font-weight:600}li.event{font-family:"akkurat-mono", "SF Mono", "Inconsolata-g", "Inconsolata-dz", Menlo, Consolas, Monaco, monospace, monospace;text-transform:uppercase;letter-spacing:.2em}body{background:#000;color:#fff;font-family:graphik, system, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;font-size:14px;line-height:22px;quotes:"“" "”"}a,a:hover{color:#fff;text-decoration:none}a:hover{border-bottom:1px solid #fff}.event-link{color:#148EFF}a.more-link,a.more-link:hover,a.more-link:visited{color:#148EFF;text-transform:uppercase;font-family:"akkurat-mono", "SF Mono", "Inconsolata-g", "Inconsolata-dz", Menlo, Consolas, Monaco, monospace, monospace;text-transform:uppercase;letter-spacing:.2em;font-size:12px}a.more-link:hover{border-bottom:none;text-decoration:underline}img{width:100%}.brand,.icon{width:auto}.brand:hover,.icon:hover{border:none}hr{border:1px solid #fff;opacity:0.2}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
$color-white: white;
|
|
||||||
$color-black: black;
|
|
||||||
$color-gray: #646464;
|
|
||||||
$color-gray-dark: #252525;
|
|
||||||
$color-gray-light: #8C8C8C;
|
|
||||||
|
|
||||||
$color-blue: #148EFF;
|
|
||||||
$color-red: #F44C3B;
|
|
||||||
$color-orange: #F2A228;
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: 'akkurat-mono';
|
|
||||||
src: url('/fonts/akkurat-mono.woff2') format('woff2'),
|
|
||||||
url('/fonts/akkurat-mono.woff') format('woff'),
|
|
||||||
url('/fonts/akkurat-mono.otf') format('opentype');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'graphik';
|
|
||||||
src: url('/fonts/graphik-light.woff2') format('woff2'),
|
|
||||||
url('/fonts/graphik-light.woff') format('woff'),
|
|
||||||
url('/fonts/graphik-light.otf') format('opentype');
|
|
||||||
font-weight: 100;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'graphik';
|
|
||||||
src: url('/fonts/graphik-regular.woff2') format('woff2'),
|
|
||||||
url('/fonts/graphik-regular.woff') format('woff'),
|
|
||||||
url('/fonts/graphik-regular.otf') format('opentype');
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'graphik';
|
|
||||||
src: url('/fonts/graphik-medium.woff2') format('woff2'),
|
|
||||||
url('/fonts/graphik-medium.woff') format('woff'),
|
|
||||||
url('/fonts/graphik-medium.otf') format('opentype');
|
|
||||||
font-weight: 600;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'graphik';
|
|
||||||
src: url('/fonts/graphik-semibold.woff2') format('woff2'),
|
|
||||||
url('/fonts/graphik-semibold.woff') format('woff'),
|
|
||||||
url('/fonts/graphik-semibold.otf') format('opentype');
|
|
||||||
font-weight: 900;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
@import "viewports.css.scss";
|
|
||||||
@import "colors.css.scss";
|
|
||||||
@import "fonts.css.scss";
|
|
||||||
@import "typography.css.scss";
|
|
||||||
@import "mixins.css.scss";
|
|
||||||
|
|
||||||
footer[role=contentinfo] {
|
|
||||||
@include font-mono();
|
|
||||||
background: $color-gray-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copyright { text-align: center; }
|
|
||||||
|
|
||||||
@media (min-width: $layout-breakpoint-sm) {
|
|
||||||
.copyright { text-align: right; }
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
@import "viewports.css.scss";
|
|
||||||
@import "colors.css.scss";
|
|
||||||
@import "fonts.css.scss";
|
|
||||||
@import "typography.css.scss";
|
|
||||||
@import "mixins.css.scss";
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: $color-black;
|
|
||||||
color: $color-white;
|
|
||||||
@include text-body();
|
|
||||||
quotes: "“" "”";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Links
|
|
||||||
a,
|
|
||||||
a:hover {
|
|
||||||
color: $color-white;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover { border-bottom: 1px solid $color-white; }
|
|
||||||
|
|
||||||
.event-link {
|
|
||||||
color: $color-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.more-link,
|
|
||||||
a.more-link:hover,
|
|
||||||
a.more-link:visited {
|
|
||||||
color: $color-blue;
|
|
||||||
text-transform: uppercase;
|
|
||||||
@include font-mono();
|
|
||||||
}
|
|
||||||
|
|
||||||
a.more-link:hover {
|
|
||||||
border-bottom: none;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Images
|
|
||||||
img { width: 100%; }
|
|
||||||
|
|
||||||
.brand,
|
|
||||||
.icon { width: auto; }
|
|
||||||
|
|
||||||
.brand:hover,
|
|
||||||
.icon:hover { border: none; }
|
|
||||||
|
|
||||||
// Horizontal rules
|
|
||||||
hr {
|
|
||||||
border: 1px solid $color-white;
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
@import "viewports.css.scss";
|
|
||||||
@import "colors.css.scss";
|
|
||||||
@import "fonts.css.scss";
|
|
||||||
@import "typography.css.scss";
|
|
||||||
@import "mixins.css.scss";
|
|
||||||
|
|
||||||
.lang {
|
|
||||||
float: right;
|
|
||||||
margin-right: 1em;
|
|
||||||
margin-top: 1em;
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure.paper {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure.paper img {
|
|
||||||
margin-bottom: -25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#hero {
|
|
||||||
padding: 11rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav-small {
|
|
||||||
#hero {
|
|
||||||
padding: 4rem 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.blurb a {
|
|
||||||
color: #148EFF;
|
|
||||||
font-family: "akkurat-mono", "SF Mono", "Inconsolata-g", "Inconsolata-dz", Menlo, Consolas, Monaco, monospace, monospace;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: .2em;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.see-more {
|
|
||||||
/*margin-top: -2em;*/
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapse:not(.show) {
|
|
||||||
height: 350px !important;
|
|
||||||
overflow: hidden;
|
|
||||||
display: -webkit-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapsing {
|
|
||||||
min-height: 350px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.see-more.collapsed:after {
|
|
||||||
content: '+ See More';
|
|
||||||
}
|
|
||||||
|
|
||||||
button.see-more:not(.collapsed):after {
|
|
||||||
content: '- See Less';
|
|
||||||
}
|
|
||||||
|
|
||||||
.paper-snippet:before {
|
|
||||||
content: "\2192";
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.date {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sections
|
|
||||||
.section-title {
|
|
||||||
border-bottom: 5px solid $color-gray;
|
|
||||||
margin-bottom: 34px;
|
|
||||||
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 28px;
|
|
||||||
letter-spacing: 0.2em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container.scroll {
|
|
||||||
height: 250px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row.scroll {
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
overflow-y: hidden;
|
|
||||||
overflow-x: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Backgrounds
|
|
||||||
.fade-in-out-container {
|
|
||||||
@include gradient-fade-in-fade-out();
|
|
||||||
padding: 10rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-in-out-container-soft {
|
|
||||||
@include gradient-fade-in-fade-out($starting_opacity: 0.7);
|
|
||||||
}
|
|
||||||
|
|
||||||
#protocol { @include cover-background-image("/images/backgrounds/protocol.jpg") }
|
|
||||||
#operators { @include cover-background-image("/images/backgrounds/operators.jpg") }
|
|
||||||
#quotes { @include cover-background-image("/images/backgrounds/quotes.jpg") }
|
|
||||||
|
|
||||||
// Icons
|
|
||||||
.icon-cornered-container { position: relative; }
|
|
||||||
|
|
||||||
.icon-cornered {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 14px;
|
|
||||||
right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-youtube { height: 20px; }
|
|
||||||
.icon-linkedin { filter: invert(1); width: 20px; }
|
|
||||||
|
|
||||||
@media (max-width: $layout-breakpoint-lg) {
|
|
||||||
.icon-cornered.icon-linkedin { position: inherit; }
|
|
||||||
button.see-more { margin-top: 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: Protocol
|
|
||||||
#protocol {
|
|
||||||
.icon-youtube { height: 47px; }
|
|
||||||
.video-caption { margin-top: 18px; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: Team
|
|
||||||
.team {
|
|
||||||
margin-left: 3em;
|
|
||||||
margin-right: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.person-card {
|
|
||||||
margin: 0 auto;
|
|
||||||
padding-left: 1em;
|
|
||||||
padding-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: Quotes
|
|
||||||
|
|
||||||
#quotes {
|
|
||||||
// Quotes
|
|
||||||
blockquote {
|
|
||||||
font-size: 2em;
|
|
||||||
line-height: 1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote:before { content: open-quote; }
|
|
||||||
blockquote:after { content: close-quote; }
|
|
||||||
|
|
||||||
.media-image { width: 66px; }
|
|
||||||
.media-title { font-size: 18px; }
|
|
||||||
|
|
||||||
.carousel-inner { height: 600px; }
|
|
||||||
.carousel-control-prev { left: -6em; }
|
|
||||||
.carousel-control-next { right: -6em; }
|
|
||||||
.carousel-control-next-icon { position: absolute; top: -2em; }
|
|
||||||
.carousel-control-prev-icon { position: absolute; top: -2em; }
|
|
||||||
@media (max-width: $layout-breakpoint-lg) {
|
|
||||||
blockquote {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
.carousel-control-prev { left: 0; }
|
|
||||||
.carousel-control-next { right: 0; }
|
|
||||||
}
|
|
||||||
.carousel-control-prev:hover { border: none; }
|
|
||||||
.carousel-control-next:hover { border: none; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: FAQ
|
|
||||||
#faq {
|
|
||||||
.faq-nav-item {
|
|
||||||
// Chevron icon (>) treatement in FAQ nav item
|
|
||||||
.icon-chevron-right { opacity: .2; }
|
|
||||||
&:hover .icon-chevron-right { opacity: .5; }
|
|
||||||
|
|
||||||
// Selected FAQ nav item
|
|
||||||
&.current { a, .icon-chevron-right { opacity: 1; color: white; } }
|
|
||||||
}
|
|
||||||
|
|
||||||
.faq-q { color: $color-red; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: Updates
|
|
||||||
.social-media-icon:hover { border: none; }
|
|
||||||
|
|
||||||
// Section: Jobs
|
|
||||||
@media (min-width: $layout-breakpoint-md) {
|
|
||||||
.btn-block { width: 75%; }
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
// Text
|
|
||||||
@mixin font-sans-serif() {
|
|
||||||
font-family: graphik, system, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin font-mono() {
|
|
||||||
font-family: "akkurat-mono", "SF Mono", "Inconsolata-g", "Inconsolata-dz", Menlo, Consolas, Monaco, monospace, monospace;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: .2em;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin text-form() {
|
|
||||||
letter-spacing: 0;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin text-body() {
|
|
||||||
@include font-sans-serif();
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Backgrounds
|
|
||||||
@mixin gradient-fade-in-fade-out($starting_opacity: 1) {
|
|
||||||
background: linear-gradient(to bottom,
|
|
||||||
rgba(0, 0, 0, $starting_opacity) 0%,
|
|
||||||
rgba(0, 0, 0, .7) 10%,
|
|
||||||
rgba(244, 76, 59, .5) 50%,
|
|
||||||
rgba(0, 0, 0, .7) 95%,
|
|
||||||
rgba(0, 0, 0, 1) 100%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin cover-background-image($url) {
|
|
||||||
background: {
|
|
||||||
image: url($url);
|
|
||||||
repeat: no-repeat;
|
|
||||||
size: cover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
@import "viewports.css.scss";
|
|
||||||
@import "colors.css.scss";
|
|
||||||
@import "fonts.css.scss";
|
|
||||||
@import "typography.css.scss";
|
|
||||||
@import "mixins.css.scss";
|
|
||||||
|
|
||||||
#home nav[role=navigation] { @include cover-background-image("/images/backgrounds/hero.png") }
|
|
||||||
|
|
||||||
.subnav, .mainnav {
|
|
||||||
height: 50%
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainnav {
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subnav {
|
|
||||||
text-align: right;
|
|
||||||
font-size: 0.9em;
|
|
||||||
//padding-bottom: 15px;
|
|
||||||
//border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
|
|
||||||
.subnav {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav-small {
|
|
||||||
ul {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.subnav {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||