Merge pull request #891 from SkynetLabs/clean-up-webapp-directory-and-update-deps
clean up webapp directory and update some deps
This commit is contained in:
commit
f6e1ce56fd
|
@ -1,47 +0,0 @@
|
|||
name: Continous Integration
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: "Static code analysis: handshake-api"
|
||||
run: yarn workspace handshake-api prettier --check .
|
||||
|
||||
- name: "Static code analysis: health-check"
|
||||
run: yarn workspace health-check prettier --check .
|
||||
|
||||
- name: "Static code analysis: website"
|
||||
run: yarn workspace website prettier --check .
|
||||
|
||||
- name: "Static code analysis: dashboard"
|
||||
run: yarn workspace dashboard prettier --check .
|
||||
|
||||
# - name: "Build webapp"
|
||||
# run: yarn workspace webapp build
|
||||
# env:
|
||||
# GATSBY_API_URL: "https://siasky.net"
|
||||
|
||||
# - name: Cypress run
|
||||
# uses: cypress-io/github-action@v2
|
||||
# env:
|
||||
# CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# with:
|
||||
# working-directory: packages/webapp
|
||||
# record: true
|
||||
# start: npx http-server public --port 8000
|
||||
# wait-on: "http://localhost:8000"
|
||||
|
||||
# - name: Cypress cache prune
|
||||
# run: yarn cypress cache prune
|
|
@ -0,0 +1,28 @@
|
|||
name: Static Code Analysis
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: "Static code analysis: handshake-api"
|
||||
run: yarn workspace handshake-api prettier --check .
|
||||
|
||||
- name: "Static code analysis: health-check"
|
||||
run: yarn workspace health-check prettier --check .
|
||||
|
||||
- name: "Static code analysis: website"
|
||||
run: yarn workspace website prettier --check .
|
||||
|
||||
- name: "Static code analysis: dashboard"
|
||||
run: yarn workspace dashboard prettier --check .
|
|
@ -69,8 +69,8 @@ yarn-error.log
|
|||
.yarn-integrity
|
||||
|
||||
# Cypress
|
||||
packages/webapp/cypress/screenshots
|
||||
packages/webapp/cypress/videos
|
||||
packages/website/cypress/screenshots
|
||||
packages/website/cypress/videos
|
||||
|
||||
# Docker data
|
||||
docker/data
|
||||
|
|
16
README.md
16
README.md
|
@ -2,14 +2,14 @@
|
|||
|
||||
## Web application
|
||||
|
||||
Use `yarn workspace webapp start` to start the development server.
|
||||
Use `yarn workspace website start` to start the development server.
|
||||
|
||||
Use `yarn workspace webapp build` to compile the application to `/public` directory.
|
||||
Use `yarn workspace website build` to compile the application to `/public` directory.
|
||||
|
||||
You can use the below build parameters to customize your web application.
|
||||
|
||||
- development example `GATSBY_API_URL=https://siasky.dev yarn workspace webapp start`
|
||||
- production example `GATSBY_API_URL=https://siasky.net yarn workspace webapp build`
|
||||
- development example `GATSBY_API_URL=https://siasky.dev yarn workspace website start`
|
||||
- production example `GATSBY_API_URL=https://siasky.net yarn workspace website build`
|
||||
|
||||
List of available parameters:
|
||||
|
||||
|
@ -36,8 +36,8 @@ Mongo needs a couple of extra steps in order to start a secure cluster.
|
|||
- Manually run an initialisation `docker run` with extra environment variables that will initialise the admin user with
|
||||
a password (example below).
|
||||
- During the initialisation run mentioned above, we need to make two extra steps within the container:
|
||||
- Change the ownership of `mgkey` to `mongodb:mongodb`
|
||||
- Change its permissions to 400
|
||||
- Change the ownership of `mgkey` to `mongodb:mongodb`
|
||||
- Change its permissions to 400
|
||||
- After these steps are done we can open a mongo shell on the primary node and run `rs.add()` in order to add the new
|
||||
node to the cluster. If you don't know which node is primary, log onto any server and jump into the Mongo's container
|
||||
(`docker exec -it mongo mongo -u admin -p`) and then get the status of the replica set (`rs.status()`).
|
||||
|
@ -185,8 +185,8 @@ Before pushing your code, you should verify that it will pass our online test su
|
|||
**Cypress Tests**
|
||||
Verify the Cypress test suite by doing the following:
|
||||
|
||||
1. In one terminal screen run `GATSBY_API_URL=https://siasky.net yarn workspace webapp start`
|
||||
1. In a second terminal screen run `yarn workspace webapp cypress run`
|
||||
1. In one terminal screen run `GATSBY_API_URL=https://siasky.net yarn workspace website serve`
|
||||
1. In a second terminal screen run `yarn workspace website cypress run`
|
||||
|
||||
## Setting up complete skynet server
|
||||
|
||||
|
|
|
@ -3,12 +3,5 @@
|
|||
"license": "SEE LICENSE IN LICENSE.md",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tailwindcss/forms": "^0.2.1",
|
||||
"autoprefixer": "^10.2.4",
|
||||
"postcss": "^8.2.6",
|
||||
"sharp": "^0.27.2",
|
||||
"tailwindcss": "^2.0.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -23,13 +23,12 @@
|
|||
"http-status-codes": "2.1.4",
|
||||
"ky": "0.25.1",
|
||||
"next": "10.2.3",
|
||||
"postcss": "8.2.14",
|
||||
"postcss": "8.3.5",
|
||||
"prettier": "2.3.1",
|
||||
"pretty-bytes": "5.6.0",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"skynet-js": "3.0.2",
|
||||
"square": "11.0.0",
|
||||
"stripe": "8.156.0",
|
||||
"superagent": "6.1.0",
|
||||
"swr": "0.5.6",
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"cypress/globals": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": ["prettier", "eslint:recommended", "plugin:react/recommended"],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["react", "cypress"]
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
# gatsby files
|
||||
.cache/
|
||||
public
|
||||
package-lock.json
|
|
@ -1,5 +0,0 @@
|
|||
/.cache
|
||||
/package.json
|
||||
/package-lock.json
|
||||
/public
|
||||
/docker/data
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"printWidth": 120
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
FROM node:16.1.0-alpine
|
||||
|
||||
RUN apk update && apk add autoconf automake libtool gcc make g++ zlib-dev file nasm util-linux
|
||||
|
||||
WORKDIR /usr/app
|
||||
|
||||
COPY package.json .
|
||||
|
||||
ENV CYPRESS_INSTALL_BINARY 0
|
||||
|
||||
RUN yarn --no-lockfile
|
||||
|
||||
COPY src ./src
|
||||
COPY static ./static
|
||||
COPY gatsby-config.js .
|
||||
|
||||
ARG WITH_ACCOUNTS=0
|
||||
|
||||
ENV GATSBY_TELEMETRY_DISABLED 1
|
||||
ENV GATSBY_WITH_ACCOUNTS $WITH_ACCOUNTS
|
||||
|
||||
EXPOSE 9000
|
||||
|
||||
CMD [ "sh", "-c", "yarn build && yarn serve --host 0.0.0.0" ]
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"baseUrl": "http://127.0.0.1:8000",
|
||||
"projectId": "6qp3um",
|
||||
"videoUploadOnPasses": false
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"ok": true
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/// <reference types="cypress" />
|
||||
|
||||
context("Skynet", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("");
|
||||
});
|
||||
|
||||
it("should render key website elements", () => {
|
||||
cy.contains("Build a Free Internet");
|
||||
cy.contains("Upload your Files");
|
||||
cy.contains("Have a Skylink?");
|
||||
});
|
||||
|
||||
it("should be able to upload a file", () => {
|
||||
cy.intercept("POST", "/skynet/skyfile").as("upload");
|
||||
|
||||
const fileName = "check.json";
|
||||
|
||||
cy.wait(1000); // delay for drag-and-drop to work properly every time
|
||||
cy.get('.home-upload input[type="file"]').attachFile(fileName, { subjectType: "drag-n-drop" });
|
||||
|
||||
cy.get(".home-upload").scrollIntoView();
|
||||
cy.get(".home-uploaded-files").children().should("have.length", 1);
|
||||
|
||||
// wait max 2 minutes, the portal might be slow at times
|
||||
cy.wait("@upload", { responseTimeout: 2 * 60 * 1000 });
|
||||
|
||||
cy.contains(".upload-file", fileName).within(() => {
|
||||
cy.get(".url")
|
||||
.invoke("text")
|
||||
.should("match", /\/[a-zA-Z0-9-_]{46}/);
|
||||
|
||||
cy.contains("Copy Link").click();
|
||||
cy.contains("Copied!").should("be.visible");
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,18 +0,0 @@
|
|||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = () => {};
|
|
@ -1,27 +0,0 @@
|
|||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
|
||||
import "cypress-file-upload";
|
|
@ -1,16 +0,0 @@
|
|||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
import "./commands";
|
|
@ -1,55 +0,0 @@
|
|||
const { defaultIcons } = require("gatsby-plugin-manifest/common");
|
||||
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: `Skynet`,
|
||||
description: `Skynet is a decentralized file sharing and content distribution protocol.`,
|
||||
author: `Nebulous`,
|
||||
siteUrl: `https://siasky.net`,
|
||||
image: `https://siasky.net/icons/icon-512x512.png`,
|
||||
},
|
||||
plugins: [
|
||||
`gatsby-plugin-sass`,
|
||||
`gatsby-plugin-react-helmet`,
|
||||
{
|
||||
resolve: `gatsby-source-filesystem`,
|
||||
options: {
|
||||
name: `images`,
|
||||
path: `${__dirname}/src/images`,
|
||||
},
|
||||
},
|
||||
`gatsby-plugin-robots-txt`,
|
||||
{
|
||||
resolve: `gatsby-plugin-manifest`,
|
||||
options: {
|
||||
name: `Skynet`,
|
||||
short_name: `Skynet`,
|
||||
start_url: `/`,
|
||||
background_color: `#f1f7f2`,
|
||||
theme_color: `#f1f7f2`,
|
||||
display: `minimal-ui`,
|
||||
icon: `src/images/logo.svg`, // This path is relative to the root of the site.
|
||||
icons: [
|
||||
...defaultIcons,
|
||||
// when we're serving content from the portal on our pathnames that do not have
|
||||
// favicon defined (basically all non-html content), we want the browsers to be
|
||||
// able to fall back to favicon.ico (firefox does that)
|
||||
{
|
||||
src: `favicon.ico`,
|
||||
sizes: `32x32`,
|
||||
type: `image/x-icon`,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: "gatsby-plugin-matomo",
|
||||
options: {
|
||||
siteId: 3,
|
||||
matomoUrl: "https://surveillance.sia.tech",
|
||||
siteUrl: "https://siasky.net",
|
||||
},
|
||||
},
|
||||
`gatsby-plugin-remove-serviceworker`,
|
||||
],
|
||||
};
|
|
@ -1,84 +0,0 @@
|
|||
{
|
||||
"name": "webapp",
|
||||
"description": "Sia Skynet",
|
||||
"version": "1.0.0",
|
||||
"author": "Nebulous",
|
||||
"dependencies": {
|
||||
"@fontsource/metropolis": "^4.2.1",
|
||||
"axios": "0.21.1",
|
||||
"boolean": "^3.0.2",
|
||||
"bytes": "3.1.0",
|
||||
"classnames": "2.3.1",
|
||||
"gatsby": "^3.0.4",
|
||||
"gatsby-plugin-manifest": "^3.0.0",
|
||||
"gatsby-plugin-matomo": "0.9.0",
|
||||
"gatsby-plugin-react-helmet": "^4.0.0",
|
||||
"gatsby-plugin-remove-serviceworker": "1.0.0",
|
||||
"gatsby-plugin-robots-txt": "1.5.6",
|
||||
"gatsby-plugin-sass": "^4.0.2",
|
||||
"gatsby-source-filesystem": "^3.0.0",
|
||||
"http-status-codes": "2.1.4",
|
||||
"js-cookie": "^2.2.1",
|
||||
"jsonp": "0.2.1",
|
||||
"node-sass": "5.0.0",
|
||||
"path-browserify": "1.0.1",
|
||||
"prop-types": "15.7.2",
|
||||
"react": "17.0.1",
|
||||
"react-countup": "4.3.3",
|
||||
"react-dom": "17.0.1",
|
||||
"react-dropzone": "11.3.2",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-mailchimp-form": "1.0.2",
|
||||
"react-mailchimp-subscribe": "^2.1.3",
|
||||
"react-syntax-highlighter": "15.4.3",
|
||||
"react-visibility-sensor": "5.1.1",
|
||||
"skynet-js": "3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cypress": "^7.1.0",
|
||||
"cypress-file-upload": "5.0.7",
|
||||
"eslint": "7.26.0",
|
||||
"eslint-config-prettier": "8.2.0",
|
||||
"eslint-plugin-cypress": "2.11.2",
|
||||
"eslint-plugin-react": "7.23.2",
|
||||
"husky": "4.3.8",
|
||||
"lint-staged": "10.5.4",
|
||||
"prettier": "2.2.1"
|
||||
},
|
||||
"keywords": [
|
||||
"sia",
|
||||
"skynet",
|
||||
"nebulous",
|
||||
"blockchain",
|
||||
"decentralized",
|
||||
"cloud storage"
|
||||
],
|
||||
"license": "SEE LICENSE IN LICENSE.md",
|
||||
"scripts": {
|
||||
"build": "gatsby build",
|
||||
"start": "gatsby develop",
|
||||
"serve": "gatsby serve",
|
||||
"clean": "gatsby clean"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": [
|
||||
"eslint --fix",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{md,html,css,scss}": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/NebulousLabs/skynet-webportal"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/NebulousLabs/skynet-webportal/issues"
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import { createContext } from "react";
|
||||
|
||||
export default createContext(null);
|
|
@ -1,34 +0,0 @@
|
|||
import React from "react";
|
||||
import TopSwoosh from "../../svg/TopSwoosh";
|
||||
import "./App.scss";
|
||||
import StickyTopMessage from "../StickyTopMessage/StickyTopMessage";
|
||||
import { HomeTop, HomeUpload, HomeBuilt, HomeSamples, HomeStay, HomeNetwork, Footer } from "../";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<StickyTopMessage />
|
||||
<div className="app">
|
||||
<TopSwoosh className="top-swoosh" />
|
||||
|
||||
<div className="width">
|
||||
<HomeTop />
|
||||
<HomeUpload />
|
||||
<HomeBuilt />
|
||||
<HomeSamples />
|
||||
</div>
|
||||
|
||||
<div className="home-white">
|
||||
<div className="width">
|
||||
<HomeStay />
|
||||
<HomeNetwork />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
|
@ -1,30 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.app {
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.top-swoosh {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
transform: translateX(-50%);
|
||||
margin-left: 340px;
|
||||
width: 622px;
|
||||
max-width: none;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-left: 380px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-white {
|
||||
background: $white;
|
||||
padding: 80px 0;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding: 120px 0;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
import React from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
import "./Button.scss";
|
||||
|
||||
export default function Button({ href, type, children, full, className, iconLeft, iconRight, ...rest }) {
|
||||
const classes = classNames("button", { iconLeft, iconRight, full }, className);
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
<a href={href} className={classes} {...rest}>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
} else if (type) {
|
||||
return (
|
||||
<button type={type} className={classes} {...rest}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<button type="button" className={classes} {...rest}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
background: $green;
|
||||
color: $white;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 16px 0 rgba(87, 181, 96, 0.1);
|
||||
line-height: 48px;
|
||||
font-weight: bold;
|
||||
padding: 0 32px;
|
||||
transition: 0.2s background-color, 0.2s color, 0.2s transform;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $greenHover;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
svg {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
&.iconLeft svg {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
&.iconRight svg {
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import "./CircleIcon.scss";
|
||||
|
||||
export default function CircleIcon({ children }) {
|
||||
return <div className="circle-icon">{children}</div>;
|
||||
}
|
||||
|
||||
CircleIcon.propTypes = {
|
||||
children: PropTypes.node,
|
||||
};
|
|
@ -1,10 +0,0 @@
|
|||
.circle-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 32px;
|
||||
box-shadow: 0 0 8px 0 rgba(23, 25, 23, 0.2);
|
||||
border: solid 2px currentColor;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
export const curl = `# upload
|
||||
curl -X POST "https://siasky.net/skynet/skyfile" -F "file=@src.jpg"
|
||||
|
||||
# download
|
||||
curl "https://siasky.net/[skylink]" -o dst.jpg`;
|
||||
|
||||
export const browserjs = `import { SkynetClient } from "skynet-js";
|
||||
|
||||
// create a client
|
||||
const client = new SkynetClient();
|
||||
|
||||
// Assume we have a file from an input form.
|
||||
|
||||
async function example() {
|
||||
try {
|
||||
// upload
|
||||
const { skylink } = await client.uploadFile(file);
|
||||
console.log(\`Upload successful, skylink: \${skylink}\`);
|
||||
|
||||
// download
|
||||
await client.downloadFile(skylink);
|
||||
console.log('Download successful');
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}`;
|
||||
|
||||
export const python = `import siaskynet as skynet
|
||||
|
||||
# create a client
|
||||
client = skynet.SkynetClient()
|
||||
|
||||
# upload
|
||||
skylink = client.upload_file("./src.jpg")
|
||||
print("Upload successful, skylink: " + skylink)
|
||||
|
||||
# download
|
||||
client.download_file("./dst.jpg", skylink)
|
||||
print("Download successful")`;
|
||||
|
||||
export const node = `const { SkynetClient } = require('@nebulous/skynet');
|
||||
|
||||
// create a client
|
||||
const client = new SkynetClient();
|
||||
|
||||
(async () => {
|
||||
// upload
|
||||
const skylink = await client.uploadFile("./src.jpg");
|
||||
console.log(\`Upload successful, skylink: \${skylink}\`);
|
||||
|
||||
// download
|
||||
await client.downloadFile("./dst.jpg", skylink);
|
||||
console.log('Download successful');
|
||||
})()`;
|
||||
|
||||
export const go = `package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
skynet "github.com/NebulousLabs/go-skynet/v2"
|
||||
)
|
||||
|
||||
// create a client
|
||||
var client = skynet.New()
|
||||
|
||||
func main() {
|
||||
// upload
|
||||
skylink, err := client.UploadFile("./src.jpg", skynet.DefaultUploadOptions)
|
||||
if err != nil {
|
||||
panic("Unable to upload: " + err.Error())
|
||||
}
|
||||
fmt.Printf("Upload successful, skylink: %v\\n", skylink)
|
||||
|
||||
// download
|
||||
err = client.DownloadFile("./dst.jpg", skylink, skynet.DefaultDownloadOptions)
|
||||
if err != nil {
|
||||
panic("Something went wrong, please try again.\\nError: " + err.Error())
|
||||
}
|
||||
fmt.Println("Download successful")
|
||||
}`;
|
|
@ -1,74 +0,0 @@
|
|||
import React, { useState, useContext } from "react";
|
||||
import classNames from "classnames";
|
||||
import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||
import { javascript, go, python, bash } from "react-syntax-highlighter/dist/esm/languages/hljs";
|
||||
import Colors from "./Colors";
|
||||
import * as snippets from "./Code";
|
||||
import "./CodeExamples.scss";
|
||||
import AppContext from "../../AppContext";
|
||||
|
||||
SyntaxHighlighter.registerLanguage("javascript", javascript);
|
||||
SyntaxHighlighter.registerLanguage("go", go);
|
||||
SyntaxHighlighter.registerLanguage("python", python);
|
||||
SyntaxHighlighter.registerLanguage("bash", bash);
|
||||
|
||||
export default function CodeExamples() {
|
||||
const [active, setActive] = useState(1);
|
||||
const { apiUrl } = useContext(AppContext);
|
||||
const interpolateRegExp = new RegExp("https://siasky.net", "g");
|
||||
const interpolateSnippet = (snippet) => snippet.replace(interpolateRegExp, apiUrl);
|
||||
|
||||
return (
|
||||
<div className="code-examples">
|
||||
<div className="code-examples-tabs">
|
||||
<button type="button" onClick={() => setActive(1)} className={classNames({ active: active === 1 })}>
|
||||
CURL
|
||||
</button>
|
||||
<button type="button" onClick={() => setActive(2)} className={classNames({ active: active === 2 })}>
|
||||
BrowserJS
|
||||
</button>
|
||||
<button type="button" onClick={() => setActive(3)} className={classNames({ active: active === 3 })}>
|
||||
Python
|
||||
</button>
|
||||
<button type="button" onClick={() => setActive(4)} className={classNames({ active: active === 4 })}>
|
||||
Node.js
|
||||
</button>
|
||||
<button type="button" onClick={() => setActive(5)} className={classNames({ active: active === 5 })}>
|
||||
Go
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="code-examples-body">
|
||||
{active === 1 && (
|
||||
<SyntaxHighlighter wrapLines showLineNumbers={true} language="bash" style={Colors}>
|
||||
{interpolateSnippet(snippets.curl)}
|
||||
</SyntaxHighlighter>
|
||||
)}
|
||||
|
||||
{active === 2 && (
|
||||
<SyntaxHighlighter wrapLines showLineNumbers={true} language="javascript" style={Colors}>
|
||||
{interpolateSnippet(snippets.browserjs)}
|
||||
</SyntaxHighlighter>
|
||||
)}
|
||||
|
||||
{active === 3 && (
|
||||
<SyntaxHighlighter wrapLines showLineNumbers={true} language="python" style={Colors}>
|
||||
{interpolateSnippet(snippets.python)}
|
||||
</SyntaxHighlighter>
|
||||
)}
|
||||
|
||||
{active === 4 && (
|
||||
<SyntaxHighlighter wrapLines showLineNumbers={true} language="javascript" style={Colors}>
|
||||
{interpolateSnippet(snippets.node)}
|
||||
</SyntaxHighlighter>
|
||||
)}
|
||||
|
||||
{active === 5 && (
|
||||
<SyntaxHighlighter wrapLines showLineNumbers={true} language="go" style={Colors}>
|
||||
{interpolateSnippet(snippets.go)}
|
||||
</SyntaxHighlighter>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.code-examples-tabs {
|
||||
border-top-left-radius: 12px;
|
||||
border-top-right-radius: 12px;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
height: 65px;
|
||||
|
||||
button {
|
||||
display: block;
|
||||
flex: 1;
|
||||
color: $white60;
|
||||
line-height: 57px;
|
||||
padding: 0 16px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
background-color: #343734;
|
||||
transition: 0.2s line-height, 0.2s background-color, 0.2s color;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
|
||||
@media (min-width: 360px) {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding: 0 32px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
button:hover,
|
||||
button.active {
|
||||
color: $white;
|
||||
background-color: #171917;
|
||||
line-height: 65px;
|
||||
}
|
||||
|
||||
button:first-child {
|
||||
border-top-left-radius: 12px;
|
||||
}
|
||||
|
||||
button:last-child {
|
||||
border-top-right-radius: 12px;
|
||||
}
|
||||
|
||||
button.filler,
|
||||
button.filler:hover {
|
||||
flex: 1;
|
||||
height: 57px;
|
||||
border-top-right-radius: 12px;
|
||||
background-color: #343734;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.code-examples-body {
|
||||
padding: 24px;
|
||||
background-color: #171917;
|
||||
border-bottom-left-radius: 12px;
|
||||
border-bottom-right-radius: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.react-syntax-highlighter-line-number {
|
||||
color: $white50;
|
||||
margin-right: 16px;
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
export default {
|
||||
hljs: {
|
||||
display: "block",
|
||||
overflowX: "auto",
|
||||
padding: "0.5em",
|
||||
background: "#171917",
|
||||
color: "#e6e1dc",
|
||||
},
|
||||
"hljs-comment": {
|
||||
color: "#bc9458",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
"hljs-quote": {
|
||||
color: "#bc9458",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
"hljs-keyword": {
|
||||
color: "#c26230",
|
||||
},
|
||||
"hljs-selector-tag": {
|
||||
color: "#c26230",
|
||||
},
|
||||
"hljs-string": {
|
||||
color: "#a5c261",
|
||||
},
|
||||
"hljs-number": {
|
||||
color: "#a5c261",
|
||||
},
|
||||
"hljs-regexp": {
|
||||
color: "#a5c261",
|
||||
},
|
||||
"hljs-variable": {
|
||||
color: "#a5c261",
|
||||
},
|
||||
"hljs-template-variable": {
|
||||
color: "#a5c261",
|
||||
},
|
||||
"hljs-subst": {
|
||||
color: "#519f50",
|
||||
},
|
||||
"hljs-tag": {
|
||||
color: "#e8bf6a",
|
||||
},
|
||||
"hljs-name": {
|
||||
color: "#e8bf6a",
|
||||
},
|
||||
"hljs-type": {
|
||||
color: "#da4939",
|
||||
},
|
||||
"hljs-symbol": {
|
||||
color: "#6d9cbe",
|
||||
},
|
||||
"hljs-bullet": {
|
||||
color: "#6d9cbe",
|
||||
},
|
||||
"hljs-built_in": {
|
||||
color: "#6d9cbe",
|
||||
},
|
||||
"hljs-builtin-name": {
|
||||
color: "#6d9cbe",
|
||||
},
|
||||
"hljs-attr": {
|
||||
color: "#6d9cbe",
|
||||
},
|
||||
"hljs-link": {
|
||||
color: "#6d9cbe",
|
||||
textDecoration: "underline",
|
||||
},
|
||||
"hljs-params": {
|
||||
color: "#d0d0ff",
|
||||
},
|
||||
"hljs-attribute": {
|
||||
color: "#cda869",
|
||||
},
|
||||
"hljs-meta": {
|
||||
color: "#9b859d",
|
||||
},
|
||||
"hljs-title": {
|
||||
color: "#ffc66d",
|
||||
},
|
||||
"hljs-section": {
|
||||
color: "#ffc66d",
|
||||
},
|
||||
"hljs-addition": {
|
||||
backgroundColor: "#144212",
|
||||
color: "#e6e1dc",
|
||||
display: "inline-block",
|
||||
width: "100%",
|
||||
},
|
||||
"hljs-deletion": {
|
||||
backgroundColor: "#600",
|
||||
color: "#e6e1dc",
|
||||
display: "inline-block",
|
||||
width: "100%",
|
||||
},
|
||||
"hljs-selector-class": {
|
||||
color: "#9b703f",
|
||||
},
|
||||
"hljs-selector-id": {
|
||||
color: "#8b98ab",
|
||||
},
|
||||
"hljs-emphasis": {
|
||||
fontStyle: "italic",
|
||||
},
|
||||
"hljs-strong": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
};
|
|
@ -1,20 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import "./FAQ.scss";
|
||||
|
||||
export default function FAQ({ title, children }) {
|
||||
return (
|
||||
<div className="faq">
|
||||
<div className="faq-dash" />
|
||||
<div className="faq-text">
|
||||
<h3>{title}</h3>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
FAQ.propTypes = {
|
||||
title: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
};
|
|
@ -1,41 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.faq {
|
||||
display: flex;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.faq-text {
|
||||
flex: 1;
|
||||
margin-left: 16px;
|
||||
|
||||
h3 {
|
||||
font-weight: 700;
|
||||
color: $gray;
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.78;
|
||||
font-size: 16px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: $lightGray;
|
||||
line-height: 1.7;
|
||||
font-size: 13px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.faq-dash {
|
||||
height: 2px;
|
||||
width: 32px;
|
||||
background: $green;
|
||||
box-shadow: 0 0 8px 0 rgba(87, 181, 96, 0.3);
|
||||
margin-top: 16px;
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
import { FooterOrb, FooterCube, Built } from "../../svg";
|
||||
import "./Footer.scss";
|
||||
import { Mailing } from "..";
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="footer" id="footer">
|
||||
<div className="width">
|
||||
<div className="footer-column">
|
||||
<Built width={120} height={120} preserveAspectRatio={"xMinYMin"} />
|
||||
</div>
|
||||
|
||||
<div className="footer-column">
|
||||
<h2>Skynet Webportals</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://skydrain.net" target="_blank" rel="noopener noreferrer">
|
||||
skydrain.net
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://skyportal.xyz" target="_blank" rel="noopener noreferrer">
|
||||
skyportal.xyz
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="footer-column">
|
||||
<h2>For Developers</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://blog.sia.tech/skynet-bdf0209d6d34" target="_blank" rel="noopener noreferrer">
|
||||
Skynet Overview
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://siasky.net/docs" target="_blank" rel="noopener noreferrer">
|
||||
API Docs
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/NebulousLabs/skynet-webportal/blob/master/setup-scripts/README.md"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Portal Setup
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://support.siasky.net/key-concepts/skynet-portals/using-a-sia-node-as-a-portal"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Accessing Skynet Locally
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="footer-column">
|
||||
<h2>Social</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://twitter.com/siatechhq" target="_blank" rel="noopener noreferrer">
|
||||
Twitter
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://discord.gg/sia" target="_blank" rel="noopener noreferrer">
|
||||
Discord
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.reddit.com/r/siacoin" target="_blank" rel="noopener noreferrer">
|
||||
Reddit
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://blog.sia.tech" target="_blank" rel="noopener noreferrer">
|
||||
Blog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="footer-column">
|
||||
<h2>Links</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://sia.tech/" target="_blank" rel="noopener noreferrer">
|
||||
Sia.tech
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://jobs.lever.co/SkynetLabs" target="_blank" rel="noopener noreferrer">
|
||||
Jobs
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://support.siasky.net" target="_blank" rel="noopener noreferrer">
|
||||
Support
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="terms.pdf" target="_blank" rel="noopener noreferrer">
|
||||
Terms
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="privacy.pdf" target="_blank" rel="noopener noreferrer">
|
||||
Privacy
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="footer-column">
|
||||
<h2>Stay up to date with Skynet updates</h2>
|
||||
<Mailing id="mailing-bottom" light />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FooterCube className="footer-cube" />
|
||||
<FooterOrb className="footer-orb" />
|
||||
</footer>
|
||||
);
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.footer {
|
||||
background-color: #171917;
|
||||
padding: 60px 0 100px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding: 60px 0 140px;
|
||||
}
|
||||
|
||||
.width {
|
||||
max-width: 1200px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.footer-column + .footer-column {
|
||||
margin-top: 40px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin: 0 0 0 60px;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
color: $white;
|
||||
margin-bottom: 25px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
ul + h2 {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $green;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
transition: 0.2s color;
|
||||
font-size: 13px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer-orb {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 100px;
|
||||
margin-top: -13px;
|
||||
margin-left: -13px;
|
||||
animation: 8s floatLarge infinite;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-left: 180px;
|
||||
right: auto;
|
||||
left: 50%;
|
||||
bottom: 90px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer-cube {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 100%;
|
||||
margin-top: -109px;
|
||||
margin-left: -163px;
|
||||
animation: 8s float infinite;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-left: -100px;
|
||||
right: auto;
|
||||
left: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.footer-built {
|
||||
margin-top: 30px;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
import "./HomeBuilt.scss";
|
||||
import { CircleIcon, CodeExamples } from "../";
|
||||
import { Cylinder, SmallOrb } from "../../svg";
|
||||
|
||||
export default function HomeBuilt() {
|
||||
return (
|
||||
<div className="home-built">
|
||||
<header className="home-built-header">
|
||||
<div className="home-built-divider">
|
||||
<div className="small-divider" />
|
||||
<div className="divider" />
|
||||
<SmallOrb className="small-orb" />
|
||||
<CircleIcon>
|
||||
<Cylinder />
|
||||
</CircleIcon>
|
||||
<SmallOrb className="small-orb" />
|
||||
<div className="divider" />
|
||||
<div className="small-divider" />
|
||||
</div>
|
||||
<h2>
|
||||
Infrastructure built for
|
||||
<br />
|
||||
<strong>application developers</strong>
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<CodeExamples />
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.home-built {
|
||||
padding-top: 80px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding-top: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-built-header {
|
||||
text-align: center;
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
margin-bottom: 50px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home-built-divider {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin: 0 auto 32px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.circle-icon {
|
||||
margin: 0 14px;
|
||||
}
|
||||
|
||||
.small-orb:first-of-type {
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.small-orb:last-of-type {
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.small-divider:first-of-type {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.small-divider:last-of-type {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import CountUp from "react-countup";
|
||||
import VisibilitySensor from "react-visibility-sensor";
|
||||
|
||||
import useStats, { AVAILABLE_STATS } from "./useStats";
|
||||
import "./HomeNetwork.scss";
|
||||
import { CircleIcon, FAQ } from "../";
|
||||
import { SmallOrb, LogoSolid, Deco6, Deco7, Deco8 } from "../../svg";
|
||||
|
||||
const STATS_MAP = [
|
||||
{ name: "TB Used", key: AVAILABLE_STATS.STORAGE_USED_TB },
|
||||
{ name: "TB Capacity", key: AVAILABLE_STATS.NETWORK_CAPACITY_TB },
|
||||
{ name: "Hosts", key: AVAILABLE_STATS.ONLINE_HOSTS_COUNT },
|
||||
{ name: "Storage/TB", key: AVAILABLE_STATS.STORAGE_COST_USD, currency: true },
|
||||
{ name: "Bandwidth/TB", key: AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD, currency: true },
|
||||
];
|
||||
|
||||
export default function HomeNetwork() {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const stats = useStats();
|
||||
const onChange = (isVisible) => {
|
||||
if (isVisible && !visible) {
|
||||
setVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="home-network">
|
||||
<header className="home-network-header">
|
||||
<div className="home-network-divider">
|
||||
<CircleIcon>
|
||||
<LogoSolid />
|
||||
</CircleIcon>
|
||||
<SmallOrb />
|
||||
<div className="divider"></div>
|
||||
<div className="small-divider"></div>
|
||||
</div>
|
||||
<h2>
|
||||
Sia
|
||||
<br />
|
||||
<strong>Network</strong>
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<VisibilitySensor onChange={onChange} partialVisibility offset={{ bottom: 100 }} scrollThrottle={50}>
|
||||
<React.Fragment>
|
||||
<div className="home-network-stats">
|
||||
{STATS_MAP.map((stat, i) => (
|
||||
<React.Fragment key={i}>
|
||||
<div key={i} className="home-network-stat">
|
||||
<div className="inner">
|
||||
{visible && <StatValue stat={stat} value={stats[stat.key]} />}
|
||||
<span className="network-stat-name">{stat.name}</span>
|
||||
</div>
|
||||
</div>
|
||||
{i !== 4 && <div className="divider" />}
|
||||
</React.Fragment>
|
||||
))}
|
||||
<Deco6 className="deco-6" />
|
||||
<Deco7 className="deco-7" />
|
||||
<Deco8 className="deco-8" />
|
||||
</div>
|
||||
<div className="home-network-stats-provider">
|
||||
stats provided by{" "}
|
||||
<a href="https://siastats.info" target="_blank" rel="noopener noreferrer">
|
||||
siastats.info
|
||||
</a>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
</VisibilitySensor>
|
||||
|
||||
<div className="home-network-columns">
|
||||
<div className="home-network-column left">
|
||||
<p>
|
||||
<strong>Skynet Webportals</strong> are low cost servers that sit between Skynet and everyday users, enabling
|
||||
them to access Skynet content without needing to operate any special software. As Skylinks are generated,
|
||||
they can be shared with anyone to retrieve data from any Webportal. The original uploader does not need to
|
||||
stay online in order for the file to remain available. The Sia network serves as the backend storage layer
|
||||
for Skynet and handles all of the pinning, guaranteeing both high speeds and excellent uptime.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Sia</strong> is the leading decentralized cloud storage platform. No signups, no servers, no trusted
|
||||
third parties. Sia leverages blockchain technology to create a data storage marketplace that is more robust
|
||||
and more affordable than traditional cloud storage providers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a className="more" href="https://sia.tech/" target="_blank" rel="noopener noreferrer">
|
||||
Learn more about Sia
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div className="home-network-column">
|
||||
<FAQ title="How do I use Skynet?">
|
||||
<p>
|
||||
Anyone can access files that have been uploaded to Skynet as long as they possess the corresponding
|
||||
Skylinks. You can use any Webportal to download files!
|
||||
<a
|
||||
href="https://support.siasky.net/using-skynet"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="more read-more"
|
||||
>
|
||||
read more
|
||||
</a>
|
||||
</p>
|
||||
</FAQ>
|
||||
|
||||
<FAQ title="How do I integrate Skynet into my app?">
|
||||
<p>
|
||||
Applications can be deployed in under a minute and be immediately available globally. Skynet includes an
|
||||
API and SDKs which integrate seamlessly with existing applications.
|
||||
<a
|
||||
href="https://support.siasky.net/the-technology/developing-on-skynet"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="more read-more"
|
||||
>
|
||||
read more
|
||||
</a>
|
||||
</p>
|
||||
</FAQ>
|
||||
|
||||
<FAQ title="How fast is Skynet?">
|
||||
<p>
|
||||
Skynet's speeds rival centralized providers and surpass all decentralized offerings. A typical Skynet
|
||||
download starts in under 500 ms and can stream at rates as high as 1 Gbps!
|
||||
<a
|
||||
href="https://support.siasky.net/key-concepts/faqs#how-fast-is-skynet"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="more read-more"
|
||||
>
|
||||
read more
|
||||
</a>
|
||||
</p>
|
||||
</FAQ>
|
||||
|
||||
<FAQ title="How much does it cost to run a Webportal?">
|
||||
<p>
|
||||
Storage costs 10x lower than centralized providers and bandwidth costs are 100x lower – without
|
||||
sacrificing performance or reliability.
|
||||
</p>
|
||||
</FAQ>
|
||||
|
||||
<a className="more more-faq" href="https://support.siasky.net" target="_blank" rel="noopener noreferrer">
|
||||
View more FAQ
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function StatValue({ stat, value }) {
|
||||
const displayDollars = stat.currency && value >= 1;
|
||||
const displayCents = stat.currency && value < 1;
|
||||
|
||||
return (
|
||||
<h3>
|
||||
{displayDollars && "$"}
|
||||
<CountUp end={displayCents ? value * 100 : value} duration={3.2} decimals={displayDollars ? 2 : 0} />
|
||||
{displayCents && "¢"}
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
StatValue.propTypes = {
|
||||
stat: PropTypes.shape({
|
||||
key: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
currency: PropTypes.bool,
|
||||
}).isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
};
|
|
@ -1,211 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.home-network {
|
||||
padding: 80px 0;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding: 120px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.home-network-header {
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-network-divider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $green;
|
||||
margin-bottom: 32px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.circle-icon {
|
||||
box-shadow: 0 0 8px 0 rgba(87, 181, 96, 0.3);
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 0 8px 0 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-network-stats {
|
||||
background: $green;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 24px 0 rgba(87, 181, 96, 0.3);
|
||||
padding: 32px 24px;
|
||||
position: relative;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 40px 30px;
|
||||
}
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding: 50px 20px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 2px;
|
||||
width: 240px;
|
||||
background: $black10;
|
||||
margin: 20px auto;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
height: 56px;
|
||||
width: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home-network-stats-provider {
|
||||
text-align: right;
|
||||
color: $green;
|
||||
font-size: 13px;
|
||||
margin-right: 12px; // keep the same as the border radius of .home-network-stats
|
||||
|
||||
a {
|
||||
color: $green;
|
||||
|
||||
&:hover {
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.deco-6 {
|
||||
position: absolute;
|
||||
top: -185px;
|
||||
right: 10px;
|
||||
animation: 8s float infinite;
|
||||
}
|
||||
|
||||
.deco-7 {
|
||||
position: absolute;
|
||||
top: -130px;
|
||||
right: 35px;
|
||||
animation: 6s float infinite;
|
||||
}
|
||||
|
||||
.deco-8 {
|
||||
position: absolute;
|
||||
top: -65px;
|
||||
right: -95px;
|
||||
animation: 10s float infinite;
|
||||
}
|
||||
|
||||
.home-network-stat {
|
||||
text-align: center;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
text-align: center;
|
||||
width: calc(20% - 2px);
|
||||
}
|
||||
|
||||
.inner {
|
||||
@media (min-width: $largebp) {
|
||||
margin: 0 auto;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
min-width: 110px;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 700;
|
||||
color: $white;
|
||||
font-size: 32px;
|
||||
min-width: 10px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.network-stat-name {
|
||||
font-size: 14px;
|
||||
color: $white50;
|
||||
}
|
||||
|
||||
.home-network-columns {
|
||||
margin-top: 40px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
display: flex;
|
||||
margin-top: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-network-column {
|
||||
@media (min-width: $largebp) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
& + & {
|
||||
margin-top: 40px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin: 0 0 0 30px;
|
||||
}
|
||||
}
|
||||
|
||||
&.left p {
|
||||
color: $gray;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
&.left p + p {
|
||||
margin-top: 30px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.more {
|
||||
color: $green;
|
||||
font-size: 13px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
transition: 0.2s color;
|
||||
|
||||
&:hover {
|
||||
color: $black;
|
||||
}
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-left: 10px;
|
||||
transition: 0.2s transform, 0.2s color;
|
||||
}
|
||||
|
||||
&:hover svg {
|
||||
transform: translateX(2px);
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
|
||||
.more-faq {
|
||||
margin-left: 48px;
|
||||
}
|
||||
|
||||
.read-more {
|
||||
display: block;
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
export const AVAILABLE_STATS = {
|
||||
ONLINE_HOSTS_COUNT: "onlineHostsCount",
|
||||
STORAGE_USED_TB: "storageUsedTB",
|
||||
NETWORK_CAPACITY_TB: "networkCapacityTB",
|
||||
STORAGE_COST_USD: "storageCostUSD",
|
||||
BANDWIDTH_DOWN_COST_USD: "bandwidthDownCostUSD",
|
||||
};
|
||||
|
||||
export default function useStats() {
|
||||
const [stats, setStats] = useState({
|
||||
[AVAILABLE_STATS.ONLINE_HOSTS_COUNT]: null,
|
||||
[AVAILABLE_STATS.STORAGE_USED_TB]: null,
|
||||
[AVAILABLE_STATS.NETWORK_CAPACITY_TB]: null,
|
||||
[AVAILABLE_STATS.STORAGE_COST_USD]: null,
|
||||
[AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD]: null,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
const [bandwidth, storage, price] = await Promise.all([getBandwidthStats(), getStorageStats(), getPriceStats()]);
|
||||
|
||||
setStats({ ...bandwidth, ...storage, ...price });
|
||||
}
|
||||
|
||||
fetchData();
|
||||
}, [setStats]);
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
async function getBandwidthStats() {
|
||||
// { up: 76.09, down: 102.66, upusd: 0.23, downusd: 0.32 }
|
||||
const { data } = await axios.get("https://siastats.info/dbs/bandwidthpricesdb.json");
|
||||
// some entries do not contain the required property so make sure to get one that does
|
||||
const current = data.reverse().find((entry) => "downusd" in entry);
|
||||
|
||||
return {
|
||||
[AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD]: current.downusd,
|
||||
};
|
||||
}
|
||||
|
||||
async function getPriceStats() {
|
||||
// { price: 504.59, newcontractformation: 30.79, usd: 1.55, sfperfees: 8.98 }
|
||||
const { data } = await axios.get("https://siastats.info/dbs/storagepricesdb.json");
|
||||
// some entries do not contain the required property so make sure to get one that does
|
||||
const current = data.reverse().find((entry) => "usd" in entry);
|
||||
|
||||
return {
|
||||
[AVAILABLE_STATS.STORAGE_COST_USD]: current.usd,
|
||||
};
|
||||
}
|
||||
|
||||
async function getStorageStats() {
|
||||
// { block_height: 247816, block_timestamp: 1582285828, hashrate: 6212581269715416,
|
||||
// difficulty: 3501953420754597000, coin_supply: 43638591164, coin_price_USD: 0.003,
|
||||
// market_cap_USD: 130915773, used_storage_TB: 725.26, network_capacity_TB: 2270.96,
|
||||
// online_hosts: 360, active_contracts: 62997 }
|
||||
const { data } = await axios.get("https://siastats.info/dbs/network_status.json");
|
||||
|
||||
return {
|
||||
[AVAILABLE_STATS.ONLINE_HOSTS_COUNT]: data.online_hosts,
|
||||
[AVAILABLE_STATS.STORAGE_USED_TB]: data.used_storage_TB,
|
||||
[AVAILABLE_STATS.NETWORK_CAPACITY_TB]: data.network_capacity_TB,
|
||||
};
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
import "./HomeSamples.scss";
|
||||
import { Sample } from "../";
|
||||
|
||||
const samples = [
|
||||
{ type: "HTML", url: "/PAL0w4SdA5rFCDGEutgpeQ50Om-YkBabtXVOJAkmedslKw" },
|
||||
{ type: "PDF", url: "/XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg" },
|
||||
{ type: "Image", url: "/IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ" },
|
||||
{ type: "Audio", url: "/_A2zt5SKoqwnnZU4cBF8uBycSKULXMyeg1c5ZISBr2Q3dA" },
|
||||
{ type: "Video", url: "/CACqf4NlIMlA0CCCieYGjpViPGyfyJ4v1x3bmuCKZX8FKA" },
|
||||
{ type: "JSON", url: "/AAC0uO43g64ULpyrW0zO3bjEknSFbAhm8c-RFP21EQlmSQ" },
|
||||
{ type: "Dapp", url: "/hns/marstorage/" },
|
||||
];
|
||||
|
||||
export default function HomeSamples() {
|
||||
return (
|
||||
<div className="home-samples">
|
||||
<p>Above are some code snippets for uploading and retrieving data.</p>
|
||||
<p>
|
||||
Skynet includes{" "}
|
||||
<a href="https://siasky.net/docs" target="_blank" rel="noopener noreferrer" className="link">
|
||||
SDKs
|
||||
</a>{" "}
|
||||
for popular programming languages and{" "}
|
||||
<a href="https://siasky.net/docs/" target="_blank" rel="noopener noreferrer" className="link">
|
||||
APIs
|
||||
</a>{" "}
|
||||
that integrate seamlessly with your existing apps. You can follow these guides to start using Skynet with{" "}
|
||||
<a href="https://github.com/NebulousLabs/skynet-cli" target="_blank" rel="noopener noreferrer" className="link">
|
||||
the Skynet CLI
|
||||
</a>{" "}
|
||||
and{" "}
|
||||
<a
|
||||
href="https://blog.sia.tech/the-skynet-sdks-751b35578b20"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="link"
|
||||
>
|
||||
integrate Skynet
|
||||
</a>{" "}
|
||||
into your application.
|
||||
</p>
|
||||
|
||||
<div className="home-samples-samples">
|
||||
{samples.map((sample, i) => (
|
||||
<Sample key={`${i}-${sample.url}`} {...sample} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.home-samples {
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
padding: 60px 0;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding: 65px 0 100px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 auto 24px;
|
||||
max-width: 460px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.sample {
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
min-width: 124px;
|
||||
text-align: center;
|
||||
|
||||
@media (min-width: $tinybp) {
|
||||
margin: 10px 20px;
|
||||
}
|
||||
|
||||
@media (min-width: $smallbp) {
|
||||
margin: 10px 40px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
|
||||
import "./HomeStay.scss";
|
||||
import { SocialLink, CircleIcon, Mailing } from "../";
|
||||
import { SmallOrb, Pyramid } from "../../svg";
|
||||
|
||||
export default class HomeStay extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="home-stay">
|
||||
<header className="home-stay-header">
|
||||
<div className="home-stay-divider">
|
||||
<CircleIcon>
|
||||
<Pyramid />
|
||||
</CircleIcon>
|
||||
<SmallOrb />
|
||||
<div className="divider" />
|
||||
<div className="small-divider" />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="home-stay-flex">
|
||||
<div className="home-stay-left">
|
||||
<header className="home-stay-header">
|
||||
<h2>
|
||||
Stay up to date with
|
||||
<br />
|
||||
<strong>Skynet updates</strong>
|
||||
</h2>
|
||||
</header>
|
||||
<Mailing id="mailing-top" />
|
||||
</div>
|
||||
|
||||
<ul className="home-stay-right">
|
||||
<li>
|
||||
<SocialLink
|
||||
icon="github"
|
||||
url="https://github.com/NebulousLabs/skynet-webportal"
|
||||
greenText="View project on Github"
|
||||
title={<strong>/Skynet-Webportal</strong>}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<SocialLink
|
||||
icon="discord"
|
||||
url="https://discord.gg/sia"
|
||||
greenText="View project on Discord"
|
||||
title={<strong>/Sia</strong>}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<SocialLink
|
||||
icon="twitter"
|
||||
url="https://twitter.com/SiaTechHQ"
|
||||
greenText="View project on Twitter"
|
||||
title={<strong>@SiaTechHQ</strong>}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.home-stay-header {
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-stay-divider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $green;
|
||||
margin-bottom: 32px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.circle-icon {
|
||||
box-shadow: 0 0 8px 0 rgba(87, 181, 96, 0.3);
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 0 8px 0 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-stay-flex {
|
||||
@media (min-width: $largebp) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.home-stay-left {
|
||||
@media (min-width: $largebp) {
|
||||
flex: 1;
|
||||
margin-right: 60px;
|
||||
}
|
||||
|
||||
p {
|
||||
max-width: 553px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.disclaimer-text {
|
||||
font-size: 13px;
|
||||
color: $lightGray;
|
||||
line-height: 1.7;
|
||||
max-width: 438px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home-stay-right {
|
||||
margin-top: 40px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
width: 305px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
import React from "react";
|
||||
import { boolean } from "boolean";
|
||||
import logo from "../../images/logo.svg";
|
||||
import "./HomeTop.scss";
|
||||
import { Skynet, Deco1, Deco2 } from "../../svg";
|
||||
|
||||
export default function HomeTop() {
|
||||
return (
|
||||
<div className="home-top">
|
||||
<img src={logo} alt="Skynet logo" className="logo" />
|
||||
<Skynet className="wordmark" />
|
||||
|
||||
<h1>Build a Free Internet.</h1>
|
||||
|
||||
<p>
|
||||
The decentralized CDN and file sharing platform for devs. Skynet is the storage foundation for a Free Internet!
|
||||
</p>
|
||||
|
||||
{boolean(process.env.GATSBY_WITH_ACCOUNTS) && (
|
||||
<p className="auth-links">
|
||||
<a href="/account/auth/registration" className="link">
|
||||
Sign up now!
|
||||
</a>{" "}
|
||||
Already have an account? Go to your{" "}
|
||||
<a href="/account/" className="link">
|
||||
dashboard
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
|
||||
<Deco1 className="deco-1" />
|
||||
<Deco2 className="deco-2" />
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.home-top {
|
||||
text-align: center;
|
||||
padding: 60px 0 50px;
|
||||
position: relative;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding: 60px 0 70px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: inline-block;
|
||||
width: 85px;
|
||||
margin-bottom: 5px;
|
||||
margin-right: 10px; // move it 10px so it looks like it's centered
|
||||
}
|
||||
|
||||
.wordmark {
|
||||
margin: 0 auto 35px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 44px;
|
||||
line-height: 1.14;
|
||||
margin-bottom: 38px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 56px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 21px;
|
||||
line-height: 1.33;
|
||||
max-width: 560px;
|
||||
margin: 0 auto;
|
||||
|
||||
&.auth-links {
|
||||
font-size: 18px;
|
||||
|
||||
.link {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 24px;
|
||||
max-width: 670px;
|
||||
}
|
||||
|
||||
& + p {
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.deco-1 {
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
bottom: 25%;
|
||||
margin-left: 20px;
|
||||
animation: 6s float infinite;
|
||||
|
||||
@media (min-width: 591px) {
|
||||
margin-left: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.deco-2 {
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
bottom: 5%;
|
||||
margin-left: -15px;
|
||||
animation: 8s float infinite;
|
||||
|
||||
@media (min-width: 591px) {
|
||||
margin-left: 50px;
|
||||
}
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
import React, { useState, useContext, useEffect } from "react";
|
||||
import bytes from "bytes";
|
||||
import classNames from "classnames";
|
||||
import { getReasonPhrase, StatusCodes } from "http-status-codes";
|
||||
import path from "path-browserify";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { Button, UploadFile } from "../";
|
||||
import { Deco3, Deco4, Deco5, Folder, DownArrow } from "../../svg";
|
||||
import "./HomeUpload.scss";
|
||||
import AppContext from "../../AppContext";
|
||||
import { SkynetClient, parseSkylink } from "skynet-js";
|
||||
|
||||
const isValidSkylink = (skylink) => {
|
||||
try {
|
||||
parseSkylink(skylink); // try to parse the skylink, it will throw on error
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const getFilePath = (file) => file.webkitRelativePath || file.path || file.name;
|
||||
|
||||
const getRelativeFilePath = (file) => {
|
||||
const filePath = getFilePath(file);
|
||||
const { root, dir, base } = path.parse(filePath);
|
||||
const relative = path.normalize(dir).slice(root.length).split(path.sep).slice(1);
|
||||
|
||||
return path.join(...relative, base);
|
||||
};
|
||||
|
||||
const getRootDirectory = (file) => {
|
||||
const filePath = getFilePath(file);
|
||||
const { root, dir } = path.parse(filePath);
|
||||
|
||||
return path.normalize(dir).slice(root.length).split(path.sep)[0];
|
||||
};
|
||||
|
||||
const createUploadErrorMessage = (error) => {
|
||||
// The request was made and the server responded with a status code that falls out of the range of 2xx
|
||||
if (error.response) {
|
||||
if (error.response.data.message) {
|
||||
return `Upload failed with error: ${error.response.data.message}`;
|
||||
}
|
||||
|
||||
const statusCode = error.response.status;
|
||||
const statusText = getReasonPhrase(error.response.status);
|
||||
|
||||
return `Upload failed, our server received your request but failed with status code: ${statusCode} ${statusText}`;
|
||||
}
|
||||
|
||||
// The request was made but no response was received. The best we can do is detect whether browser is online.
|
||||
// This will be triggered mostly if the server is offline or misconfigured and doesn't respond to valid request.
|
||||
if (error.request) {
|
||||
if (!navigator.onLine) {
|
||||
return "You are offline, please connect to the internet and try again";
|
||||
}
|
||||
|
||||
// TODO: We should add a note "our team has been notified" and have some kind of notification with this error.
|
||||
return "Server failed to respond to your request, please try again later.";
|
||||
}
|
||||
|
||||
// TODO: We should add a note "our team has been notified" and have some kind of notification with this error.
|
||||
return `Critical error, please refresh the application and try again. ${error.message}`;
|
||||
};
|
||||
|
||||
export default function HomeUpload() {
|
||||
const [files, setFiles] = useState([]);
|
||||
const [skylink, setSkylink] = useState("");
|
||||
const { apiUrl } = useContext(AppContext);
|
||||
const [directoryMode, setDirectoryMode] = useState(false);
|
||||
const client = new SkynetClient(apiUrl);
|
||||
|
||||
useEffect(() => {
|
||||
if (directoryMode) {
|
||||
inputRef.current.setAttribute("webkitdirectory", "true");
|
||||
} else {
|
||||
inputRef.current.removeAttribute("webkitdirectory");
|
||||
}
|
||||
}, [directoryMode]);
|
||||
|
||||
const handleDrop = async (acceptedFiles) => {
|
||||
if (directoryMode && acceptedFiles.length) {
|
||||
const rootDir = getRootDirectory(acceptedFiles[0]); // get the file path from the first file
|
||||
|
||||
acceptedFiles = [{ name: rootDir, directory: true, files: acceptedFiles }];
|
||||
}
|
||||
|
||||
setFiles((previousFiles) => [...acceptedFiles.map((file) => ({ file, status: "uploading" })), ...previousFiles]);
|
||||
|
||||
const onFileStateChange = (file, state) => {
|
||||
setFiles((previousFiles) => {
|
||||
const index = previousFiles.findIndex((f) => f.file === file);
|
||||
|
||||
return [
|
||||
...previousFiles.slice(0, index),
|
||||
{
|
||||
...previousFiles[index],
|
||||
...state,
|
||||
},
|
||||
...previousFiles.slice(index + 1),
|
||||
];
|
||||
});
|
||||
};
|
||||
|
||||
acceptedFiles.forEach((file) => {
|
||||
const onUploadProgress = (progress) => {
|
||||
const status = progress === 1 ? "processing" : "uploading";
|
||||
|
||||
onFileStateChange(file, { status, progress });
|
||||
};
|
||||
|
||||
// Reject files larger than our hard limit of 1 GB with proper message
|
||||
if (file.size > bytes("1 GB")) {
|
||||
onFileStateChange(file, { status: "error", error: "This file size exceeds the maximum allowed size of 1 GB." });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const upload = async () => {
|
||||
try {
|
||||
let response;
|
||||
|
||||
if (file.directory) {
|
||||
const directory = file.files.reduce((acc, file) => ({ ...acc, [getRelativeFilePath(file)]: file }), {});
|
||||
|
||||
response = await client.uploadDirectory(directory, encodeURIComponent(file.name), { onUploadProgress });
|
||||
} else {
|
||||
response = await client.uploadFile(file, { onUploadProgress });
|
||||
}
|
||||
|
||||
onFileStateChange(file, { status: "complete", url: client.getSkylinkUrl(response.skylink) });
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === StatusCodes.TOO_MANY_REQUESTS) {
|
||||
onFileStateChange(file, { progress: -1 });
|
||||
|
||||
return new Promise((resolve) => setTimeout(() => resolve(upload()), 3000));
|
||||
}
|
||||
|
||||
onFileStateChange(file, { status: "error", error: createUploadErrorMessage(error) });
|
||||
}
|
||||
};
|
||||
|
||||
upload();
|
||||
});
|
||||
};
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive, inputRef } = useDropzone({ onDrop: handleDrop });
|
||||
|
||||
const handleSkylink = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
// only try to open a valid skylink
|
||||
if (isValidSkylink(skylink)) {
|
||||
client.openFile(skylink);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="home-upload">
|
||||
<div className="home-upload-white">
|
||||
<div className="home-upload-split">
|
||||
<div className="home-upload-box ">
|
||||
<div
|
||||
className={classNames("home-upload-dropzone", {
|
||||
"drop-active": isDragActive,
|
||||
})}
|
||||
{...getRootProps()}
|
||||
>
|
||||
<span className="home-upload-text">
|
||||
<h3>Upload your {directoryMode ? "Directory" : "Files"}</h3>
|
||||
Drop your {directoryMode ? "directory" : "files"} here to pin to Skynet
|
||||
</span>
|
||||
<Button iconLeft>
|
||||
<Folder />
|
||||
Browse
|
||||
</Button>
|
||||
</div>
|
||||
<input {...getInputProps()} className="offscreen" />
|
||||
<button
|
||||
type="button"
|
||||
className="home-upload-mode-switch link"
|
||||
onClick={() => setDirectoryMode(!directoryMode)}
|
||||
>
|
||||
{directoryMode ? "⇐ Switch back to uploading files" : "Do you want to upload an entire directory?"}
|
||||
</button>
|
||||
{directoryMode && (
|
||||
<p className="home-upload-directory-mode-notice">
|
||||
Please note that directory upload is not a standard browser feature and the browser support is limited.
|
||||
To check whether your browser is compatible, visit{" "}
|
||||
<a
|
||||
href="https://caniuse.com/#feat=mdn-api_htmlinputelement_webkitdirectory"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="link"
|
||||
>
|
||||
caniuse.com
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="home-upload-retrieve">
|
||||
<div className="home-upload-text">
|
||||
<h3 id="skylink-retrieve-title">Have a Skylink?</h3>
|
||||
<p>Paste the link to retrieve your file</p>
|
||||
|
||||
<form
|
||||
className={classNames("home-upload-retrieve-form", { invalid: skylink && !isValidSkylink(skylink) })}
|
||||
onSubmit={handleSkylink}
|
||||
>
|
||||
<input
|
||||
name="skylink"
|
||||
type="text"
|
||||
placeholder="sia://"
|
||||
aria-labelledby="skylink-retrieve-title"
|
||||
onChange={(event) => setSkylink(event.target.value)}
|
||||
/>
|
||||
<button type="submit" aria-label="Retrieve file">
|
||||
<DownArrow />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{files.length > 0 && (
|
||||
<div className="home-uploaded-files">
|
||||
{files.map((file, i) => {
|
||||
return <UploadFile key={i} {...file} />;
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p className="bottom-text">
|
||||
Upon uploading a file, Skynet generates a 46 byte link called a <strong>Skylink</strong>. This link can then be
|
||||
shared with anyone to retrieve the file on any Skynet Webportal.
|
||||
</p>
|
||||
|
||||
<Deco3 className="deco-3" />
|
||||
<Deco4 className="deco-4" />
|
||||
<Deco5 className="deco-5" />
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,269 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.home-upload {
|
||||
position: relative;
|
||||
|
||||
.bottom-text {
|
||||
color: $lightGray;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
max-width: 590px;
|
||||
margin: 25px auto 0;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home-upload-white {
|
||||
background: $white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 24px 0 rgba(90, 94, 91, 0.15), 0 2px 4px 0 rgba(0, 0, 0, 0.05);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.home-upload-split {
|
||||
border: 1px dashed #c5cec7;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.home-upload-box {
|
||||
padding-bottom: 20px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
width: 50%;
|
||||
padding-bottom: 0;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-upload-dropzone {
|
||||
border-radius: 4px;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover .button {
|
||||
background-color: $greenHover;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
&.drop-active {
|
||||
background-color: $green;
|
||||
border: 1px solid $green;
|
||||
|
||||
h3 {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: 20px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home-upload-mode-switch {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
margin: 10px auto 0;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-upload-directory-mode-notice {
|
||||
color: $lightGray;
|
||||
font-size: 13px;
|
||||
line-height: 1.2em;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.home-upload-text {
|
||||
color: $gray;
|
||||
display: block;
|
||||
transition: 0.2s color;
|
||||
font-size: 13px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.drop-active & {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
margin-bottom: 5px;
|
||||
color: $darkGray;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.deco-3 {
|
||||
position: absolute;
|
||||
top: -70px;
|
||||
left: -5px;
|
||||
animation: 8s float infinite;
|
||||
}
|
||||
|
||||
.deco-4 {
|
||||
position: absolute;
|
||||
top: -32px;
|
||||
left: -90px;
|
||||
animation: 6s float infinite;
|
||||
}
|
||||
|
||||
.deco-5 {
|
||||
position: absolute;
|
||||
top: 52px;
|
||||
left: -56px;
|
||||
animation: 10s float infinite;
|
||||
}
|
||||
|
||||
.home-uploaded-files {
|
||||
border: solid 1px #c5cec7;
|
||||
padding: 0 20px;
|
||||
margin-top: 10px;
|
||||
border-radius: 4px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
.upload-file + .upload-file {
|
||||
border-top: 1px solid rgba(197, 206, 199, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.home-upload-retrieve {
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
border-top: 1px dashed #c5cec7;
|
||||
height: 200px;
|
||||
padding: 40px 20px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
width: 50%;
|
||||
padding: 20px 40px;
|
||||
border-top: 0;
|
||||
border-left: 1px dashed #c5cec7;
|
||||
}
|
||||
|
||||
.home-upload-text {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.home-upload-retrieve-form {
|
||||
width: 100%;
|
||||
margin-top: 3px;
|
||||
position: relative;
|
||||
margin-top: 20px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
input {
|
||||
border: 1px solid #cbd3cd;
|
||||
border-radius: 4px;
|
||||
line-height: 46px;
|
||||
transition: 0.2s border-color;
|
||||
padding: 0 64px 0 16px;
|
||||
font-size: 13px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
input:hover,
|
||||
input:hover + button {
|
||||
border-color: rgb(143, 143, 143);
|
||||
}
|
||||
|
||||
input:focus,
|
||||
input:focus + button {
|
||||
border-color: $green;
|
||||
}
|
||||
|
||||
button {
|
||||
border-left: 1px solid #cbd3cd;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
width: 46px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: #cbd3cd;
|
||||
transition: 0.2s background-color, 0.2s border-color, 0.2s color;
|
||||
|
||||
&:hover {
|
||||
background: $green;
|
||||
color: $white;
|
||||
border-color: $green;
|
||||
}
|
||||
}
|
||||
|
||||
&.invalid {
|
||||
input {
|
||||
border-color: $red;
|
||||
}
|
||||
|
||||
input:hover,
|
||||
input:hover + button {
|
||||
border-color: $red;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
input:focus + button {
|
||||
border-color: $red;
|
||||
}
|
||||
|
||||
button {
|
||||
border-color: $red;
|
||||
|
||||
&:hover {
|
||||
background: $red;
|
||||
border-color: $red;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
import "./LoadingSpinner.scss";
|
||||
import { Loading } from "../../svg";
|
||||
|
||||
export default function LoadingSpinner() {
|
||||
return (
|
||||
<div className="loading-spinner">
|
||||
<Loading />
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
@-webkit-keyframes spin {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes spin {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
-webkit-animation: spin 1.5s linear infinite;
|
||||
animation: spin 1.5s linear infinite;
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import MailchimpSubscribe from "react-mailchimp-subscribe";
|
||||
import classNames from "classnames";
|
||||
import "./Mailing.scss";
|
||||
|
||||
const url = "https://tech.us11.list-manage.com/subscribe/post?u=5df238d9e852f9801b5f2c92e&id=ab6bea4cc2";
|
||||
|
||||
const CustomForm = ({ status, message, onValidated, light, id }) => {
|
||||
let email, user;
|
||||
|
||||
const checkboxId = `${id}-check`;
|
||||
const submitId = `${id}-submit`;
|
||||
|
||||
const submit = () => {
|
||||
if ((email, user, email.value.indexOf("@") > -1)) {
|
||||
onValidated({
|
||||
EMAIL: email.value,
|
||||
USER: user.checked ? "Yes" : "No",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form className={classNames("home-stay-form", { light })} onSubmit={(e) => e.preventDefault()}>
|
||||
<input
|
||||
ref={(node) => (email = node)}
|
||||
type="email"
|
||||
placeholder="Email Address"
|
||||
validate="true"
|
||||
aria-labelledby={submitId}
|
||||
/>
|
||||
<div className="home-form-stay-existing">
|
||||
<input ref={(node) => (user = node)} type="checkbox" id={checkboxId} />
|
||||
<label htmlFor={checkboxId}>I have previous experience using Sia</label>
|
||||
</div>
|
||||
<button className="button" onClick={submit} id={submitId}>
|
||||
Get Updates
|
||||
</button>
|
||||
|
||||
{status === "sending" && <p className="message">sending...</p>}
|
||||
{status === "error" && <p className="message red-text" dangerouslySetInnerHTML={{ __html: message }} />}
|
||||
{status === "success" && <p className="message" dangerouslySetInnerHTML={{ __html: message }} />}
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
CustomForm.propTypes = {
|
||||
status: PropTypes.string,
|
||||
message: PropTypes.string,
|
||||
onValidated: PropTypes.func,
|
||||
light: PropTypes.bool,
|
||||
id: PropTypes.string,
|
||||
};
|
||||
|
||||
export default function Mailing({ light, id }) {
|
||||
return (
|
||||
<MailchimpSubscribe
|
||||
url={url}
|
||||
render={({ subscribe, status, message }) => (
|
||||
<CustomForm
|
||||
id={id}
|
||||
status={status}
|
||||
message={message}
|
||||
light={light}
|
||||
onValidated={(formData) => subscribe(formData)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Mailing.propTypes = {
|
||||
light: PropTypes.bool,
|
||||
id: PropTypes.string,
|
||||
};
|
|
@ -1,109 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.home-stay-form {
|
||||
max-width: 342px;
|
||||
margin: 36px 0 24px;
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.message {
|
||||
font-size: 12px;
|
||||
margin-top: 10px;
|
||||
color: $lightGray;
|
||||
|
||||
&.red-text {
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="email"] {
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px 0 rgba(90, 94, 91, 0.1);
|
||||
border: solid 1px #cbd3cd;
|
||||
padding: 12px 0 12px 16px;
|
||||
transition: 0.2s border-color;
|
||||
|
||||
&:hover {
|
||||
border-color: rgb(143, 143, 143);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: $green;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #cbd3cd;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: -2px 8px 0 0;
|
||||
background-image: url("../../images/green-check.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 28px;
|
||||
background-position: top -300px center;
|
||||
|
||||
&:checked {
|
||||
background-position: top -3px center;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
font-weight: 400;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.email-error {
|
||||
font-size: 12px;
|
||||
margin-top: 8px;
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
|
||||
.home-stay-form.light {
|
||||
input[type="email"] {
|
||||
box-shadow: 0 2px 4px 0 rgba(90, 94, 91, 0.1);
|
||||
border-color: $white50;
|
||||
color: $white;
|
||||
|
||||
&:hover {
|
||||
border-color: $white;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: $green;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
border-color: $white50;
|
||||
}
|
||||
|
||||
label {
|
||||
color: $white50;
|
||||
}
|
||||
|
||||
.message {
|
||||
color: $white30;
|
||||
|
||||
&.red-text {
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home-form-stay-existing {
|
||||
margin: 15px 0 20px 0;
|
||||
|
||||
label {
|
||||
color: $darkGray;
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import classNames from "classnames";
|
||||
import "./Sample.scss";
|
||||
import { Download } from "../../svg";
|
||||
|
||||
export default function Sample({ type, url, className }) {
|
||||
return (
|
||||
<div className={classNames("sample", className)}>
|
||||
<a href={url} target="_blank" rel="noopener noreferrer">
|
||||
<Download />
|
||||
<span className="sample-name">
|
||||
<strong>{type}</strong> Sample
|
||||
</span>
|
||||
<span className="sample-download">Download</span>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Sample.propTypes = {
|
||||
type: PropTypes.string,
|
||||
url: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,48 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.sample {
|
||||
display: block;
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
transition: 0.2s transform;
|
||||
display: block;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
transform: translateY(5px);
|
||||
}
|
||||
|
||||
svg {
|
||||
margin: 0 auto;
|
||||
width: 34px;
|
||||
height: 46px;
|
||||
}
|
||||
}
|
||||
|
||||
.sample-name {
|
||||
color: $darkGray;
|
||||
display: block;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
a:hover & {
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
|
||||
.sample-download {
|
||||
display: block;
|
||||
color: $green;
|
||||
font-size: 13px;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
a:hover & {
|
||||
color: $greenHover;
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import "./SocialLink.scss";
|
||||
import { Github, Discord, Twitter } from "../../svg";
|
||||
|
||||
export default function SocialLink({ icon, title, greenText, url }) {
|
||||
const getIcon = () => {
|
||||
if (icon === "github") {
|
||||
return <Github />;
|
||||
} else if (icon === "discord") {
|
||||
return <Discord />;
|
||||
} else if (icon === "twitter") {
|
||||
return <Twitter />;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<a href={url} className="social-link">
|
||||
<span className="social-link-icon">{getIcon(icon)}</span>
|
||||
<span className="social-link-text">
|
||||
<span className="social-link-title">{title}</span>
|
||||
<span className="social-link-green">{greenText}</span>
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
SocialLink.propTypes = {
|
||||
icon: PropTypes.string,
|
||||
title: PropTypes.node,
|
||||
greenText: PropTypes.string,
|
||||
url: PropTypes.string,
|
||||
};
|
|
@ -1,42 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.social-link {
|
||||
display: flex;
|
||||
color: $darkGray;
|
||||
}
|
||||
|
||||
.social-link-icon {
|
||||
width: 32px;
|
||||
transition: 0.2s transform;
|
||||
|
||||
a:hover & {
|
||||
transform: scale(1.07);
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.social-link-text {
|
||||
flex: 1;
|
||||
margin-left: 16px;
|
||||
transition: 0.2s color;
|
||||
}
|
||||
|
||||
.social-link-title {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.social-link-green {
|
||||
color: $green;
|
||||
font-size: 14px;
|
||||
display: inline-flex;
|
||||
|
||||
transition: 0.2s color;
|
||||
|
||||
a:hover & {
|
||||
color: $darkGray;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// import React from "react";
|
||||
// import "./StickyTopMessage.scss";
|
||||
|
||||
export default function StickyTopMessage() {
|
||||
return null; // returns nothing, uncomment when we need a new message
|
||||
// return (
|
||||
// <div className="sticky-top-message" role="alert">
|
||||
// <p>
|
||||
// We are working on improved performance as part of the upcoming Sia v1.5.0 release. In the meantime, you can try
|
||||
// other webportals listed at the <a href="#footer">bottom</a>.
|
||||
// </p>
|
||||
// </div>
|
||||
// );
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.sticky-top-message {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
font-weight: bold;
|
||||
z-index: 999;
|
||||
background-color: #fbe6e6;
|
||||
border-bottom: 1px solid #e65c5c;
|
||||
color: $red;
|
||||
|
||||
a {
|
||||
color: $red;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
color: darken($red, 15%);
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
import React, { useState, useRef, useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import "./UploadFile.scss";
|
||||
import { LoadingSpinner } from "../";
|
||||
import { File, FileCheck, FileError, Copy } from "../../svg";
|
||||
|
||||
export default function UploadFile({ file, url, status, progress, error }) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
const urlRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (copied) {
|
||||
const timeoutId = setTimeout(() => {
|
||||
setCopied(false);
|
||||
}, 1500);
|
||||
|
||||
return () => clearTimeout(timeoutId);
|
||||
}
|
||||
}, [copied, setCopied]);
|
||||
|
||||
const getIcon = () => {
|
||||
if (status === "uploading" || status === "processing") {
|
||||
return <File />;
|
||||
} else if (status === "error") {
|
||||
return <FileError />;
|
||||
} else {
|
||||
return <FileCheck />;
|
||||
}
|
||||
};
|
||||
|
||||
const copyToClipboard = (e) => {
|
||||
urlRef.current.select();
|
||||
document.execCommand("copy");
|
||||
e.target.focus();
|
||||
setCopied(true);
|
||||
};
|
||||
|
||||
const copyText = copied ? "Copied!" : "Copy to clipboard";
|
||||
const getProgressText = (progress) => {
|
||||
if (progress === -1) {
|
||||
return "Waiting...";
|
||||
} else if (progress > 0) {
|
||||
return `Uploading ${Math.round(progress * 100)}%`;
|
||||
}
|
||||
return "Uploading...";
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="upload-file">
|
||||
<div className="upload-file-icon">{getIcon()}</div>
|
||||
<div className="upload-file-text">
|
||||
<h3>{file.name}</h3>
|
||||
<p>
|
||||
{status === "uploading" && getProgressText(progress)}
|
||||
{status === "processing" && "Processing..."}
|
||||
{status === "error" && <span className="red-text">{error || "Upload failed."}</span>}
|
||||
{status === "complete" && (
|
||||
<a href={url} className="url green-text" target="_blank" rel="noopener noreferrer">
|
||||
{url}
|
||||
</a>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
{(status === "uploading" || status === "processing") && (
|
||||
<div className="upload-file-loading">
|
||||
<LoadingSpinner />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{status === "complete" && (
|
||||
<button onClick={copyToClipboard} className="upload-file-copy">
|
||||
<p className="upload-file-copy-tooltip">{copyText}</p>
|
||||
<div className="upload-file-copy-button">
|
||||
Copy Link
|
||||
<Copy />
|
||||
</div>
|
||||
<textarea value={url} ref={urlRef} readOnly={true} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
UploadFile.propTypes = {
|
||||
file: PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
}),
|
||||
status: PropTypes.string.isRequired,
|
||||
url: PropTypes.string,
|
||||
progress: PropTypes.number,
|
||||
error: PropTypes.string,
|
||||
};
|
|
@ -1,143 +0,0 @@
|
|||
@import "../../variables.scss";
|
||||
|
||||
.upload-file {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.upload-file-icon {
|
||||
display: none;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
display: block;
|
||||
min-width: 36px;
|
||||
width: 36px;
|
||||
max-width: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-file-text {
|
||||
display: block;
|
||||
margin: 0 18px;
|
||||
flex: 1;
|
||||
|
||||
h3 {
|
||||
margin-bottom: 5px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
word-break: break-all;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: $lightGray;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
.url {
|
||||
word-break: break-all;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload-file-loading,
|
||||
.upload-file-copy {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.upload-file-copy {
|
||||
position: relative;
|
||||
|
||||
@media (max-width: $largebp) {
|
||||
flex-basis: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
textarea {
|
||||
position: absolute;
|
||||
left: -999em;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-file-copy-tooltip {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
margin-bottom: 10px;
|
||||
transform: translateX(-50%);
|
||||
color: $white;
|
||||
background: rgba(23, 25, 23, 0.9);
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
line-height: 32px;
|
||||
box-shadow: 0 2px 8px 0 rgba(23, 25, 23, 0.2);
|
||||
border-radius: 4px;
|
||||
width: 140px;
|
||||
text-align: center;
|
||||
opacity: 0;
|
||||
left: -9999em;
|
||||
transition: $fadeOff;
|
||||
|
||||
.upload-file-copy:hover & {
|
||||
left: 50%;
|
||||
opacity: 1;
|
||||
transition: $fadeOn;
|
||||
}
|
||||
|
||||
&::after {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 6px 6px 0 6px;
|
||||
border-color: rgba(23, 25, 23, 0.9) transparent transparent transparent;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
content: "";
|
||||
position: absolute;
|
||||
box-shadow: 0 2px 8px 0 rgba(23, 25, 23, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.upload-file-copy-button {
|
||||
border: 1px solid $green;
|
||||
border-radius: 3px;
|
||||
color: $green;
|
||||
line-height: 40px;
|
||||
font-size: 13px;
|
||||
padding: 0 10px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-weight: 700;
|
||||
transition: 0.2s color, 0.2s background-color;
|
||||
|
||||
@media (min-width: $largebp) {
|
||||
font-size: 14px;
|
||||
padding: 0 15px;
|
||||
line-height: 46px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $green;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
import App from "./App/App";
|
||||
import Button from "./Button/Button";
|
||||
import CodeExamples from "./CodeExamples/CodeExamples";
|
||||
import Sample from "./Sample/Sample";
|
||||
import SocialLink from "./SocialLink/SocialLink";
|
||||
import CircleIcon from "./CircleIcon/CircleIcon";
|
||||
import FAQ from "./FAQ/FAQ";
|
||||
import UploadFile from "./UploadFile/UploadFile";
|
||||
import LoadingSpinner from "./LoadingSpinner/LoadingSpinner";
|
||||
import Footer from "./Footer/Footer";
|
||||
import Mailing from "./Mailing/Mailing";
|
||||
|
||||
import HomeTop from "./HomeTop/HomeTop";
|
||||
import HomeUpload from "./HomeUpload/HomeUpload";
|
||||
import HomeBuilt from "./HomeBuilt/HomeBuilt";
|
||||
import HomeSamples from "./HomeSamples/HomeSamples";
|
||||
import HomeStay from "./HomeStay/HomeStay";
|
||||
import HomeNetwork from "./HomeNetwork/HomeNetwork";
|
||||
|
||||
export {
|
||||
App,
|
||||
HomeTop,
|
||||
HomeUpload,
|
||||
Button,
|
||||
HomeBuilt,
|
||||
CodeExamples,
|
||||
Sample,
|
||||
HomeSamples,
|
||||
HomeStay,
|
||||
SocialLink,
|
||||
CircleIcon,
|
||||
HomeNetwork,
|
||||
FAQ,
|
||||
UploadFile,
|
||||
LoadingSpinner,
|
||||
Footer,
|
||||
Mailing,
|
||||
};
|
|
@ -1,88 +0,0 @@
|
|||
/**
|
||||
* SEO component that queries for data with
|
||||
* Gatsby's useStaticQuery React hook
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { Helmet } from "react-helmet";
|
||||
import { useStaticQuery, graphql } from "gatsby";
|
||||
|
||||
function SEO({ lang, meta }) {
|
||||
const { site } = useStaticQuery(
|
||||
graphql`
|
||||
query {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
author
|
||||
description
|
||||
image
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
return (
|
||||
<Helmet
|
||||
htmlAttributes={{
|
||||
lang,
|
||||
}}
|
||||
title={site.siteMetadata.title}
|
||||
meta={[
|
||||
{
|
||||
name: `description`,
|
||||
content: site.siteMetadata.description,
|
||||
},
|
||||
{
|
||||
property: `og:title`,
|
||||
content: site.siteMetadata.title,
|
||||
},
|
||||
{
|
||||
property: `og:description`,
|
||||
content: site.siteMetadata.description,
|
||||
},
|
||||
{
|
||||
property: `og:type`,
|
||||
content: `website`,
|
||||
},
|
||||
{
|
||||
property: `og:image`,
|
||||
content: site.siteMetadata.image,
|
||||
},
|
||||
{
|
||||
name: `twitter:card`,
|
||||
content: `summary`,
|
||||
},
|
||||
{
|
||||
name: `twitter:creator`,
|
||||
content: site.siteMetadata.author,
|
||||
},
|
||||
{
|
||||
name: `twitter:title`,
|
||||
content: site.siteMetadata.title,
|
||||
},
|
||||
{
|
||||
name: `twitter:description`,
|
||||
content: site.siteMetadata.description,
|
||||
},
|
||||
].concat(meta)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
SEO.defaultProps = {
|
||||
lang: `en`,
|
||||
meta: [],
|
||||
description: ``,
|
||||
};
|
||||
|
||||
SEO.propTypes = {
|
||||
lang: PropTypes.string,
|
||||
meta: PropTypes.arrayOf(PropTypes.object),
|
||||
};
|
||||
|
||||
export default SEO;
|
|
@ -1,148 +0,0 @@
|
|||
@import "./variables.scss";
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 1.78;
|
||||
font-family: $font;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
background-color: $greenBg;
|
||||
color: $darkGray;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 500;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
button,
|
||||
textarea {
|
||||
appearance: none;
|
||||
border: none;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
font-family: $font;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
input[type="email"],
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="search"] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a,
|
||||
button,
|
||||
label,
|
||||
input[type="submit"],
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.red-text {
|
||||
color: $red;
|
||||
}
|
||||
|
||||
.green-text {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
.dark-gray-text {
|
||||
color: $darkGray;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: $green;
|
||||
transition: 0.2s color;
|
||||
|
||||
&:hover {
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
|
||||
.truncate {
|
||||
width: 250px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.offscreen {
|
||||
position: absolute;
|
||||
left: -999em;
|
||||
}
|
||||
|
||||
.width {
|
||||
width: 90%;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 48px;
|
||||
height: 2px;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
.small-divider {
|
||||
width: 8px;
|
||||
height: 2px;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
50% {
|
||||
transform: translate(0, -20%);
|
||||
}
|
||||
100% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes floatLarge {
|
||||
0% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
50% {
|
||||
transform: translate(0, -40%);
|
||||
}
|
||||
100% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
<svg width="24px" height="22px" viewBox="0 0 24 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<polyline id="path-1" points="0 36 3 39 8 34"></polyline>
|
||||
<filter x="-167.7%" y="-268.3%" width="435.4%" height="628.3%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feMorphology radius="1" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
|
||||
<feOffset dx="0" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feMorphology radius="1" operator="erode" in="SourceAlpha" result="shadowInner"></feMorphology>
|
||||
<feOffset dx="0" dy="0" in="shadowInner" result="shadowInner"></feOffset>
|
||||
<feComposite in="shadowOffsetOuter1" in2="shadowInner" operator="out" result="shadowOffsetOuter1"></feComposite>
|
||||
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.341176471 0 0 0 0 0.709803922 0 0 0 0 0.376470588 0 0 0 0.3 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="Homepage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||
<g id="State---Multiple" transform="translate(-319.000000, -358.000000)">
|
||||
<g id="Group" transform="translate(271.000000, 80.000000)">
|
||||
<g id="Group-4" transform="translate(16.000000, 240.000000)">
|
||||
<g id="Group-5" transform="translate(40.000000, 12.000000)">
|
||||
<g id="Rectangle-2">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use stroke="#57B560" stroke-width="2" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.9 KiB |
|
@ -1,8 +0,0 @@
|
|||
<svg viewBox="19.88800048828125 37.1175193787 132.07760620117188 132.07760620117188" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<style>.cls-1,.cls-2{fill:#0071bc;}.cls-1{fill-rule:evenodd;}.cls-2{font-size:87px;font-family:Karbon-Light, Karbon;font-weight:300;letter-spacing:-0.05em;}.cls-3{letter-spacing:-0.05em;}.cls-4{letter-spacing:-0.05em;}</style>
|
||||
</defs>
|
||||
<path class="cls-1" d="M 116.388 139.371 C 92.969 148.816 66.759 134.5 62.048 109.691 L 46.308 98.821 C 43.843 141.32 88.308 170.55 126.346 151.435 C 130.805 149.195 134.94 146.361 138.638 143.011 L 138.698 143.011 C 141.248 140.637 140.685 136.456 137.598 134.841 L 19.888 72.671 Z" style="fill: rgb(88, 181, 96);"></path>
|
||||
<path class="cls-1" d="M 149.398 127.121 L 149.398 127.021 C 150.067 124.651 148.83 122.161 146.538 121.261 L 67.478 90.011 L 142.478 130.011 C 145.178 131.489 148.552 130.08 149.398 127.121 Z" style="fill: rgb(88, 181, 96);"></path>
|
||||
<path class="cls-1" d="M 151.848 109.801 C 152.508 94.561 150.578 79.801 141.228 67.721 C 130.128 53.411 111.498 47.801 96.588 49.081 C 95.428 49.181 94.268 49.351 93.108 49.451 C 77.448 50.901 62.598 59.941 53.728 75.301 C 52.968 76.621 52.278 77.971 51.638 79.301 C 51.238 79.841 50.838 80.371 50.458 80.931 L 63.838 88.061 C 64.463 86.395 65.194 84.772 66.028 83.201 C 80.584 55.935 119.197 54.651 135.532 80.889 C 140.199 88.386 142.264 97.212 141.408 106.001 L 91.518 92.621 L 145.258 113.861 C 148.274 115.053 151.585 112.994 151.848 109.761 Z" style="fill: rgb(88, 181, 96);"></path>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.5 KiB |
|
@ -1,27 +0,0 @@
|
|||
import React, { useMemo } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import SEO from "../components/seo";
|
||||
import { App } from "../components";
|
||||
import "../global.scss";
|
||||
import AppContext from "../AppContext";
|
||||
import "@fontsource/metropolis/all.css"; // import Metropolis typeface
|
||||
|
||||
export default function IndexPage({ location }) {
|
||||
const context = useMemo(
|
||||
() => ({
|
||||
apiUrl: process.env.GATSBY_API_URL || location.origin,
|
||||
}),
|
||||
[location.origin]
|
||||
);
|
||||
|
||||
return (
|
||||
<AppContext.Provider value={context}>
|
||||
<SEO />
|
||||
<App />
|
||||
</AppContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
IndexPage.propTypes = {
|
||||
location: PropTypes.object.isRequired,
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function Arrow({ className }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 15 7" width={15} height={7} xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 6h12L7 1" stroke="currentColor" strokeWidth="2" fill="none" fillRule="evenodd" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Arrow.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,23 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Built(props) {
|
||||
return (
|
||||
<svg width="74" height="65" viewBox="0 0 74 65" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M70.723 64.302a7.37 7.37 0 01-1.284-.378c-.773-.31-1.922-.92-2.798-1.486-1.213-.783-3.053-2.198-4.377-3.366-.197-.174-.5-.44-.675-.591a30.765 30.765 0 01-.6-.54l-.697-.645c-1.56-1.439-4.53-4.45-5.93-6.012a130.07 130.07 0 00-.74-.815c-.78-.853-1.041-1.162-1.034-1.223.006-.053.031-.057.397-.065l.391-.008.106.094c.059.052.287.301.508.554.386.442.631.71 1.102 1.207.12.126.358.385.529.574.695.773 2.875 2.99 3.775 3.84l.773.728c2.248 2.122 4.849 4.165 6.701 5.264.977.58 1.39.776 2.212 1.053.665.225.984.288 1.441.288.315 0 .407-.011.604-.073.656-.203 1.032-.63 1.236-1.404.227-.863.18-1.9-.156-3.475-.407-1.902-1.404-4.676-2.618-7.284l-.48-1.034a102.853 102.853 0 00-1.512-3.031l-.435-.804a102.52 102.52 0 00-1.62-2.902c-.849-1.456-1.166-1.992-1.27-2.14-.185-.263-.25-.411-.265-.604-.01-.135-.004-.182.03-.211.1-.082.099-.083 1.212 1.791a151.95 151.95 0 011.618 2.83c.154.277.322.574.373.661.05.087.218.397.371.69.153.292.372.706.486.919 2.905 5.452 4.814 10.273 5.253 13.263.137.933.157 1.79.057 2.457a2.6 2.6 0 01-.287.887c-.103.207-.17.297-.371.492-.424.413-.778.543-1.46.538a4.251 4.251 0 01-.566-.04zm-35.6-38.46l-.167-.267c-.05-.078-.212-.352-.361-.61-.428-.738-1.288-2.173-1.341-2.236a4.831 4.831 0 01-.225-.366l-.176-.309.007-.953.008-.953.183.342c.101.189.317.586.48.884.164.298.353.647.42.776.122.232.505.899.788 1.37.081.133.226.38.323.545.096.166.217.363.269.438.124.18.385.632.386.669 0 .026-.435.704-.495.77-.012.014-.056-.029-.1-.1zm12.844-7.816a15.927 15.927 0 01-.397-.454 46.908 46.908 0 00-.6-.69l-.894-1.005A102.4 102.4 0 0043 12.545c-1.017-1.063-3.083-3.11-3.403-3.37-.062-.05-.298-.267-.524-.48-.225-.214-.64-.589-.921-.833l-.77-.672c-.241-.21-.842-.701-1.5-1.228-1.467-1.172-3.393-2.41-4.442-2.857-1.46-.621-2.446-.748-3.135-.403-.473.237-.808.689-.977 1.317-.123.462-.164 1.581-.074 2.018.017.08.058.361.092.627.055.423.057.49.021.526-.045.044-1.114.5-1.173.499-.08-.001-.116-.066-.267-.476-.297-.805-.465-1.339-.54-1.717a10.455 10.455 0 00-.115-.522c-.038-.137-.135-.79-.186-1.25a13.667 13.667 0 01-.028-.905c-.003-.608.003-.723.058-.976.15-.702.369-1.111.759-1.423.366-.294.714-.4 1.308-.401.55 0 .946.077 1.605.318 1.856.676 4.035 2.07 6.575 4.205.32.27.662.554.758.633.097.08.404.35.683.604.28.252.555.498.614.546.17.138 1.753 1.635 2.5 2.365.378.368.993.989 1.368 1.379.375.39.73.754.789.81.059.054.342.352.63.66l.927.991c.222.237.589.637.815.89.226.252.508.563.625.69.203.219.786.879 1.255 1.42a95.017 95.017 0 011.823 2.12c.194.23.32.404.314.433-.007.04-.047.051-.195.058-.183.008-.185.008-.302-.115z"
|
||||
fill="#8B8C8B"
|
||||
/>
|
||||
<g fill="#57B560">
|
||||
<path d="M10.955 47.843c-3.147-.218-5.926-1.194-8.708-3.057a18.634 18.634 0 01-.64-.455 21.592 21.592 0 00-.406-.3 35.55 35.55 0 01-1.031-.848l-.13-.112.26-.267c.306-.313.935-.953 1.1-1.119l.825-.84a4399.636 4399.636 0 011.623-1.66c.047-.05.068-.034.509.4 1.054 1.037 2.124 1.78 3.564 2.472.306.147.57.267.588.267.017 0 .073.022.124.048.312.158 1.476.511 1.96.594l.52.088c.335.057 1.562.083 1.93.042.766-.086 1.517-.283 2.07-.543a4.835 4.835 0 001.2-.77c.665-.56 1.04-1.157 1.113-1.774.078-.653-.073-1.318-.415-1.828a3.3 3.3 0 00-.39-.443c-.363-.345-.711-.557-1.309-.8-.352-.142-.818-.26-1.708-.434l-1.086-.213-1.071-.212c-1.24-.242-2.214-.456-2.809-.617-1.057-.286-2.059-.616-2.692-.887l-.435-.185c-.4-.172-.97-.486-1.418-.783-.612-.405-1.24-1.016-1.626-1.584-.443-.65-.648-1.117-.907-2.063-.155-.57-.208-1.908-.107-2.745.11-.916.459-2.015.88-2.775.279-.503.385-.666.714-1.095.97-1.267 2.307-2.315 3.695-2.895.908-.38 1.885-.654 2.721-.762l.695-.09c.45-.057 2.034-.083 2.563-.042 1.672.132 2.948.401 4.458.941.526.188 1.62.69 2.244 1.032.29.157.548.306.782.45.135.083.272.165.304.182.198.107 1.55 1.03 1.642 1.12.053.053.077.018-.411.618-.279.344-.544.674-.637.795a44.636 44.636 0 00-.565.697l-.478.597c-.071.088-.215.268-.318.399-.104.13-.234.292-.29.358-.055.066-.178.218-.272.337a1.43 1.43 0 01-.192.218c-.012 0-.182-.136-.38-.303-.302-.256-.926-.73-1.182-.9-.966-.64-1.63-.972-2.592-1.295a11.186 11.186 0 00-2.156-.49c-.361-.042-1.381-.035-1.723.013-1.295.183-2.325.624-3.048 1.306a2.68 2.68 0 00-.872 1.779c-.05.522.072 1.098.31 1.478.136.215.465.58.61.677.057.038.156.107.22.153.308.223 1.21.592 1.694.692l.535.113c.32.068.596.124 1.998.408l.97.195c.263.054.712.144.999.201.287.057.697.142.912.187.215.046.495.101.623.123 1.097.19 2.707.695 3.402 1.066l.245.13c1.846.978 2.981 2.441 3.37 4.344.135.657.159.9.159 1.647 0 .533-.012.771-.052 1.01-.32 1.95-1.058 3.45-2.385 4.853-1.045 1.105-2.265 1.868-3.929 2.459-1.064.377-2.259.603-3.706.7-.466.03-1.588.03-2.055-.003zM25.88 33.702v-14.17h5.733v28.341H25.88zM28.326 16.627a4.613 4.613 0 01-.432-.111c-.955-.29-1.7-1.068-1.93-2.016-.402-1.65.727-3.245 2.45-3.462.326-.04.369-.04.728.012 1.161.169 2.062.954 2.374 2.071.068.243.079.333.08.705.001.399-.005.448-.092.748-.23.786-.691 1.351-1.426 1.748a3.68 3.68 0 01-.93.306 3.288 3.288 0 01-.822-.001zm19.67 31.215a20.2 20.2 0 01-1.921-.256c-.954-.198-1.92-.491-2.664-.81a2.324 2.324 0 00-.255-.098c-.042 0-1.005-.482-1.349-.675a14.43 14.43 0 01-3.826-3.124 10.298 10.298 0 01-.52-.628 30.045 30.045 0 00-.238-.33c-.303-.415-.573-.814-.573-.849a.283.283 0 00-.053-.088c-.147-.187-.579-1.008-.881-1.676-.546-1.207-.938-2.705-1.124-4.297-.043-.367-.043-2.24 0-2.618.218-1.903.66-3.419 1.462-5.008.205-.405.254-.496.49-.896a16.639 16.639 0 011.104-1.576c.314-.413 1.152-1.29 1.666-1.744.268-.237.846-.7 1.135-.91a20.14 20.14 0 011.109-.724c1.055-.594 1.854-.954 2.826-1.274.787-.259 1.748-.486 2.429-.573l.695-.089c.186-.024.705-.05 1.18-.059.855-.016 1.314.005 1.99.094.175.023.42.054.545.068.664.077 2.155.467 2.826.74.117.047.224.086.238.086.022 0 .304.119.72.304 1.104.493 2.243 1.208 3.27 2.051.19.157.889.801 1.076.992 1.531 1.566 2.728 3.55 3.367 5.588.261.83.486 1.837.542 2.427.015.16.042.392.06.518.025.166.037 2.282.044 7.846l.01 7.62-7.536-.005c-4.145-.002-7.675-.014-7.845-.027zm9.645-9.965c0-5.097.002-5.045-.24-6.081a8.79 8.79 0 00-1.259-2.829c-.725-1.062-1.812-2.064-2.907-2.68a13.402 13.402 0 00-1.21-.565c-.725-.254-1.163-.367-1.797-.463-.453-.068-.584-.076-1.272-.076-.685 0-.823.009-1.274.076-1.203.18-2.33.59-3.33 1.21-1.069.662-1.94 1.506-2.688 2.601-.082.12-.15.23-.15.245a.263.263 0 01-.053.094c-.059.075-.355.634-.466.88a8.535 8.535 0 00-.58 1.919c-.194 1.1-.196 1.826-.01 2.917.076.454.27 1.168.399 1.482.04.098.074.188.074.2 0 .026.195.44.34.723.672 1.305 1.758 2.485 3.033 3.293 1.297.823 2.705 1.28 4.3 1.397.07.005 2.146.011 4.61.014l4.48.005v-4.362z" />
|
||||
</g>
|
||||
<g fill="#8B8C8B">
|
||||
<path d="M12.858 15.565a1.32 1.32 0 01-.906-.946c-.035-.14-.043-.398-.043-1.377v-1.205h-.647v-1.023h.647V9.776h1.264v1.238h1.012v1.023h-1.012v1.085c0 1.07.001 1.086.063 1.204a.56.56 0 00.16.18c.133.086.367.084.547-.003.09-.043.137-.055.145-.034l.153.403.142.372-.064.051a2.122 2.122 0 01-.602.28c-.236.058-.652.053-.859-.01zm-11.01-2.282l-.8-2.255.629-.007a9.34 9.34 0 01.641.004c.007.006.21.633.45 1.393.24.76.445 1.39.455 1.401.01.011.226-.613.482-1.386l.464-1.405H5.26l.464 1.406c.255.773.471 1.397.481 1.386.01-.01.192-.57.405-1.244l.44-1.393.055-.169h1.28l-.802 2.262-.804 2.261-.588-.007-.59-.007-.436-1.418c-.24-.78-.442-1.412-.45-1.405-.009.008-.212.646-.453 1.419l-.437 1.404-.589.007-.588.007-.8-2.254zM9.127 13.275v-2.261h1.32v4.522h-1.32v-2.261zM15.253 12.481V9.426h1.292v1.063c0 .585.01 1.064.024 1.064.013 0 .065-.05.116-.11.123-.147.45-.349.691-.427.267-.087.789-.108 1.052-.043a1.692 1.692 0 011.225 1.16c.045.143.051.327.06 1.782l.01 1.621h-1.265l-.008-1.433c-.008-1.43-.008-1.434-.073-1.588a.892.892 0 00-.498-.476.819.819 0 00-.392-.05c-.395.02-.675.188-.835.5l-.093.18-.008 1.433-.008 1.434h-1.29v-3.055zm-5.79-2.187c-.428-.207-.52-.728-.187-1.057.447-.44 1.198-.145 1.198.472 0 .505-.538.816-1.012.585z" />
|
||||
</g>
|
||||
<g fill="#8B8C8B">
|
||||
<path d="M9.392 6.591a1.669 1.669 0 01-1.225-1.185c-.053-.195-.057-.303-.057-1.791V2.03h1.282v1.408c0 1.356.002 1.414.06 1.574a.919.919 0 00.442.49c.12.058.178.067.41.067.237 0 .292-.01.445-.076a.902.902 0 00.552-.68c.015-.087.028-.75.028-1.471V2.031h1.31v4.522h-1.31V6.27c0-.155-.003-.282-.008-.282-.004 0-.104.088-.22.195-.35.32-.717.452-1.251.449a2.547 2.547 0 01-.458-.04zm10.761-.01a1.329 1.329 0 01-.918-.946c-.035-.14-.044-.398-.044-1.377V3.054h-.655V2.03h.655V.793h1.281V2.03h1.026v1.023h-1.026v1.084c0 1.071.001 1.086.065 1.204a.562.562 0 00.16.181c.136.085.373.084.556-.004.09-.043.139-.054.147-.033l.155.403.144.371-.065.052a2.163 2.163 0 01-.61.279c-.24.058-.662.054-.87-.01zM13.836 4.292V2.031h1.338v4.522h-1.338V4.292zM16.342 3.498V.443h1.339v6.11h-1.339V3.498zM14.176 1.31c-.434-.207-.527-.728-.19-1.056.454-.441 1.216-.146 1.216.471 0 .504-.543.815-1.026.586zM2.043.444h1.34v1.103c0 .607.002 1.104.006 1.104s.098-.082.21-.182c.394-.355.734-.49 1.296-.511.447-.017.694.029 1.047.196.555.263.96.763 1.148 1.414.057.197.066.29.066.711 0 .548-.048.792-.23 1.167-.283.582-.848 1.03-1.45 1.148-.18.036-.708.05-.855.023-.45-.088-.832-.287-1.095-.57l-.143-.153v.66h-1.34V.443zm2.926 5.1c.44-.123.765-.459.876-.904.179-.716-.201-1.41-.876-1.599a1.68 1.68 0 00-.707-.002c-.374.107-.641.35-.796.721-.086.204-.108.673-.044.909.118.432.397.736.794.864.187.06.558.066.753.011z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Copy(props) {
|
||||
return (
|
||||
<svg width={12} height={14} viewBox="0 0 12 14" {...props}>
|
||||
<path
|
||||
d="M8 1H4a3 3 0 00-3 3v6h0m4-6h5a1 1 0 011 1v7a1 1 0 01-1 1H5a1 1 0 01-1-1V5a1 1 0 011-1z"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function Cylinder({ className }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 34 34" width={34} height={34} xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M17 13c8.837 0 16-2.686 16-6s-7.163-6-16-6S1 3.686 1 7s7.163 6 16 6zm0 20c8.837 0 16-2.686 16-6s-7.163-6-16-6-16 2.686-16 6 7.163 6 16 6zM33 7v20M1 27V7m7 25V12"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Cylinder.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,20 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Deco1(props) {
|
||||
return (
|
||||
<svg viewBox="0 0 108 90" width={108} height={90} xmlns="http://www.w3.org/2000/svg" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M2.503 60.68C17.967 87.463 52.216 96.64 79 81.176c26.784-15.464 35.961-49.713 20.497-76.498m-96.994 56C17.967 87.464 52.216 96.641 79 81.177c-24.689 4.287-42.188-2.498-52.497-20.354M59 46.536c26.784-15.464 44.916-34.204 40.497-41.857C95.08-2.973 69.784 3.36 43 18.823S-1.916 53.027 2.503 60.68C6.92 68.332 32.216 62 59 46.536z"
|
||||
stroke="#57B560"
|
||||
strokeWidth="2"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M2.503 60.68c2.507 4.343 11.738 4.181 24.15.403C36.983 78.745 54.431 85.443 79 81.177 52.216 96.64 17.967 87.464 2.503 60.679z"
|
||||
fill="#57B560"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Deco2(props) {
|
||||
return (
|
||||
<svg width={54} height={41} viewBox="0 0 54 41" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M16.37 15.835l4.977 23.803a5.993 5.993 0 01-3.932-3.067L3.382 9.611c2.529 2.237 7.161 4.467 12.988 6.224z"
|
||||
fill="#57B560"
|
||||
/>
|
||||
<path
|
||||
d="M25.53 17.995c14.141 2.493 26.225.999 26.99-3.338.764-4.338-10.08-9.875-24.22-12.368-14.142-2.494-26.226-1-26.99 3.338C.545 9.964 11.389 15.5 25.53 17.995zM1.31 5.627L17.419 36.58a6 6 0 009.376 1.653L52.52 14.657h0M1.31 5.627L17.415 36.57a5.993 5.993 0 003.932 3.067l-5.005-23.941"
|
||||
stroke="#57B560"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Deco3(props) {
|
||||
return (
|
||||
<svg width={27} height={27} viewBox="0 0 27 27" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M2.485 9.73c-1.134 3.12 2.996 7.482 9.224 9.749 6.228 2.267 12.195 1.58 13.328-1.534a11.921 11.921 0 01-3.562 5.088c-5.077 4.26-12.646 3.598-16.906-1.479A11.995 11.995 0 012.485 9.73z"
|
||||
fill="#57B560"
|
||||
/>
|
||||
<path
|
||||
d="M21.475 23.033c5.076-4.26 5.739-11.829 1.479-16.906C18.694 1.05 11.124.388 6.048 4.648.97 8.908.308 16.478 4.568 21.554c4.26 5.077 11.83 5.74 16.907 1.48zm3.562-5.088c-1.133 3.114-7.1 3.8-13.328 1.534-6.228-2.267-10.358-6.629-9.224-9.743"
|
||||
stroke="#57B560"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Deco4(props) {
|
||||
return (
|
||||
<svg width={51} height={51} viewBox="0 0 51 51" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M7.389 10.392l-.013.022c-4.26 5.077.518 16.1 10.672 24.62 10.153 8.52 21.838 11.31 26.098 6.234l.016-.013a23.89 23.89 0 01-10.192 7.138C21.514 52.927 7.742 46.505 3.208 34.05c-3.04-8.355-1.152-17.303 4.18-23.657z"
|
||||
fill="#57B560"
|
||||
/>
|
||||
<path
|
||||
d="M33.97 48.393c12.455-4.533 18.877-18.305 14.344-30.76C43.78 5.176 30.008-1.246 17.553 3.287 5.097 7.822-1.325 21.594 3.208 34.05 7.742 46.505 21.514 52.927 33.97 48.393zm10.176-7.125c-4.26 5.077-15.945 2.285-26.098-6.235-10.154-8.52-14.932-19.542-10.672-24.62"
|
||||
stroke="#57B560"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Deco5(props) {
|
||||
return (
|
||||
<svg width={97} height={95} viewBox="0 0 97 95" {...props}>
|
||||
<defs>
|
||||
<filter id="prefix__a" width="133.3%" height="136.1%" x="-16.7%" y="-18.1%" filterUnits="objectBoundingBox">
|
||||
<feMorphology in="SourceAlpha" operator="dilate" radius={1} result="shadowSpreadOuter1" />
|
||||
<feOffset in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feMorphology in="SourceAlpha" radius={1} result="shadowInner" />
|
||||
<feOffset in="shadowInner" result="shadowInner" />
|
||||
<feComposite in="shadowOffsetOuter1" in2="shadowInner" operator="out" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation={4} />
|
||||
<feColorMatrix
|
||||
in="shadowBlurOuter1"
|
||||
values="0 0 0 0 0.341176471 0 0 0 0 0.709803922 0 0 0 0 0.376470588 0 0 0 0.3 0"
|
||||
/>
|
||||
</filter>
|
||||
<path
|
||||
id="prefix__b"
|
||||
d="M34.5 24c18.225 0 33-5.373 33-12S52.725 0 34.5 0s-33 5.373-33 12 14.775 12 33 12zm0 48c18.225 0 33-5.373 33-12s-14.775-12-33-12-33 5.373-33 12 14.775 12 33 12zm33-60v48m-66 0V12m12 9v48"
|
||||
/>
|
||||
</defs>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
fill="#FFF"
|
||||
fillOpacity={0.8}
|
||||
d="M9.782 36.669l-.064-.188c-1.961-6.242 10.014-16.204 26.97-22.375 17.126-6.234 32.847-6.238 35.114-.01L88.219 59.2c2.266 6.228-9.78 16.33-26.906 22.563-17.126 6.233-32.847 6.238-35.114.01L9.782 36.67z"
|
||||
/>
|
||||
<path
|
||||
fill="#57B560"
|
||||
d="M9.782 36.669c1.287 3.536 6.911 5.063 14.667 4.581l16.417 45.105c-7.756.482-13.38-1.045-14.667-4.58L9.782 36.668z"
|
||||
/>
|
||||
<g strokeLinejoin="round" transform="rotate(-20 75.593 .85)">
|
||||
<use fill="#000" filter="url(#prefix__a)" xlinkHref="#prefix__b" />
|
||||
<use stroke="#57B560" strokeWidth={2} xlinkHref="#prefix__b" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Deco6(props) {
|
||||
return (
|
||||
<svg width={26} height={26} viewBox="0 0 26 26" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M2.604 18.997c1.66 2.873 7.656 2.513 13.396-.8C21.74 14.881 25.05 9.87 23.392 7A11.919 11.919 0 0125 13c0 6.627-5.373 12-12 12a11.995 11.995 0 01-10.396-6.003z"
|
||||
fill="#171917"
|
||||
/>
|
||||
<path
|
||||
d="M25 13c0-6.627-5.373-12-12-12S1 6.373 1 13s5.373 12 12 12 12-5.373 12-12zm-1.608-6C25.05 9.87 21.74 14.882 16 18.196S4.265 21.87 2.608 19"
|
||||
stroke="#171917"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Deco7(props) {
|
||||
return (
|
||||
<svg width={57} height={52} viewBox="0 0 57 52" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path fill="#171917" d="M29 26L1.66 30.947l18.447 19.485 26.657-3.068z" />
|
||||
<path
|
||||
d="M37.893 1.568L10.78 5.888l-9.12 25.06 18.447 19.484 26.657-3.068 9.12-25.058L37.894 1.568zm17.992 20.738L29 26 10.78 5.889m35.984 41.475L29 26 1.66 30.947"
|
||||
stroke="#171917"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Deco8(props) {
|
||||
return (
|
||||
<svg width={146} height={146} viewBox="0 0 146 146" {...props}>
|
||||
<g transform="translate(1 1)" fill="none" fillRule="evenodd">
|
||||
<circle fillOpacity={0.8} fill="#FFF" cx={72} cy={72} r={72} />
|
||||
<path
|
||||
d="M72 144c39.765 0 72-32.235 72-72S111.765 0 72 0 0 32.235 0 72s32.235 72 72 72zm36-9.646C90.781 144.295 60.705 124.437 40.823 90 20.941 55.563 18.781 19.587 36 9.646"
|
||||
stroke="#171917"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M36.094 9.578L36 9.646C18.781 19.587 20.94 55.563 40.823 90c19.882 34.437 49.958 54.295 67.177 44.354l.045-.013C97.445 140.484 85.133 144 72 144c-39.765 0-72-32.235-72-72C0 45.311 14.521 22.014 36.094 9.578z"
|
||||
fill="#171917"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function Discord({ className }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 32 36" width={32} height={36} xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M3.746 0h24.49a3.768 3.768 0 013.757 3.524l.007.198V36l-3.947-3.395-2.212-2.015-2.339-2.142.969 3.322H3.746c-1.998 0-3.637-1.564-3.74-3.524L0 28.048V3.722C0 1.736 1.575.108 3.548.005L3.746 0h24.49zm9.613 8.623l-.236-.217c-.374.005-2.658.111-5.064 1.887 0 0-2.631 4.702-2.631 10.494 0 0 1.535 2.614 5.574 2.741 0 0 .676-.799 1.224-1.489-2.32-.69-3.198-2.124-3.198-2.124s.183.127.512.309c.018 0 .036.018.073.036.055.037.11.055.164.091.457.254.914.454 1.334.617.75.309 1.645.581 2.687.78 1.37.255 2.979.346 4.733.019.86-.163 1.736-.4 2.65-.78.64-.237 1.352-.582 2.102-1.072 0 0-.914 1.47-3.308 2.142.548.672 1.206 1.453 1.206 1.453 4.039-.127 5.574-2.741 5.574-2.723 0-5.792-2.632-10.494-2.632-10.494-2.389-1.776-4.687-1.882-5.063-1.887h-.054l-.256.29c3.107.926 4.551 2.287 4.551 2.287a15.265 15.265 0 00-5.5-1.724 15.565 15.565 0 00-3.692.036c-.11 0-.202.018-.311.036-.64.073-2.193.29-4.149 1.144-.676.29-1.078.508-1.078.508l.017-.015c.166-.152 1.585-1.391 4.477-2.26l.294-.085-.183-.218zm5.995 6.481c1.023 0 1.864.89 1.864 1.997 0 1.108-.823 1.997-1.864 1.997-1.024 0-1.865-.89-1.865-1.997 0-1.107.823-1.997 1.865-1.997zm-6.671 0c1.042 0 1.882.89 1.864 1.997 0 1.108-.822 1.997-1.864 1.997-1.023 0-1.864-.89-1.864-1.997 0-1.107.822-1.997 1.864-1.997z"
|
||||
fill="currentColor"
|
||||
fillRule="nonzero"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Discord.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,21 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function DoubleRight({ className }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 12 12" width={12} height={12} xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M1 1l5 5-5 5M6 1l5 5-5 5"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
DoubleRight.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function DownArrow(props) {
|
||||
return (
|
||||
<svg width={12} height={13} viewBox="0 0 12 13" {...props}>
|
||||
<path
|
||||
d="M6 1v11M1 7l5 5 5-5"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function Download({ className }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 34 46" width={34} height={46} xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M5 33H3a2 2 0 01-2-2V3a2 2 0 012-2h16l14 14v16a2 2 0 01-2 2h-2 0"
|
||||
stroke="#171917"
|
||||
strokeWidth="2"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M17 45c6.627 0 12-5.373 12-12s-5.373-12-12-12S5 26.373 5 33s5.373 12 12 12zm-5-12l5 5 5-5m-5 5V27"
|
||||
stroke="#57B560"
|
||||
strokeWidth="2"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path d="M19 1l14 14H21a2 2 0 01-2-2V1z" fill="#171917" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Download.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function File(props) {
|
||||
return (
|
||||
<svg viewBox="0 0 36 40" width="36" height="40" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M35.5 16.207L19.793.5H2A1.5 1.5 0 00.5 2v36A1.5 1.5 0 002 39.5h32a1.5 1.5 0 001.5-1.5V16.207z"
|
||||
stroke="#C5CEC7"
|
||||
fill="#FFF"
|
||||
/>
|
||||
<path d="M20 1l15 15H22a2 2 0 01-2-2V1z" fill="#C5CEC7" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function FileCheck(props) {
|
||||
return (
|
||||
<svg width={38} height={42} viewBox="0 0 38 42" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M3 1h18l16 16v22a2 2 0 01-2 2H3a2 2 0 01-2-2V3a2 2 0 012-2zm12 24l3 3 5-5"
|
||||
stroke="#57B560"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path d="M21 2l15 15H23a2 2 0 01-2-2V2z" fill="#57B560" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function FileError(props) {
|
||||
return (
|
||||
<svg width={38} height={42} viewBox="0 0 38 42" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M3 1h18l16 16v22a2 2 0 01-2 2H3a2 2 0 01-2-2V3a2 2 0 012-2zm15 21v7m0 2v2"
|
||||
stroke="#E65C5C"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path d="M21 2l15 15H23a2 2 0 01-2-2V2z" fill="#E65C5C" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Folder(props) {
|
||||
return (
|
||||
<svg width={14} height={12} viewBox="0 0 14 12" {...props}>
|
||||
<path
|
||||
d="M2 1h3.586a1 1 0 01.707.293l1.414 1.414A1 1 0 008.414 3H12a1 1 0 011 1v6a1 1 0 01-1 1H2a1 1 0 01-1-1V2a1 1 0 011-1z"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function FooterCube(props) {
|
||||
return (
|
||||
<svg width={263} height={258} viewBox="0 0 263 258" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path fill="#343734" d="M132 129L1.726 176.77l-.058.329 107.758 79.926 128.596-38.25.057-.329z" />
|
||||
<path
|
||||
d="M154.574.975L24.821 45.791 1.668 177.1l107.758 79.926 128.596-38.25 23.153-131.308L154.575.975zm106.6 86.492L132 129 24.82 45.791m213.202 172.983L132 129 1.668 177.099"
|
||||
stroke="#343734"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function FooterOrb(props) {
|
||||
return (
|
||||
<svg width={26} height={26} viewBox="0 0 26 26" {...props}>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M2.604 18.997c1.66 2.873 7.656 2.513 13.396-.8C21.74 14.881 25.05 9.87 23.392 7A11.919 11.919 0 0125 13c0 6.627-5.373 12-12 12a11.995 11.995 0 01-10.396-6.003z"
|
||||
fill="#343734"
|
||||
/>
|
||||
<path
|
||||
d="M25 13c0-6.627-5.373-12-12-12S1 6.373 1 13s5.373 12 12 12 12-5.373 12-12zm-1.608-6C25.05 9.87 21.74 14.882 16 18.196S4.265 21.87 2.608 19"
|
||||
stroke="#343734"
|
||||
strokeWidth={2}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function Github({ className }) {
|
||||
return (
|
||||
<svg viewBox="0 0 32 32" width={32} height={32} className={className} xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M0 16.406c0 7.247 4.584 13.397 10.942 15.566.8.151 1.092-.356 1.092-.79 0-.39-.013-1.422-.021-2.79-4.45.99-5.39-2.2-5.39-2.2-.728-1.895-1.777-2.4-1.777-2.4-1.452-1.018.11-.997.11-.997 1.606.116 2.451 1.691 2.451 1.691 1.428 2.507 3.745 1.783 4.657 1.363.145-1.06.559-1.783 1.015-2.194-3.552-.414-7.288-1.82-7.288-8.107 0-1.792.624-3.256 1.647-4.403-.164-.415-.713-2.083.158-4.34 0 0 1.343-.443 4.399 1.68A14.975 14.975 0 0116 7.933c1.36.006 2.728.188 4.007.552 3.054-2.123 4.395-1.68 4.395-1.68.873 2.257.324 3.925.16 4.34 1.025 1.147 1.644 2.611 1.644 4.403 0 6.301-3.74 7.688-7.305 8.095.575.507 1.085 1.508 1.085 3.038 0 2.193-.018 3.963-.018 4.5 0 .44.288.949 1.1.789C27.42 29.797 32 23.652 32 16.406 32 7.345 24.836 0 15.999 0 7.164 0 0 7.345 0 16.406z"
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Github.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Loading(props) {
|
||||
return (
|
||||
<svg width={26} height={26} viewBox="0 0 26 26" {...props}>
|
||||
<path
|
||||
d="M13 25c6.627 0 12-5.373 12-12S19.627 1 13 1 1 6.373 1 13"
|
||||
stroke="#171917"
|
||||
strokeWidth={2}
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function Logo({ className }) {
|
||||
return (
|
||||
<svg viewBox="0 0 66 66" width={66} height={66} className={className} xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M52 52V33.287C52 22.784 43.599 14.052 33.096 14 22.544 13.948 13.948 22.543 14 33.096 14.052 43.599 22.784 52 33.287 52H52zM33 1c17.673 0 32 14.326 32 32v32H33C15.326 65 1 50.673 1 33 1 15.326 15.326 1 33 1z"
|
||||
fillRule="nonzero"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Logo.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,18 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function LogoSolid({ className }) {
|
||||
return (
|
||||
<svg className={className} width={32} height={32} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M26 26v-9.849C26 10.623 21.578 6.027 16.05 6 10.497 5.973 5.973 10.496 6 16.05 6.028 21.578 10.623 26 16.151 26H26zM16 0c8.837 0 16 7.163 16 16v16H16C7.163 32 0 24.837 0 16S7.163 0 16 0z"
|
||||
fill="currentColor"
|
||||
fillRule="nonzero"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
LogoSolid.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function Pyramid({ className }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 38 38" width={38} height={38} xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path fill="currentColor" d="M19 25L1 31l18 6 18-6z" />
|
||||
<path
|
||||
d="M19 1L1 31l18 6 18-6L19 1zm0 0v36m18-6l-18-6-18 6"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Pyramid.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,13 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function Skynet(props) {
|
||||
return (
|
||||
<svg width={169} height={39} viewBox="0 0 169 39" {...props}>
|
||||
<path
|
||||
d="M160.701 31.245c-2.736 0-4.788-.706-6.156-2.118-1.369-1.411-2.053-3.424-2.053-6.039V2.674h7.487v6.33H169v6.15h-9.02v7.355c0 1.753.886 2.63 2.66 2.63h6.134v6.106h-8.073zm-24.942 0c-1.744 0-3.352-.268-4.826-.803-1.473-.535-2.751-1.292-3.833-2.273a10.275 10.275 0 01-2.526-3.521c-.602-1.367-.902-2.882-.902-4.546 0-1.635.3-3.135.902-4.502a10.275 10.275 0 012.526-3.521c1.082-.98 2.36-1.738 3.833-2.273 1.474-.535 3.082-.803 4.826-.803h5.728c1.293 0 2.42.179 3.383.535.962.357 1.767.847 2.413 1.471a5.823 5.823 0 011.443 2.251c.316.877.474 1.835.474 2.875 0 1.961-.571 3.432-1.714 4.412-1.143.981-3.022 1.471-5.638 1.471h-8.028v-4.056h6.45c1.172 0 1.759-.52 1.759-1.56 0-1.1-.572-1.649-1.714-1.649h-4.6c-1.354 0-2.451.46-3.293 1.382-.842.921-1.263 2.228-1.263 3.922s.42 2.964 1.263 3.811c.842.847 1.94 1.27 3.292 1.27h12.268v6.107H135.76zm-22.867 0V19.567c0-2.526-1.308-3.789-3.924-3.789h-7.532v15.467H93.86V9.003h15.29c3.728 0 6.54.922 8.434 2.764 1.894 1.842 2.841 4.457 2.841 7.844v11.634h-7.532zM67.293 39v-6.418h2.39c.963 0 1.715-.193 2.256-.58a4.58 4.58 0 001.308-1.426L62.422 9.003h7.623l6.675 14.263 6.855-14.263h7.668L78.749 33.43c-.48.95-.984 1.775-1.51 2.473a7.85 7.85 0 01-1.782 1.739 7.11 7.11 0 01-2.233 1.025c-.827.223-1.781.334-2.864.334h-3.067zm-14.207-7.755l-7.713-9.316a4.647 4.647 0 01-.54-.914 2.306 2.306 0 01-.181-.913v-.535c0-.654.225-1.278.676-1.872l7.487-8.692h8.48l-9.02 10.787 9.47 11.455h-8.66zm-17.41 0V0h7.532v31.245h-7.532zm-35.315 0v-7.488h21.92c.571 0 1.037-.171 1.398-.513.36-.342.541-.825.541-1.449 0-.624-.18-1.114-.541-1.47-.36-.357-.827-.535-1.398-.535H9.38c-1.353 0-2.608-.216-3.766-.647-1.157-.43-2.15-1.025-2.976-1.782a8.005 8.005 0 01-1.94-2.742C.233 13.55 0 12.361 0 11.054 0 9.746.233 8.55.7 7.466A8.184 8.184 0 012.638 4.68c.826-.773 1.819-1.367 2.976-1.783 1.158-.416 2.413-.624 3.766-.624h22.281v7.444H9.742c-.571 0-1.03.163-1.375.49-.346.327-.52.802-.52 1.426 0 .594.174 1.07.52 1.426.345.357.804.535 1.375.535h12.9c1.383 0 2.646.216 3.788.647a9.097 9.097 0 012.977 1.805 8.038 8.038 0 011.962 2.785c.466 1.085.7 2.266.7 3.544 0 1.337-.234 2.548-.7 3.632a8.267 8.267 0 01-1.962 2.808 8.62 8.62 0 01-2.977 1.806c-1.142.416-2.405.624-3.788.624H.36z"
|
||||
fill="#57B560"
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function SmallOrb({ className }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 18 18" width={18} height={18} xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M9 17A8 8 0 109 1a8 8 0 000 16zm4-1.072C11.087 17.033 7.745 14.826 5.536 11 3.326 7.174 3.086 3.176 5 2.072"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
SmallOrb.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,47 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default function TopSwoosh({ ...props }) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
width="622"
|
||||
viewBox="0 0 622 151"
|
||||
{...props}
|
||||
>
|
||||
<defs>
|
||||
<filter id="a" width="103.4%" height="103.4%" x="-1.7%" y="-1.7%" filterUnits="objectBoundingBox">
|
||||
<feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"></feMorphology>
|
||||
<feOffset in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feMorphology in="SourceAlpha" radius="1" result="shadowInner"></feMorphology>
|
||||
<feOffset in="shadowInner" result="shadowInner"></feOffset>
|
||||
<feComposite
|
||||
in="shadowOffsetOuter1"
|
||||
in2="shadowInner"
|
||||
operator="out"
|
||||
result="shadowOffsetOuter1"
|
||||
></feComposite>
|
||||
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="4"></feGaussianBlur>
|
||||
<feColorMatrix
|
||||
in="shadowBlurOuter1"
|
||||
values="0 0 0 0 0.341176471 0 0 0 0 0.709803922 0 0 0 0 0.376470588 0 0 0 0.3 0"
|
||||
></feColorMatrix>
|
||||
</filter>
|
||||
<path
|
||||
id="b"
|
||||
d="M384 768c212.077 0 384-171.923 384-384S596.077 0 384 0 0 171.923 0 384s171.923 384 384 384zm192-51.446c-91.832 53.02-252.238-52.89-358.277-236.554C111.684 296.336 100.168 104.466 192 51.446"
|
||||
></path>
|
||||
</defs>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<g strokeLinejoin="round" transform="translate(-73 -626)">
|
||||
<use fill="#000" filter="url(#a)" xlinkHref="#b"></use>
|
||||
<use stroke="#57B560" strokeWidth="2" xlinkHref="#b"></use>
|
||||
</g>
|
||||
<path
|
||||
fill="#57B560"
|
||||
d="M119.706-574.998l-.78.524C27.13-521.461 38.642-329.612 144.64-145.968 250.637 37.676 410.982 143.572 502.779 90.559l.218-.052C446.488 123.254 380.859 142 310.853 142 98.857 142-73-29.904-73-241.957c0-142.44 77.542-266.765 192.706-333.04z"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function Twitter({ className }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 32 32" width={32} height={36} xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M28 0a4 4 0 014 4v24a4 4 0 01-4 4H4a4 4 0 01-4-4V4a4 4 0 014-4h24zm-8.7 10.182c-1.73 0-3.131 1.48-3.131 3.304 0 .26.026.512.08.753-2.604-.138-4.912-1.452-6.459-3.453a3.436 3.436 0 00-.424 1.662c0 1.146.554 2.158 1.394 2.751a3.021 3.021 0 01-1.42-.413v.04c0 1.603 1.08 2.938 2.515 3.241-.264.078-.54.116-.827.116-.201 0-.398-.02-.589-.058.399 1.312 1.556 2.269 2.927 2.294a6.083 6.083 0 01-4.639 1.37 8.544 8.544 0 004.803 1.484c5.765 0 8.915-5.036 8.915-9.403 0-.144-.002-.286-.008-.427A6.55 6.55 0 0024 11.73a6.005 6.005 0 01-1.8.52 3.28 3.28 0 001.378-1.827 6.076 6.076 0 01-1.99.802 3.05 3.05 0 00-2.287-1.044z"
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Twitter.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,64 +0,0 @@
|
|||
import Logo from "./Logo";
|
||||
import Download from "./Download";
|
||||
import DoubleRight from "./DoubleRight";
|
||||
import Github from "./Github";
|
||||
import Twitter from "./Twitter";
|
||||
import Discord from "./Discord";
|
||||
import Arrow from "./Arrow";
|
||||
import Cylinder from "./Cylinder";
|
||||
import SmallOrb from "./SmallOrb";
|
||||
import Pyramid from "./Pyramid";
|
||||
import LogoSolid from "./LogoSolid";
|
||||
import File from "./File";
|
||||
import FileCheck from "./FileCheck";
|
||||
import FileError from "./FileError";
|
||||
import Loading from "./Loading";
|
||||
import Skynet from "./Skynet";
|
||||
import Copy from "./Copy";
|
||||
import FooterOrb from "./FooterOrb";
|
||||
import FooterCube from "./FooterCube";
|
||||
import Built from "./Built";
|
||||
import DownArrow from "./DownArrow";
|
||||
import Folder from "./Folder";
|
||||
|
||||
import Deco1 from "./Deco1";
|
||||
import Deco2 from "./Deco2";
|
||||
import Deco3 from "./Deco3";
|
||||
import Deco4 from "./Deco4";
|
||||
import Deco5 from "./Deco5";
|
||||
import Deco6 from "./Deco6";
|
||||
import Deco7 from "./Deco7";
|
||||
import Deco8 from "./Deco8";
|
||||
|
||||
export {
|
||||
Logo,
|
||||
Download,
|
||||
DoubleRight,
|
||||
Github,
|
||||
Twitter,
|
||||
Discord,
|
||||
Arrow,
|
||||
Cylinder,
|
||||
SmallOrb,
|
||||
Pyramid,
|
||||
LogoSolid,
|
||||
File,
|
||||
FileCheck,
|
||||
FileError,
|
||||
Loading,
|
||||
Copy,
|
||||
Skynet,
|
||||
FooterOrb,
|
||||
FooterCube,
|
||||
Built,
|
||||
DownArrow,
|
||||
Folder,
|
||||
Deco1,
|
||||
Deco2,
|
||||
Deco3,
|
||||
Deco4,
|
||||
Deco5,
|
||||
Deco6,
|
||||
Deco7,
|
||||
Deco8,
|
||||
};
|
|
@ -1,47 +0,0 @@
|
|||
// Colors
|
||||
$white: #fff;
|
||||
$white90: rgba(255, 255, 255, 0.9);
|
||||
$white80: rgba(255, 255, 255, 0.8);
|
||||
$white70: rgba(255, 255, 255, 0.7);
|
||||
$white60: rgba(255, 255, 255, 0.6);
|
||||
$white50: rgba(255, 255, 255, 0.5);
|
||||
$white40: rgba(255, 255, 255, 0.4);
|
||||
$white30: rgba(255, 255, 255, 0.3);
|
||||
$white20: rgba(255, 255, 255, 0.2);
|
||||
$white10: rgba(255, 255, 255, 0.1);
|
||||
|
||||
$black: #000;
|
||||
$black90: rgba(0, 0, 0, 0.9);
|
||||
$black80: rgba(0, 0, 0, 0.8);
|
||||
$black70: rgba(0, 0, 0, 0.7);
|
||||
$black60: rgba(0, 0, 0, 0.6);
|
||||
$black50: rgba(0, 0, 0, 0.5);
|
||||
$black40: rgba(0, 0, 0, 0.4);
|
||||
$black30: rgba(0, 0, 0, 0.3);
|
||||
$black20: rgba(0, 0, 0, 0.2);
|
||||
$black10: rgba(0, 0, 0, 0.1);
|
||||
|
||||
$greenBg: #f1f7f2;
|
||||
$green: #57b560;
|
||||
$greenHover: #4ea156;
|
||||
|
||||
$darkGray: #171917;
|
||||
$gray: #5a5e5b;
|
||||
$lightGray: #969a97;
|
||||
$red: #e65c5c;
|
||||
|
||||
// fonts
|
||||
$font: "Metropolis", Helvetica, Arial, Sans-Serif;
|
||||
$font2: "Metropolis", Helvetica, Arial, Sans-Serif;
|
||||
|
||||
// Breakpoints
|
||||
$tinybp: 374px;
|
||||
$smallbp: 500px;
|
||||
$smbp: 640px;
|
||||
$mediumbp: 680px;
|
||||
$largebp: 840px;
|
||||
$xlargebp: 1100px;
|
||||
|
||||
// Transitions
|
||||
$fadeOff: left 0s 0.15s, opacity 0.15s;
|
||||
$fadeOn: left 0s, opacity 0.15s;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue