many updates
This commit is contained in:
parent
5ddbdffbff
commit
6464e2fc4a
2
Makefile
2
Makefile
|
@ -1,6 +1,5 @@
|
|||
.PHONY: build
|
||||
build:
|
||||
# Build Docker image
|
||||
docker build -t distrust-co .
|
||||
|
||||
.PHONY: fullclean
|
||||
|
@ -18,5 +17,4 @@ _site: build
|
|||
|
||||
.PHONY: serve
|
||||
serve: build
|
||||
# Run Docker container with listener for current dir and port mapping
|
||||
docker run --rm -p 0.0.0.0:4000:80 -it distrust-co
|
||||
|
|
12
_config.yml
12
_config.yml
|
@ -18,25 +18,23 @@
|
|||
# You can create any custom variable you would like, and they will be accessible
|
||||
# in the templates via {{ site.myvariable }}.
|
||||
|
||||
title: Distrust
|
||||
email: lance@distrust.co
|
||||
title: Distrust Disaster Recovery
|
||||
email: sales@distrust.co
|
||||
description: >- # this means to ignore newlines until "baseurl:"
|
||||
Trust Nothing
|
||||
baseurl: "" # the subpath of your site, e.g. /blog
|
||||
url: "https://distrust.co" # the base hostname & protocol for your site, e.g. http://example.com
|
||||
url: "https://dr.distrust.co" # the base hostname & protocol for your site, e.g. http://example.com
|
||||
|
||||
header_pages:
|
||||
- index.md
|
||||
- about.md
|
||||
- pricing.md
|
||||
- wizard.md
|
||||
- recovery_policy.md
|
||||
- data_storage.md
|
||||
- q&a.md
|
||||
- contact.md
|
||||
|
||||
style: dark # dark (default), light or hacker
|
||||
listen_for_clients_preferred_style: false # false (default) or true
|
||||
style: light
|
||||
listen_for_clients_preferred_style: true # false (default) or true
|
||||
|
||||
footer: '2024 Distrust, LLC'
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{ "/assets/main.css" | relative_url }}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/assets/favicons/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png">
|
||||
|
@ -11,8 +13,6 @@
|
|||
<meta name="robots" content="{{page.robots}}" />
|
||||
{% endif %}
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{ "/assets/main.css" | relative_url }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ "/assets/main-dark.css" | relative_url }}">
|
||||
|
||||
<!-- "Really, there is nothing interesting to see here. It is a static website. -->
|
||||
<!-- Here is the terraform code that deployed it, and here is the site source repo. -->
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
<div class="menu">
|
||||
<div>
|
||||
<a id="home-link" href="/index.html">
|
||||
<img class="menu-logo" src="assets/base/distrust-text-white.svg"
|
||||
alt="Distrust broken chain logo with white text" />
|
||||
Distrust Disaster Recovery
|
||||
</a>
|
||||
</div>
|
||||
<div class="right-menu">
|
||||
|
@ -20,6 +19,10 @@
|
|||
<li class="show">
|
||||
<a href="/contact.html" class="action-button">Join Waitlist</a>
|
||||
</li>
|
||||
<!-- <label class="switch">
|
||||
<input type="checkbox" id="theme-toggle">
|
||||
<span class="slider"></span>
|
||||
</label> -->
|
||||
</ul>
|
||||
<div id="hamburger-menu" class="hide menu-button-container" for="menu-toggle">
|
||||
<input id="menu-toggle" type="checkbox" />
|
||||
|
@ -30,3 +33,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<script type="text/javascript" src="/assets/js/main.js"></script>
|
||||
|
|
|
@ -8,42 +8,41 @@
|
|||
{%- include header.html -%}
|
||||
|
||||
<main>
|
||||
<section class="flex-container">
|
||||
<div class="flex-container-inner">
|
||||
<h1>Distrust Disaster Recovery</h1>
|
||||
|
||||
<div class="flex-container-inner">
|
||||
<h1>Distrust Disaster Recovery</h1>
|
||||
<p>
|
||||
The only fully open source, technology agnostic disaster
|
||||
recovery and key escrow service.
|
||||
</p>
|
||||
<a href="https://docs.distrust.co/qkm" class="action-button">Documentation</a>
|
||||
<a href="/contact.html" class="action-button">Join Waitlist</a>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<div class="flex-container-inner">
|
||||
<h1>Quick Start</h1>
|
||||
<div class="cta-well">
|
||||
<p>
|
||||
The only fully open source, technology agnostic disaster
|
||||
recovery and key escrow service.
|
||||
If you are ready to protect your data, you can use
|
||||
the Wizard which will walk you through the process.
|
||||
</p>
|
||||
<a href="https://docs.distrust.co/qkm" class="action-button">Documentation</a>
|
||||
<a href="/contact.html" class="action-button">Join Waitlist</a>
|
||||
<br />
|
||||
<a href="/wizard.html" class="action-button">Quick Start</a>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
<section class="flex-container">
|
||||
<div class="flex-container-inner">
|
||||
<h1>Quick Start</h1>
|
||||
<div class="cta-well">
|
||||
<p>
|
||||
If you are ready to protect your data, you can use
|
||||
the Wizard which will walk you through the process.
|
||||
</p>
|
||||
<a href="/contact.html" class="action-button">Quick Start</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<br />
|
||||
|
||||
<section class="flex-container">
|
||||
<div class="flex-container-inner">
|
||||
<h1 style="text-align: center">How it Works</h1>
|
||||
<p>
|
||||
Distrust used the <a href="https://docs.distrust.co/qkm/">
|
||||
Quorum Key Management</a> specification to generate
|
||||
Quorum Key Management</a> specification to generate
|
||||
entropy offline and used it to derive a
|
||||
<a href="/public_key">PGP key</a> which anyone can
|
||||
encrypt to.
|
||||
|
@ -65,13 +64,11 @@
|
|||
Clients may choose to generate their own encryption key,
|
||||
encrypt data, then encrypt that key to the
|
||||
<a href="/public-key">Distrust Disaster Recovery Public
|
||||
Key</a>. In this way the data is never exposed to
|
||||
Key</a>. In this way the data is never exposed to
|
||||
Distrust in any form, but the client is responsible for backing up data.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="flex-container">
|
||||
<div class="flex-container-inner">
|
||||
<h1 style="text-align: center">Security</h1>
|
||||
<p>
|
||||
|
@ -97,7 +94,7 @@
|
|||
<p>
|
||||
Being able to verify the compiler by
|
||||
<a href="https://en.wikipedia.org/wiki/Bootstrapping_(compilers)">
|
||||
bootstrapping</a> it in order to ensure it is not
|
||||
bootstrapping</a> it in order to ensure it is not
|
||||
capable of injection malicious code at runtime is an
|
||||
essential part of supply chain security - and often
|
||||
ignored.
|
||||
|
@ -129,9 +126,7 @@
|
|||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="flex-container">
|
||||
<div class="flex-container-inner">
|
||||
<h1 style="text-align: center">The Approach</h1>
|
||||
<p>
|
||||
|
@ -147,7 +142,8 @@
|
|||
you can use our blueprint to set up the system yourself
|
||||
- and we invite you to do so. You can find the
|
||||
documentation on how QKM works
|
||||
<a href="https://docs.distrust.co/qkm">here</a></p>
|
||||
<a href="https://docs.distrust.co/qkm">here</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Most, if not all current commercial backup/disaster
|
||||
|
@ -164,7 +160,6 @@
|
|||
We invite you to question any part of our system.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
{%- include footer.html -%}
|
||||
</div>
|
||||
|
|
|
@ -28,44 +28,46 @@
|
|||
The dates are always interpreted in UTC (Coordinated Universal Time), at 12:00AM of the
|
||||
selected date.
|
||||
|
||||
The two dates which are configurable, <b>from_date</b> and <b>upto_date</b> allow for
|
||||
The two dates which are configurable, <b>from_date</b> and <b>to_date</b> allow for
|
||||
the following configurations:
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>from_date < upto_date</b>: makes the policy active during a time window. (e.g from_date:
|
||||
2024/08/01, upto_date: 2024/09/01 would make the policy active only between those dates)
|
||||
</li>
|
||||
<li>
|
||||
<b>upto_date < from_date</b>: makes the policy in-active during a time window (e.g upto_date:
|
||||
2024/08/01, from_date: 2024/09/01 would make the policy in-active only between those
|
||||
dates)
|
||||
</li>
|
||||
<li>
|
||||
<b>upto_date only</b>: makes the policy expire after the <b>upto_date</b> (e.g upto_date:
|
||||
2027/01/01 means the policy is never active again after this date.)
|
||||
</li>
|
||||
<li>
|
||||
<b>from_date only</b>: makes the policy active after the <b>from_date</b> (e.g from_date:
|
||||
2025/01/01 means the policy is active only starting after that date)
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
|
||||
<label for="policy_valid_upto_date"><b>upto_date</b> *</label>
|
||||
<input required type="date" id="policy_valid_upto_date" name="policy_valid_upto_date">
|
||||
<label for="policy_valid_after_date"><b>from_date</b></label>
|
||||
<input type="date" id="policy_valid_after_date" name="policy_valid_after_date">
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<label for="policy_valid_after_date"><b>from_date</b> *</label>
|
||||
<input required type="date" id="policy_valid_after_date" name="policy_valid_after_date">
|
||||
<label for="policy_valid_to_date"><b>to_date</b></label>
|
||||
<input type="date" id="policy_valid_to_date" name="policy_valid_to_date">
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<label for="policy_mutable">Is the policy editable (mutable) while it's active?</label>
|
||||
<div class="timeline">
|
||||
<div id="segment-left" class="segment"></div>
|
||||
<div id="segment-middle" class="segment"></div>
|
||||
<div id="segment-right" class="segment"></div>
|
||||
<div class="marker marker-1">
|
||||
</div>
|
||||
<div class="date-container from-date-container">
|
||||
<span id="from-date-arrow"></span>
|
||||
<div id="from_date"></div>
|
||||
</div>
|
||||
<div class="marker marker-2">
|
||||
</div>
|
||||
<div class="date-container to-date-container">
|
||||
<span id="to-date-arrow"></span>
|
||||
<div id="to_date"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<label for="policy_mutable">
|
||||
Is the policy editable (mutable) while it's active?
|
||||
</label>
|
||||
<br>
|
||||
<select required name="policy_mutable" id="policy_mutable">
|
||||
<option disabled selected value> -- select an option -- </option>
|
||||
|
@ -79,10 +81,11 @@
|
|||
<section>
|
||||
<h2>Remote Recovery via Cryptographic Signatures</h2>
|
||||
<p>
|
||||
This type of recovery makes it possible to recover data remotely
|
||||
by providing cryptographic signatures to show intent of recovery.
|
||||
We support all widely used types of signatures such as `OpenPGP`,
|
||||
ETH, BTC, etc.
|
||||
This type of recovery makes it possible to recover data
|
||||
remotely by providing cryptographic signatures to show
|
||||
intent of recovery. We support all widely used types of
|
||||
signatures such as OpenPGP, ETH, BTC, etc. (Contact us if
|
||||
you would like us to support other protocols)
|
||||
</p>
|
||||
|
||||
<label for="remote_available">Can recovery be authorized using threshold based cryptographic
|
||||
|
@ -98,17 +101,22 @@
|
|||
<br>
|
||||
|
||||
<div id="remote_available_container" class="hidden">
|
||||
<label>What threshold would you like to use for the cryptographic signing recovery method? (2/3,
|
||||
3/5,
|
||||
4/7
|
||||
etc)</label>
|
||||
<label>
|
||||
What threshold would you like to use for the
|
||||
cryptographic signing recovery method? (2/3, 3/5, 4/7,
|
||||
etc.)
|
||||
</label>
|
||||
<br>
|
||||
<input type="text" id="remote_threshold" name="remote_threshold">
|
||||
<!-- if is_remote_available is true -->
|
||||
<p>Please select public keys which can be used for recovery. These keys should be valid public keys
|
||||
for whichever protocols you would like to use. You may use a mix of protocols. Ensure each file
|
||||
only has 1 key:</p>
|
||||
<div class="error-field" id="remote_threshold_error"></div>
|
||||
<p>
|
||||
Please select public keys which can be used for recovery.
|
||||
These keys should be valid public keys for whichever
|
||||
protocols you would like to use. You may use a mix of
|
||||
protocols. Ensure each file only has 1 key:</p>
|
||||
<input type="file" id="pub_keys" name="files[]" multiple>
|
||||
<br>
|
||||
<div class="error-field" id="pub_keys_error"></div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
@ -142,21 +150,23 @@
|
|||
<input type="text" id="kyc_threshold" name="kyc_threshold">
|
||||
|
||||
<p>
|
||||
Please select KYC data for individuals who can participate in recovery.
|
||||
Each person's data should be a `.toml` file. Pictures of front and back
|
||||
of IDs should be base64 encoded and listed in the <b>id_images</b> array.
|
||||
The supported ID types are Driver's License, Passport, National Identity Card:
|
||||
Please select KYC data for individuals who can
|
||||
participate in recovery. Each person's data should be a
|
||||
.toml file. Pictures of front and back of IDs should be
|
||||
base64 encoded and listed in the <b>id_images</b> array.
|
||||
The supported ID types are Driver's License, Passport,
|
||||
National Identity Card:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
first_name = "John"
|
||||
last_name = "Doe"
|
||||
date_of_birth = "1990-01-01"
|
||||
id_images = ["<base_64_encoded_image>", "<base_64_encoded_image>", ...]
|
||||
country_of_birth = "US"
|
||||
first_name = "John"
|
||||
last_name = "Doe"
|
||||
date_of_birth = "1990-01-01"
|
||||
id_images = ["<base_64_encoded_image>", "<base_64_encoded_image>", ...]
|
||||
country_of_birth = "US"
|
||||
</code>
|
||||
</pre>
|
||||
</pre>
|
||||
|
||||
<input type="file" id="kyc_data" name="files[]" multiple>
|
||||
</div>
|
||||
|
@ -167,10 +177,11 @@
|
|||
<section>
|
||||
<h2>Data Storage</h2>
|
||||
<p>
|
||||
This part of the policy allows you to select wether you would like
|
||||
Distrust to fully back up all your data, or to only hold an encryption
|
||||
key in escrow, in which case you are responsible for redundantly backing up
|
||||
the encrypted data (learn more <a href="/data-storage.html">here</a>)
|
||||
This part of the policy allows you to select wether you
|
||||
would like Distrust to fully back up all your data, or to
|
||||
only hold an encryption key in escrow, in which case you are
|
||||
responsible for redundantly backing up the encrypted data
|
||||
(learn more <a href="/data-storage.html">here</a>)
|
||||
</p>
|
||||
<label>Type of data storage *</label>
|
||||
<br>
|
||||
|
@ -193,6 +204,24 @@
|
|||
<option value="true">Yes</option>
|
||||
<option value="false">No</option>
|
||||
</select>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<label>Is this a deadman switch?</label>
|
||||
<p>
|
||||
Deadman switches can only be used with "key-escrow" mode,
|
||||
and not "fully managed". If a policy is defined as a deadman
|
||||
switch, the escrow key will be emailed to the designated
|
||||
email addresses or posted on the Distrust website, or both,
|
||||
as preferred.
|
||||
</p>
|
||||
<br>
|
||||
<select required name="multi_rule_requirement" id="multi_rule_requirement">
|
||||
<option disabled selected value> -- select an option -- </option>
|
||||
<option value="true">Yes</option>
|
||||
<option value="false">No</option>
|
||||
</select>
|
||||
</section>
|
||||
|
||||
<input type="submit" value="Generate Policy">
|
||||
|
@ -200,188 +229,13 @@
|
|||
|
||||
|
||||
<form id="policy">
|
||||
<textarea id="generated-policy-form" disabled placeholder="Click 'Generate Policy'"></textarea>
|
||||
<textarea
|
||||
id="generated-policy-form"
|
||||
disabled placeholder="Click 'Generate Policy'">
|
||||
</textarea>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function resetFormFields() {
|
||||
const form = document.getElementById('wizard-container');
|
||||
form.reset();
|
||||
|
||||
const policy_field = document.getElementById('policy');
|
||||
form.reset();
|
||||
}
|
||||
|
||||
window.onload = resetFormFields;
|
||||
|
||||
function extractValues() {
|
||||
const policy = {}
|
||||
|
||||
const policy_valid_upto_date_el = document.getElementById('policy_valid_upto_date');
|
||||
const policy_valid_upto_date = policy_valid_upto_date_el.value.replace(/-/g, "/");
|
||||
if (policy_valid_upto_date) {
|
||||
policy.policy_valid_upto_date = policy_valid_upto_date;
|
||||
console.log(policy_valid_upto_date);
|
||||
}
|
||||
|
||||
const policy_valid_after_date_el = document.getElementById('policy_valid_after_date');
|
||||
const policy_valid_after_date = policy_valid_after_date_el.value.replace(/-/g, "/");
|
||||
if (policy_valid_after_date) {
|
||||
policy.policy_valid_after_date = policy_valid_after_date;
|
||||
console.log(policy_valid_after_date);
|
||||
}
|
||||
|
||||
const policy_mutable_el = document.getElementById('policy_mutable');
|
||||
const policy_mutable = policy_mutable_el.value;
|
||||
if (policy_mutable) {
|
||||
policy.policy_mutable = policy_mutable;
|
||||
console.log(policy_mutable);
|
||||
}
|
||||
|
||||
const remote_available_el = document.getElementById('remote_available');
|
||||
const remote_available = remote_available_el.value;
|
||||
if (remote_available) {
|
||||
policy.remote_available = remote_available;
|
||||
console.log(remote_available);
|
||||
}
|
||||
|
||||
const remote_threshold_el = document.getElementById('remote_threshold');
|
||||
const remote_threshold = remote_threshold_el.value;
|
||||
if (remote_threshold) {
|
||||
policy.remote_threshold = remote_threshold;
|
||||
console.log(remote_threshold);
|
||||
}
|
||||
|
||||
const pub_keys_el = document.getElementById('pub_keys');
|
||||
const pub_keys = pub_keys_el.files;
|
||||
if (pub_keys) {
|
||||
policy.pub_keys = pub_keys;
|
||||
console.log(pub_keys);
|
||||
}
|
||||
|
||||
const kyc_available_el = document.getElementById('kyc_available');
|
||||
const kyc_available = kyc_available_el.value;
|
||||
if (kyc_available) {
|
||||
policy.kyc_available = kyc_available;
|
||||
console.log(kyc_available);
|
||||
}
|
||||
|
||||
const kyc_threshold_el = document.getElementById('kyc_threshold');
|
||||
const kyc_threshold = kyc_threshold_el.value;
|
||||
if (kyc_threshold) {
|
||||
policy.kyc_threshold = kyc_threshold;
|
||||
console.log(kyc_threshold);
|
||||
}
|
||||
|
||||
const kyc_data_el = document.getElementById('kyc_data');
|
||||
const kyc_data = kyc_data_el.files;
|
||||
if (kyc_data) {
|
||||
policy.kyc_data = kyc_data;
|
||||
console.log(kyc_data);
|
||||
}
|
||||
|
||||
const data_storage_el = document.getElementById('data_storage');
|
||||
const data_storage = data_storage_el.value;
|
||||
if (data_storage) {
|
||||
policy.data_storage = data_storage;
|
||||
console.log(data_storage)
|
||||
}
|
||||
|
||||
const multi_rule_requirement_el = document.getElementById('multi_rule_requirement');
|
||||
const multi_rule_requirement = multi_rule_requirement_el.value;
|
||||
if (multi_rule_requirement) {
|
||||
policy.multi_rule_requirement = multi_rule_requirement;
|
||||
console.log(multi_rule_requirement);
|
||||
}
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
function generatePolicy(event) {
|
||||
event.preventDefault()
|
||||
const policy_values = extractValues();
|
||||
|
||||
const toml_policy = objectToTOML(policy_values);
|
||||
console.log(toml_policy);
|
||||
|
||||
const policy_text_el = document.getElementById('policy');
|
||||
policy_text_el.value = toml_policy;
|
||||
}
|
||||
|
||||
function objectToTOML(obj, indent = '') {
|
||||
let toml = '';
|
||||
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
const value = obj[key];
|
||||
|
||||
if (typeof value === 'object' && !Array.isArray(value)) {
|
||||
toml += `${indent}[${key}]\n`;
|
||||
toml += objectToTOML(value, `${indent} `);
|
||||
} else if (Array.isArray(value)) {
|
||||
toml += `${indent}${key} = [${value.map(v => JSON.stringify(v)).join(', ')}]\n`;
|
||||
} else {
|
||||
toml += `${indent}${key} = ${JSON.stringify(value)}\n`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toml;
|
||||
}
|
||||
|
||||
let remote_available_el = document.getElementById('remote_available');
|
||||
remote_available_el.addEventListener('input', function () {
|
||||
let currentValue = remote_available_el.value;
|
||||
let remote_available_container = document.getElementById('remote_available_container');
|
||||
if (currentValue == 'true') {
|
||||
remote_available_container.classList.remove('hidden');
|
||||
} else {
|
||||
remote_available_container.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
let kyc_available_el = document.getElementById('kyc_available');
|
||||
kyc_available_el.addEventListener('input', function () {
|
||||
let currentValue = kyc_available_el.value;
|
||||
let remote_available_container = document.getElementById('kyc_available_container');
|
||||
if (currentValue == 'true') {
|
||||
remote_available_container.classList.remove('hidden');
|
||||
} else {
|
||||
remote_available_container.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
textarea::-webkit-input-placeholder {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
#wizard-container {
|
||||
border: 1px solid white;
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
color: white;
|
||||
margin: 50px 0px;
|
||||
}
|
||||
|
||||
#generated-policy-form {
|
||||
height: 400px;
|
||||
padding: 30px;
|
||||
margin-top: 30px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
</style>
|
||||
</main>
|
||||
{%- include footer.html -%}
|
||||
</div>
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
* Dark theme variables
|
||||
*/
|
||||
|
||||
:root {
|
||||
--base-color: #FFFFFF;
|
||||
--border: solid 2px rgba(219, 219, 219, 0.9);
|
||||
--selection-background: rgba(219, 219, 219, 0.99);
|
||||
--selection-text: #000;
|
||||
--background-color: #04355d;
|
||||
--text-color: var(--base-color);
|
||||
--placeholder-color: var(--base-color);
|
||||
--link-color: var(--base-color);
|
||||
--code-color-1: #aaaaaa;
|
||||
--code-color-2: #ffffcc;
|
||||
--code-color-3: #F00000;
|
||||
--code-color-4: #F0A0A0;
|
||||
--code-color-5: #b38aff;
|
||||
--code-color-6: #5ba711;
|
||||
--code-color-7: #e4e477;
|
||||
--code-color-8: #000080;
|
||||
--code-color-9: #05ca05;
|
||||
--code-color-10: #888888;
|
||||
--code-color-11: #555555;
|
||||
--code-color-12: #800080;
|
||||
--code-color-13: #00d4d4;
|
||||
--code-color-14: #00c1c1;
|
||||
--code-color-15: #ed9d13;
|
||||
--code-color-16: #1e90ff;
|
||||
--code-color-17: #800000;
|
||||
--code-color-18: #bbbbbb;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
* Base variables
|
||||
*/
|
||||
|
||||
:root {
|
||||
--base-color: #000;
|
||||
--border: dashed 1px rgba(0, 0, 0, 1);
|
||||
--selection-background: rgba(0, 0, 0, 0.99);
|
||||
--selection-text: #FFF;
|
||||
--background-color: #FFF;
|
||||
--text-color: var(--base-color);
|
||||
--placeholder-color: var(--base-color);
|
||||
--link-color: var(--base-color);
|
||||
--code-color-1: #aaaaaa;
|
||||
--code-color-2: #ffffcc;
|
||||
--code-color-3: #F00000;
|
||||
--code-color-4: #F0A0A0;
|
||||
--code-color-5: #0000aa;
|
||||
--code-color-6: #4c8317;
|
||||
--code-color-7: #aa0000;
|
||||
--code-color-8: #000080;
|
||||
--code-color-9: #00aa00;
|
||||
--code-color-10: #888888;
|
||||
--code-color-11: #555555;
|
||||
--code-color-12: #800080;
|
||||
--code-color-13: #00aaaa;
|
||||
--code-color-14: #009999;
|
||||
--code-color-15: #aa5500;
|
||||
--code-color-16: #1e90ff;
|
||||
--code-color-17: #800000;
|
||||
--code-color-18: #bbbbbb;
|
||||
}
|
775
_sass/base.scss
775
_sass/base.scss
|
@ -1,21 +1,127 @@
|
|||
@charset "utf-8";
|
||||
// @import url('https://fonts.googleapis.com/css?family=Rubik:400,700');
|
||||
// @import url('Rubik-VariableFont_wght.ttf');
|
||||
|
||||
@font-face {
|
||||
font-family: 'Rubik';
|
||||
src: url('fonts/Rubik-VariableFont_wght.ttf') format('truetype');
|
||||
}
|
||||
|
||||
/**
|
||||
* Style variables
|
||||
*/
|
||||
$base-font-family: 'Rubik', monospace !default;
|
||||
$base-font-size: 1.125rem !default;
|
||||
$mobile-font-size: 1.125rem !default;
|
||||
$base-line-height: 1.5 !default;
|
||||
$container-width: 90% !default;
|
||||
$container-max-width: 1300px !default;
|
||||
$container-max-width: 1000px !default;
|
||||
|
||||
html {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
:root {
|
||||
--base-color: rgba(0, 0, 0, 0.87);
|
||||
--header-color: black;
|
||||
--border: dashed 1px rgba(0, 0, 0, 1);
|
||||
--selection-background: rgba(0, 0, 0, 0.40);
|
||||
--selection-text: #FFF;
|
||||
--background-color: #FFF;
|
||||
--text-color: var(--base-color);
|
||||
--placeholder-color: var(--base-color);
|
||||
--link-color: blue;
|
||||
--navbar-link-color: black;
|
||||
--navbar-link-hover-color: gray;
|
||||
--theme-slider-state: translateX(0px);
|
||||
--code-color-1: #aaaaaa;
|
||||
--code-color-2: #ffffcc;
|
||||
--code-color-3: #F00000;
|
||||
}
|
||||
|
||||
|
||||
:root.dark-theme {
|
||||
--base-color: rgba(255, 255, 255, 0.87);
|
||||
--header-color: white;
|
||||
--border: solid 2px rgba(219, 219, 219, 0.9);
|
||||
--selection-background: rgba(219, 219, 219, 0.99);
|
||||
--selection-text: #000;
|
||||
--background-color: #141414;
|
||||
--text-color: var(--base-color);
|
||||
--placeholder-color: rgba(0, 0, 0, 0.5);
|
||||
--link-color: var(--base-color);
|
||||
--navbar-link-color: white;
|
||||
--navbar-link-hover-color: gray;
|
||||
--theme-slider-state: translateX(26px);
|
||||
/* yoinkt from Material Design 2014, Light Blue A200 */
|
||||
--mega-color: #40C4FF;
|
||||
--code-color-1: #569fe8;
|
||||
--code-color-2: #ffffcc;
|
||||
--code-color-3: #F00000;
|
||||
}
|
||||
|
||||
/* Dark mode */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--base-color: rgba(255, 255, 255, 0.87);
|
||||
--header-color: white;
|
||||
--border: solid 2px rgba(219, 219, 219, 0.9);
|
||||
--selection-background: rgba(219, 219, 219, 0.99);
|
||||
--selection-text: #000;
|
||||
--background-color: #141414;
|
||||
--text-color: var(--base-color);
|
||||
--placeholder-color: rgba(0, 0, 0, 0.5);
|
||||
--link-color: var(--base-color);
|
||||
--navbar-link-color: white;
|
||||
--navbar-link-hover-color: gray;
|
||||
--theme-slider-state: translateX(26px);
|
||||
/* yoinkt from Material Design 2014, Light Blue A200 */
|
||||
--mega-color: #40C4FF;
|
||||
--code-color-1: #569fe8;
|
||||
--code-color-2: #ffffcc;
|
||||
--code-color-3: #F00000;
|
||||
}
|
||||
}
|
||||
|
||||
/* Theme toggle button */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
transition: .4s;
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: var(--code-color-1);
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
transform: var(--theme-slider-state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Global
|
||||
|
@ -65,7 +171,7 @@ h6 {
|
|||
margin-top: 0px;
|
||||
margin-bottom: 12px;
|
||||
font-weight: bold;
|
||||
color: var(--text-color);
|
||||
color: var(--header-color);
|
||||
}
|
||||
|
||||
p,
|
||||
|
@ -78,11 +184,12 @@ ol {
|
|||
a {
|
||||
text-decoration: underline;
|
||||
color: var(--link-color);
|
||||
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--background-color);
|
||||
background-color: var(--base-color);
|
||||
color: var(--base-color);
|
||||
background-color: var(--background-color);
|
||||
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
|
@ -103,11 +210,6 @@ a:hover {
|
|||
}
|
||||
|
||||
p {
|
||||
/*
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
white-space: pre-wrap;
|
||||
*/
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
@ -121,8 +223,9 @@ footer {
|
|||
}
|
||||
|
||||
header {
|
||||
margin-top: 24px;
|
||||
padding: 24px;
|
||||
margin-bottom: 24px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.13);
|
||||
}
|
||||
|
||||
header p {
|
||||
|
@ -142,12 +245,18 @@ hr {
|
|||
* Navbar
|
||||
*/
|
||||
.menu-logo {
|
||||
height: 60px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
|
||||
#home-link {
|
||||
color: var(--base-color);
|
||||
background: var(--background-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#home-link:hover {
|
||||
background: none;
|
||||
text-decoration: none;
|
||||
color:var(--navbar-link-hover-color);
|
||||
}
|
||||
|
||||
.header-page-links li:before {
|
||||
|
@ -158,11 +267,20 @@ hr {
|
|||
margin: 0px 4px;
|
||||
font-size: 1.1rem;
|
||||
text-decoration: none;
|
||||
color: var(--navbar-link-color);
|
||||
}
|
||||
|
||||
.header-page-links a:hover {
|
||||
background-color: transparent;
|
||||
color: lightgrey;
|
||||
color: var(--navbar-link-hover-color);
|
||||
}
|
||||
|
||||
.left-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.left-menu img {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.right-menu {
|
||||
|
@ -190,7 +308,7 @@ hr {
|
|||
.menu-button::before,
|
||||
.menu-button::after {
|
||||
display: block;
|
||||
background-color: #fff;
|
||||
background-color: var(--background-color);
|
||||
position: absolute;
|
||||
height: 4px;
|
||||
width: 30px;
|
||||
|
@ -283,22 +401,35 @@ hr {
|
|||
/**
|
||||
* Buttons
|
||||
*/
|
||||
.action-button {
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 10px 20px 9px 20px;
|
||||
margin-top: 10px;
|
||||
border-color: white;
|
||||
border: solid 1px;
|
||||
color: black;
|
||||
background-color: white;
|
||||
color: var(--base-color);
|
||||
background-color: var(--background-color);
|
||||
border: 2px solid white;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.action-button:hover {
|
||||
background-color: transparent;
|
||||
border-color: white;
|
||||
border: solid 1px;
|
||||
color: white;
|
||||
.button:hover {
|
||||
/* invert */
|
||||
background-color: var(--base-color);
|
||||
color: var(--background-color);
|
||||
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
/* important button */
|
||||
.mega.button {
|
||||
background-color: var(--mega-color);
|
||||
color: var(--base-color);
|
||||
border: 2px solid var(--mega-color);
|
||||
}
|
||||
|
||||
.mega.button:hover {
|
||||
/* invert */
|
||||
background-color: color-mix(in srgb, var(--mega-color), white 10%);
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.button-container {
|
||||
|
@ -344,17 +475,13 @@ hr {
|
|||
* Header/Navigation
|
||||
*/
|
||||
.menu {
|
||||
border-bottom: var(--border);
|
||||
margin-bottom: 20px;
|
||||
/* border-bottom: var(--border); */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 25px;
|
||||
}
|
||||
|
||||
.menu ul {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
padding-left: 0px;
|
||||
list-style-type: none;
|
||||
text-align: right;
|
||||
|
@ -384,12 +511,9 @@ select,
|
|||
textarea {
|
||||
width: 100%;
|
||||
resize: none;
|
||||
background-color: var(--background-color);
|
||||
color: var(--text-color);
|
||||
caret-color: var(--text-color);
|
||||
font-size: $base-font-size;
|
||||
font-family: $base-font-family;
|
||||
line-height: $base-line-height;
|
||||
background-color: white;
|
||||
color: black;
|
||||
caret-color: black;
|
||||
}
|
||||
|
||||
input,
|
||||
|
@ -434,6 +558,50 @@ textarea {
|
|||
vertical-align: top;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contact Form
|
||||
*/
|
||||
.required:after {
|
||||
content: "*";
|
||||
color: red;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.form-input,
|
||||
.form-select,
|
||||
.form-textarea {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.form-checkbox-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-submit-button {
|
||||
padding: 10px 20px;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.form-submit-button:hover {
|
||||
background-color: #45a049;
|
||||
}
|
||||
|
||||
/**
|
||||
* Homepage
|
||||
*/
|
||||
|
@ -457,375 +625,18 @@ textarea {
|
|||
}
|
||||
|
||||
section {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.extra-spacing {
|
||||
margin-top: 70px;
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
|
||||
.companies {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 30px 0px;
|
||||
}
|
||||
|
||||
.companies div {
|
||||
width: 27%;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 120px;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.companies a img {
|
||||
height: 45px;
|
||||
filter: grayscale(100%);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.companies a:hover {
|
||||
background-color: none;
|
||||
background: none;
|
||||
text-decoration: none;
|
||||
margin-top: 48px;
|
||||
margin-bottom: 120px;
|
||||
}
|
||||
|
||||
.text-well {
|
||||
max-width: 600px;
|
||||
max-width: 100%;
|
||||
padding-right: 35px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Code and syntax highlighting
|
||||
*/
|
||||
.lineno {
|
||||
color: var(--code-color-1);
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
figure.highlight {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: var(--background-color);
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
font-size: $base-font-size;
|
||||
color: var(--text-color);
|
||||
line-height: 1.7 !important;
|
||||
font-family: $base-font-family !important;
|
||||
}
|
||||
|
||||
.highlight .hll {
|
||||
background-color: var(--code-color-2);
|
||||
}
|
||||
|
||||
.highlight .c {
|
||||
color: var(--code-color-1);
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment */
|
||||
.highlight .err {
|
||||
color: var(--code-color-3);
|
||||
background-color: var(--code-color-4);
|
||||
}
|
||||
|
||||
/* Error */
|
||||
.highlight .k {
|
||||
color: var(--code-color-5);
|
||||
}
|
||||
|
||||
/* Keyword */
|
||||
.highlight .cm {
|
||||
color: var(--code-color-1);
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment.Multiline */
|
||||
.highlight .cp {
|
||||
color: var(--code-color-6);
|
||||
}
|
||||
|
||||
/* Comment.Preproc */
|
||||
.highlight .c1 {
|
||||
color: var(--code-color-1);
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment.Single */
|
||||
.highlight .cs {
|
||||
color: var(--code-color-5);
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Comment.Special */
|
||||
.highlight .gd {
|
||||
color: var(--code-color-7);
|
||||
}
|
||||
|
||||
/* Generic.Deleted */
|
||||
.highlight .ge {
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
/* Generic.Emph */
|
||||
.highlight .gr {
|
||||
color: var(--code-color-7);
|
||||
}
|
||||
|
||||
/* Generic.Error */
|
||||
.highlight .gh {
|
||||
color: var(--code-color-8);
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Generic.Heading */
|
||||
.highlight .gi {
|
||||
color: var(--code-color-9);
|
||||
}
|
||||
|
||||
/* Generic.Inserted */
|
||||
.highlight .go {
|
||||
color: var(--code-color-10);
|
||||
}
|
||||
|
||||
/* Generic.Output */
|
||||
.highlight .gp {
|
||||
color: var(--code-color-11);
|
||||
}
|
||||
|
||||
/* Generic.Prompt */
|
||||
.highlight .gs {
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Generic.Strong */
|
||||
.highlight .gu {
|
||||
color: var(--code-color-12);
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Generic.Subheading */
|
||||
.highlight .gt {
|
||||
color: var(--code-color-7);
|
||||
}
|
||||
|
||||
/* Generic.Traceback */
|
||||
.highlight .kc {
|
||||
color: var(--code-color-5);
|
||||
}
|
||||
|
||||
/* Keyword.Constant */
|
||||
.highlight .kd {
|
||||
color: var(--code-color-5);
|
||||
}
|
||||
|
||||
/* Keyword.Declaration */
|
||||
.highlight .kn {
|
||||
color: var(--code-color-5);
|
||||
}
|
||||
|
||||
/* Keyword.Namespace */
|
||||
.highlight .kp {
|
||||
color: var(--code-color-5);
|
||||
}
|
||||
|
||||
/* Keyword.Pseudo */
|
||||
.highlight .kr {
|
||||
color: var(--code-color-5);
|
||||
}
|
||||
|
||||
/* Keyword.Reserved */
|
||||
.highlight .kt {
|
||||
color: var(--code-color-13);
|
||||
}
|
||||
|
||||
/* Keyword.Type */
|
||||
.highlight .m {
|
||||
color: var(--code-color-14);
|
||||
}
|
||||
|
||||
/* Literal.Number */
|
||||
.highlight .s {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String */
|
||||
.highlight .na {
|
||||
color: var(--code-color-16);
|
||||
}
|
||||
|
||||
/* Name.Attribute */
|
||||
.highlight .nb {
|
||||
color: var(--code-color-13);
|
||||
}
|
||||
|
||||
/* Name.Builtin */
|
||||
.highlight .nc {
|
||||
color: var(--code-color-9);
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
/* Name.Class */
|
||||
.highlight .no {
|
||||
color: var(--code-color-7);
|
||||
}
|
||||
|
||||
/* Name.Constant */
|
||||
.highlight .nd {
|
||||
color: var(--code-color-10);
|
||||
}
|
||||
|
||||
/* Name.Decorator */
|
||||
.highlight .ni {
|
||||
color: var(--code-color-17);
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Name.Entity */
|
||||
.highlight .nf {
|
||||
color: var(--code-color-9);
|
||||
}
|
||||
|
||||
/* Name.Function */
|
||||
.highlight .nn {
|
||||
color: var(--code-color-13);
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
/* Name.Namespace */
|
||||
.highlight .nt {
|
||||
color: var(--code-color-16);
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
/* Name.Tag */
|
||||
.highlight .nv {
|
||||
color: var(--code-color-7);
|
||||
}
|
||||
|
||||
/* Name.Variable */
|
||||
.highlight .ow {
|
||||
color: var(--code-color-5);
|
||||
}
|
||||
|
||||
/* Operator.Word */
|
||||
.highlight .w {
|
||||
color: var(--code-color-18);
|
||||
}
|
||||
|
||||
/* Text.Whitespace */
|
||||
.highlight .mf {
|
||||
color: var(--code-color-14);
|
||||
}
|
||||
|
||||
/* Literal.Number.Float */
|
||||
.highlight .mh {
|
||||
color: var(--code-color-14);
|
||||
}
|
||||
|
||||
/* Literal.Number.Hex */
|
||||
.highlight .mi {
|
||||
color: var(--code-color-14);
|
||||
}
|
||||
|
||||
/* Literal.Number.Integer */
|
||||
.highlight .mo {
|
||||
color: var(--code-color-14);
|
||||
}
|
||||
|
||||
/* Literal.Number.Oct */
|
||||
.highlight .sb {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Backtick */
|
||||
.highlight .sc {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Char */
|
||||
.highlight .sd {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Doc */
|
||||
.highlight .s2 {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Double */
|
||||
.highlight .se {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Escape */
|
||||
.highlight .sh {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Heredoc */
|
||||
.highlight .si {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Interpol */
|
||||
.highlight .sx {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Other */
|
||||
.highlight .sr {
|
||||
color: var(--code-color-14);
|
||||
}
|
||||
|
||||
/* Literal.String.Regex */
|
||||
.highlight .s1 {
|
||||
color: var(--code-color-15);
|
||||
}
|
||||
|
||||
/* Literal.String.Single */
|
||||
.highlight .ss {
|
||||
color: var(--code-color-5);
|
||||
}
|
||||
|
||||
/* Literal.String.Symbol */
|
||||
.highlight .bp {
|
||||
color: var(--code-color-13);
|
||||
}
|
||||
|
||||
/* Name.Builtin.Pseudo */
|
||||
.highlight .vc {
|
||||
color: var(--code-color-7);
|
||||
}
|
||||
|
||||
/* Name.Variable.Class */
|
||||
.highlight .vg {
|
||||
color: var(--code-color-7);
|
||||
}
|
||||
|
||||
/* Name.Variable.Global */
|
||||
.highlight .vi {
|
||||
color: var(--code-color-7);
|
||||
}
|
||||
|
||||
/* Name.Variable.Instance */
|
||||
.highlight .il {
|
||||
color: var(--code-color-14);
|
||||
}
|
||||
|
||||
/* Literal.Number.Integer.Long */
|
||||
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
width: 100%;
|
||||
|
@ -835,66 +646,6 @@ pre {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Carousel
|
||||
*/
|
||||
|
||||
.carousel-container {
|
||||
padding-left: 80px;
|
||||
}
|
||||
|
||||
#carousel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
height: 320px;
|
||||
padding-left: 100px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.carousel-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
max-width: 400px;
|
||||
height: 80px;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
opacity: 0.5;
|
||||
margin: 5px 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transition: transform 1s ease, font-size 1s ease, opacity 1s ease;
|
||||
transform-origin: center;
|
||||
visibility: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.carousel-link {
|
||||
text-align: left;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1.2;
|
||||
max-height: 2.4em;
|
||||
width: 100%;
|
||||
margin: 0 10px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.carousel-item.active {
|
||||
transform: translateY(0) scale(1.2);
|
||||
font-size: 20px;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
/** end carousel */
|
||||
|
||||
/**
|
||||
* Blog
|
||||
*/
|
||||
|
@ -934,6 +685,104 @@ body {
|
|||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
.timeline {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.segment {
|
||||
height: 5px;
|
||||
background-color: white;
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
.active-segment {
|
||||
background-color: #33ff57;
|
||||
}
|
||||
|
||||
.marker {
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
width: 120px;
|
||||
border-left: 2px solid black;
|
||||
}
|
||||
|
||||
/**
|
||||
* timeline
|
||||
*/
|
||||
|
||||
#to-date,
|
||||
#from-date {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#from-date-arrow,
|
||||
#to-date-arrow {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.date-container {
|
||||
width: 120px;
|
||||
position: absolute;
|
||||
margin-left: -60px;
|
||||
margin-top: -5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.from-date-container {
|
||||
left: 33.33%;
|
||||
}
|
||||
|
||||
.to-date-container {
|
||||
left: 66.66%;
|
||||
}
|
||||
|
||||
.marker-1 {
|
||||
left: 33.33%;
|
||||
}
|
||||
|
||||
.marker-2 {
|
||||
left: 66.66%;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wizard
|
||||
*/
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
textarea::-webkit-input-placeholder {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
#wizard-container {
|
||||
border: 1px solid white;
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
color: white;
|
||||
margin: 50px 0px;
|
||||
}
|
||||
|
||||
#generated-policy-form {
|
||||
height: 400px;
|
||||
padding: 30px;
|
||||
margin-top: 30px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
/**
|
||||
* media queries
|
||||
*/
|
||||
|
@ -970,4 +819,4 @@ body {
|
|||
padding-top: 50px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
[
|
||||
{
|
||||
"link": "https://www.wired.com/story/the-untold-story-of-solarwinds-the-boldest-supply-chain-hack-ever/",
|
||||
"description": "SolarWind: The Untold Story of the Boldest Supply-Chain Hack Ever"
|
||||
},
|
||||
{
|
||||
"link": "https://www.theverge.com/2018/4/24/17275982/myetherwallet-hack-bgp-dns-hijacking-stolen-ethereum",
|
||||
"description": "Hackers emptied Ethereum wallets by breaking the basic infrastructure of the internet"
|
||||
},
|
||||
{
|
||||
"link": "https://milksad.info/",
|
||||
"description": "A practical explanation of how weak entropy can ruin your day - and your savings."
|
||||
},
|
||||
{
|
||||
"link": "https://thehackerblog.com/zero-days-without-incident-compromising-angular-via-expired-npm-publisher-email-domains-7kZplW4x/",
|
||||
"description": "Compromising Angular via Expired npm Publisher Email Domains"
|
||||
},
|
||||
{
|
||||
"link": "https://blog.ryotak.net/post/homebrew-security-incident-en/",
|
||||
"description": "Remote code execution in Homebrew by compromising the official Cask repository"
|
||||
},
|
||||
{
|
||||
"link": "https://gizmodo.com/u-s-federal-investigators-are-reportedly-looking-into-1846707144link4",
|
||||
"description": "U.S. Federal Investigators Are Reportedly Looking Into Codecov Security Breach, Undetected for Months"
|
||||
},
|
||||
{
|
||||
"link": "https://www.bleepingcomputer.com/news/security/big-sabotage-famous-npm-package-deletes-files-to-protest-ukraine-war/",
|
||||
"description": "BIG sabotage: Famous npm package deletes files to protest Ukraine war"
|
||||
},
|
||||
{
|
||||
"link": "https://certitude.consulting/blog/en/invisible-backdoor/",
|
||||
"description": "The Invisible JavaScript Backdoor"
|
||||
},
|
||||
{
|
||||
"link": "https://thehackernews.com/2022/06/multiple-backdoored-python-libraries.html?m=1",
|
||||
"description": "Multiple Backdoored Python Libraries Caught Stealing AWS Secrets and Keys"
|
||||
},
|
||||
{
|
||||
"link": "https://www.wired.com/story/3cx-supply-chain-attack-times-two/",
|
||||
"description": "The Huge 3CX Breach Was Actually 2 Linked Supply Chain Attacks"
|
||||
},
|
||||
{
|
||||
"link": "https://www.zdnet.com/article/iota-cryptocurrency-shuts-down-entire-network-after-wallet-hack/",
|
||||
"description": "IOTA cryptocurrency shuts down entire network after wallet hack "
|
||||
},
|
||||
{
|
||||
"link": "https://arstechnica.com/information-technology/2021/02/supply-chain-attack-that-fooled-apple-and-microsoft-is-attracting-copycats/",
|
||||
"description": "New type of supply-chain attack hit Apple, Microsoft and 33 other companies"
|
||||
},
|
||||
{
|
||||
"link": "https://www.bankinfosecurity.com/crypto-exchange-klayswap-loses-19m-after-bgp-hijack-a-18518",
|
||||
"description": "Crypto Exchange KLAYswap Loses $1.9M After BGP Hijack"
|
||||
},
|
||||
{
|
||||
"link": "https://www.businessinsider.com/kidnapped-crypto-exec-released-after-paying-1-million-bitcoin-ransom-2017-12",
|
||||
"description": "A kidnapped crypto executive was reportedly released after paying a $1 million bitcoin ransom"
|
||||
},
|
||||
{
|
||||
"link": "https://www.independent.co.uk/tech/bitcoin-robbery-torture-cryptocurrency-netherlands-a8807986.html",
|
||||
"description": "Bitcoin trader brutally tortured with drill in cryptocurrency robbery"
|
||||
},
|
||||
{
|
||||
"link": "https://www.vice.com/en/article/ne4pvg/police-in-ottawa-canada-charged-a-teen-with-armed-bitcoin-robbery-are-hunting-two-suspects",
|
||||
"description": "Three Armed Men Attempted to Rob a Bitcoin Exchange In Canada"
|
||||
},
|
||||
{
|
||||
"link": "https://www.birminghammail.co.uk/news/midlands-news/watch-masked-raiders-hold-up-16599570",
|
||||
"description": "Watch - Masked raiders hold up Bitcoin Exchange store in Sparkhill in front of dozens of witnesses"
|
||||
},
|
||||
{
|
||||
"link": "https://www.nzherald.co.nz/nz/crypto-heist-raiders-steal-safe-containing-4m-in-cryptocurrency-from-westmere-home/PI3L5LMS6PCSVABJDYSW5O4YGA/",
|
||||
"description": "Crypto heist: Raiders steal safe containing $4m in cryptocurrency from Westmere home"
|
||||
},
|
||||
{
|
||||
"link": "https://www.computerworld.com/article/2538534/data-center-robbery-leads-to-new-thinking-on-security.html",
|
||||
"description": "Data center robbery leads to new thinking on security"
|
||||
},
|
||||
{
|
||||
"link": "https://www.thirdsector.co.uk/plan-uk-alerts-supporters-theft-computer-servers-its-offices/management/article/1375208",
|
||||
"description": "Plan UK alerts supporters to theft of computer servers from its offices"
|
||||
},
|
||||
{
|
||||
"link": "https://www.pcmag.com/news/vudu-resets-passwords-after-user-data-stolen-in-burglary",
|
||||
"description": "Vudu Resets Passwords After User Data Stolen in Burglary"
|
||||
},
|
||||
{
|
||||
"link": "https://finance.yahoo.com/news/hackers-scored-data-center-logins-020028440.html",
|
||||
"description": "Hackers Scored Data Center Logins for Some of the World's Biggest Companies"
|
||||
},
|
||||
{
|
||||
"link": "https://www.cbsnews.com/news/nsa-broke-into-yahoo-and-google-data-centers-around-world-report-says/",
|
||||
"description": "NSA broke into Yahoo and Google data centers around world, report says"
|
||||
},
|
||||
{
|
||||
"link": "https://www.vice.com/en/article/3kxy4k/high-tech-japanese-hotel-service-robots-easily-hackable",
|
||||
"description": "High-Tech Japanese Hotel Finds Out Its Service Robots Are Easily Hackable"
|
||||
},
|
||||
{
|
||||
"link": "https://www.washingtonpost.com/news/innovations/wp/2017/07/21/how-a-fish-tank-helped-hack-a-casino/",
|
||||
"description": "How a fish tank helped hack a casino"
|
||||
},
|
||||
{
|
||||
"link": "https://www.wsj.com/articles/fraudsters-use-ai-to-mimic-ceos-voice-in-unusual-cybercrime-case-11567157402",
|
||||
"description": "Fraudsters Used AI to Mimic CEO's Voice in Unusual Cybercrime Case"
|
||||
},
|
||||
{
|
||||
"link": "https://www.forbes.com/sites/iainmartin/2023/08/21/blockchain-capitals-bart-stephens-lost-63-million-in-sim-swap-crypto-hack/?sh=6cc4576bf74c",
|
||||
"description": "Blockchain Capital's Bart Stephens Lost $6.3 Million In SIM-Swap Crypto Hack"
|
||||
},
|
||||
{
|
||||
"link": "https://www.wsj.com/articles/he-thought-his-phone-was-secure-then-he-lost-24-million-to-hackers-11573221600",
|
||||
"description": "He Thought His Phone Was Secure; Then He Lost $24 Million to Hackers"
|
||||
},
|
||||
{
|
||||
"link": "https://arstechnica.com/information-technology/2018/02/tesla-cloud-resources-are-hacked-to-run-cryptocurrency-mining-malware/",
|
||||
"description": "Tesla cloud resources are hacked to run cryptocurrency-mining malware"
|
||||
},
|
||||
{
|
||||
"link": "https://www.wired.com/story/sea-turtle-dns-hijacking/",
|
||||
"description": "Cyberspies Hijacked the Internet Domains of Entire Countries"
|
||||
}
|
||||
]
|
|
@ -9,57 +9,335 @@ collapsibleButton.addEventListener("click", function () {
|
|||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
fetch('../assets/js/carousel-items.json')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
createCarouselItems(data);
|
||||
initializeCarousel();
|
||||
})
|
||||
.catch(error => console.error('Error loading JSON:', error));
|
||||
// Toggle theme
|
||||
const toggleButton = document.getElementById('theme-toggle');
|
||||
const htmlElement = document.documentElement;
|
||||
|
||||
function applyTheme() {
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
if (savedTheme === 'dark') {
|
||||
toggleButton.checked = true;
|
||||
htmlElement.classList.add('dark-theme');
|
||||
} else {
|
||||
htmlElement.classList.remove('dark-theme');
|
||||
}
|
||||
}
|
||||
|
||||
toggleButton.addEventListener('click', () => {
|
||||
if (htmlElement.classList.contains('dark-theme')) {
|
||||
htmlElement.classList.remove('dark-theme');
|
||||
localStorage.setItem('theme', 'light');
|
||||
} else {
|
||||
htmlElement.classList.add('dark-theme');
|
||||
localStorage.setItem('theme', 'dark');
|
||||
}
|
||||
});
|
||||
|
||||
function createCarouselItems(items) {
|
||||
const carousel = document.querySelector('#carousel');
|
||||
items.forEach(item => {
|
||||
const itemDiv = document.createElement('div');
|
||||
itemDiv.className = 'carousel-item'
|
||||
// Load the saved theme on page load
|
||||
window.onload = () => {
|
||||
console.log('ih')
|
||||
// applyTheme();
|
||||
resetFormFields()
|
||||
};
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.className = 'carousel-link';
|
||||
link.href = item.link;
|
||||
link.target = '_blank';
|
||||
link.rel = 'noopener noreferrer';
|
||||
const linkText = document.createTextNode(item.description);
|
||||
|
||||
link.appendChild(linkText);
|
||||
itemDiv.appendChild(link);
|
||||
carousel.appendChild(itemDiv);
|
||||
function resetFormFields() {
|
||||
const form = document.getElementById('wizard-container');
|
||||
form.reset();
|
||||
|
||||
const policy_field = document.getElementById('policy');
|
||||
policy_field.reset();
|
||||
}
|
||||
|
||||
function readFileAsText(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function (e) {
|
||||
resolve(e.target.result);
|
||||
};
|
||||
|
||||
reader.onerror = function (e) {
|
||||
reject(new Error(`Error reading file ${file.name}: ${e.target.error.message}`));
|
||||
};
|
||||
|
||||
return reader.readAsText(file);
|
||||
});
|
||||
}
|
||||
|
||||
function initializeCarousel() {
|
||||
const carousel = document.querySelector('#carousel');
|
||||
const items = Array.from(carousel.children);
|
||||
const totalItems = items.length;
|
||||
const middleIndex = Math.floor(totalItems / 2);
|
||||
let currentIndex = -middleIndex;
|
||||
async function extractValues() {
|
||||
const policy = {}
|
||||
|
||||
function cycleItems() {
|
||||
currentIndex = (currentIndex - 1 + totalItems) % totalItems;
|
||||
updateCarouselItems();
|
||||
const policyValidToDateEl = document.getElementById('policy_valid_to_date');
|
||||
const policyValidToDate = policyValidToDateEl.value.replace(/-/g, "/");
|
||||
if (policyValidToDate) {
|
||||
policy.policy_valid_to_date = policyValidToDate;
|
||||
console.log(policyValidToDate);
|
||||
}
|
||||
|
||||
function updateCarouselItems() {
|
||||
items.forEach((item, index) => {
|
||||
let positionIndex = (currentIndex + index + totalItems) % totalItems;
|
||||
let offset = positionIndex - middleIndex;
|
||||
item.style.transform = `translateY(${offset * 100}%)`;
|
||||
item.classList.toggle('active', positionIndex === middleIndex);
|
||||
item.style.visibility = 'visible';
|
||||
});
|
||||
const policyValidAfterDateEl = document.getElementById('policy_valid_after_date');
|
||||
const policyValidAfterDate = policyValidAfterDateEl.value.replace(/-/g, "/");
|
||||
if (policyValidAfterDate) {
|
||||
policy.policy_valid_after_date = policyValidAfterDate;
|
||||
console.log(policyValidAfterDate);
|
||||
}
|
||||
|
||||
updateCarouselItems();
|
||||
setInterval(cycleItems, 7000);
|
||||
}
|
||||
const policyMutableLl = document.getElementById('policy_mutable');
|
||||
const policyMutable = policyMutableLl.value;
|
||||
if (policyMutable) {
|
||||
policy.policy_mutable = policyMutable;
|
||||
console.log(policyMutable);
|
||||
}
|
||||
|
||||
const remoteAvailableEl = document.getElementById('remote_available');
|
||||
const remoteAvailable = remoteAvailableEl.value;
|
||||
if (remoteAvailable) {
|
||||
policy.remote_available = remoteAvailable;
|
||||
console.log(remoteAvailable);
|
||||
}
|
||||
|
||||
const remoteThresholdEl = document.getElementById('remote_threshold');
|
||||
const remoteThreshold = remoteThresholdEl.value;
|
||||
if (remoteThreshold) {
|
||||
policy.remote_threshold = remoteThreshold;
|
||||
console.log(remoteThreshold);
|
||||
}
|
||||
|
||||
const pubKeysEl = document.getElementById('pub_keys');
|
||||
const pubKeys = pubKeysEl.files;
|
||||
|
||||
let pubKeyData = [];
|
||||
for (let i = 0; i < pubKeys.length; i++) {
|
||||
const pubKeyFile = pubKeys[i];
|
||||
const fileText = await readFileAsText(pubKeyFile);
|
||||
pubKeyData.push(fileText);
|
||||
}
|
||||
if (pubKeyData.length) {
|
||||
policy.pub_keys = pubKeyData;
|
||||
console.log(pubKeys);
|
||||
}
|
||||
|
||||
const kycAvailableEl = document.getElementById('kyc_available');
|
||||
const kycAvailable = kycAvailableEl.value;
|
||||
if (kycAvailable) {
|
||||
policy.kyc_available = kycAvailable;
|
||||
console.log(kycAvailable);
|
||||
}
|
||||
|
||||
const kycThresholdEl = document.getElementById('kyc_threshold');
|
||||
const kycThreshold = kycThresholdEl.value;
|
||||
if (kycThreshold) {
|
||||
policy.kyc_threshold = kycThreshold;
|
||||
console.log(kycThreshold);
|
||||
}
|
||||
|
||||
const kycDataEl = document.getElementById('kyc_data');
|
||||
const kycData = kycDataEl.files;
|
||||
if (kycData) {
|
||||
policy.kyc_data = kycData;
|
||||
console.log(kycData);
|
||||
}
|
||||
|
||||
const dataStorageEl = document.getElementById('data_storage');
|
||||
const dataStorage = dataStorageEl.value;
|
||||
if (dataStorage) {
|
||||
policy.data_storage = dataStorage;
|
||||
console.log(dataStorage)
|
||||
}
|
||||
|
||||
const multiRuleRequirementEl = document.getElementById('multi_rule_requirement');
|
||||
const multiRuleRequirement = multiRuleRequirementEl.value;
|
||||
if (multiRuleRequirement) {
|
||||
policy.multi_rule_requirement = multiRuleRequirement;
|
||||
console.log(multiRuleRequirement);
|
||||
}
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
async function generatePolicy(event) {
|
||||
event.preventDefault()
|
||||
const policyValues = extractValues();
|
||||
|
||||
const tomlPolicy = objectToTOML(policyValues);
|
||||
console.log(tomlPolicy);
|
||||
|
||||
const policyTextEl = document.getElementById('policy');
|
||||
policyTextEl.value = toml_policy;
|
||||
}
|
||||
|
||||
function validateThreshold(threshold) {
|
||||
const regex = /^\d+\/\d+$/;
|
||||
const valid = regex.test(threshold);
|
||||
let res = {
|
||||
threshold,
|
||||
};
|
||||
|
||||
console.log('threshold', threshold)
|
||||
if (valid) {
|
||||
const numbers = threshold.split('/');
|
||||
console.log('numbers', numbers)
|
||||
if (Number(numbers[0]) > Number(numbers[1])) {
|
||||
res.error = "Error: first number has to be lesser than second.";
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
res.error = "Error: invalid threshold value. Use n/m format where n < m"
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function objectToTOML(obj, indent = '') {
|
||||
let toml = '';
|
||||
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
const value = obj[key];
|
||||
|
||||
if (typeof value === 'object' && !Array.isArray(value)) {
|
||||
toml += `${indent}[${key}]\n`;
|
||||
toml += objectToTOML(value, `${indent} `);
|
||||
} else if (Array.isArray(value)) {
|
||||
toml += `${indent}${key} = [${value.map(v => JSON.stringify(v)).join(', ')}]\n`;
|
||||
} else {
|
||||
toml += `${indent}${key} = ${JSON.stringify(value)}\n`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toml;
|
||||
}
|
||||
|
||||
function clearSegments() {
|
||||
const segmentLeft = document.getElementById('segment-left');
|
||||
const segmentMiddle = document.getElementById('segment-middle');
|
||||
const segmentRight = document.getElementById('segment-right');
|
||||
|
||||
segmentLeft.classList.remove('active-segment');
|
||||
segmentMiddle.classList.remove('active-segment');
|
||||
segmentRight.classList.remove('active-segment');
|
||||
|
||||
const fromDateArrow = document.getElementById('from-date-arrow');
|
||||
const toDateArrow = document.getElementById('to-date-arrow');
|
||||
|
||||
fromDateArrow.innerText = "";
|
||||
toDateArrow.innerText = "";
|
||||
}
|
||||
|
||||
function colorSegment(from_date, to_date) {
|
||||
clearSegments();
|
||||
|
||||
const segmentLeft = document.getElementById('segment-left');
|
||||
const segmentMiddle = document.getElementById('segment-middle');
|
||||
const segmentRight = document.getElementById('segment-right');
|
||||
|
||||
const fromDateArrow = document.getElementById('from-date-arrow');
|
||||
const toDateArrow = document.getElementById('to-date-arrow');
|
||||
|
||||
if (from_date && !to_date) {
|
||||
segmentMiddle.classList.add('active-segment');
|
||||
segmentRight.classList.add('active-segment');
|
||||
|
||||
fromDateArrow.innerText = '→';
|
||||
} else if (!from_date && to_date) {
|
||||
segmentLeft.classList.add('active-segment');
|
||||
segmentMiddle.classList.add('active-segment');
|
||||
|
||||
toDateArrow.innerText = '←';
|
||||
} else if (from_date && to_date) {
|
||||
const fromDateTyped = new Date(from_date);
|
||||
const toDateTyped = new Date(to_date);
|
||||
if (fromDateTyped < toDateTyped) {
|
||||
segmentMiddle.classList.add('active-segment');
|
||||
|
||||
fromDateArrow.innerText = '→';
|
||||
toDateArrow.innerText = '←';
|
||||
} else if (fromDateTyped > toDateTyped) {
|
||||
segmentLeft.classList.add('active-segment');
|
||||
segmentRight.classList.add('active-segment');
|
||||
|
||||
fromDateArrow.innerText = '←';
|
||||
toDateArrow.innerText = '→';
|
||||
} else {
|
||||
clearSegments();
|
||||
}
|
||||
} else {
|
||||
clearSegments();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fix listeners to only activate if on the correct
|
||||
|
||||
const toDatePicker = document.getElementById('policy_valid_to_date');
|
||||
const fromDatePicker = document.getElementById('policy_valid_after_date');
|
||||
const fromDateMarker = document.getElementById('from_date');
|
||||
const toDateMarker = document.getElementById('to_date');
|
||||
|
||||
fromDatePicker.addEventListener('change', function () {
|
||||
fromDateMarker.innerText = fromDatePicker.value;
|
||||
toDateMarker.innerText = toDatePicker.value;
|
||||
|
||||
let from_value = fromDatePicker.value;
|
||||
let to_value = toDatePicker.value;
|
||||
|
||||
colorSegment(from_value, to_value);
|
||||
});
|
||||
|
||||
toDatePicker.addEventListener('change', function () {
|
||||
fromDateMarker.innerText = fromDatePicker.value;
|
||||
toDateMarker.innerText = toDatePicker.value;
|
||||
|
||||
let fromValue = fromDatePicker.value;
|
||||
let toValue = toDatePicker.value;
|
||||
|
||||
colorSegment(fromValue, toValue);
|
||||
});
|
||||
|
||||
let remoteAvailableEl = document.getElementById('remote_available');
|
||||
remoteAvailableEl.addEventListener('input', function () {
|
||||
let currentValue = remoteAvailableEl.value;
|
||||
let remoteAvailableContainer = document.getElementById('remote_available_container');
|
||||
if (currentValue == 'true') {
|
||||
remoteAvailableContainer.classList.remove('hidden');
|
||||
} else {
|
||||
remoteAvailableContainer.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
const remoteThresholdEl = document.getElementById('remote_threshold');
|
||||
remoteThresholdEl.addEventListener('input', function () {
|
||||
const remoteThresholdErrorEl = document.getElementById('remote_threshold_error');
|
||||
remoteThresholdErrorEl.innerText = "";
|
||||
const currentValue = remoteThresholdEl.value;
|
||||
|
||||
const thresholdRes = validateThreshold(currentValue)
|
||||
if (thresholdRes.error) {
|
||||
remoteThresholdErrorEl.innerText = thresholdRes.error;
|
||||
}
|
||||
});
|
||||
|
||||
const pubKeysErrorEl = document.getElementById('pub_keys_error');
|
||||
const pubKeys = document.getElementById('pub_keys')
|
||||
pubKeys.addEventListener('change', function () {
|
||||
pubKeysErrorEl.innerText = "";
|
||||
const res = validateThreshold(remoteThresholdEl.value);
|
||||
console.log(res, remoteThresholdEl)
|
||||
if (pubKeys.files.length < res.threshold.split('/')[1] || !res || !res.threshold) {
|
||||
console.log('uhoh')
|
||||
pubKeysErrorEl.innerText = "Please select a valid threshold";
|
||||
pubKeys.value = "";
|
||||
}
|
||||
});
|
||||
|
||||
let kycAvailableEl = document.getElementById('kyc_available');
|
||||
kycAvailableEl.addEventListener('input', function () {
|
||||
let currentValue = kycAvailableEl.value;
|
||||
let remoteAvailableContainer = document.getElementById('kyc_available_container');
|
||||
if (currentValue == 'true') {
|
||||
remoteAvailableContainer.classList.remove('hidden');
|
||||
} else {
|
||||
remoteAvailableContainer.classList.add('hidden');
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue