diff --git a/.env b/.env
index 7e40b56..297d271 100644
--- a/.env
+++ b/.env
@@ -24,3 +24,4 @@ REACT_APP_WHO_API_KEY=''
# API_CORS_ORIGIN='*' # Enable CORS, by setting your allowed hostname(s) here
# API_ENABLE_RATE_LIMIT='true' # Enable rate limiting for the API
# REACT_APP_API_ENDPOINT='/api' # The endpoint for the API (can be local or remote)
+# ENABLE_ANALYTICS='false' # Enable Plausible hit counter for the frontend
diff --git a/.github/README.md b/.github/README.md
index 3573edc..abf0619 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -911,128 +911,193 @@ Credit to the following users for contributing to Web-Check
@@ -1042,178 +1107,177 @@ Huge thanks to these wonderful people, who sponsor me on GitHub, their support h
diff --git a/.github/workflows/credits.yml b/.github/workflows/credits.yml
index 0259921..0056930 100644
--- a/.github/workflows/credits.yml
+++ b/.github/workflows/credits.yml
@@ -12,9 +12,9 @@ jobs:
name: Inserts Sponsors 💓
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Updates readme with sponsors
- uses: JamesIves/github-sponsors-readme-action@1.0.5
+ uses: JamesIves/github-sponsors-readme-action@v1
with:
token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
file: .github/README.md
@@ -25,7 +25,7 @@ jobs:
name: Inserts Contributors 💓
steps:
- name: Updates readme with contributors
- uses: akhilmhdh/contributors-readme-action@v2.3.4
+ uses: akhilmhdh/contributors-readme-action@v2.3.10
env:
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
with:
diff --git a/.github/workflows/deploy-aws.yml b/.github/workflows/deploy-aws.yml
index 3f53ab0..971858a 100644
--- a/.github/workflows/deploy-aws.yml
+++ b/.github/workflows/deploy-aws.yml
@@ -19,15 +19,15 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Setup Node.js
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v4
with:
node-version: 16
- name: Cache node_modules
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
@@ -35,7 +35,7 @@ jobs:
${{ runner.os }}-yarn-
- name: Create GitHub deployment for API
- uses: chrnorm/deployment-action@releases/v1
+ uses: chrnorm/deployment-action@releases/v2
id: deployment_api
with:
token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
@@ -56,7 +56,7 @@ jobs:
- name: Update GitHub deployment status (API)
if: always()
- uses: chrnorm/deployment-status@releases/v1
+ uses: chrnorm/deployment-status@v2
with:
token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
state: "${{ job.status }}"
@@ -68,15 +68,15 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Setup Node.js
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v4
with:
node-version: 16
- name: Cache node_modules
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
@@ -84,7 +84,7 @@ jobs:
${{ runner.os }}-yarn-
- name: Create GitHub deployment for Frontend
- uses: chrnorm/deployment-action@releases/v1
+ uses: chrnorm/deployment-action@v2
id: deployment_frontend
with:
token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
@@ -97,7 +97,7 @@ jobs:
yarn build
- name: Setup AWS
- uses: aws-actions/configure-aws-credentials@v1
+ uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -109,7 +109,7 @@ jobs:
run: aws s3 sync ./build/ s3://$AWS_S3_BUCKET/ --delete
- name: Invalidate CloudFront cache
- uses: chetan/invalidate-cloudfront-action@v2.4
+ uses: chetan/invalidate-cloudfront-action@v2
env:
DISTRIBUTION: E30XKAM2TG9FD8
PATHS: '/*'
@@ -119,7 +119,7 @@ jobs:
- name: Update GitHub deployment status (Frontend)
if: always()
- uses: chrnorm/deployment-status@releases/v1
+ uses: chrnorm/deployment-status@v2
with:
token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
state: "${{ job.status }}"
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index f335f59..53dcead 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -23,14 +23,14 @@ jobs:
docker:
runs-on: ubuntu-latest
steps:
- - name: Checkout
+ - name: Checkout 🛎️
uses: actions/checkout@v2
- - name: Extract tag name
+ - name: Extract tag name 🏷️
shell: bash
run: echo "GIT_TAG=$(echo ${GITHUB_REF#refs/tags/} | sed 's/\//_/g')" >> $GITHUB_ENV
- - name: Compute tags
+ - name: Compute tags 🔖
id: compute-tags
run: |
if [[ "${{ github.ref }}" == "refs/heads/master" ]]; then
@@ -41,27 +41,27 @@ jobs:
echo "DOCKERHUB_TAG=${DOCKERHUB_REGISTRY}/${DOCKER_USER}/${IMAGE_NAME}:${GIT_TAG}" >> $GITHUB_ENV
fi
- - name: Set up QEMU
+ - name: Set up QEMU 🐧
uses: docker/setup-qemu-action@v1
- - name: Set up Docker Buildx
+ - name: Set up Docker Buildx 🐳
uses: docker/setup-buildx-action@v1
- - name: Login to GitHub Container Registry
+ - name: Login to GitHub Container Registry 🔑
uses: docker/login-action@v1
with:
registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- - name: Login to DockerHub
+ - name: Login to DockerHub 🔑
uses: docker/login-action@v1
with:
registry: ${{ env.DOCKERHUB_REGISTRY }}
username: ${{ env.DOCKER_USER }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- - name: Build and push Docker images
+ - name: Build and push Docker images 🛠️
uses: docker/build-push-action@v2
with:
context: .
diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml
index 44c11f4..5bf3c37 100644
--- a/.github/workflows/mirror.yml
+++ b/.github/workflows/mirror.yml
@@ -8,7 +8,7 @@ jobs:
codeberg:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: pixta-dev/repository-mirroring-action@v1
with:
diff --git a/.gitignore b/.gitignore
index 9c077d8..d818df7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,12 +9,14 @@
/build/
# ------------------------
-# DEPLOYMENT
+# BUILT FILES
# ------------------------
+dist/
.vercel/
.netlify/
.webpack/
.serverless/
+.astro/
# ------------------------
# DEPENDENCIES
diff --git a/Dockerfile b/Dockerfile
index 7a95405..a01ddd8 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Specify the Node.js version to use
-ARG NODE_VERSION=16
+ARG NODE_VERSION=21
# Specify the Debian version to use, the default is "bullseye"
ARG DEBIAN_VERSION=bullseye
@@ -30,7 +30,7 @@ COPY package.json yarn.lock ./
# Run yarn install to install dependencies and clear yarn cache
RUN apt-get update && \
- yarn install --production --frozen-lockfile --network-timeout 100000 && \
+ yarn install --frozen-lockfile --network-timeout 100000 && \
rm -rf /app/node_modules/.cache
# Copy all files to working directory
@@ -59,4 +59,4 @@ EXPOSE ${PORT:-3000}
ENV CHROME_PATH='/usr/bin/chromium'
# Define the command executed when the container starts and start the server.js of the Node.js application
-CMD ["yarn", "serve"]
\ No newline at end of file
+CMD ["yarn", "start"]
diff --git a/api/_common/middleware.js b/api/_common/middleware.js
index a80e16e..b00f3b6 100644
--- a/api/_common/middleware.js
+++ b/api/_common/middleware.js
@@ -2,13 +2,47 @@ const normalizeUrl = (url) => {
return url.startsWith('http') ? url : `https://${url}`;
};
+// If present, set a shorter timeout for API requests
+const TIMEOUT = process.env.API_TIMEOUT_LIMIT ? parseInt(process.env.API_TIMEOUT_LIMIT, 10) : 60000;
+
+// If present, set CORS allowed origins for responses
+const ALLOWED_ORIGINS = process.env.API_CORS_ORIGIN || '*';
+
+// Set the platform currently being used
+let PLATFORM = 'NETLIFY';
+if (process.env.PLATFORM) { PLATFORM = process.env.PLATFORM.toUpperCase(); }
+else if (process.env.VERCEL) { PLATFORM = 'VERCEL'; }
+else if (process.env.WC_SERVER) { PLATFORM = 'NODE'; }
+
+// Define the headers to be returned with each response
const headers = {
- 'Access-Control-Allow-Origin': process.env.API_CORS_ORIGIN || '*',
+ 'Access-Control-Allow-Origin': ALLOWED_ORIGINS,
'Access-Control-Allow-Credentials': true,
'Content-Type': 'application/json;charset=UTF-8',
};
+
+const timeoutErrorMsg = 'You can re-trigger this request, by clicking "Retry"\n'
++ 'If you\'re running your own instance of Web Check, then you can '
++ 'resolve this issue, by increasing the timeout limit in the '
++ '`API_TIMEOUT_LIMIT` environmental variable to a higher value (in milliseconds), '
++ 'or if you\'re hosting on Vercel increase the maxDuration in vercel.json.\n\n'
++ `The public instance currently has a lower timeout of ${TIMEOUT}ms `
++ 'in order to keep running costs affordable, so that Web Check can '
++ 'remain freely available for everyone.';
+
+// A middleware function used by all API routes on all platforms
const commonMiddleware = (handler) => {
+
+ // Create a timeout promise, to throw an error if a request takes too long
+ const createTimeoutPromise = (timeoutMs) => {
+ return new Promise((_, reject) => {
+ setTimeout(() => {
+ reject(new Error(`Request timed-out after ${timeoutMs} ms`));
+ }, timeoutMs);
+ });
+ };
+
// Vercel
const vercelHandler = async (request, response) => {
const queryParams = request.query || {};
@@ -21,7 +55,12 @@ const commonMiddleware = (handler) => {
const url = normalizeUrl(rawUrl);
try {
- const handlerResponse = await handler(url, request);
+ // Race the handler against the timeout
+ const handlerResponse = await Promise.race([
+ handler(url, request),
+ createTimeoutPromise(TIMEOUT)
+ ]);
+
if (handlerResponse.body && handlerResponse.statusCode) {
response.status(handlerResponse.statusCode).json(handlerResponse.body);
} else {
@@ -30,7 +69,12 @@ const commonMiddleware = (handler) => {
);
}
} catch (error) {
- response.status(500).json({ error: error.message });
+ let errorCode = 500;
+ if (error.message.includes('timed-out') || response.statusCode === 504) {
+ errorCode = 408;
+ error.message = `${error.message}\n\n${timeoutErrorMsg}`;
+ }
+ response.status(errorCode).json({ error: error.message });
}
};
@@ -51,7 +95,12 @@ const commonMiddleware = (handler) => {
const url = normalizeUrl(rawUrl);
try {
- const handlerResponse = await handler(url, event, context);
+ // Race the handler against the timeout
+ const handlerResponse = await Promise.race([
+ handler(url, event, context),
+ createTimeoutPromise(TIMEOUT)
+ ]);
+
if (handlerResponse.body && handlerResponse.statusCode) {
callback(null, handlerResponse);
} else {
@@ -71,12 +120,12 @@ const commonMiddleware = (handler) => {
};
// The format of the handlers varies between platforms
- // E.g. Netlify + AWS expect Lambda functions, but Vercel or Node needs standard handler
- const platformEnv = (process.env.PLATFORM || '').toUpperCase(); // Has user set platform manually?
-
- const nativeMode = (['VERCEL', 'NODE'].includes(platformEnv) || process.env.VERCEL || process.env.WC_SERVER);
-
+ const nativeMode = (['VERCEL', 'NODE'].includes(PLATFORM));
return nativeMode ? vercelHandler : netlifyHandler;
};
-module.exports = commonMiddleware;
+if (PLATFORM === 'NETLIFY') {
+ module.exports = commonMiddleware;
+}
+
+export default commonMiddleware;
diff --git a/api/archives.js b/api/archives.js
index 6c7cb48..7c6ae99 100644
--- a/api/archives.js
+++ b/api/archives.js
@@ -1,5 +1,5 @@
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import middleware from './_common/middleware.js';
const convertTimestampToDate = (timestamp) => {
const [year, month, day, hour, minute, second] = [
@@ -46,7 +46,7 @@ const getScanFrequency = (firstScan, lastScan, totalScans, changeCount) => {
};
};
-const getWaybackData = async (url) => {
+const wayBackHandler = async (url) => {
const cdxUrl = `https://web.archive.org/cdx/search/cdx?url=${url}&output=json&fl=timestamp,statuscode,digest,length,offset`;
try {
@@ -80,5 +80,5 @@ const getWaybackData = async (url) => {
}
};
-module.exports = middleware(getWaybackData);
-module.exports.handler = middleware(getWaybackData);
+export const handler = middleware(wayBackHandler);
+export default handler;
diff --git a/api/block-lists.js b/api/block-lists.js
index 82f6b1c..34d46a1 100644
--- a/api/block-lists.js
+++ b/api/block-lists.js
@@ -1,6 +1,6 @@
-const dns = require('dns');
-const { URL } = require('url');
-const middleware = require('./_common/middleware');
+import dns from 'dns';
+import { URL } from 'url';
+import middleware from './_common/middleware.js';
const DNS_SERVERS = [
{ name: 'AdGuard', ip: '176.103.130.130' },
@@ -94,12 +94,12 @@ const checkDomainAgainstDnsServers = async (domain) => {
return results;
};
-const handler = async (url) => {
+export const blockListHandler = async (url) => {
const domain = new URL(url).hostname;
const results = await checkDomainAgainstDnsServers(domain);
return { blocklists: results };
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(blockListHandler);
+export default handler;
diff --git a/api/carbon.js b/api/carbon.js
index a2c5210..7db750c 100644
--- a/api/carbon.js
+++ b/api/carbon.js
@@ -1,7 +1,7 @@
-const https = require('https');
-const middleware = require('./_common/middleware');
+import https from 'https';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const carbonHandler = async (url) => {
// First, get the size of the website's HTML
const getHtmlSize = (url) => new Promise((resolve, reject) => {
@@ -48,5 +48,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(carbonHandler);
+export default handler;
diff --git a/api/cookies.js b/api/cookies.js
index 1f10470..a86ccb6 100644
--- a/api/cookies.js
+++ b/api/cookies.js
@@ -1,6 +1,6 @@
-const axios = require('axios');
-const puppeteer = require('puppeteer');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import puppeteer from 'puppeteer';
+import middleware from './_common/middleware.js';
const getPuppeteerCookies = async (url) => {
const browser = await puppeteer.launch({
@@ -21,7 +21,7 @@ const getPuppeteerCookies = async (url) => {
}
};
-const handler = async (url) => {
+const cookieHandler = async (url) => {
let headerCookies = null;
let clientCookies = null;
@@ -54,5 +54,5 @@ const handler = async (url) => {
return { headerCookies, clientCookies };
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(cookieHandler);
+export default handler;
diff --git a/api/dns-server.js b/api/dns-server.js
index c9af720..29ac34f 100644
--- a/api/dns-server.js
+++ b/api/dns-server.js
@@ -1,9 +1,8 @@
-const dns = require('dns');
-const dnsPromises = dns.promises;
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import { promises as dnsPromises, lookup } from 'dns';
+import axios from 'axios';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const dnsHandler = async (url) => {
try {
const domain = url.replace(/^(?:https?:\/\/)?/i, "");
const addresses = await dnsPromises.resolve4(domain);
@@ -41,5 +40,7 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+
+export const handler = middleware(dnsHandler);
+export default handler;
+
diff --git a/api/dns.js b/api/dns.js
index 34d6c02..e01a8a8 100644
--- a/api/dns.js
+++ b/api/dns.js
@@ -1,8 +1,8 @@
-const dns = require('dns');
-const util = require('util');
-const middleware = require('./_common/middleware');
+import dns from 'dns';
+import util from 'util';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const dnsHandler = async (url) => {
let hostname = url;
// Handle URLs by extracting hostname
@@ -51,5 +51,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(dnsHandler);
+export default handler;
diff --git a/api/dnssec.js b/api/dnssec.js
index 1ce4bfb..21f7510 100644
--- a/api/dnssec.js
+++ b/api/dnssec.js
@@ -1,7 +1,7 @@
-const https = require('https');
-const middleware = require('./_common/middleware'); // Make sure this path is correct
+import https from 'https';
+import middleware from './_common/middleware.js';
-const handler = async (domain) => {
+const dnsSecHandler = async (domain) => {
const dnsTypes = ['DNSKEY', 'DS', 'RRSIG'];
const records = {};
@@ -25,7 +25,11 @@ const handler = async (domain) => {
});
res.on('end', () => {
- resolve(JSON.parse(data));
+ try {
+ resolve(JSON.parse(data));
+ } catch (error) {
+ reject(new Error('Invalid JSON response'));
+ }
});
res.on('error', error => {
@@ -49,6 +53,5 @@ const handler = async (domain) => {
return records;
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
-
+export const handler = middleware(dnsSecHandler);
+export default handler;
diff --git a/api/features.js b/api/features.js
index 67e4c81..148a854 100644
--- a/api/features.js
+++ b/api/features.js
@@ -1,7 +1,7 @@
-const https = require('https');
-const middleware = require('./_common/middleware');
+import https from 'https';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const featuresHandler = async (url) => {
const apiKey = process.env.BUILT_WITH_API_KEY;
if (!url) {
@@ -45,5 +45,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(featuresHandler);
+export default handler;
diff --git a/api/firewall.js b/api/firewall.js
index 39afde3..bc46ba6 100644
--- a/api/firewall.js
+++ b/api/firewall.js
@@ -1,5 +1,5 @@
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import middleware from './_common/middleware.js';
const hasWaf = (waf) => {
return {
@@ -7,7 +7,7 @@ const hasWaf = (waf) => {
}
};
-const handler = async (url) => {
+const firewallHandler = async (url) => {
const fullUrl = url.startsWith('http') ? url : `http://${url}`;
try {
@@ -91,6 +91,14 @@ const handler = async (url) => {
return hasWaf('IBM WebSphere DataPower');
}
+ if (headers['server'] && headers['server'].includes('QRATOR')) {
+ return hasWaf('QRATOR WAF');
+ }
+
+ if (headers['server'] && headers['server'].includes('ddos-guard')) {
+ return hasWaf('DDoS-Guard WAF');
+ }
+
return {
hasWaf: false,
}
@@ -102,5 +110,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(firewallHandler);
+export default handler;
diff --git a/api/get-ip.js b/api/get-ip.js
index 303a0f1..aa7d058 100644
--- a/api/get-ip.js
+++ b/api/get-ip.js
@@ -1,5 +1,5 @@
-const dns = require('dns');
-const middleware = require('./_common/middleware');
+import dns from 'dns';
+import middleware from './_common/middleware.js';
const lookupAsync = (address) => {
return new Promise((resolve, reject) => {
@@ -13,11 +13,11 @@ const lookupAsync = (address) => {
});
};
-const handler = async (url) => {
+const ipHandler = async (url) => {
const address = url.replaceAll('https://', '').replaceAll('http://', '');
return await lookupAsync(address);
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(ipHandler);
+export default handler;
diff --git a/api/headers.js b/api/headers.js
index 84b179f..13c2792 100644
--- a/api/headers.js
+++ b/api/headers.js
@@ -1,7 +1,7 @@
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import middleware from './_common/middleware.js';
-const handler = async (url, event, context) => {
+const headersHandler = async (url, event, context) => {
try {
const response = await axios.get(url, {
validateStatus: function (status) {
@@ -15,5 +15,5 @@ const handler = async (url, event, context) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(headersHandler);
+export default handler;
diff --git a/api/hsts.js b/api/hsts.js
index d06bf1c..a98d4c0 100644
--- a/api/hsts.js
+++ b/api/hsts.js
@@ -1,7 +1,7 @@
-const https = require('https');
-const middleware = require('./_common/middleware');
+import https from 'https';
+import middleware from './_common/middleware.js';
-const handler = async (url, event, context) => {
+const hstsHandler = async (url, event, context) => {
const errorResponse = (message, statusCode = 500) => {
return {
statusCode: statusCode,
@@ -45,6 +45,5 @@ const handler = async (url, event, context) => {
});
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
-
+export const handler = middleware(hstsHandler);
+export default handler;
diff --git a/api/http-security.js b/api/http-security.js
index 2f8370a..764cb93 100644
--- a/api/http-security.js
+++ b/api/http-security.js
@@ -1,7 +1,7 @@
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const httpsSecHandler = async (url) => {
const fullUrl = url.startsWith('http') ? url : `http://${url}`;
try {
@@ -22,5 +22,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(httpsSecHandler);
+export default handler;
diff --git a/api/legacy-rank.js b/api/legacy-rank.js
index 19dd1bd..301cc2c 100644
--- a/api/legacy-rank.js
+++ b/api/legacy-rank.js
@@ -1,8 +1,8 @@
-const axios = require('axios');
-const unzipper = require('unzipper');
-const csv = require('csv-parser');
-const fs = require('fs');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import unzipper from 'unzipper';
+import csv from 'csv-parser';
+import fs from 'fs';
+import middleware from './_common/middleware.js';
// Should also work with the following sources:
// https://www.domcop.com/files/top/top10milliondomains.csv.zip
@@ -14,7 +14,7 @@ const middleware = require('./_common/middleware');
const FILE_URL = 'https://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip';
const TEMP_FILE_PATH = '/tmp/top-1m.csv';
-const handler = async (url) => {
+const rankHandler = async (url) => {
let domain = null;
try {
@@ -66,6 +66,5 @@ return new Promise((resolve, reject) => {
});
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
-
+export const handler = middleware(rankHandler);
+export default handler;
diff --git a/api/linked-pages.js b/api/linked-pages.js
index 60dd88f..e576d3a 100644
--- a/api/linked-pages.js
+++ b/api/linked-pages.js
@@ -1,9 +1,9 @@
-const axios = require('axios');
-const cheerio = require('cheerio');
-const urlLib = require('url');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import cheerio from 'cheerio';
+import urlLib from 'url';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const linkedPagesHandler = async (url) => {
const response = await axios.get(url);
const html = response.data;
const $ = cheerio.load(html);
@@ -33,17 +33,17 @@ const handler = async (url) => {
if (internalLinks.length === 0 && externalLinks.length === 0) {
return {
statusCode: 400,
- body: JSON.stringify({
+ body: {
skipped: 'No internal or external links found. '
+ 'This may be due to the website being dynamically rendered, using a client-side framework (like React), and without SSR enabled. '
+ 'That would mean that the static HTML returned from the HTTP request doesn\'t contain any meaningful content for Web-Check to analyze. '
+ 'You can rectify this by using a headless browser to render the page instead.',
- }),
+ },
};
}
return { internal: internalLinks, external: externalLinks };
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(linkedPagesHandler);
+export default handler;
diff --git a/api/mail-config.js b/api/mail-config.js
index 402fd67..1c8aff8 100644
--- a/api/mail-config.js
+++ b/api/mail-config.js
@@ -1,9 +1,10 @@
-const middleware = require('./_common/middleware');
+import dns from 'dns';
+import URL from 'url-parse';
+import middleware from './_common/middleware.js';
-const dns = require('dns').promises;
-const URL = require('url-parse');
+// TODO: Fix.
-const handler = async (url, event, context) => {
+const mailConfigHandler = async (url, event, context) => {
try {
const domain = new URL(url).hostname || new URL(url).pathname;
@@ -71,11 +72,11 @@ const handler = async (url, event, context) => {
} else {
return {
statusCode: 500,
- body: JSON.stringify({ error: error.message }),
+ body: { error: error.message },
};
}
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(mailConfigHandler);
+export default handler;
diff --git a/api/ports.js b/api/ports.js
index 63e2c25..6cef48d 100644
--- a/api/ports.js
+++ b/api/ports.js
@@ -1,5 +1,5 @@
-const net = require('net');
-const middleware = require('./_common/middleware');
+import net from 'net';
+import middleware from './_common/middleware.js';
// A list of commonly used ports.
const PORTS = [
@@ -34,7 +34,7 @@ async function checkPort(port, domain) {
});
}
-const handler = async (url, event, context) => {
+const portsHandler = async (url, event, context) => {
const domain = url.replace(/(^\w+:|^)\/\//, '');
const delay = ms => new Promise(res => setTimeout(res, ms));
@@ -72,7 +72,11 @@ const handler = async (url, event, context) => {
if(timeoutReached){
return errorResponse('The function timed out before completing.');
}
-
+
+ // Sort openPorts and failedPorts before returning
+ openPorts.sort((a, b) => a - b);
+ failedPorts.sort((a, b) => a - b);
+
return { openPorts, failedPorts };
};
@@ -80,5 +84,5 @@ const errorResponse = (message, statusCode = 444) => {
return { error: message };
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(portsHandler);
+export default handler;
diff --git a/api/quality.js b/api/quality.js
index a49afe1..1d123c1 100644
--- a/api/quality.js
+++ b/api/quality.js
@@ -1,7 +1,7 @@
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import middleware from './_common/middleware.js';
-const handler = async (url, event, context) => {
+const qualityHandler = async (url, event, context) => {
const apiKey = process.env.GOOGLE_CLOUD_API_KEY;
if (!apiKey) {
@@ -18,5 +18,5 @@ const handler = async (url, event, context) => {
return (await axios.get(endpoint)).data;
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(qualityHandler);
+export default handler;
diff --git a/api/rank.js b/api/rank.js
index 1947185..d2936ee 100644
--- a/api/rank.js
+++ b/api/rank.js
@@ -1,7 +1,7 @@
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const rankHandler = async (url) => {
const domain = url ? new URL(url).hostname : null;
if (!domain) throw new Error('Invalid URL');
@@ -21,6 +21,6 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(rankHandler);
+export default handler;
diff --git a/api/redirects.js b/api/redirects.js
index cd815b1..af7016e 100644
--- a/api/redirects.js
+++ b/api/redirects.js
@@ -1,9 +1,10 @@
-const handler = async (url) => {
- const redirects = [url];
- const got = await import('got');
+import got from 'got';
+import middleware from './_common/middleware.js';
+const redirectsHandler = async (url) => {
+ const redirects = [url];
try {
- await got.default(url, {
+ await got(url, {
followRedirect: true,
maxRedirects: 12,
hooks: {
@@ -23,7 +24,5 @@ const handler = async (url) => {
}
};
-const middleware = require('./_common/middleware');
-
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(redirectsHandler);
+export default handler;
diff --git a/api/robots-txt.js b/api/robots-txt.js
index 9f008e3..afe6f52 100644
--- a/api/robots-txt.js
+++ b/api/robots-txt.js
@@ -1,5 +1,5 @@
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import middleware from './_common/middleware.js';
const parseRobotsTxt = (content) => {
const lines = content.split('\n');
@@ -31,7 +31,7 @@ const parseRobotsTxt = (content) => {
return { robots: rules };
}
-const handler = async function(url) {
+const robotsHandler = async function(url) {
let parsedURL;
try {
parsedURL = new URL(url);
@@ -67,5 +67,5 @@ const handler = async function(url) {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(robotsHandler);
+export default handler;
diff --git a/api/screenshot.js b/api/screenshot.js
index 9345f14..f6d33bf 100644
--- a/api/screenshot.js
+++ b/api/screenshot.js
@@ -1,8 +1,8 @@
-const puppeteer = require('puppeteer-core');
-const chromium = require('chrome-aws-lambda');
-const middleware = require('./_common/middleware');
+import puppeteer from 'puppeteer-core';
+import chromium from 'chrome-aws-lambda';
+import middleware from './_common/middleware.js';
-const handler = async (targetUrl) => {
+const screenshotHandler = async (targetUrl) => {
if (!targetUrl) {
throw new Error('URL is missing from queryStringParameters');
@@ -58,5 +58,5 @@ const handler = async (targetUrl) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(screenshotHandler);
+export default handler;
diff --git a/api/security-txt.js b/api/security-txt.js
index dd08ca0..08cdcff 100644
--- a/api/security-txt.js
+++ b/api/security-txt.js
@@ -1,6 +1,8 @@
-const { https } = require('follow-redirects');
-const { URL } = require('url');
-const middleware = require('./_common/middleware');
+import { URL } from 'url';
+import followRedirects from 'follow-redirects';
+import middleware from './_common/middleware.js';
+
+const { https } = followRedirects;
const SECURITY_TXT_PATHS = [
'/security.txt',
@@ -38,7 +40,7 @@ const isPgpSigned = (result) => {
return false;
};
-const handler = async (urlParam) => {
+const securityTxtHandler = async (urlParam) => {
let url;
try {
@@ -90,5 +92,5 @@ async function fetchSecurityTxt(baseURL, path) {
});
}
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(securityTxtHandler);
+export default handler;
diff --git a/api/sitemap.js b/api/sitemap.js
index 8d593e4..282bf77 100644
--- a/api/sitemap.js
+++ b/api/sitemap.js
@@ -1,20 +1,21 @@
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import xml2js from 'xml2js';
+import middleware from './_common/middleware.js';
-const axios = require('axios');
-const xml2js = require('xml2js');
-
-const handler = async (url) => {
+const sitemapHandler = async (url) => {
let sitemapUrl = `${url}/sitemap.xml`;
+ const hardTimeOut = 5000;
+
try {
// Try to fetch sitemap directly
let sitemapRes;
try {
- sitemapRes = await axios.get(sitemapUrl, { timeout: 5000 });
+ sitemapRes = await axios.get(sitemapUrl, { timeout: hardTimeOut });
} catch (error) {
if (error.response && error.response.status === 404) {
// If sitemap not found, try to fetch it from robots.txt
- const robotsRes = await axios.get(`${url}/robots.txt`, { timeout: 5000 });
+ const robotsRes = await axios.get(`${url}/robots.txt`, { timeout: hardTimeOut });
const robotsTxt = robotsRes.data.split('\n');
for (let line of robotsTxt) {
@@ -28,7 +29,7 @@ const handler = async (url) => {
return { skipped: 'No sitemap found' };
}
- sitemapRes = await axios.get(sitemapUrl, { timeout: 5000 });
+ sitemapRes = await axios.get(sitemapUrl, { timeout: hardTimeOut });
} else {
throw error; // If other error, throw it
}
@@ -40,13 +41,13 @@ const handler = async (url) => {
return sitemap;
} catch (error) {
if (error.code === 'ECONNABORTED') {
- return { error: 'Request timed out after 5000ms' };
+ return { error: `Request timed-out after ${hardTimeOut}ms` };
} else {
return { error: error.message };
}
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(sitemapHandler);
+export default handler;
diff --git a/api/social-tags.js b/api/social-tags.js
index f8b38a3..e2c6bb4 100644
--- a/api/social-tags.js
+++ b/api/social-tags.js
@@ -1,9 +1,8 @@
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import cheerio from 'cheerio';
+import middleware from './_common/middleware.js';
-const axios = require('axios');
-const cheerio = require('cheerio');
-
-const handler = async (url) => {
+const socialTagsHandler = async (url) => {
// Check if url includes protocol
if (!url.startsWith('http://') && !url.startsWith('https://')) {
@@ -61,5 +60,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(socialTagsHandler);
+export default handler;
diff --git a/api/ssl.js b/api/ssl.js
index 1eb5c55..6f58be0 100644
--- a/api/ssl.js
+++ b/api/ssl.js
@@ -1,7 +1,7 @@
-const tls = require('tls');
-const middleware = require('./_common/middleware');
+import tls from 'tls';
+import middleware from './_common/middleware.js';
-const handler = async (urlString) => {
+const sslHandler = async (urlString) => {
try {
const parsedUrl = new URL(urlString);
const options = {
@@ -40,5 +40,5 @@ const handler = async (urlString) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(sslHandler);
+export default handler;
diff --git a/api/status.js b/api/status.js
index 2a70b66..0fcc578 100644
--- a/api/status.js
+++ b/api/status.js
@@ -1,8 +1,8 @@
-const https = require('https');
-const { performance, PerformanceObserver } = require('perf_hooks');
-const middleware = require('./_common/middleware');
+import https from 'https';
+import { performance, PerformanceObserver } from 'perf_hooks';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const statusHandler = async (url) => {
if (!url) {
throw new Error('You must provide a URL query parameter!');
}
@@ -55,5 +55,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(statusHandler);
+export default handler;
diff --git a/api/tech-stack.js b/api/tech-stack.js
index d649d2b..dcf0b8a 100644
--- a/api/tech-stack.js
+++ b/api/tech-stack.js
@@ -1,7 +1,7 @@
-const Wappalyzer = require('wappalyzer');
-const middleware = require('./_common/middleware');
+import Wappalyzer from 'wappalyzer';
+import middleware from './_common/middleware.js';
-const handler = async (url) => {
+const techStackHandler = async (url) => {
const options = {};
const wappalyzer = new Wappalyzer(options);
@@ -27,5 +27,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(techStackHandler);
+export default handler;
diff --git a/api/threats.js b/api/threats.js
index afff98c..de95932 100644
--- a/api/threats.js
+++ b/api/threats.js
@@ -1,6 +1,6 @@
-const axios = require('axios');
-const xml2js = require('xml2js');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import xml2js from 'xml2js';
+import middleware from './_common/middleware.js';
const getGoogleSafeBrowsingResult = async (url) => {
try {
@@ -84,7 +84,7 @@ const getCloudmersiveResult = async (url) => {
}
};
-const handler = async (url) => {
+const threatsHandler = async (url) => {
try {
const urlHaus = await getUrlHausResult(url);
const phishTank = await getPhishTankResult(url);
@@ -99,5 +99,5 @@ const handler = async (url) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(threatsHandler);
+export default handler;
diff --git a/api/tls.js b/api/tls.js
index 09aeaeb..5249f6f 100644
--- a/api/tls.js
+++ b/api/tls.js
@@ -1,9 +1,9 @@
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import axios from 'axios';
+import middleware from './_common/middleware.js';
const MOZILLA_TLS_OBSERVATORY_API = 'https://tls-observatory.services.mozilla.com/api/v1';
-const handler = async (url) => {
+const tlsHandler = async (url) => {
try {
const domain = new URL(url).hostname;
const scanResponse = await axios.post(`${MOZILLA_TLS_OBSERVATORY_API}/scan?target=${domain}`);
@@ -12,18 +12,18 @@ const handler = async (url) => {
if (typeof scanId !== 'number') {
return {
statusCode: 500,
- body: JSON.stringify({ error: 'Failed to get scan_id from TLS Observatory' }),
+ body: { error: 'Failed to get scan_id from TLS Observatory' },
};
}
const resultResponse = await axios.get(`${MOZILLA_TLS_OBSERVATORY_API}/results?id=${scanId}`);
return {
statusCode: 200,
- body: JSON.stringify(resultResponse.data),
+ body: resultResponse.data,
};
} catch (error) {
return { error: error.message };
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(tlsHandler);
+export default handler;
diff --git a/api/trace-route.js b/api/trace-route.js
index 2b71e48..50cd3b1 100644
--- a/api/trace-route.js
+++ b/api/trace-route.js
@@ -1,8 +1,8 @@
-const traceroute = require('traceroute');
-const url = require('url');
-const middleware = require('./_common/middleware');
+import url from 'url';
+import traceroute from 'traceroute';
+import middleware from './_common/middleware.js';
-const handler = async (urlString, context) => {
+const traceRouteHandler = async (urlString, context) => {
// Parse the URL and get the hostname
const urlObject = url.parse(urlString);
const host = urlObject.hostname;
@@ -28,5 +28,5 @@ const handler = async (urlString, context) => {
};
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(traceRouteHandler);
+export default handler;
diff --git a/api/txt-records.js b/api/txt-records.js
index ed88dd7..73104f1 100644
--- a/api/txt-records.js
+++ b/api/txt-records.js
@@ -1,7 +1,7 @@
-const dns = require('dns').promises;
-const middleware = require('./_common/middleware');
+import dns from 'dns/promises';
+import middleware from './_common/middleware.js';
-const handler = async (url, event, context) => {
+const txtRecordHandler = async (url, event, context) => {
try {
const parsedUrl = new URL(url);
@@ -29,5 +29,5 @@ const handler = async (url, event, context) => {
}
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(txtRecordHandler);
+export default handler;
diff --git a/api/whois.js b/api/whois.js
index 7224b22..8daba8a 100644
--- a/api/whois.js
+++ b/api/whois.js
@@ -1,7 +1,7 @@
-const net = require('net');
-const psl = require('psl');
-const axios = require('axios');
-const middleware = require('./_common/middleware');
+import net from 'net';
+import psl from 'psl';
+import axios from 'axios';
+import middleware from './_common/middleware.js';
const getBaseDomain = (url) => {
let protocol = '';
@@ -83,7 +83,7 @@ const fetchFromMyAPI = async (hostname) => {
}
};
-const handler = async (url) => {
+const whoisHandler = async (url) => {
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = 'http://' + url;
}
@@ -106,6 +106,6 @@ const handler = async (url) => {
};
};
-module.exports = middleware(handler);
-module.exports.handler = middleware(handler);
+export const handler = middleware(whoisHandler);
+export default handler;
diff --git a/astro.config.mjs b/astro.config.mjs
new file mode 100644
index 0000000..1790e63
--- /dev/null
+++ b/astro.config.mjs
@@ -0,0 +1,79 @@
+import { defineConfig } from 'astro/config';
+
+// Integrations
+import svelte from '@astrojs/svelte';
+import react from "@astrojs/react";
+import partytown from '@astrojs/partytown';
+import sitemap from '@astrojs/sitemap';
+
+// Adapters
+import vercelAdapter from '@astrojs/vercel/serverless';
+import netlifyAdapter from '@astrojs/netlify';
+import nodeAdapter from '@astrojs/node';
+import cloudflareAdapter from '@astrojs/cloudflare';
+
+// Helper function to unwrap both Vite and Node environment variables
+const unwrapEnvVar = (varName, fallbackValue) => {
+ const classicEnvVar = process?.env && process.env[varName];
+ const viteEnvVar = import.meta.env[varName];
+ return classicEnvVar || viteEnvVar || fallbackValue;
+}
+
+// Determine the deploy target (vercel, netlify, cloudflare, node)
+const deployTarget = unwrapEnvVar('PLATFORM', 'node').toLowerCase();
+
+// Determine the output mode (server, hybrid or static)
+const output = unwrapEnvVar('OUTPUT', 'hybrid');
+
+// The FQDN of where the site is hosted (used for sitemaps & canonical URLs)
+const site = unwrapEnvVar('SITE_URL', 'https://web-check.xyz');
+
+// The base URL of the site (if serving from a subdirectory)
+const base = unwrapEnvVar('BASE_URL', '/');
+
+// Should run the app in boss-mode (requires extra configuration)
+const isBossServer = unwrapEnvVar('BOSS_SERVER', false);
+
+// Initialize Astro integrations
+const integrations = [svelte(), react(), partytown(), sitemap()];
+
+// Set the appropriate adapter, based on the deploy target
+function getAdapter(target) {
+ switch(target) {
+ case 'vercel':
+ return vercelAdapter();
+ case 'netlify':
+ return netlifyAdapter();
+ case 'cloudflare':
+ return cloudflareAdapter();
+ case 'node':
+ return nodeAdapter({ mode: 'middleware' });
+ default:
+ throw new Error(`Unsupported deploy target: ${target}`);
+ }
+}
+const adapter = getAdapter(deployTarget);
+
+// Print build information to console
+console.log(
+ `\n\x1b[1m\x1b[35m Preparing to start build of Web Check.... \x1b[0m\n`,
+ `\x1b[35m\x1b[2mCompiling for "${deployTarget}" using "${output}" mode, `
+ + `to deploy to "${site}" at "${base}"\x1b[0m\n`,
+ `\x1b[2m\x1b[36m🛟 For documentation and support, visit the GitHub repo: ` +
+ `https://github.com/lissy93/web-check \n`,
+ `💖 Found Web-Check useful? Consider sponsoring us on GitHub ` +
+ `to help fund maintenance & development.\x1b[0m\n`,
+);
+
+const redirects = {
+ '/about': '/check/about',
+};
+
+// Skip the marketing homepage for self-hosted users
+if (!isBossServer && isBossServer !== true) {
+ redirects['/'] = '/check';
+}
+
+// Export Astro configuration
+export default defineConfig({ output, base, integrations, site, adapter, redirects });
+
diff --git a/fly.toml b/fly.toml
new file mode 100644
index 0000000..a529b54
--- /dev/null
+++ b/fly.toml
@@ -0,0 +1,17 @@
+app = 'web-check'
+primary_region = 'lhr'
+
+[build]
+
+[http_service]
+ internal_port = 3000
+ force_https = true
+ auto_stop_machines = true
+ auto_start_machines = true
+ min_machines_running = 0
+ processes = ['app']
+
+[[vm]]
+ memory = '1gb'
+ cpu_kind = 'shared'
+ cpus = 1
diff --git a/netlify.toml b/netlify.toml
index 3c9dab1..136485e 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -2,11 +2,13 @@
[build]
base = "/"
command = "yarn build"
- publish = "build"
+ publish = "dist"
functions = "api"
# Environmental variables and optional secrets
[build.environment]
+ PLATFORM = "netlify"
+ PUBLIC_API_ENDPOINT = "/.netlify/functions"
# Build configuration env vars (uncomment if you want to conigure these)
# CI="false" # Set CI to false, to prevent warnings from exiting the build
# CHROME_PATH='/usr/bin/chromium' # Path to Chromium binary
@@ -25,12 +27,6 @@
status = 301
force = true
-# For router history mode, ensure pages land on index
-[[redirects]]
- from = "/*"
- to = "/index.html"
- status = 200
-
# Plugins
[[plugins]]
package = "netlify-plugin-chromium"
diff --git a/package.json b/package.json
index 86af95e..d7da205 100644
--- a/package.json
+++ b/package.json
@@ -1,103 +1,73 @@
{
"name": "web-check",
- "version": "1.1.0",
- "private": false,
- "description": "All-in-one OSINT tool for analyzing any website",
- "repository": "github:lissy93/web-check",
+ "type": "module",
+ "version": "2.0.0",
"homepage": "https://web-check.xyz",
- "license": "MIT",
- "author": {
- "name": "Alicia Sykes",
- "email": "alicia@omg.lol"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Lissy93"
- },
"scripts": {
- "dev": "netlify dev",
- "serve": "node server",
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
+ "start": "node server",
+ "start-pm": "pm2 start server.js -i max",
+ "build": "astro check && astro build",
"dev:vercel": "PLATFORM='vercel' npx vercel dev",
"dev:netlify": "PLATFORM='netlify' npx netlify dev",
- "dev:node": "npx concurrently --names \"frontend,backend\" \"REACT_APP_API_ENDPOINT='http://localhost:3001/api' npx react-scripts start\" \"PLATFORM='node' DISABLE_GUI='true' PORT='3001' API_CORS_ORIGIN='*' npx nodemon server\""
+ "dev:api": "DISABLE_GUI='true' PORT='3001' nodemon server",
+ "dev:astro": "PUBLIC_API_ENDPOINT=http://localhost:3001/api astro dev",
+ "dev": "concurrently -c magenta,cyan -n backend,frontend 'yarn dev:api' 'yarn dev:astro'"
},
"dependencies": {
- "@netlify/functions": "^1.6.0",
- "@sentry/react": "^7.60.0",
- "@testing-library/jest-dom": "^5.17.0",
- "@testing-library/react": "^14.0.0",
- "@testing-library/user-event": "^14.4.3",
- "@types/jest": "^29.5.3",
- "@types/node": "^20.4.4",
- "@types/react": "^18.2.15",
- "@types/react-dom": "^18.2.7",
- "@types/react-router-dom": "^5.3.3",
- "@types/react-simple-maps": "^3.0.0",
- "@types/styled-components": "^5.1.26",
- "axios": "^1.4.0",
+ "@astrojs/check": "^0.5.10",
+ "@astrojs/react": "^3.3.2",
+ "@emotion/react": "^11.11.4",
+ "@emotion/styled": "^11.11.5",
+ "@fortawesome/fontawesome-svg-core": "^6.5.2",
+ "@fortawesome/free-brands-svg-icons": "^6.5.2",
+ "@fortawesome/free-regular-svg-icons": "^6.5.2",
+ "@fortawesome/free-solid-svg-icons": "^6.5.2",
+ "@fortawesome/svelte-fontawesome": "^0.2.2",
+ "@types/react": "^18.3.1",
+ "@types/react-dom": "^18.3.0",
+ "astro": "^4.7.1",
+ "axios": "^1.4.8",
"cheerio": "^1.0.0-rc.12",
"chrome-aws-lambda": "^10.1.0",
"chromium": "^3.0.3",
"connect-history-api-fallback": "^2.0.0",
"cors": "^2.8.5",
"csv-parser": "^3.0.0",
- "dotenv": "^16.3.1",
+ "dotenv": "^16.4.5",
+ "express": "^4.19.2",
"express-rate-limit": "^7.2.0",
- "flatted": "^3.2.7",
- "follow-redirects": "^1.15.2",
- "got": "^13.0.0",
- "jest-styled-components": "^7.1.1",
- "netlify-cli": "^15.9.1",
- "perf_hooks": "^0.0.1",
+ "framer-motion": "^11.2.6",
+ "got": "^14.2.1",
+ "pm2": "^5.3.1",
"psl": "^1.9.0",
- "puppeteer": "^20.9.0",
- "puppeteer-core": "^21.0.3",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
+ "puppeteer": "^22.8.0",
+ "puppeteer-core": "^22.8.0",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
"react-masonry-css": "^1.0.16",
- "react-router-dom": "^6.14.2",
- "react-scripts": "5.0.1",
+ "react-router-dom": "^6.23.0",
"react-simple-maps": "^3.0.0",
- "react-toastify": "^9.1.3",
- "recharts": "^2.7.3",
- "styled-components": "^6.0.5",
+ "react-toastify": "^10.0.5",
+ "recharts": "^2.12.6",
+ "svelte": "^4.2.17",
"traceroute": "^1.0.0",
- "typescript": "^5.1.6",
- "unzipper": "^0.10.14",
+ "typescript": "^5.4.5",
+ "unzipper": "^0.11.5",
+ "url-parse": "^1.5.10",
"wappalyzer": "^6.10.65",
- "web-vitals": "^3.4.0",
"xml2js": "^0.6.2"
},
- "eslintConfig": {
- "extends": [
- "react-app",
- "react-app/jest"
- ]
- },
- "browserslist": {
- "production": [
- ">0.2%",
- "not dead",
- "not op_mini all"
- ],
- "development": [
- "last 1 chrome version",
- "last 1 firefox version",
- "last 1 safari version"
- ]
- },
- "compilerOptions": {
- "allowJs": true,
- "outDir": "./dist"
- },
"devDependencies": {
- "serverless-domain-manager": "^7.1.1",
- "serverless-offline": "^12.0.4",
- "serverless-webpack": "^5.13.0",
- "webpack": "^5.88.2",
- "webpack-node-externals": "^3.0.0"
+ "@astrojs/cloudflare": "^10.2.5",
+ "@astrojs/netlify": "^5.2.0",
+ "@astrojs/node": "^8.2.5",
+ "@astrojs/partytown": "^2.1.0",
+ "@astrojs/sitemap": "^3.1.4",
+ "@astrojs/svelte": "^5.4.0",
+ "@astrojs/ts-plugin": "^1.6.1",
+ "@astrojs/vercel": "^7.5.4",
+ "concurrently": "^8.2.2",
+ "nodemon": "^3.1.0",
+ "sass": "^1.77.1"
}
}
diff --git a/public/assets/badges/dockerhub.svg b/public/assets/badges/dockerhub.svg
new file mode 100644
index 0000000..8463f32
--- /dev/null
+++ b/public/assets/badges/dockerhub.svg
@@ -0,0 +1 @@
+DockerHub: Lissy93/Web Check DockerHub DockerHub Lissy93/Web Check Lissy93/Web Check
\ No newline at end of file
diff --git a/public/assets/badges/github.svg b/public/assets/badges/github.svg
new file mode 100644
index 0000000..a6bf455
--- /dev/null
+++ b/public/assets/badges/github.svg
@@ -0,0 +1 @@
+GitHub: Lissy93/Web Check GitHub GitHub Lissy93/Web Check Lissy93/Web Check
\ No newline at end of file
diff --git a/public/assets/badges/sponsor.svg b/public/assets/badges/sponsor.svg
new file mode 100644
index 0000000..790c486
--- /dev/null
+++ b/public/assets/badges/sponsor.svg
@@ -0,0 +1 @@
+Sponsor: Alicia Sykes Sponsor Sponsor Alicia Sykes Alicia Sykes
\ No newline at end of file
diff --git a/public/assets/badges/webcheck.svg b/public/assets/badges/webcheck.svg
new file mode 100644
index 0000000..a5f7287
--- /dev/null
+++ b/public/assets/badges/webcheck.svg
@@ -0,0 +1 @@
+Website: web-check.zyz Website Website web-check.zyz webcheck.zyz
diff --git a/public/assets/images/background-dots.svg b/public/assets/images/background-dots.svg
new file mode 100644
index 0000000..1ec8456
--- /dev/null
+++ b/public/assets/images/background-dots.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/assets/images/docker.svg b/public/assets/images/docker.svg
new file mode 100644
index 0000000..b8a5f2c
--- /dev/null
+++ b/public/assets/images/docker.svg
@@ -0,0 +1 @@
+Docker
diff --git a/public/assets/images/fly.svg b/public/assets/images/fly.svg
new file mode 100644
index 0000000..7800b6b
--- /dev/null
+++ b/public/assets/images/fly.svg
@@ -0,0 +1 @@
+
diff --git a/public/assets/images/github.svg b/public/assets/images/github.svg
new file mode 100644
index 0000000..2334976
--- /dev/null
+++ b/public/assets/images/github.svg
@@ -0,0 +1 @@
+GitHub
diff --git a/public/assets/images/netlify.svg b/public/assets/images/netlify.svg
new file mode 100644
index 0000000..fd6acf8
--- /dev/null
+++ b/public/assets/images/netlify.svg
@@ -0,0 +1 @@
+Netlify
diff --git a/public/assets/images/swagger.svg b/public/assets/images/swagger.svg
new file mode 100644
index 0000000..38af79d
--- /dev/null
+++ b/public/assets/images/swagger.svg
@@ -0,0 +1 @@
+Swagger
diff --git a/public/assets/images/vercel.svg b/public/assets/images/vercel.svg
new file mode 100644
index 0000000..7e9d62e
--- /dev/null
+++ b/public/assets/images/vercel.svg
@@ -0,0 +1 @@
+Vercel
diff --git a/public/assets/images/webauthn.svg b/public/assets/images/webauthn.svg
new file mode 100644
index 0000000..209807b
--- /dev/null
+++ b/public/assets/images/webauthn.svg
@@ -0,0 +1 @@
+WebAuthn
diff --git a/public/favicon.svg b/public/favicon.svg
new file mode 100644
index 0000000..ed4ef50
--- /dev/null
+++ b/public/favicon.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/fonts/Hubot-Sans/Hubot-Sans.ttf b/public/fonts/Hubot-Sans/Hubot-Sans.ttf
new file mode 100644
index 0000000..2b74a40
Binary files /dev/null and b/public/fonts/Hubot-Sans/Hubot-Sans.ttf differ
diff --git a/public/fonts/Hubot-Sans/Hubot-Sans.woff2 b/public/fonts/Hubot-Sans/Hubot-Sans.woff2
new file mode 100644
index 0000000..c828121
Binary files /dev/null and b/public/fonts/Hubot-Sans/Hubot-Sans.woff2 differ
diff --git a/public/fonts/Hubot-Sans/LICENSE b/public/fonts/Hubot-Sans/LICENSE
new file mode 100644
index 0000000..49e454d
--- /dev/null
+++ b/public/fonts/Hubot-Sans/LICENSE
@@ -0,0 +1,93 @@
+Copyright (c) 2022, GitHub https://github.com/github/hubot-sans
+with Reserved Font Name "Hubot Sans"
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting — in part or in whole — any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
\ No newline at end of file
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Black.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-Black.otf
new file mode 100644
index 0000000..1931b37
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-Black.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-BlackItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-BlackItalic.otf
new file mode 100644
index 0000000..7d765d1
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-BlackItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Bold.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-Bold.otf
new file mode 100644
index 0000000..518391b
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-Bold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-BoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-BoldItalic.otf
new file mode 100644
index 0000000..5504dab
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-BoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBold.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBold.otf
new file mode 100644
index 0000000..1204363
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBoldItalic.otf
new file mode 100644
index 0000000..0a2fb07
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLight.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLight.otf
new file mode 100644
index 0000000..c945af2
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLight.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLightItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLightItalic.otf
new file mode 100644
index 0000000..d73534f
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLightItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Italic.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-Italic.otf
new file mode 100644
index 0000000..03868be
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-Italic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Light.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-Light.otf
new file mode 100644
index 0000000..f142b34
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-Light.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-LightItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-LightItalic.otf
new file mode 100644
index 0000000..b8c9b03
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-LightItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Medium.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-Medium.otf
new file mode 100644
index 0000000..9ba599b
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-Medium.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-MediumItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-MediumItalic.otf
new file mode 100644
index 0000000..5bce903
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-MediumItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Regular.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-Regular.otf
new file mode 100644
index 0000000..8d2e29e
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-Regular.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBold.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBold.otf
new file mode 100644
index 0000000..c17a1a7
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBoldItalic.otf
new file mode 100644
index 0000000..29fed55
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Black.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Black.otf
new file mode 100644
index 0000000..9384628
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Black.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BlackItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BlackItalic.otf
new file mode 100644
index 0000000..2093a14
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BlackItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Bold.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Bold.otf
new file mode 100644
index 0000000..9648ee7
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Bold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BoldItalic.otf
new file mode 100644
index 0000000..8be495b
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBold.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBold.otf
new file mode 100644
index 0000000..735e71f
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBoldItalic.otf
new file mode 100644
index 0000000..b765fd8
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLight.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLight.otf
new file mode 100644
index 0000000..f1f0bbc
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLight.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLightItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLightItalic.otf
new file mode 100644
index 0000000..aa1c2dc
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLightItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Italic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Italic.otf
new file mode 100644
index 0000000..c2c00d9
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Italic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Light.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Light.otf
new file mode 100644
index 0000000..4ab8ac0
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Light.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-LightItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-LightItalic.otf
new file mode 100644
index 0000000..d581fc8
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-LightItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Medium.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Medium.otf
new file mode 100644
index 0000000..b708673
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Medium.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-MediumItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-MediumItalic.otf
new file mode 100644
index 0000000..0a54597
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-MediumItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Regular.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Regular.otf
new file mode 100644
index 0000000..f1c26f9
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Regular.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBold.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBold.otf
new file mode 100644
index 0000000..59681e9
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBoldItalic.otf
new file mode 100644
index 0000000..24323d5
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Black.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Black.otf
new file mode 100644
index 0000000..7788a78
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Black.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BlackItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BlackItalic.otf
new file mode 100644
index 0000000..d4ed13e
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BlackItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Bold.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Bold.otf
new file mode 100644
index 0000000..b9eeb7d
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Bold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BoldItalic.otf
new file mode 100644
index 0000000..adfdd78
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBold.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBold.otf
new file mode 100644
index 0000000..f34ca1e
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBoldItalic.otf
new file mode 100644
index 0000000..67d951c
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLight.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLight.otf
new file mode 100644
index 0000000..260be7d
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLight.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLightItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLightItalic.otf
new file mode 100644
index 0000000..20e5ef3
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLightItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Italic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Italic.otf
new file mode 100644
index 0000000..23acbd3
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Italic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Light.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Light.otf
new file mode 100644
index 0000000..e6457e1
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Light.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-LightItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-LightItalic.otf
new file mode 100644
index 0000000..ef082e7
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-LightItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Medium.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Medium.otf
new file mode 100644
index 0000000..3fd3fb3
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Medium.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-MediumItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-MediumItalic.otf
new file mode 100644
index 0000000..c14d0e0
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-MediumItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Regular.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Regular.otf
new file mode 100644
index 0000000..097c410
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Regular.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBold.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBold.otf
new file mode 100644
index 0000000..0fd65cc
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBold.otf differ
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBoldItalic.otf b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBoldItalic.otf
new file mode 100644
index 0000000..39c2e1f
Binary files /dev/null and b/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBoldItalic.otf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Black.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-Black.ttf
new file mode 100644
index 0000000..48efb8b
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-Black.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-BlackItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-BlackItalic.ttf
new file mode 100644
index 0000000..b79c3bc
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-BlackItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Bold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-Bold.ttf
new file mode 100644
index 0000000..f60d805
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-Bold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-BoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-BoldItalic.ttf
new file mode 100644
index 0000000..7aac29a
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-BoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBold.ttf
new file mode 100644
index 0000000..0e48f55
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBoldItalic.ttf
new file mode 100644
index 0000000..229a706
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLight.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLight.ttf
new file mode 100644
index 0000000..54710c1
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLight.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLightItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLightItalic.ttf
new file mode 100644
index 0000000..a2fa306
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLightItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Italic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-Italic.ttf
new file mode 100644
index 0000000..4e73f01
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-Italic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Light.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-Light.ttf
new file mode 100644
index 0000000..cdc4c58
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-Light.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-LightItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-LightItalic.ttf
new file mode 100644
index 0000000..b12418c
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-LightItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Medium.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-Medium.ttf
new file mode 100644
index 0000000..4a0d740
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-Medium.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-MediumItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-MediumItalic.ttf
new file mode 100644
index 0000000..56bfc46
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-MediumItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Regular.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-Regular.ttf
new file mode 100644
index 0000000..293fb69
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-Regular.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBold.ttf
new file mode 100644
index 0000000..a57a347
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBoldItalic.ttf
new file mode 100644
index 0000000..f965b2e
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Black.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Black.ttf
new file mode 100644
index 0000000..ff33433
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Black.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BlackItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BlackItalic.ttf
new file mode 100644
index 0000000..74c0cb1
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BlackItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Bold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Bold.ttf
new file mode 100644
index 0000000..937775a
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Bold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BoldItalic.ttf
new file mode 100644
index 0000000..5bbbf99
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBold.ttf
new file mode 100644
index 0000000..e8edf2e
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBoldItalic.ttf
new file mode 100644
index 0000000..ebcf745
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLight.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLight.ttf
new file mode 100644
index 0000000..2b926b5
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLight.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLightItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLightItalic.ttf
new file mode 100644
index 0000000..59d8318
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLightItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Italic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Italic.ttf
new file mode 100644
index 0000000..310c6cd
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Italic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Light.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Light.ttf
new file mode 100644
index 0000000..0389708
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Light.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-LightItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-LightItalic.ttf
new file mode 100644
index 0000000..b270fa1
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-LightItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Medium.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Medium.ttf
new file mode 100644
index 0000000..ad02d63
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Medium.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-MediumItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-MediumItalic.ttf
new file mode 100644
index 0000000..ef837a2
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-MediumItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Regular.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Regular.ttf
new file mode 100644
index 0000000..7004de7
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Regular.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBold.ttf
new file mode 100644
index 0000000..9c01e86
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBoldItalic.ttf
new file mode 100644
index 0000000..7aef86e
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Black.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Black.ttf
new file mode 100644
index 0000000..7fd97d9
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Black.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BlackItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BlackItalic.ttf
new file mode 100644
index 0000000..764c2fb
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BlackItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Bold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Bold.ttf
new file mode 100644
index 0000000..eae654f
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Bold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BoldItalic.ttf
new file mode 100644
index 0000000..31038be
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBold.ttf
new file mode 100644
index 0000000..d87dc12
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBoldItalic.ttf
new file mode 100644
index 0000000..dff888c
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLight.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLight.ttf
new file mode 100644
index 0000000..eb308ba
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLight.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLightItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLightItalic.ttf
new file mode 100644
index 0000000..1ca3833
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLightItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Italic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Italic.ttf
new file mode 100644
index 0000000..e53a1bf
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Italic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Light.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Light.ttf
new file mode 100644
index 0000000..04f47da
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Light.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-LightItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-LightItalic.ttf
new file mode 100644
index 0000000..bd2a555
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-LightItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Medium.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Medium.ttf
new file mode 100644
index 0000000..62b8387
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Medium.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-MediumItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-MediumItalic.ttf
new file mode 100644
index 0000000..e5b39b6
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-MediumItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Regular.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Regular.ttf
new file mode 100644
index 0000000..a446d1e
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Regular.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBold.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBold.ttf
new file mode 100644
index 0000000..7974442
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBold.ttf differ
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBoldItalic.ttf b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBoldItalic.ttf
new file mode 100644
index 0000000..fba5ac9
Binary files /dev/null and b/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBoldItalic.ttf differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Black.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Black.woff2
new file mode 100644
index 0000000..5b68c1d
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Black.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-BlackItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-BlackItalic.woff2
new file mode 100644
index 0000000..ec0d285
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-BlackItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Bold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Bold.woff2
new file mode 100644
index 0000000..bda3db2
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Bold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-BoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-BoldItalic.woff2
new file mode 100644
index 0000000..c53405d
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-BoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBold.woff2
new file mode 100644
index 0000000..6e91ab5
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBoldItalic.woff2
new file mode 100644
index 0000000..4e5a956
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLight.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLight.woff2
new file mode 100644
index 0000000..1172db7
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLight.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLightItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLightItalic.woff2
new file mode 100644
index 0000000..f340380
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLightItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Italic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Italic.woff2
new file mode 100644
index 0000000..93f2f55
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Italic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Light.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Light.woff2
new file mode 100644
index 0000000..28495e5
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Light.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-LightItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-LightItalic.woff2
new file mode 100644
index 0000000..bc56160
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-LightItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Medium.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Medium.woff2
new file mode 100644
index 0000000..cfcd325
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Medium.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-MediumItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-MediumItalic.woff2
new file mode 100644
index 0000000..dffe146
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-MediumItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Regular.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Regular.woff2
new file mode 100644
index 0000000..5c05680
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-Regular.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBold.woff2
new file mode 100644
index 0000000..1714325
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBoldItalic.woff2
new file mode 100644
index 0000000..b0be7d0
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Black.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Black.woff2
new file mode 100644
index 0000000..9bd3191
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Black.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BlackItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BlackItalic.woff2
new file mode 100644
index 0000000..2ed4c8b
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BlackItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Bold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Bold.woff2
new file mode 100644
index 0000000..873382d
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Bold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BoldItalic.woff2
new file mode 100644
index 0000000..11ecf04
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBold.woff2
new file mode 100644
index 0000000..81e9cf2
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBoldItalic.woff2
new file mode 100644
index 0000000..d94bf8f
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLight.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLight.woff2
new file mode 100644
index 0000000..93793d5
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLight.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLightItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLightItalic.woff2
new file mode 100644
index 0000000..5565655
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLightItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Italic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Italic.woff2
new file mode 100644
index 0000000..b416d82
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Italic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Light.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Light.woff2
new file mode 100644
index 0000000..2a6b79a
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Light.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-LightItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-LightItalic.woff2
new file mode 100644
index 0000000..dd9c9cf
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-LightItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Medium.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Medium.woff2
new file mode 100644
index 0000000..3d58451
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Medium.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-MediumItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-MediumItalic.woff2
new file mode 100644
index 0000000..50341f5
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-MediumItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Regular.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Regular.woff2
new file mode 100644
index 0000000..1580ee6
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Regular.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBold.woff2
new file mode 100644
index 0000000..fa70199
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBoldItalic.woff2
new file mode 100644
index 0000000..7560dea
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Black.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Black.woff2
new file mode 100644
index 0000000..986ef50
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Black.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BlackItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BlackItalic.woff2
new file mode 100644
index 0000000..a72a530
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BlackItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Bold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Bold.woff2
new file mode 100644
index 0000000..409c9a0
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Bold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BoldItalic.woff2
new file mode 100644
index 0000000..9c82783
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBold.woff2
new file mode 100644
index 0000000..59979d2
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBoldItalic.woff2
new file mode 100644
index 0000000..9a8346e
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLight.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLight.woff2
new file mode 100644
index 0000000..b7209ab
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLight.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLightItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLightItalic.woff2
new file mode 100644
index 0000000..0af2bd2
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLightItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Italic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Italic.woff2
new file mode 100644
index 0000000..26d3753
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Italic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Light.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Light.woff2
new file mode 100644
index 0000000..a8304f4
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Light.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-LightItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-LightItalic.woff2
new file mode 100644
index 0000000..b45656a
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-LightItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Medium.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Medium.woff2
new file mode 100644
index 0000000..0f90b1a
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Medium.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-MediumItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-MediumItalic.woff2
new file mode 100644
index 0000000..0b5c93a
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-MediumItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Regular.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Regular.woff2
new file mode 100644
index 0000000..e391548
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Regular.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBold.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBold.woff2
new file mode 100644
index 0000000..4de6cf7
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBold.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBoldItalic.woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBoldItalic.woff2
new file mode 100644
index 0000000..f845542
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBoldItalic.woff2 differ
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans[slnt,wdth,wght].woff2 b/public/fonts/Hubot-Sans/WOFF2/HubotSans[slnt,wdth,wght].woff2
new file mode 100644
index 0000000..c828121
Binary files /dev/null and b/public/fonts/Hubot-Sans/WOFF2/HubotSans[slnt,wdth,wght].woff2 differ
diff --git a/public/fonts/Inter-Black.ttf b/public/fonts/Inter-Black.ttf
new file mode 100644
index 0000000..b27822b
Binary files /dev/null and b/public/fonts/Inter-Black.ttf differ
diff --git a/public/fonts/Inter-Bold.ttf b/public/fonts/Inter-Bold.ttf
new file mode 100644
index 0000000..fe23eeb
Binary files /dev/null and b/public/fonts/Inter-Bold.ttf differ
diff --git a/public/fonts/Inter-ExtraBold.ttf b/public/fonts/Inter-ExtraBold.ttf
new file mode 100644
index 0000000..874b1b0
Binary files /dev/null and b/public/fonts/Inter-ExtraBold.ttf differ
diff --git a/public/fonts/Inter-ExtraLight.ttf b/public/fonts/Inter-ExtraLight.ttf
new file mode 100644
index 0000000..c993e82
Binary files /dev/null and b/public/fonts/Inter-ExtraLight.ttf differ
diff --git a/public/fonts/Inter-Light.ttf b/public/fonts/Inter-Light.ttf
new file mode 100644
index 0000000..71188f5
Binary files /dev/null and b/public/fonts/Inter-Light.ttf differ
diff --git a/public/fonts/Inter-Medium.ttf b/public/fonts/Inter-Medium.ttf
new file mode 100644
index 0000000..a01f377
Binary files /dev/null and b/public/fonts/Inter-Medium.ttf differ
diff --git a/public/fonts/Inter-Regular.ttf b/public/fonts/Inter-Regular.ttf
new file mode 100644
index 0000000..5e4851f
Binary files /dev/null and b/public/fonts/Inter-Regular.ttf differ
diff --git a/public/fonts/Inter-SemiBold.ttf b/public/fonts/Inter-SemiBold.ttf
new file mode 100644
index 0000000..ecc7041
Binary files /dev/null and b/public/fonts/Inter-SemiBold.ttf differ
diff --git a/public/fonts/Inter-Thin.ttf b/public/fonts/Inter-Thin.ttf
new file mode 100644
index 0000000..fe77243
Binary files /dev/null and b/public/fonts/Inter-Thin.ttf differ
diff --git a/public/fonts/Inter-VariableFont_slnt,wght.ttf b/public/fonts/Inter-VariableFont_slnt,wght.ttf
new file mode 100644
index 0000000..e724708
Binary files /dev/null and b/public/fonts/Inter-VariableFont_slnt,wght.ttf differ
diff --git a/src/assets/fonts/PTMono-Regular.ttf b/public/fonts/PTMono-Regular.ttf
similarity index 100%
rename from src/assets/fonts/PTMono-Regular.ttf
rename to public/fonts/PTMono-Regular.ttf
diff --git a/public/index.html b/public/index.html
index 4c8bce5..af45561 100644
--- a/public/index.html
+++ b/public/index.html
@@ -20,6 +20,9 @@
+
+
+
diff --git a/public/placeholder.html b/public/placeholder.html
index 9b2038c..b59b553 100644
--- a/public/placeholder.html
+++ b/public/placeholder.html
@@ -32,6 +32,7 @@
}
p, span, a, section, div { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; }
code { color: #9fef00cc;}
+ .logs { background: #141d2b; padding: 0.5rem;}