refactor: website files are now templated and compiled
8
.gitignore
vendored
@ -1,4 +1,6 @@
|
|||||||
upload
|
|
||||||
data.db
|
data.db
|
||||||
target/*
|
pack.yml
|
||||||
logs/*
|
upload/
|
||||||
|
target/
|
||||||
|
logs/
|
||||||
|
static/
|
||||||
|
|||||||
67
Cargo.lock
generated
@ -32,6 +32,48 @@ version = "1.0.98"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "askama"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4"
|
||||||
|
dependencies = [
|
||||||
|
"askama_derive",
|
||||||
|
"itoa",
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "askama_derive"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f"
|
||||||
|
dependencies = [
|
||||||
|
"askama_parser",
|
||||||
|
"basic-toml",
|
||||||
|
"memchr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustc-hash",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"syn 2.0.100",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "askama_parser"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
@ -120,6 +162,15 @@ version = "0.22.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "basic-toml"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.0"
|
version = "2.9.0"
|
||||||
@ -871,6 +922,7 @@ name = "pack"
|
|||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"askama",
|
||||||
"axum",
|
"axum",
|
||||||
"bytes",
|
"bytes",
|
||||||
"env_filter",
|
"env_filter",
|
||||||
@ -1093,6 +1145,12 @@ version = "0.1.24"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "2.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
@ -2099,6 +2157,15 @@ version = "0.53.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen-rt"
|
name = "wit-bindgen-rt"
|
||||||
version = "0.39.0"
|
version = "0.39.0"
|
||||||
|
|||||||
@ -6,6 +6,7 @@ authors = ["Kenneth Jao"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
|
askama = { version = "0.14.0", features = ["blocks"] }
|
||||||
axum = { version = "0.8.1", features = ["multipart"] }
|
axum = { version = "0.8.1", features = ["multipart"] }
|
||||||
bytes = "1.10.1"
|
bytes = "1.10.1"
|
||||||
env_filter = "0.1.3"
|
env_filter = "0.1.3"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
9
pack.yml
@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
host: "192.168.0.220"
|
|
||||||
port: "3000"
|
|
||||||
db_path: "data.db"
|
|
||||||
log_path: "logs"
|
|
||||||
upload_path: "upload"
|
|
||||||
gitea_host: "https://git.kjao.me"
|
|
||||||
client_id: "3d463405-d098-4038-8b25-a44ca5b9ab9c"
|
|
||||||
client_secret: "gto_5tammfpac43kdnb2hsp2ckk7i6fkpmtki7baxechkccpkurl5gkq"
|
|
||||||
10
pack.yml.template
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
host: "127.0.0.1"
|
||||||
|
port: "3000"
|
||||||
|
domain:
|
||||||
|
db_path: "data.db"
|
||||||
|
log_path: "logs"
|
||||||
|
upload_path: "upload"
|
||||||
|
gitea_host:
|
||||||
|
client_id:
|
||||||
|
client_secret:
|
||||||
59
src/api.rs
@ -1,4 +1,4 @@
|
|||||||
use std::{fs, path, slice::Iter};
|
use std::{fs, fmt, path, slice::Iter};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use rand::distr::{Alphanumeric, SampleString};
|
use rand::distr::{Alphanumeric, SampleString};
|
||||||
@ -17,9 +17,9 @@ use serde_json::Value;
|
|||||||
|
|
||||||
use crate::{query, ServerState};
|
use crate::{query, ServerState};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
enum RepoFeature {
|
pub enum RepoFeature {
|
||||||
Docs = 0,
|
Docs = 0,
|
||||||
Builds = 1,
|
Builds = 1,
|
||||||
Nightly = 2,
|
Nightly = 2,
|
||||||
@ -35,6 +35,32 @@ impl RepoFeature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for RepoFeature {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
fmt::Debug::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RepoFeature> for String {
|
||||||
|
fn from(value: RepoFeature) -> Self {
|
||||||
|
value.to_string().to_lowercase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&str> for RepoFeature {
|
||||||
|
type Error = APIError;
|
||||||
|
|
||||||
|
fn try_from(value: &str) -> Result<Self> {
|
||||||
|
for feature in RepoFeature::iter() {
|
||||||
|
if feature.to_string().to_lowercase() == value.to_lowercase() {
|
||||||
|
return Ok(*feature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(APIError::InvalidFeature { feature: value.to_owned() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum APIError {
|
pub enum APIError {
|
||||||
#[error("Request error: {0}")]
|
#[error("Request error: {0}")]
|
||||||
@ -105,37 +131,12 @@ impl IntoResponse for APIError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RepoFeature> for &str {
|
|
||||||
fn from(value: RepoFeature) -> Self {
|
|
||||||
match value {
|
|
||||||
RepoFeature::Docs => "docs",
|
|
||||||
RepoFeature::Builds => "builds",
|
|
||||||
RepoFeature::Nightly => "nightly",
|
|
||||||
RepoFeature::PreProd => "preprod",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&str> for RepoFeature {
|
|
||||||
type Error = APIError;
|
|
||||||
|
|
||||||
fn try_from(value: &str) -> Result<Self> {
|
|
||||||
match value.to_lowercase().as_str() {
|
|
||||||
"docs" => Ok(RepoFeature::Docs),
|
|
||||||
"builds" => Ok(RepoFeature::Builds),
|
|
||||||
"nightly" => Ok(RepoFeature::Nightly),
|
|
||||||
"preprod" => Ok(RepoFeature::PreProd),
|
|
||||||
other => Err(APIError::InvalidFeature { feature: other.to_owned() }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_feature_list(value: u64) -> FeatureList {
|
fn as_feature_list(value: u64) -> FeatureList {
|
||||||
let mut v: Vec<String> = Vec::new();
|
let mut v: Vec<String> = Vec::new();
|
||||||
for feature in RepoFeature::iter() {
|
for feature in RepoFeature::iter() {
|
||||||
let feat_num = 1 << (*feature as u64);
|
let feat_num = 1 << (*feature as u64);
|
||||||
if (value & feat_num) == feat_num {
|
if (value & feat_num) == feat_num {
|
||||||
v.push(Into::<&str>::into(*feature).to_owned());
|
v.push(Into::<String>::into(*feature).to_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v
|
v
|
||||||
|
|||||||
104
src/compile.rs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
use anyhow::{Context, Result};
|
||||||
|
use askama::Template;
|
||||||
|
use std::{fs, io, path::Path};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct WebStates<'a> {
|
||||||
|
auth: &'a str,
|
||||||
|
error: &'a str,
|
||||||
|
loading: &'a str,
|
||||||
|
repo_selected: &'a str,
|
||||||
|
repo_created: &'a str,
|
||||||
|
button_on: &'a str,
|
||||||
|
feature_on: &'a str,
|
||||||
|
confirm_on: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
ext = "html",
|
||||||
|
path = "html/contentDefault.html",
|
||||||
|
whitespace = "suppress"
|
||||||
|
)]
|
||||||
|
struct Default<'a> {
|
||||||
|
config: crate::ServerConfig,
|
||||||
|
features: Vec<String>,
|
||||||
|
content_text: String,
|
||||||
|
state: WebStates<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(ext = "html", path = "html/base.html", whitespace = "suppress")]
|
||||||
|
struct NotFound {
|
||||||
|
config: crate::ServerConfig,
|
||||||
|
content_text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "index.css", escape = "txt", whitespace = "suppress")]
|
||||||
|
struct Css<'a> {
|
||||||
|
state: WebStates<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_templates(config: &crate::ServerConfig) -> Result<()> {
|
||||||
|
let states = WebStates {
|
||||||
|
auth: "auth",
|
||||||
|
error: "error",
|
||||||
|
loading: "loading",
|
||||||
|
repo_selected: "repoSelected",
|
||||||
|
repo_created: "repoCreated",
|
||||||
|
button_on: "enabled",
|
||||||
|
feature_on: "fEnabled",
|
||||||
|
confirm_on: "enabled",
|
||||||
|
};
|
||||||
|
|
||||||
|
let default = Default {
|
||||||
|
config: config.clone(),
|
||||||
|
features: crate::api::RepoFeature::iter()
|
||||||
|
.map(|f| f.to_string())
|
||||||
|
.collect(),
|
||||||
|
content_text: "awaiting authorization...".to_owned(),
|
||||||
|
state: states,
|
||||||
|
}
|
||||||
|
.render()
|
||||||
|
.context("Unable to process 'Default' template")?;
|
||||||
|
|
||||||
|
fs::write("static/index.html", default).context("Could not write to static/index.html")?;
|
||||||
|
|
||||||
|
let not_found = NotFound {
|
||||||
|
config: config.clone(),
|
||||||
|
content_text: "404: not found...".to_owned(),
|
||||||
|
}
|
||||||
|
.render()
|
||||||
|
.context("Unable to process 'NotFound' template.")?;
|
||||||
|
|
||||||
|
fs::write("static/404.html", not_found).context("Could not write to static/404.html")?;
|
||||||
|
|
||||||
|
let css = Css { state: states }
|
||||||
|
.render()
|
||||||
|
.context("Unable to process 'CSS' template.")?;
|
||||||
|
|
||||||
|
fs::write("static/index.css", css).context("Could not write to static/index.css")?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||||
|
fs::create_dir_all(&dst)?;
|
||||||
|
for entry in fs::read_dir(src)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let ty = entry.file_type()?;
|
||||||
|
if ty.is_dir() {
|
||||||
|
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
|
||||||
|
} else {
|
||||||
|
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_assets() -> Result<()> {
|
||||||
|
fs::create_dir("static").context("Could not create directory 'static'.")?;
|
||||||
|
copy_dir_all("assets", "static").context("Could not copy 'assets' into 'static'.")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@ -24,6 +24,7 @@ use tracing_appender::rolling;
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
|
mod compile;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
type SQLConn = sqlite::ConnectionThreadSafe;
|
type SQLConn = sqlite::ConnectionThreadSafe;
|
||||||
@ -34,6 +35,7 @@ type SQLConn = sqlite::ConnectionThreadSafe;
|
|||||||
struct ServerConfig {
|
struct ServerConfig {
|
||||||
host: String,
|
host: String,
|
||||||
port: String,
|
port: String,
|
||||||
|
domain: String,
|
||||||
db_path: String,
|
db_path: String,
|
||||||
log_path: String,
|
log_path: String,
|
||||||
upload_path: String,
|
upload_path: String,
|
||||||
@ -81,9 +83,12 @@ async fn main() -> Result<()> {
|
|||||||
.context(format!("Failed to setup SQLite database at '{}'.", &config.db_path))?;
|
.context(format!("Failed to setup SQLite database at '{}'.", &config.db_path))?;
|
||||||
|
|
||||||
// Make file upload folder.
|
// Make file upload folder.
|
||||||
fs::create_dir_all(&config.upload_path)?;
|
fs::create_dir_all(&config.upload_path)
|
||||||
|
.context(format!("Unable to make directory at '{}'.", &config.upload_path))?;
|
||||||
let log_file = rolling::daily(&config.log_path, "");
|
let log_file = rolling::daily(&config.log_path, "");
|
||||||
let upload_path = config.upload_path.clone();
|
let upload_path = config.upload_path.clone();
|
||||||
|
compile::copy_assets()?;
|
||||||
|
compile::make_templates(&config)?;
|
||||||
|
|
||||||
let sql: &'static sqlite::ConnectionThreadSafe = Box::leak(Box::new(sql));
|
let sql: &'static sqlite::ConnectionThreadSafe = Box::leak(Box::new(sql));
|
||||||
let server_state = ServerState { config, sql };
|
let server_state = ServerState { config, sql };
|
||||||
@ -118,11 +123,9 @@ async fn main() -> Result<()> {
|
|||||||
method = format!("{}", request.method()),
|
method = format!("{}", request.method()),
|
||||||
version = format!("{:?}", request.version()),
|
version = format!("{:?}", request.version()),
|
||||||
remote_ip = addr,
|
remote_ip = addr,
|
||||||
|
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Build routes
|
// Build routes
|
||||||
let api_routes = Router::new()
|
let api_routes = Router::new()
|
||||||
.route("/token", post(api::token).patch(api::refresh_token))
|
.route("/token", post(api::token).patch(api::refresh_token))
|
||||||
|
|||||||
@ -1,191 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
|
||||||
<title>Pack</title>
|
|
||||||
<link rel="icon" href="assets/favicon.ico?v=2">
|
|
||||||
<link rel="stylesheet" href="assets/index.css">
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Quicksand:300,400" rel="stylesheet">
|
|
||||||
<!-- <link href="https://fonts.googleapis.com/css?family=Roboto+Slab:100,300" rel="stylesheet"> -->
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
|
||||||
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> -->
|
|
||||||
<!-- <script src="https://use.fontawesome.com/c8d5486cd8.js"></script> -->
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="themeSwitchContainer">
|
|
||||||
<input type="checkbox" id="themeSwitch">
|
|
||||||
<span></span><span></span><span></span>
|
|
||||||
</div>
|
|
||||||
<div id="package">
|
|
||||||
<img src="assets/fragile.svg">
|
|
||||||
<img src="assets/keep_dry.svg">
|
|
||||||
<img src="assets/recycle.svg">
|
|
||||||
<img src="assets/qr_code.svg">
|
|
||||||
</div>
|
|
||||||
<svg id="packageTape" viewbox="0 0 100 10">
|
|
||||||
<rect width="100" height="0.3" x="0" y="4.85" style="fill:#483320;fill-opacity:0.8" />
|
|
||||||
<rect width="100" height="10" x="0" y="0" style="fill:#111;fill-opacity:0.8" />
|
|
||||||
|
|
||||||
<polygon points="21,0.0 20,0.625 21,1.25 20,1.875 21,2.5 20,3.125 21,3.75 20,4.375 21,5.0 20,5.625 21,6.25 20,6.875 21,7.5 20,8.125 21,8.75 20,9.375 21,10.0 100,10 100,0" style="fill:#111;fill-opacity:0.5"/>
|
|
||||||
<text><textPath href="#packTape0">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape1">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape2">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape3">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape4">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape5">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape6">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape7">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape8">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape9">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape10">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape11">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape12">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape13">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape14">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape15">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape16">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape17">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape18">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape19">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape20">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape21">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape22">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape23">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape24">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape25">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape26">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape27">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape28">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape29">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape30">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape31">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape32">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape33">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape34">PACK.PACK.PACK.PACK.</textPath></text>
|
|
||||||
<path id="packTape0" fill="none" stroke="none" d="M-3.00 -0.00 l6 20"><path id="packTape1" fill="none" stroke="none" d="M-0.60 -2.00 l6 20"><path id="packTape2" fill="none" stroke="none" d="M1.80 -4.00 l6 20"><path id="packTape3" fill="none" stroke="none" d="M6.00 -0.00 l6 20"><path id="packTape4" fill="none" stroke="none" d="M8.40 -2.00 l6 20"><path id="packTape5" fill="none" stroke="none" d="M10.80 -4.00 l6 20"><path id="packTape6" fill="none" stroke="none" d="M15.00 -0.00 l6 20"><path id="packTape7" fill="none" stroke="none" d="M17.40 -2.00 l6 20"><path id="packTape8" fill="none" stroke="none" d="M19.80 -4.00 l6 20"><path id="packTape9" fill="none" stroke="none" d="M24.00 -0.00 l6 20"><path id="packTape10" fill="none" stroke="none" d="M26.40 -2.00 l6 20"><path id="packTape11" fill="none" stroke="none" d="M28.80 -4.00 l6 20"><path id="packTape12" fill="none" stroke="none" d="M33.00 -0.00 l6 20"><path id="packTape13" fill="none" stroke="none" d="M35.40 -2.00 l6 20"><path id="packTape14" fill="none" stroke="none" d="M37.80 -4.00 l6 20"><path id="packTape15" fill="none" stroke="none" d="M42.00 -0.00 l6 20"><path id="packTape16" fill="none" stroke="none" d="M44.40 -2.00 l6 20"><path id="packTape17" fill="none" stroke="none" d="M46.80 -4.00 l6 20"><path id="packTape18" fill="none" stroke="none" d="M51.00 -0.00 l6 20"><path id="packTape19" fill="none" stroke="none" d="M53.40 -2.00 l6 20"><path id="packTape20" fill="none" stroke="none" d="M55.80 -4.00 l6 20"><path id="packTape21" fill="none" stroke="none" d="M60.00 -0.00 l6 20"><path id="packTape22" fill="none" stroke="none" d="M62.40 -2.00 l6 20"><path id="packTape23" fill="none" stroke="none" d="M64.80 -4.00 l6 20"><path id="packTape24" fill="none" stroke="none" d="M69.00 -0.00 l6 20"><path id="packTape25" fill="none" stroke="none" d="M71.40 -2.00 l6 20"><path id="packTape26" fill="none" stroke="none" d="M73.80 -4.00 l6 20"><path id="packTape27" fill="none" stroke="none" d="M78.00 -0.00 l6 20"><path id="packTape28" fill="none" stroke="none" d="M80.40 -2.00 l6 20"><path id="packTape29" fill="none" stroke="none" d="M82.80 -4.00 l6 20"><path id="packTape30" fill="none" stroke="none" d="M87.00 -0.00 l6 20"><path id="packTape31" fill="none" stroke="none" d="M89.40 -2.00 l6 20"><path id="packTape32" fill="none" stroke="none" d="M91.80 -4.00 l6 20"><path id="packTape33" fill="none" stroke="none" d="M96.00 -0.00 l6 20"><path id="packTape34" fill="none" stroke="none" d="M98.40 -2.00 l6 20">
|
|
||||||
</svg>
|
|
||||||
<div id="packageLabel">
|
|
||||||
<div id="packageLabelTop">
|
|
||||||
<div>
|
|
||||||
<svg width="48" height="48" viewBox="0 0 12.7 12.7" version="1.1">
|
|
||||||
<defs id="defs2" />
|
|
||||||
<path d="m 12.323869,4.1992062 -6.2301843,2.5959093 -1e-7,0.095169 6.3500004,-2.6458336 z" />
|
|
||||||
<path d="M 12.443685,4.2444508 V 4.3735617 L 9.2686845,4.925839 V 4.7967281 Z" />
|
|
||||||
<path d="M 6.0936845,1.6003079 12.443177,4.2450847 9.2686845,4.796728 2.9191918,2.1519511 Z" />
|
|
||||||
<path d="m 9.2686845,3.8880996 0.062387,0.1201924 -3.237387,3.0585598 2e-7,-0.17699 z" />
|
|
||||||
<path d="M 9.2686845,4.7967281 V 4.925839 L 8.6378103,4.6632589 8.7123025,4.564976 Z" />
|
|
||||||
<rect width="6.8791666" height="5.8977885" x="-13.480659" y="9.4293194" transform="matrix(-0.92307692,0.3846154,0,1,0,0)" />
|
|
||||||
<rect width="6.8791666" height="5.8977885" x="-0.27767482" y="4.3512492" transform="matrix(0.92307692,0.3846154,0,1,0,0)" />
|
|
||||||
<path d="M 2.9186843,1.2431113 9.2686845,3.8880996 6.0936849,6.8898618 -0.2563155,4.2448735 Z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<p><b>BYTE TRANSIT FEES PAID</b></p>
|
|
||||||
<p>64 OF 64</p>
|
|
||||||
<p>6.28 TB FIBRE OPTIC EXPRESS RATE</p>
|
|
||||||
<p>ACCEPTS TAR.GZ, ZIP</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<svg width="618" height="124" viewBox="0 0 618 124" version="1.1">
|
|
||||||
<path d="M 2.1999999e-6,0 H 41.200002 V 123.6 H 2.1999999e-6 Z M 46.350002,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 H 113.3 v 15.45 h 5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 30.9 H 103 V 46.35 H 97.850002 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 H 103 v 15.450002 h 5.15 V 61.8 h 5.15 v 61.8 H 87.550002 Z M 118.45,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 25.75 v 15.45 h 5.15 V 30.9 H 154.5 V 15.45 h -15.45 z m 36.05,0 h 15.45 v 30.9 h -5.15 v 30.9 h 5.15 v 15.450002 h -5.15 v 15.45 h -5.15 V 108.15 h 10.3 V 123.6 H 175.1 Z m 20.6,0 h 5.15 V 15.45 H 195.7 Z M 206,0 h 10.3 v 15.45 h -5.15 V 30.9 h 5.15 V 15.45 h 10.3 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 h 5.15 v 15.450002 h -5.15 v 15.45 h 5.15 V 108.15 H 226.6 V 123.6 H 216.3 V 92.700002 H 206 V 123.6 h -5.15 V 108.15 H 195.7 V 92.700002 h 5.15 v -15.45 H 206 V 61.8 h 5.15 v 15.450002 h 10.3 V 61.8 H 216.3 V 46.35 H 206 V 61.8 H 190.55 V 46.35 h 5.15 V 30.9 H 206 Z m 20.6,0 h 20.6 v 46.35 h -5.15 V 15.45 H 226.6 Z m 36.05,0 h 10.3 v 30.9 h -5.15 v 15.45 h 5.15 v 30.900002 h -5.15 v 15.45 h 10.3 V 108.15 h 5.15 v 15.45 h -10.3 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 10.3 V 30.9 H 309 V 0 h 5.15 v 30.9 h 5.15 v 15.45 h -5.15 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -10.3 v -15.45 h -10.3 v 15.45 H 298.7 V 108.15 H 288.4 V 77.250002 h 10.3 V 61.8 h 5.15 V 46.35 H 298.7 V 30.9 h -10.3 v 30.9 h -5.15 V 15.45 h 10.3 z m 25.75,0 h 5.15 v 15.45 h 20.6 V 30.9 H 319.3 Z m 30.9,0 h 5.15 v 15.45 h 5.15 V 0 h 15.45 v 15.45 h -10.3 V 30.9 h -10.3 v 15.45 h 5.15 v 46.350002 h 5.15 V 108.15 h 5.15 v 15.45 h -20.6 z m 46.35,0 H 412 v 15.45 h 5.15 v 30.9 H 412 V 61.8 h 5.15 v 15.450002 h 5.15 V 61.8 h 10.3 v 15.450002 h -5.15 v 15.45 h -20.6 v -15.45 h -10.3 V 61.8 h 10.3 V 46.35 h -10.3 V 30.9 h 5.15 V 15.45 h -5.15 z m 20.6,0 h 5.15 v 15.45 h -5.15 z m 20.6,0 h 25.75 v 15.45 h -5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 61.8 h 5.15 V 46.35 h 5.15 V 77.250002 H 453.2 V 123.6 h -5.15 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 H 515 V 15.45 H 494.4 V 30.9 h 25.75 V 61.8 H 515 v 15.450002 h -10.3 v 15.45 h 15.45 V 108.15 h -10.3 V 123.6 H 494.4 V 92.700002 h 5.15 V 61.8 H 494.4 V 46.35 h -5.15 z m 36.05,0 h 36.05 V 123.6 H 525.3 Z m 41.2,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 15.45,0 H 618 v 123.6 h -5.15 z M 123.6,15.45 h 5.15 V 30.9 h 5.15 V 15.45 h 5.15 V 30.9 h 5.15 v 15.45 h -10.3 v 30.900002 h 15.45 v 15.45 h 5.15 V 61.8 H 144.2 V 46.35 h 25.75 V 61.8 h -5.15 v 30.900002 h 5.15 V 108.15 H 154.5 V 123.6 H 144.2 V 92.700002 h -5.15 V 123.6 H 133.9 V 108.15 H 123.6 V 92.700002 h 5.15 v -15.45 h -5.15 v 15.45 h -5.15 V 61.8 H 113.3 V 46.35 h 10.3 z m 257.5,0 h 5.15 V 30.9 h -5.15 z m 41.2,0 h 10.3 V 30.9 h -10.3 z m 41.2,0 h 5.15 V 30.9 h -5.15 z m 10.3,0 h 5.15 V 30.9 H 473.8 Z M 231.75,30.9 h 5.15 v 15.45 h -5.15 z m 41.2,0 h 5.15 v 15.45 h -5.15 z m 97.85,0 h 5.15 v 15.45 h 5.15 v 30.900002 h -5.15 V 61.8 h -5.15 z m 15.45,0 h 5.15 v 15.45 h -5.15 z m 72.1,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h 10.3 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -5.15 V 123.6 h -30.9 V 77.250002 h 5.15 V 108.15 h 10.3 V 92.700002 h -5.15 v -15.45 h 5.15 V 61.8 h -5.15 V 77.250002 H 463.5 V 46.35 h 5.15 z M 103,46.35 h 5.15 V 61.8 H 103 Z m 149.35,0 h 5.15 v 77.25 h -5.15 V 108.15 H 247.2 V 92.700002 h 5.15 z m 77.25,0 h 15.45 V 61.8 h -10.3 v 15.450002 h 10.3 v 15.45 H 339.9 V 108.15 H 329.6 V 123.6 H 303.85 V 92.700002 h 10.3 V 108.15 h 10.3 V 92.700002 h 5.15 v -15.45 h -5.15 V 61.8 h 5.15 z m 61.8,0 h 5.15 V 61.8 H 391.4 Z M 278.1,61.8 h 5.15 v 15.450002 h -5.15 z m -41.2,15.450002 h 5.15 v 15.45 h -5.15 z m 128.75,0 h 10.3 v 15.45 h 5.15 v -15.45 h 5.15 v 15.45 h 5.15 V 108.15 h -5.15 v 15.45 h -10.3 V 108.15 H 370.8 V 92.700002 h -5.15 z M 103,92.700002 V 108.15 h 5.15 V 92.700002 Z m 293.55,0 h 10.3 V 108.15 h -10.3 z m 30.9,0 h 5.15 V 123.6 h -5.15 z M 118.45,108.15 h 5.15 v 15.45 h -5.15 z m 221.45,0 h 5.15 v 15.45 h -5.15 z m 66.95,0 h 10.3 v 15.45 h -10.3 z" fill-rule="evenodd" style="stroke-width:0.858333" />
|
|
||||||
</svg>
|
|
||||||
<h1 id="login"></h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="packageLabelTitle">
|
|
||||||
<h1><b></b></h1>
|
|
||||||
</div>
|
|
||||||
<div id="packageLabelContent">
|
|
||||||
<h1>AWAITING AUTHORIZATION...</h1>
|
|
||||||
<div>
|
|
||||||
<div id="repoSelect">
|
|
||||||
<h1>REPOSITORY:</h1>
|
|
||||||
<input id="repoSelectInput" type="text" size="32" placeholder="<user>/<repository>">
|
|
||||||
<input class="enabled" id="repoSelectButton" type="submit" value="Select">
|
|
||||||
<p id="repoSelectError"></p>
|
|
||||||
</div>
|
|
||||||
<div id="repoInfo">
|
|
||||||
<h1>ACTIONS:</h1>
|
|
||||||
<div id="repoActions">
|
|
||||||
<input class="enabled" id="repoCreate" type="submit" value="Create">
|
|
||||||
<input id="repoDelete" type="submit" value="Delete">
|
|
||||||
<input id="repoSecret" type="submit" value="Regenerate Secret">
|
|
||||||
</div>
|
|
||||||
<div id="repoFeatures">
|
|
||||||
<h1>LINK:</h1>
|
|
||||||
<input id="repoLinkInput" type="text" size="32" readonly>
|
|
||||||
<input class="enabled" id="repoLinkButton" type="submit" value="Copy">
|
|
||||||
<h1>FEATURES:</h1>
|
|
||||||
<div id="featureBox">
|
|
||||||
<input class="feature" type="submit" data-tag="docs" value="Docs">
|
|
||||||
<input class="feature" type="submit" data-tag="builds" value="Builds">
|
|
||||||
<input class="feature" type="submit" data-tag="nightly" value="Nightly">
|
|
||||||
<input class="feature" type="submit" data-tag="preprod" value="PreProd">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="confirmOverlay">
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<h1>CONFIRMATION:</h1>
|
|
||||||
<input id="confirmInput" type="text" size="32" placeholder="<user>/<repository>">
|
|
||||||
<input class="enabled" id="confirmButtonYes" type="submit" value="Confirm">
|
|
||||||
<input class="enabled" id="confirmButtonNo" type="submit" value="Cancel">
|
|
||||||
<p>This will (irreversibly) delete all associated files! Please type in the full repository name to confirm.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="packageLabelBot">
|
|
||||||
<svg width="1596" height="432" viewBox="0 0 1596 432" version="1.1">
|
|
||||||
<path d="M 0,432 H 12 V 0 H 0 Z" />
|
|
||||||
<path d="m 18,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 36,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 66,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="M 84,432 H 96 V 0 H 84 Z" />
|
|
||||||
<path d="m 120,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 132,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 150,432 h 24 V 0 h -24 z" />
|
|
||||||
<path d="m 180,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 198,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 216,432 h 24 V 0 h -24 z" />
|
|
||||||
<path d="m 246,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 264,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 276,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 294,432 h 24 V 0 h -24 z" />
|
|
||||||
<path d="m 330,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 342,432 h 24 V 0 h -24 z" />
|
|
||||||
<path d="m 378,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 396,432 h 18 V 0 h -18 z" />
|
|
||||||
<path d="m 426,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 444,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 462,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 474,432 h 18 V 0 h -18 z" />
|
|
||||||
<path d="m 504,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 528,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 540,432 h 18 V 0 h -18 z" />
|
|
||||||
<path d="m 570,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 594,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 606,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 624,432 h 24 V 0 h -24 z" />
|
|
||||||
<path d="m 660,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 678,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 690,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 726,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 756,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 768,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 792,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 828,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 846,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 858,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 876,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 900,432 h 18 V 0 h -18 z" />
|
|
||||||
<path d="m 924,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 960,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 978,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 990,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1020,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 1044,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1056,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1074,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1086,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 1122,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1146,432 h 24 V 0 h -24 z" />
|
|
||||||
<path d="m 1176,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1188,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1206,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 1230,432 h 18 V 0 h -18 z" />
|
|
||||||
<path d="m 1254,432 h 24 V 0 h -24 z" />
|
|
||||||
<path d="m 1284,432 h 18 V 0 h -18 z" />
|
|
||||||
<path d="m 1308,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1320,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1332,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 1356,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1386,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1398,432 h 18 V 0 h -18 z" />
|
|
||||||
<path d="m 1428,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 1452,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1470,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1488,432 h 24 V 0 h -24 z" />
|
|
||||||
<path d="m 1518,432 h 12 V 0 h -12 z" />
|
|
||||||
<path d="m 1548,432 h 18 V 0 h -18 z" />
|
|
||||||
<path d="m 1572,432 h 6 V 0 h -6 z" />
|
|
||||||
<path d="m 1584,432 h 12 V 0 h -12 z" />
|
|
||||||
</svg>
|
|
||||||
<a href="/">https://pack.kjao.me/</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
<script src="assets/index.js"></script>
|
|
||||||
</html>
|
|
||||||
42
templates/html/base.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||||
|
<title>Pack</title>
|
||||||
|
<link rel="icon" href="assets/favicon.ico?v=2">
|
||||||
|
<link rel="stylesheet" href="assets/index.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Quicksand:300,400" rel="stylesheet">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="themeSwitchContainer">
|
||||||
|
<input type="checkbox" id="themeSwitch">
|
||||||
|
<span></span><span></span><span></span>
|
||||||
|
</div>
|
||||||
|
<div id="package">
|
||||||
|
<img src="assets/fragile.svg">
|
||||||
|
<img src="assets/keep_dry.svg">
|
||||||
|
<img src="assets/recycle.svg">
|
||||||
|
<img src="assets/qr_code.svg">
|
||||||
|
</div>
|
||||||
|
{% include "svgTape.svg" %}
|
||||||
|
<div id="packageLabel">
|
||||||
|
<div id="packageLabelTop">{% include "labelTop.html" %}</div>
|
||||||
|
<div id="packageLabelTitle">
|
||||||
|
<h1><b></b></h1>
|
||||||
|
</div>
|
||||||
|
<div id="packageLabelContent">
|
||||||
|
<h1>{{ content_text | upper }}</h1>
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
<div id="packageLabelBot">
|
||||||
|
{% include "labelBot.svg" %}
|
||||||
|
<a href="/">{{ config.domain }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
{% include "js/base.js" %}
|
||||||
|
{% block script %}{% endblock %}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
47
templates/html/contentDefault.html
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div>
|
||||||
|
<div id="repoSelect">
|
||||||
|
<h1>REPOSITORY:</h1>
|
||||||
|
<input id="repoSelectInput" type="text" size="32" placeholder="<user>/<repository>">
|
||||||
|
<input class="enabled" id="repoSelectButton" type="submit" value="Select">
|
||||||
|
<p id="repoSelectError"></p>
|
||||||
|
</div>
|
||||||
|
<div id="repoInfo">
|
||||||
|
<h1>ACTIONS:</h1>
|
||||||
|
<div id="repoActions">
|
||||||
|
<input class="enabled" id="repoCreate" type="submit" value="Create">
|
||||||
|
<input id="repoDelete" type="submit" value="Delete">
|
||||||
|
<input id="repoSecret" type="submit" value="Regenerate Secret">
|
||||||
|
</div>
|
||||||
|
<div id="repoFeatures">
|
||||||
|
<h1>LINK:</h1>
|
||||||
|
<input id="repoLinkInput" type="text" size="32" readonly>
|
||||||
|
<input class="enabled" id="repoLinkButton" type="submit" value="Copy">
|
||||||
|
<h1>FEATURES:</h1>
|
||||||
|
<div id="featureBox">
|
||||||
|
{% for feature in features %}
|
||||||
|
<input class="feature" type="submit" data-tag="{{ feature | lower }}" value="{{ feature }}">
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="confirmOverlay">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<h1>CONFIRMATION:</h1>
|
||||||
|
<input id="confirmInput" type="text" size="32" placeholder="<user>/<repository>">
|
||||||
|
<input class="enabled" id="confirmButtonYes" type="submit" value="Confirm">
|
||||||
|
<input class="enabled" id="confirmButtonNo" type="submit" value="Cancel">
|
||||||
|
<p>This will (irreversibly) delete all associated files! Please type in the full repository name to confirm.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
{% include "js/token.js" %}
|
||||||
|
{% include "js/default.js" %}
|
||||||
|
{% endblock %}
|
||||||
75
templates/html/labelBot.svg
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<svg width="1596" height="432" viewBox="0 0 1596 432" version="1.1">
|
||||||
|
<path d="M 0,432 H 12 V 0 H 0 Z" />
|
||||||
|
<path d="m 18,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 36,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 66,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="M 84,432 H 96 V 0 H 84 Z" />
|
||||||
|
<path d="m 120,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 132,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 150,432 h 24 V 0 h -24 z" />
|
||||||
|
<path d="m 180,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 198,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 216,432 h 24 V 0 h -24 z" />
|
||||||
|
<path d="m 246,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 264,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 276,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 294,432 h 24 V 0 h -24 z" />
|
||||||
|
<path d="m 330,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 342,432 h 24 V 0 h -24 z" />
|
||||||
|
<path d="m 378,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 396,432 h 18 V 0 h -18 z" />
|
||||||
|
<path d="m 426,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 444,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 462,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 474,432 h 18 V 0 h -18 z" />
|
||||||
|
<path d="m 504,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 528,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 540,432 h 18 V 0 h -18 z" />
|
||||||
|
<path d="m 570,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 594,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 606,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 624,432 h 24 V 0 h -24 z" />
|
||||||
|
<path d="m 660,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 678,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 690,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 726,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 756,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 768,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 792,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 828,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 846,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 858,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 876,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 900,432 h 18 V 0 h -18 z" />
|
||||||
|
<path d="m 924,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 960,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 978,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 990,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1020,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 1044,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1056,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1074,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1086,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 1122,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1146,432 h 24 V 0 h -24 z" />
|
||||||
|
<path d="m 1176,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1188,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1206,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 1230,432 h 18 V 0 h -18 z" />
|
||||||
|
<path d="m 1254,432 h 24 V 0 h -24 z" />
|
||||||
|
<path d="m 1284,432 h 18 V 0 h -18 z" />
|
||||||
|
<path d="m 1308,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1320,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1332,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 1356,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1386,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1398,432 h 18 V 0 h -18 z" />
|
||||||
|
<path d="m 1428,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 1452,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1470,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1488,432 h 24 V 0 h -24 z" />
|
||||||
|
<path d="m 1518,432 h 12 V 0 h -12 z" />
|
||||||
|
<path d="m 1548,432 h 18 V 0 h -18 z" />
|
||||||
|
<path d="m 1572,432 h 6 V 0 h -6 z" />
|
||||||
|
<path d="m 1584,432 h 12 V 0 h -12 z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |
27
templates/html/labelTop.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<div>
|
||||||
|
<svg width="48" height="48" viewBox="0 0 12.7 12.7" version="1.1">
|
||||||
|
<defs id="defs2" />
|
||||||
|
<path d="m 12.323869,4.1992062 -6.2301843,2.5959093 -1e-7,0.095169 6.3500004,-2.6458336 z" />
|
||||||
|
<path d="M 12.443685,4.2444508 V 4.3735617 L 9.2686845,4.925839 V 4.7967281 Z" />
|
||||||
|
<path d="M 6.0936845,1.6003079 12.443177,4.2450847 9.2686845,4.796728 2.9191918,2.1519511 Z" />
|
||||||
|
<path d="m 9.2686845,3.8880996 0.062387,0.1201924 -3.237387,3.0585598 2e-7,-0.17699 z" />
|
||||||
|
<path d="M 9.2686845,4.7967281 V 4.925839 L 8.6378103,4.6632589 8.7123025,4.564976 Z" />
|
||||||
|
<rect width="6.8791666" height="5.8977885" x="-13.480659" y="9.4293194" transform="matrix(-0.92307692,0.3846154,0,1,0,0)" />
|
||||||
|
<rect width="6.8791666" height="5.8977885" x="-0.27767482" y="4.3512492" transform="matrix(0.92307692,0.3846154,0,1,0,0)" />
|
||||||
|
<path d="M 2.9186843,1.2431113 9.2686845,3.8880996 6.0936849,6.8898618 -0.2563155,4.2448735 Z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<p><b>BYTE TRANSIT FEES PAID</b></p>
|
||||||
|
<p>64 OF 64</p>
|
||||||
|
<p>6.28 TB FIBRE OPTIC EXPRESS RATE</p>
|
||||||
|
<p>ACCEPTS TAR.GZ, ZIP</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<svg width="618" height="124" viewBox="0 0 618 124" version="1.1">
|
||||||
|
<path d="M 2.1999999e-6,0 H 41.200002 V 123.6 H 2.1999999e-6 Z M 46.350002,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 H 113.3 v 15.45 h 5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 30.9 H 103 V 46.35 H 97.850002 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 H 103 v 15.450002 h 5.15 V 61.8 h 5.15 v 61.8 H 87.550002 Z M 118.45,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 25.75 v 15.45 h 5.15 V 30.9 H 154.5 V 15.45 h -15.45 z m 36.05,0 h 15.45 v 30.9 h -5.15 v 30.9 h 5.15 v 15.450002 h -5.15 v 15.45 h -5.15 V 108.15 h 10.3 V 123.6 H 175.1 Z m 20.6,0 h 5.15 V 15.45 H 195.7 Z M 206,0 h 10.3 v 15.45 h -5.15 V 30.9 h 5.15 V 15.45 h 10.3 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 h 5.15 v 15.450002 h -5.15 v 15.45 h 5.15 V 108.15 H 226.6 V 123.6 H 216.3 V 92.700002 H 206 V 123.6 h -5.15 V 108.15 H 195.7 V 92.700002 h 5.15 v -15.45 H 206 V 61.8 h 5.15 v 15.450002 h 10.3 V 61.8 H 216.3 V 46.35 H 206 V 61.8 H 190.55 V 46.35 h 5.15 V 30.9 H 206 Z m 20.6,0 h 20.6 v 46.35 h -5.15 V 15.45 H 226.6 Z m 36.05,0 h 10.3 v 30.9 h -5.15 v 15.45 h 5.15 v 30.900002 h -5.15 v 15.45 h 10.3 V 108.15 h 5.15 v 15.45 h -10.3 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 10.3 V 30.9 H 309 V 0 h 5.15 v 30.9 h 5.15 v 15.45 h -5.15 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -10.3 v -15.45 h -10.3 v 15.45 H 298.7 V 108.15 H 288.4 V 77.250002 h 10.3 V 61.8 h 5.15 V 46.35 H 298.7 V 30.9 h -10.3 v 30.9 h -5.15 V 15.45 h 10.3 z m 25.75,0 h 5.15 v 15.45 h 20.6 V 30.9 H 319.3 Z m 30.9,0 h 5.15 v 15.45 h 5.15 V 0 h 15.45 v 15.45 h -10.3 V 30.9 h -10.3 v 15.45 h 5.15 v 46.350002 h 5.15 V 108.15 h 5.15 v 15.45 h -20.6 z m 46.35,0 H 412 v 15.45 h 5.15 v 30.9 H 412 V 61.8 h 5.15 v 15.450002 h 5.15 V 61.8 h 10.3 v 15.450002 h -5.15 v 15.45 h -20.6 v -15.45 h -10.3 V 61.8 h 10.3 V 46.35 h -10.3 V 30.9 h 5.15 V 15.45 h -5.15 z m 20.6,0 h 5.15 v 15.45 h -5.15 z m 20.6,0 h 25.75 v 15.45 h -5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 61.8 h 5.15 V 46.35 h 5.15 V 77.250002 H 453.2 V 123.6 h -5.15 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 H 515 V 15.45 H 494.4 V 30.9 h 25.75 V 61.8 H 515 v 15.450002 h -10.3 v 15.45 h 15.45 V 108.15 h -10.3 V 123.6 H 494.4 V 92.700002 h 5.15 V 61.8 H 494.4 V 46.35 h -5.15 z m 36.05,0 h 36.05 V 123.6 H 525.3 Z m 41.2,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 15.45,0 H 618 v 123.6 h -5.15 z M 123.6,15.45 h 5.15 V 30.9 h 5.15 V 15.45 h 5.15 V 30.9 h 5.15 v 15.45 h -10.3 v 30.900002 h 15.45 v 15.45 h 5.15 V 61.8 H 144.2 V 46.35 h 25.75 V 61.8 h -5.15 v 30.900002 h 5.15 V 108.15 H 154.5 V 123.6 H 144.2 V 92.700002 h -5.15 V 123.6 H 133.9 V 108.15 H 123.6 V 92.700002 h 5.15 v -15.45 h -5.15 v 15.45 h -5.15 V 61.8 H 113.3 V 46.35 h 10.3 z m 257.5,0 h 5.15 V 30.9 h -5.15 z m 41.2,0 h 10.3 V 30.9 h -10.3 z m 41.2,0 h 5.15 V 30.9 h -5.15 z m 10.3,0 h 5.15 V 30.9 H 473.8 Z M 231.75,30.9 h 5.15 v 15.45 h -5.15 z m 41.2,0 h 5.15 v 15.45 h -5.15 z m 97.85,0 h 5.15 v 15.45 h 5.15 v 30.900002 h -5.15 V 61.8 h -5.15 z m 15.45,0 h 5.15 v 15.45 h -5.15 z m 72.1,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h 10.3 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -5.15 V 123.6 h -30.9 V 77.250002 h 5.15 V 108.15 h 10.3 V 92.700002 h -5.15 v -15.45 h 5.15 V 61.8 h -5.15 V 77.250002 H 463.5 V 46.35 h 5.15 z M 103,46.35 h 5.15 V 61.8 H 103 Z m 149.35,0 h 5.15 v 77.25 h -5.15 V 108.15 H 247.2 V 92.700002 h 5.15 z m 77.25,0 h 15.45 V 61.8 h -10.3 v 15.450002 h 10.3 v 15.45 H 339.9 V 108.15 H 329.6 V 123.6 H 303.85 V 92.700002 h 10.3 V 108.15 h 10.3 V 92.700002 h 5.15 v -15.45 h -5.15 V 61.8 h 5.15 z m 61.8,0 h 5.15 V 61.8 H 391.4 Z M 278.1,61.8 h 5.15 v 15.450002 h -5.15 z m -41.2,15.450002 h 5.15 v 15.45 h -5.15 z m 128.75,0 h 10.3 v 15.45 h 5.15 v -15.45 h 5.15 v 15.45 h 5.15 V 108.15 h -5.15 v 15.45 h -10.3 V 108.15 H 370.8 V 92.700002 h -5.15 z M 103,92.700002 V 108.15 h 5.15 V 92.700002 Z m 293.55,0 h 10.3 V 108.15 h -10.3 z m 30.9,0 h 5.15 V 123.6 h -5.15 z M 118.45,108.15 h 5.15 v 15.45 h -5.15 z m 221.45,0 h 5.15 v 15.45 h -5.15 z m 66.95,0 h 10.3 v 15.45 h -10.3 z" fill-rule="evenodd" style="stroke-width:0.858333" />
|
||||||
|
</svg>
|
||||||
|
<h1 id="login"></h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
78
templates/html/svgTape.svg
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<svg id="packageTape" viewbox="0 0 100 10">
|
||||||
|
<rect width="100" height="0.3" x="0" y="4.85" style="fill:#483320;fill-opacity:0.8" />
|
||||||
|
<rect width="100" height="10" x="0" y="0" style="fill:#111;fill-opacity:0.8" />
|
||||||
|
|
||||||
|
<polygon points="21,0.0 20,0.625 21,1.25 20,1.875 21,2.5 20,3.125 21,3.75 20,4.375 21,5.0 20,5.625 21,6.25 20,6.875 21,7.5 20,8.125 21,8.75 20,9.375 21,10.0 100,10 100,0" style="fill:#111;fill-opacity:0.5"/>
|
||||||
|
<text>
|
||||||
|
<textPath href="#packTape0">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape1">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape2">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape3">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape4">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape5">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape6">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape7">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape8">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape9">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape10">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape11">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape12">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape13">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape14">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape15">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape16">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape17">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape18">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape19">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape20">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape21">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape22">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape23">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape24">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape25">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape26">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape27">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape28">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape29">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape30">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape31">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape32">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape33">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
<textPath href="#packTape34">PACK.PACK.PACK.PACK.</textPath>
|
||||||
|
</text>
|
||||||
|
<path id="packTape0" fill="none" stroke="none" d="M-3.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape1" fill="none" stroke="none" d="M-0.60 -2.00 l6 20"/>
|
||||||
|
<path id="packTape2" fill="none" stroke="none" d="M1.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape3" fill="none" stroke="none" d="M6.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape4" fill="none" stroke="none" d="M8.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape5" fill="none" stroke="none" d="M10.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape6" fill="none" stroke="none" d="M15.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape7" fill="none" stroke="none" d="M17.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape8" fill="none" stroke="none" d="M19.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape9" fill="none" stroke="none" d="M24.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape10" fill="none" stroke="none" d="M26.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape11" fill="none" stroke="none" d="M28.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape12" fill="none" stroke="none" d="M33.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape13" fill="none" stroke="none" d="M35.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape14" fill="none" stroke="none" d="M37.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape15" fill="none" stroke="none" d="M42.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape16" fill="none" stroke="none" d="M44.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape17" fill="none" stroke="none" d="M46.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape18" fill="none" stroke="none" d="M51.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape19" fill="none" stroke="none" d="M53.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape20" fill="none" stroke="none" d="M55.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape21" fill="none" stroke="none" d="M60.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape22" fill="none" stroke="none" d="M62.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape23" fill="none" stroke="none" d="M64.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape24" fill="none" stroke="none" d="M69.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape25" fill="none" stroke="none" d="M71.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape26" fill="none" stroke="none" d="M73.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape27" fill="none" stroke="none" d="M78.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape28" fill="none" stroke="none" d="M80.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape29" fill="none" stroke="none" d="M82.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape30" fill="none" stroke="none" d="M87.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape31" fill="none" stroke="none" d="M89.40 -2.00 l6 20"/>
|
||||||
|
<path id="packTape32" fill="none" stroke="none" d="M91.80 -4.00 l6 20"/>
|
||||||
|
<path id="packTape33" fill="none" stroke="none" d="M96.00 -0.00 l6 20"/>
|
||||||
|
<path id="packTape34" fill="none" stroke="none" d="M98.40 -2.00 l6 20"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.4 KiB |
@ -438,7 +438,7 @@ body {
|
|||||||
font-family: 'Courier';
|
font-family: 'Courier';
|
||||||
}
|
}
|
||||||
|
|
||||||
input.error {
|
input.{{ state.error }} {
|
||||||
outline: 2px solid red !important;
|
outline: 2px solid red !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ body {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=submit].enabled {
|
input[type=submit].{{ state.button_on }} {
|
||||||
color: var(--c-text);
|
color: var(--c-text);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
@ -468,7 +468,7 @@ body {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=submit].loading {
|
input[type=submit].{{ state.loading }} {
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
background: linear-gradient(var(--c-label), var(--c-label)) padding-box, conic-gradient(
|
background: linear-gradient(var(--c-label), var(--c-label)) padding-box, conic-gradient(
|
||||||
from var(--angle),
|
from var(--angle),
|
||||||
@ -537,19 +537,6 @@ body {
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
/* .feature { */
|
|
||||||
/* border: 1px solid var(--c-lines); */
|
|
||||||
/* padding: 2%; */
|
|
||||||
/* margin-right: 2%; */
|
|
||||||
/* font-size: 150%; */
|
|
||||||
/* cursor: pointer; */
|
|
||||||
/* user-select: none; */
|
|
||||||
/* transition: background-color 0.15s ease-in-out; */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* .feature:hover { */
|
|
||||||
/* background-color: var(--c-login-hover); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* Feature states. */
|
/* Feature states. */
|
||||||
.feature {
|
.feature {
|
||||||
@ -557,7 +544,7 @@ body {
|
|||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature.fEnabled {
|
.feature.{{ state.feature_on }} {
|
||||||
color: var(--c-text);
|
color: var(--c-text);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
|
|
||||||
@ -611,7 +598,7 @@ body {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#confirmOverlay.enabled {
|
#confirmOverlay.{{ state.confirm_on }} {
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
top: 0;
|
top: 0;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@ -622,7 +609,7 @@ body {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#repoInfo.repoSelected, #repoFeatures.repoCreated {
|
#repoInfo.{{ state.repo_selected }}, #repoFeatures.{{ state.repo_created }} {
|
||||||
opacity: 1
|
opacity: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -674,7 +661,7 @@ body { /* Default no authentication */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body.auth {
|
body.{{ state.auth }} {
|
||||||
#packageLabelTitle h1::before {
|
#packageLabelTitle h1::before {
|
||||||
content: "PACKAGE INFO"
|
content: "PACKAGE INFO"
|
||||||
}
|
}
|
||||||
63
templates/js/base.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
const CONFIG = {
|
||||||
|
client_id: "{{ config.client_id }}",
|
||||||
|
redirect_uri: "{{ config.domain }}",
|
||||||
|
authorization_endpoint: "{{ config.gitea_host }}/login/oauth/authorize",
|
||||||
|
token_endpoint: "{{ config.gitea_host }}/login/oauth/access_token",
|
||||||
|
requested_scopes: "read:repository,write:repository"
|
||||||
|
};
|
||||||
|
|
||||||
|
var G_AUTH = window.localStorage.getItem("token") !== null;
|
||||||
|
|
||||||
|
document.on = document.addEventListener;
|
||||||
|
function sugar(obj) {
|
||||||
|
obj.on = obj.addEventListener;
|
||||||
|
obj.addClass = (x) => obj.classList.add(x);
|
||||||
|
obj.delClass = (x) => obj.classList.remove(x);
|
||||||
|
obj.hasClass = (x) => obj.classList.contains(x);
|
||||||
|
obj.setClass = (x, y) => obj.classList.toggle(x, y);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(s) {
|
||||||
|
let x = [...document.querySelectorAll(s)].map(sugar);
|
||||||
|
return (x.length === 1) ? x[0] : x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if object is empty.
|
||||||
|
function isEmpty(obj) {
|
||||||
|
for (const prop in obj) {
|
||||||
|
if (Object.hasOwn(obj, prop)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns error and resolves promise if necessary.
|
||||||
|
function getErr(f) {
|
||||||
|
return (err) => {
|
||||||
|
if (err instanceof Promise) {
|
||||||
|
return err.then(f);
|
||||||
|
} else {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get("#login").on("click", async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (G_AUTH) {
|
||||||
|
window.localStorage.clear();
|
||||||
|
window.location = "/";
|
||||||
|
} else {
|
||||||
|
// Build the authorization URL
|
||||||
|
let url = CONFIG.authorization_endpoint
|
||||||
|
+ "?response_type=code"
|
||||||
|
+ "&client_id="+encodeURIComponent(CONFIG.client_id)
|
||||||
|
+ "&scope="+encodeURIComponent(CONFIG.requested_scopes)
|
||||||
|
+ "&redirect_uri="+encodeURIComponent(CONFIG.redirect_uri);
|
||||||
|
|
||||||
|
// Redirect to the authorization server
|
||||||
|
window.location = url;
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -1,20 +1,12 @@
|
|||||||
const CONFIG = {
|
|
||||||
client_id: "3d463405-d098-4038-8b25-a44ca5b9ab9c",
|
|
||||||
redirect_uri: "http://127.0.0.1:3000/",
|
|
||||||
authorization_endpoint: "https://git.kjao.me/login/oauth/authorize",
|
|
||||||
token_endpoint: "https://git.kjao.me/login/oauth/access_token",
|
|
||||||
requested_scopes: "read:repository,write:repository"
|
|
||||||
};
|
|
||||||
|
|
||||||
const STATES = { // Either the non-d
|
const STATES = { // Either the non-d
|
||||||
auth: "auth",
|
auth: "{{ state.auth }}",
|
||||||
error: "error",
|
error: "{{ state.error }}",
|
||||||
loading: "loading",
|
loading: "{{ state.loading }}",
|
||||||
repoSelected: "repoSelected",
|
repoSelected: "{{ state.repo_selected }}",
|
||||||
repoCreated: "repoCreated",
|
repoCreated: "{{ state.repo_created }}",
|
||||||
buttonOn: "enabled",
|
buttonOn: "{{ state.button_on }}",
|
||||||
featureOn: "fEnabled",
|
featureOn: "{{ state.feature_on }}",
|
||||||
confirmOn: "enabled",
|
confirmOn: "{{ state.confirm_on }}",
|
||||||
}
|
}
|
||||||
|
|
||||||
var G_REPO_VALUE = "",
|
var G_REPO_VALUE = "",
|
||||||
@ -23,108 +15,15 @@ var G_REPO_VALUE = "",
|
|||||||
|
|
||||||
// UTILITY //
|
// UTILITY //
|
||||||
|
|
||||||
document.on = document.addEventListener;
|
|
||||||
function sugar(obj) {
|
|
||||||
obj.on = obj.addEventListener;
|
|
||||||
obj.addClass = (x) => obj.classList.add(x);
|
|
||||||
obj.delClass = (x) => obj.classList.remove(x);
|
|
||||||
obj.hasClass = (x) => obj.classList.contains(x);
|
|
||||||
obj.setClass = (x, y) => obj.classList.toggle(x, y);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
function get(s) {
|
|
||||||
let x = [...document.querySelectorAll(s)].map(sugar);
|
|
||||||
return (x.length === 1) ? x[0] : x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if object is empty.
|
|
||||||
function isEmpty(obj) {
|
|
||||||
for (const prop in obj) {
|
|
||||||
if (Object.hasOwn(obj, prop)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns error and resolves promise if necessary.
|
|
||||||
function getErr(f) {
|
|
||||||
return (err) => {
|
|
||||||
if (err instanceof Promise) {
|
|
||||||
return err.then(f);
|
|
||||||
} else {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse a query string into an object
|
// Parse a query string into an object
|
||||||
function parseQueryString(string) {
|
function parseQueryString(string) {
|
||||||
if(string == "") { return {}; }
|
if(string == "") { return {}; }
|
||||||
var segments = string.split("&").map(s => s.split("=") );
|
var segments = string.split("&").map(s => s.split("=") );
|
||||||
var queryString = {};
|
var queryString = {};
|
||||||
segments.forEach(s => G_QUERYString[s[0]] = s[1]);
|
segments.forEach(s => queryString[s[0]] = s[1]);
|
||||||
return queryString;
|
return queryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch function for applet use case.
|
|
||||||
async function jfetch(url, method, obj={}) {
|
|
||||||
let request = {
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": window.localStorage.getItem("token"),
|
|
||||||
},
|
|
||||||
method: method,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!isEmpty(obj)) request["body"] = JSON.stringify(obj);
|
|
||||||
|
|
||||||
return fetch(url, request)
|
|
||||||
.then((response) => {
|
|
||||||
let contentType = response.headers.get("Content-Type");
|
|
||||||
let json;
|
|
||||||
if (contentType && contentType.indexOf("application/json" !== -1)) {
|
|
||||||
json = response.json();
|
|
||||||
} else { // Reprocess non-json into json.
|
|
||||||
json = response.text().then((text) => {
|
|
||||||
return { status: response.status, "message": text };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!response.ok) { throw json; }
|
|
||||||
return json;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// OAUTH //
|
|
||||||
|
|
||||||
async function getToken() {
|
|
||||||
let response;
|
|
||||||
if (G_QUERY.code) {
|
|
||||||
response = await jfetch("/api/token", "POST", { code: G_QUERY.code });
|
|
||||||
} else {
|
|
||||||
response = await jfetch("/api/token", "PATCH", { code: window.localStorage.getItem("refresh_token") });
|
|
||||||
}
|
|
||||||
|
|
||||||
window.localStorage.setItem("token", response.access_token);
|
|
||||||
window.localStorage.setItem("token_expiry", (Date.now() + response.expires_in*1000).toString());
|
|
||||||
window.localStorage.setItem("refresh_token", response.refresh_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function tryRefresh() {
|
|
||||||
if (Date.now() < parseInt(window.localStorage.getItem("token_expiry"))) return; // Not expired.
|
|
||||||
await getToken().catch((err) => {
|
|
||||||
let json = err.json();
|
|
||||||
if (json.status == 401 && json.code === 0) { // Could not refresh, so refresh token expired.
|
|
||||||
window.localStorage.clear();
|
|
||||||
alert(`Could not get new session, did you remove access from Gitea?`);
|
|
||||||
window.location = "/";
|
|
||||||
} else {
|
|
||||||
throw json;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// BUTTON ONCLICK MIDDLEWARE //
|
// BUTTON ONCLICK MIDDLEWARE //
|
||||||
|
|
||||||
// Refresh token if necessary.
|
// Refresh token if necessary.
|
||||||
@ -137,7 +36,6 @@ function tryAuth(f) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Adds loading classes for UI while awaiting.
|
// Adds loading classes for UI while awaiting.
|
||||||
function doLoading(f) {
|
function doLoading(f) {
|
||||||
return async (e) => {
|
return async (e) => {
|
||||||
@ -188,24 +86,6 @@ document.on("keydown", (e) => {
|
|||||||
|
|
||||||
// BUTTON ONCLICK FUNCTIONS //
|
// BUTTON ONCLICK FUNCTIONS //
|
||||||
|
|
||||||
get("#login").on("click", async (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (G_AUTH) {
|
|
||||||
window.localStorage.clear();
|
|
||||||
window.location = "/";
|
|
||||||
} else {
|
|
||||||
// Build the authorization URL
|
|
||||||
let url = CONFIG.authorization_endpoint
|
|
||||||
+ "?response_type=code"
|
|
||||||
+ "&client_id="+encodeURIComponent(CONFIG.client_id)
|
|
||||||
+ "&scope="+encodeURIComponent(CONFIG.requested_scopes)
|
|
||||||
+ "&redirect_uri="+encodeURIComponent(CONFIG.redirect_uri);
|
|
||||||
|
|
||||||
// Redirect to the authorization server
|
|
||||||
window.location = url;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
get("#repoSelectInput").on("keydown", (e) => {
|
get("#repoSelectInput").on("keydown", (e) => {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
get("#repoSelectButton").click();
|
get("#repoSelectButton").click();
|
||||||
@ -364,5 +244,4 @@ async function init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var G_QUERY = parseQueryString(window.location.search.substring(1));
|
var G_QUERY = parseQueryString(window.location.search.substring(1));
|
||||||
var G_AUTH = window.localStorage.getItem("token") !== null;
|
|
||||||
init();
|
init();
|
||||||
56
templates/js/token.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Fetch function for applet use case.
|
||||||
|
async function jfetch(url, method, obj={}) {
|
||||||
|
let request = {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": window.localStorage.getItem("token"),
|
||||||
|
},
|
||||||
|
method: method,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isEmpty(obj)) request["body"] = JSON.stringify(obj);
|
||||||
|
|
||||||
|
return fetch(url, request)
|
||||||
|
.then((response) => {
|
||||||
|
let contentType = response.headers.get("Content-Type");
|
||||||
|
let json;
|
||||||
|
if (contentType && contentType.indexOf("application/json" !== -1)) {
|
||||||
|
json = response.json();
|
||||||
|
} else { // Reprocess non-json into json.
|
||||||
|
json = response.text().then((text) => {
|
||||||
|
return { status: response.status, "message": text };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!response.ok) { throw json; }
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// OAUTH //
|
||||||
|
|
||||||
|
async function getToken() {
|
||||||
|
let response;
|
||||||
|
if (G_QUERY.code) {
|
||||||
|
response = await jfetch("/api/token", "POST", { code: G_QUERY.code });
|
||||||
|
} else {
|
||||||
|
response = await jfetch("/api/token", "PATCH", { code: window.localStorage.getItem("refresh_token") });
|
||||||
|
}
|
||||||
|
|
||||||
|
window.localStorage.setItem("token", response.access_token);
|
||||||
|
window.localStorage.setItem("token_expiry", (Date.now() + response.expires_in*1000).toString());
|
||||||
|
window.localStorage.setItem("refresh_token", response.refresh_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tryRefresh() {
|
||||||
|
if (Date.now() < parseInt(window.localStorage.getItem("token_expiry"))) return; // Not expired.
|
||||||
|
await getToken().catch((err) => {
|
||||||
|
let json = err.json();
|
||||||
|
if (json.status == 401 && json.code === 0) { // Could not refresh, so refresh token expired.
|
||||||
|
window.localStorage.clear();
|
||||||
|
alert(`Could not get new session, did you remove access from Gitea?`);
|
||||||
|
window.location = "/";
|
||||||
|
} else {
|
||||||
|
throw json;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||