Rewrite the app (#23)

* chore: Removed everything not needed, and added base for rewrite
feat(error_handling): Added 404 general cache
feat(index): Added informations about the app in the / route.

* feat(indexing): Brought back the indexing, with conditions to make it easier

* fix: Fixed build error with a forgotten call

* feat: Add Docker development enviroment (#19)

* ci: add a *lot* of new actions

* fix: rename linting action

* fix: invalid yaml begone(?)

* ci: Added cache to speed up build times

* fix(ci): 🦀ed the yaml errors

* fix(ci): fixed a missing hyphen

* ci: Added matrix of rust versions, and changed way to install rust toolchain

* fix(ci): Added names to build with the matrix so it's easier to find the source of the problem

* style(ci): Added eof lines

* refactor: Finished moving the search.rs file to a separate module.

* Search Endpoint

* refactor: Moved around functions and struct for a better understanding of what it does.

* chore: Change env default settings to resolve conversation

* refactor: Removed #[use_macros]
fix: Fixed meilisearch address from env

* chore: Added email to Aeledfyr

* fix: Brought back the dotenv variables

* style: Ran `cargo fmt`

Co-authored-by: Charalampos Fanoulis <charalampos.fanoulis@gmail.com>
Co-authored-by: Jai A <jai.a@tuta.io>
This commit is contained in:
Valentin Ricard 2020-06-30 19:23:52 +02:00 committed by GitHub
parent 1ff2a08d19
commit 7a6ecd86c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
87 changed files with 881 additions and 3231 deletions

7
.env
View File

@ -1,2 +1,7 @@
INDEX_CURSEFORGE=false
DEBUG=true
DEBUG=true
MONGODB_ADDR=mongodb://localhost:27017
MEILISEARCH_ADDR=http://localhost:7700
PORT=8000

32
.github/workflows/codequality.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: Code quality
on:
push:
branches: [ master ]
pull_request:
env:
CARGO_TERM_COLOR: always
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
components: rustfmt, clippy
- name: Cache build artifacts
id: cache-build
uses: actions/cache@v2
with:
path: target/**
key: ${{ runner.os }}-build-cache
- name: Annotate commit with clippy warnings
uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features

View File

@ -1,10 +1,9 @@
name: Rust
name: Rust building
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
CARGO_TERM_COLOR: always
@ -16,7 +15,17 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- name: Get build cache
id: cache-build
uses: actions/cache@v2
with:
path: target/**
key: ${{ runner.os }}-build-cache
- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- uses: actions-rs/cargo@v1
name: Build program
with:
command: build

20
.github/workflows/security.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: Security audit
on:
push:
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
pull_request:
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
jobs:
security_audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/audit-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}

39
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Unit Tests
on:
push:
branches: [ master ]
pull_request:
jobs:
test:
name: ${{ matrix.os }}-rust-${{ matrix.rust }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
rust:
- stable
- beta
- nightly
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
name: Install toolchain
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
- name: Cache build artifacts
id: cache-build
uses: actions/cache@v2
with:
path: target/**
key: ${{ runner.os }}-build-cache-${{ matrix.rust }}
- uses: actions-rs/cargo@v1
with:
command: build
- uses: actions-rs/cargo@v1
with:
command: test

1
.gitignore vendored
View File

@ -103,3 +103,4 @@ Cargo.lock
**/*.rs.bk
# End of https://www.gitignore.io/api/rust,clion

14
.idea/deployment.xml generated Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData">
<serverData>
<paths name="Remote Host (b864ed82-8c7b-4ccd-920b-a7b8ba7cc008)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData>
</component>
</project>

View File

@ -1,6 +1,11 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="56" name="Rust" />
</Languages>
</inspection_tool>
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myValues">
<value>

View File

@ -1,10 +1,15 @@
## Contributing
Contributions to fabricate are welcome! However, we do have a couple dependencies that you need to get up and running.
Contributions to labrinth are welcome! However, we do have a couple dependencies that you need to get up and running.
We reccomend using [Docker](https://www.docker.com/) for setting up your dev enviroment. If you have Docker and docker-compose installed, you may run:
```sh
docker-compose up
```
which will deploy a Meilisearch container on port 7700, a MongoDB instance on port 27017 and a MongoDB web UI on port 8081
Alternatively, follow theese steps:
1. Install and run a [MeiliSearch](https://docs.meilisearch.com/guides/introduction/quick_start_guide.html) instance
2. Install [A local MongoDB server](https://www.mongodb.com/try/download/community)
3. Run `mongod --dbpath path/to/db`
4. Everything should be setup and you should be ready to contribute.
A docker container for all of this is coming soon to make this process easier.
4. Everything should be setup and you should be ready to contribute.

View File

@ -1,7 +1,8 @@
[package]
name = "fabricate"
version = "0.1.0"
authors = ["geometrically <jai.a@tuta.io>"]
#Team members, please add your emails and usernames
authors = ["geometrically <jai.a@tuta.io>", "Redblueflame <contact@redblueflame.com>", "Aeledfyr <aeledfyr@gmail.com>", "cfanoulis"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -15,7 +16,6 @@ reqwest = "0.10.4"
meilisearch-sdk = "0.1.4"
handlebars = { version = "3.0.0", features = ["dir_source"] }
serde_json = "1.0"
serde = {version="1.0", features=["derive"]}
@ -26,8 +26,8 @@ env_logger = "0.7.1"
mongodb = "1.0.0"
bson = "1.0.0"
futures = "0.3.5"
futures-timer = "3.0.2"
thiserror = "1.0.20"
async-trait = "0.1.36"
pulldown-cmark = "0.7.1"
human_format = "1.0.3"
futures = "0.3.5"
futures-timer = "3.0.2"

33
docker-compose.yml Normal file
View File

@ -0,0 +1,33 @@
version: '3'
services:
mongo:
image: mongo
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: toor
MONGO_INITDB_ROOT_PASSWORD: modrinthadmin
volumes:
- mongodb-data:/data/db
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: toor
ME_CONFIG_MONGODB_ADMINPASSWORD: modrinthadmin
ME_CONFIG_OPTIONS_EDITORTHEME: material
meilisearch:
image: getmeili/meilisearch
restart: on-failure
ports:
- 7700:7700
volumes:
- meilisearch-data:/data.ms
volumes:
meilisearch-data:
external: true
mongodb-data:
external: true

View File

@ -1,12 +0,0 @@
use mongodb::options::ClientOptions;
use mongodb::Client;
use mongodb::error::Error;
pub async fn connect() -> Result<Client, Error> {
info!("Initializing database connection");
let mut client_options = ClientOptions::parse("mongodb://localhost:27017").await?;
client_options.app_name = Some("Actix Web Server".to_string());
Client::with_options(client_options)
}

View File

@ -1,6 +1,19 @@
mod database;
mod models;
pub mod models;
mod mongo_database;
pub use database::connect;
pub use models::Mod;
pub use models::Version;
pub use mongo_database::connect;
use thiserror::Error;
type Result<T> = std::result::Result<T, DatabaseError>;
#[derive(Error, Debug)]
pub enum DatabaseError {
#[error("Impossible to find document")]
NotFound(),
#[error("BSON deserialization error")]
BsonError(#[from] bson::de::Error),
#[error("Local database error")]
LocalDatabaseError(#[from] mongodb::error::Error),
}

View File

@ -1,28 +0,0 @@
use serde::{Serialize, Deserialize};
#[derive(Deserialize, Serialize)]
pub struct Mod {
pub id: i32,
pub title: String,
pub description: String,
pub published: String,
pub author: String,
pub downloads: i32,
pub categories: Vec<String>,
pub body_path: String,
pub icon_path: String,
}
#[derive(Deserialize, Serialize)]
pub struct Version {
pub version_id: i32,
pub mod_id: i32,
pub title: String,
pub changelog_path: String,
pub files_path: Vec<String>,
pub date_published: String,
pub author: String,
pub downloads: i32,
pub dependencies: Vec<String>,
pub game_versions: Vec<String>,
}

View File

@ -0,0 +1,27 @@
mod mod_item;
mod version_item;
use crate::database::DatabaseError::NotFound;
use crate::database::Result;
use async_trait::async_trait;
use bson::doc;
use bson::Document;
pub use mod_item::Mod;
use mongodb::Database;
pub use version_item::Version;
#[async_trait]
pub trait Item {
fn get_collection() -> &'static str;
async fn get_by_id(client: Database, id: &str) -> Result<Box<Self>> {
let filter = doc! { "_id": id };
let collection = client.collection(Self::get_collection());
let doc: Document = match collection.find_one(filter, None).await? {
Some(e) => e,
None => return Err(NotFound()),
};
let elem: Box<Self> = Self::from_doc(doc)?;
Ok(elem)
}
fn from_doc(elem: Document) -> Result<Box<Self>>;
}

View File

@ -0,0 +1,27 @@
use crate::database::models::Item;
use crate::database::Result;
use bson::{Bson, Document};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
pub struct Mod {
pub id: i32,
pub title: String,
pub description: String,
pub published: String,
pub author: String,
pub downloads: i32,
pub categories: Vec<String>,
pub body_path: String,
pub icon_path: String,
}
impl Item for Mod {
fn get_collection() -> &'static str {
"mods"
}
fn from_doc(elem: Document) -> Result<Box<Mod>> {
let result: Mod = bson::from_bson(Bson::from(elem))?;
Ok(Box::from(result))
}
}

View File

@ -0,0 +1,28 @@
use crate::database::models::Item;
use crate::database::Result;
use bson::{Bson, Document};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
pub struct Version {
pub version_id: i32,
pub mod_id: i32,
pub title: String,
pub changelog_path: String,
pub files_path: Vec<String>,
pub date_published: String,
pub author: String,
pub downloads: i32,
pub dependencies: Vec<String>,
pub game_versions: Vec<String>,
}
impl Item for Version {
fn get_collection() -> &'static str {
"versions"
}
fn from_doc(elem: Document) -> Result<Box<Version>> {
let version: Version = bson::from_bson(Bson::from(elem))?;
Ok(Box::from(version))
}
}

View File

@ -0,0 +1,13 @@
use log::info;
use mongodb::error::Error;
use mongodb::options::ClientOptions;
use mongodb::Client;
pub async fn connect() -> Result<Client, Error> {
info!("Initializing database connection");
let mut client_options = ClientOptions::parse(&dotenv::var("PORT").unwrap()).await?;
client_options.app_name = Some("labrinth".to_string());
Client::with_options(client_options)
}

View File

@ -1,35 +0,0 @@
use handlebars::*;
#[derive(Clone, Copy)]
pub struct ContainsHelper;
impl HelperDef for ContainsHelper {
fn call<'reg: 'rc, 'rc>(
&self,
h: &Helper<'reg, 'rc>,
r: &'reg Handlebars<'_>,
ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> HelperResult {
let array = h
.param(0)
.map(|v| serde_json::from_value::<Vec<String>>(v.value().clone()).unwrap())
.ok_or_else(|| RenderError::new("Parameter not found!"))?;
let value = h
.param(1)
.map(|v| v.value().as_str().unwrap())
.ok_or_else(|| RenderError::new("Parameter not found!"))?;
let tmpl = if array.contains(&String::from(value)) {
h.template()
} else {
h.inverse()
};
match tmpl {
Some(ref t) => t.render(r, ctx, rc, out),
None => Ok(()),
}
}
}

View File

@ -1,36 +0,0 @@
use handlebars::*;
#[derive(Clone, Copy)]
pub struct EqualsHelper;
impl HelperDef for EqualsHelper {
fn call<'reg: 'rc, 'rc>(
&self,
h: &Helper<'reg, 'rc>,
r: &'reg Handlebars<'_>,
ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> HelperResult {
let a = h
.param(0)
.map(|v| v.value().as_object().unwrap())
.ok_or_else(|| RenderError::new("Parameter not found!"))?;
let b = h
.param(1)
.map(|v| v.value().as_object().unwrap())
.ok_or_else(|| RenderError::new("Parameter not found!"))?;
let tmpl = if a == b {
h.template()
} else {
h.inverse()
};
match tmpl {
Some(ref t) => t.render(r, ctx, rc, out),
None => Ok(()),
}
}
}

View File

@ -1,31 +0,0 @@
extern crate human_format;
use handlebars::*;
#[derive(Clone, Copy)]
pub struct HumanFormatHelper;
impl HelperDef for HumanFormatHelper {
fn call<'reg: 'rc, 'rc>(
&self,
h: &Helper<'reg, 'rc>,
_r: &'reg Handlebars<'_>,
_ctx: &'rc Context,
_rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> HelperResult {
let param = h.param(0).and_then(|v| v.value().as_f64()).unwrap_or(0.0);
let string = &param.to_string();
if string.len() > 3 {
let mut formatted = human_format::Formatter::new().format(param);
formatted.retain(|c| !c.is_whitespace());
out.write(formatted.to_uppercase().as_ref())?;
} else {
out.write(string)?;
}
Ok(())
}
}

View File

@ -1,13 +0,0 @@
mod contains;
mod format_human;
mod equals;
use handlebars::*;
pub fn register_helpers(handlebars: &mut Handlebars) {
handlebars.register_helper("contains", Box::new(contains::ContainsHelper));
handlebars.register_helper("format", Box::new(format_human::HumanFormatHelper));
//This helper is not used yet, but could be useful in many circumstances
handlebars.register_helper("equals", Box::new(equals::EqualsHelper));
}

View File

@ -1,40 +1,40 @@
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate bson;
#[macro_use]
extern crate log;
use actix_files as fs;
use actix_web::{web, App, HttpServer};
use handlebars::*;
use crate::search::indexing::index_mods;
use actix_web::middleware::Logger;
use actix_web::{web, App, HttpServer};
use env_logger::Env;
use log::info;
use std::env;
use std::fs::File;
mod database;
mod helpers;
mod models;
mod routes;
mod search;
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
env_logger::from_env(Env::default().default_filter_or("info")).init();
dotenv::dotenv().ok();
//Handlebars
let mut handlebars = Handlebars::new();
helpers::register_helpers(&mut handlebars);
handlebars
.register_templates_directory(".hbs", "./templates")
.unwrap();
let handlebars_ref = web::Data::new(handlebars);
let client = database::connect().await.unwrap();
routes::index_mods(client).await.unwrap();
// Get executable path
let mut exe_path = env::current_exe()?.parent().unwrap().to_path_buf();
// Create the path to the index lock file
exe_path.push("index.v1.lock");
//Indexing mods if not already done
if env::args().any(|x| x == "regen") {
// User forced regen of indexing
info!("Forced regeneration of indexes!");
index_mods(client).await.unwrap();
} else if exe_path.exists() {
// The indexes were not created, or the version was upgraded
info!("Indexing of mods for first time...");
index_mods(client).await.unwrap();
// Create the lock file
File::create(exe_path)?;
}
info!("Starting Actix HTTP server!");
@ -43,15 +43,11 @@ async fn main() -> std::io::Result<()> {
App::new()
.wrap(Logger::default())
.wrap(Logger::new("%a %{User-Agent}i"))
.app_data(handlebars_ref.clone())
.service(fs::Files::new("/static", "./static").show_files_listing())
.service(routes::index_get)
.service(routes::search_post)
.service(routes::search_get)
.service(routes::mod_page_get)
.service(routes::mod_create_get)
.service(routes::mod_search)
.default_service(web::get().to(routes::not_found))
})
.bind("127.0.0.1:8000")?
.bind("127.0.0.1:".to_string() + &dotenv::var("PORT").unwrap())?
.run()
.await
}

6
src/models/error.rs Normal file
View File

@ -0,0 +1,6 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct ApiError<'a> {
pub error: &'a str,
pub description: &'a str,
}

2
src/models/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod error;
pub mod mods;

10
src/models/mods.rs Normal file
View File

@ -0,0 +1,10 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct SearchRequest {
pub query: Option<String>,
pub filters: Option<String>,
pub version: Option<String>,
pub offset: Option<String>,
pub index: Option<String>,
}

View File

@ -1,12 +1,15 @@
use actix_web::{get, web, HttpResponse};
use handlebars::*;
use serde_json::json;
#[get("/")]
pub async fn index_get(hb: web::Data<Handlebars<'_>>) -> HttpResponse {
pub async fn index_get() -> HttpResponse {
let data = json!({
"name": "Handlebars"
"name": "modrinth-labrinth",
"version": env!("CARGO_PKG_VERSION"),
//TODO: Add the documentation link
"documentation": "Nowhere yet",
"about": "Welcome traveler !"
});
let body = hb.render("index", &data).unwrap();
HttpResponse::Ok().body(body)
HttpResponse::Ok().json(data)
}

View File

@ -1,14 +1,7 @@
mod index;
mod mod_page;
mod search;
mod mod_create;
pub use self::mod_page::mod_page_get;
pub use self::mod_create::mod_create_get;
pub use self::search::index_mods;
pub use self::search::search_get;
pub use self::search::search_post;
mod mods;
mod not_found;
pub use self::index::index_get;
pub use self::mods::mod_search;
pub use self::not_found::not_found;

View File

@ -1,30 +0,0 @@
use actix_web::{get, post, web, HttpResponse};
use handlebars::*;
use serde::Deserialize;
#[derive(Deserialize)]
struct CreatedMod {
name: String,
description: String,
body: String,
}
#[get("createmod")]
pub async fn mod_create_get(hb: web::Data<Handlebars<'_>>) -> HttpResponse {
let data = json!({
"name": "Handlebars"
});
let body = hb.render("mod-create", &data).unwrap();
HttpResponse::Ok().body(body)
}
#[post("createmod")]
pub async fn mod_create_post(hb: web::Data<Handlebars<'_>>) -> HttpResponse {
let data = json!({
"name": "Handlebars"
});
let body = hb.render("mod-create", &data).unwrap();
HttpResponse::Ok().body(body)
}

View File

@ -1,12 +0,0 @@
use actix_web::{get, web, HttpResponse};
use handlebars::*;
#[get("mod/testmod")]
pub async fn mod_page_get(hb: web::Data<Handlebars<'_>>) -> HttpResponse {
let data = json!({
"name": "Handlebars"
});
let body = hb.render("mod-page", &data).unwrap();
HttpResponse::Ok().body(body)
}

13
src/routes/mods.rs Normal file
View File

@ -0,0 +1,13 @@
use crate::models::mods::SearchRequest;
use crate::search::search_for_mod;
use actix_web::{get, web, HttpResponse};
#[get("api/v1/mods")]
pub fn mod_search(web::Query(info): web::Query<SearchRequest>) -> HttpResponse {
//TODO: Fix this line with anyhow
let body = serde_json::to_string(&search_for_mod(&info).unwrap()).unwrap();
HttpResponse::Ok()
.content_type("application/json")
.body(body)
}

11
src/routes/not_found.rs Normal file
View File

@ -0,0 +1,11 @@
use crate::models::error::ApiError;
use actix_web::{HttpResponse, Responder};
pub async fn not_found() -> impl Responder {
let data = ApiError {
error: "not_found",
description: "the route you called is not (yet) implemented",
};
HttpResponse::NotFound().json(data)
}

View File

@ -1,464 +0,0 @@
use actix_web::{get, post, web, web::Data, HttpResponse};
use handlebars::*;
use meilisearch_sdk::{client::*, document::*, search::*};
use serde::{Deserialize, Serialize};
use meilisearch_sdk::settings::Settings;
use futures::stream::StreamExt;
use bson::Bson;
use std::collections::{HashMap, VecDeque};
use std::error::Error;
use crate::database::*;
use futures_timer::Delay;
use futures::TryFutureExt;
use std::time::Duration;
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Attachment {
url: String,
thumbnail_url: String,
is_default: bool,
}
#[derive(Serialize, Deserialize, Debug)]
struct Category {
name: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct Author {
name: String,
url: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct CurseVersion {
game_version: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct CurseForgeMod {
id: i32,
name: String,
authors: Vec<Author>,
attachments: Vec<Attachment>,
website_url: String,
summary: String,
download_count: f32,
categories: Vec<Category>,
game_version_latest_files: Vec<CurseVersion>,
date_created: String,
date_modified: String,
game_slug: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct SearchMod {
mod_id: i32,
author: String,
title: String,
description: String,
keywords: Vec<String>,
versions: Vec<String>,
downloads: i32,
page_url: String,
icon_url: String,
author_url: String,
date_created: String,
created: i64,
date_modified: String,
updated: i64,
latest_version: String,
empty: String,
}
impl Document for SearchMod {
type UIDType = i32;
fn get_uid(&self) -> &Self::UIDType {
&self.mod_id
}
}
#[derive(Serialize, Deserialize)]
pub struct SearchRequest {
#[serde(rename = "q")]
query: Option<String>,
#[serde(rename = "f")]
filters: Option<String>,
#[serde(rename = "v")]
version: Option<String>,
#[serde(rename = "o")]
offset: Option<String>,
#[serde(rename = "s")]
index: Option<String>,
}
#[post("search")]
pub async fn search_post(
web::Query(info): web::Query<SearchRequest>,
hb: Data<Handlebars<'_>>,
) -> HttpResponse {
let results = search(&info);
let data = json!({
"query": info,
"results": results,
});
let body = hb.render("search-results", &data).unwrap();
HttpResponse::Ok().body(body)
}
#[get("search")]
pub async fn search_get(
web::Query(info): web::Query<SearchRequest>,
hb: Data<Handlebars<'_>>,
) -> HttpResponse {
let results = search(&info);
let data = json!({
"query": info,
"results": results,
});
let body = hb.render("search", &data).unwrap();
HttpResponse::Ok().body(body)
}
fn search(info: &SearchRequest) -> Vec<SearchMod> {
let client = Client::new("http://localhost:7700", "");
let search_query: &str;
let mut filters = String::new();
let mut offset = 0;
let mut index = "relevance";
match info.query.as_ref() {
Some(q) => search_query = q,
None => search_query = "{}{}{}",
}
if let Some(f) = info.filters.as_ref() {
filters = f.clone();
}
if let Some(v) = info.version.as_ref() {
if filters.is_empty() {
filters = v.clone();
} else {
filters = format!("({}) AND ({})", filters, v);
}
}
if let Some(o) = info.offset.as_ref() {
offset = o.parse().unwrap();
}
if let Some(s) = info.index.as_ref() {
index = s;
}
let mut query = Query::new(search_query).with_limit(10).with_offset(offset);
if !filters.is_empty() {
query = query.with_filters(&filters);
}
client.get_index(format!("{}_mods", index).as_ref()).unwrap()
.search::<SearchMod>(&query).unwrap().hits
}
/*
TODO This method needs a lot of refactoring. Here's a list of changes that need to be made:
- Move Curseforge Indexing to another method/module
- Get rid of the 4 indexes (when MeiliSearch updates) and replace it with different rules
- Remove code fragment duplicates
*/
pub async fn index_mods(db: mongodb::Client) -> Result<(), Box<dyn Error>>{
let mut docs_to_add: Vec<SearchMod> = vec![];
docs_to_add.append(&mut index_database(db.clone()).await?);
//docs_to_add.append(&mut index_curseforge(1, 400000).await?);
//Write Indexes
//Relevance Index
let client = Client::new("http://localhost:7700", "");
let mut relevance_index = client.get_or_create("relevance_mods").unwrap();
let mut relevance_rules = default_rules();
relevance_rules.push_back("desc(downloads)".to_string());
relevance_index.set_settings(&default_settings().with_ranking_rules(relevance_rules.into())).unwrap();
relevance_index.add_documents(docs_to_add.clone(), Some("mod_id")).unwrap();
//Downloads Index
let mut downloads_index = client.get_or_create("downloads_mods").unwrap();
let mut downloads_rules = default_rules();
downloads_rules.push_front("desc(downloads)".to_string());
downloads_index.set_settings(&default_settings().with_ranking_rules(downloads_rules.into())).unwrap();
downloads_index.add_documents(docs_to_add.clone(), Some("mod_id")).unwrap();
//Updated Index
let mut updated_index = client.get_or_create("updated_mods").unwrap();
let mut updated_rules = default_rules();
updated_rules.push_front("desc(updated)".to_string());
updated_index.set_settings(&default_settings().with_ranking_rules(updated_rules.into())).unwrap();
updated_index.add_documents(docs_to_add.clone(), Some("mod_id")).unwrap();
//Created Index
let mut newest_index = client.get_or_create("newest_mods").unwrap();
let mut newest_rules = default_rules();
newest_rules.push_back("desc(created)".to_string());
newest_index.set_settings(&default_settings().with_ranking_rules(newest_rules.into())).unwrap();
newest_index.add_documents(docs_to_add.clone(), Some("mod_id")).unwrap();
Ok(())
}
async fn index_database(client: mongodb::Client) -> Result<Vec<SearchMod>, Box<dyn Error>> {
info!("Indexing database mods!");
let mut docs_to_add: Vec<SearchMod> = vec![];
let db = client.database("fabricate");
let mods = db.collection("mods");
let versions = db.collection("versions");
let mut results = mods.find(None, None).await?;
while let Some(unparsed_result) = results.next().await {
let result : Mod = bson::from_bson(Bson::from(unparsed_result?))?;
let mut mod_versions = versions.find(doc!{ "mod_id": result.id}, None).await?;
let mut mod_game_versions = vec![];
while let Some(unparsed_version) = mod_versions.next().await {
let mut version : Version = bson::from_bson(Bson::from(unparsed_version?))?;
mod_game_versions.append(&mut version.game_versions);
}
docs_to_add.push(SearchMod {
mod_id: result.id,
author: result.author,
title: result.title,
description: result.description,
keywords: result.categories,
versions: mod_game_versions,
downloads: result.downloads,
page_url: "".to_string(),
icon_url: result.icon_path,
author_url: "".to_string(),
date_created: "".to_string(),
created: 0,
date_modified: "".to_string(),
updated: 0,
latest_version: "".to_string(),
empty: String::from("{}{}{}"),
});
}
Ok(docs_to_add)
}
async fn index_curseforge(start_index: i32, end_index: i32) -> Result<Vec<SearchMod>, Box<dyn Error>>{
info!("Indexing curseforge mods!");
let mut docs_to_add: Vec<SearchMod> = vec![];
let res = reqwest::Client::new().post("https://addons-ecs.forgesvc.net/api/v2/addon")
.header(reqwest::header::CONTENT_TYPE, "application/json")
.body(format!("{:?}", (start_index..end_index).collect::<Vec<_>>()))
.send().await?;
let text = &res.text().await?;
let curseforge_mods : Vec<CurseForgeMod> = serde_json::from_str(text)?;
let mut max_index = 0;
for curseforge_mod in curseforge_mods {
max_index = curseforge_mod.id;
if curseforge_mod.game_slug != "minecraft" || !curseforge_mod.website_url.contains("/mc-mods/") { continue; }
let mut mod_game_versions = vec![];
let mut using_forge = false;
let mut using_fabric = false;
for version in curseforge_mod.game_version_latest_files {
let version_number: String = version
.game_version
.chars()
.skip(2)
.take(version.game_version.len())
.collect();
if version_number.parse::<f32>()? < 14.0 {
using_forge = true;
}
mod_game_versions.push(version.game_version);
}
let mut mod_categories = vec![];
for category in curseforge_mod.categories {
match &category.name[..] {
"World Gen" => mod_categories.push(String::from("worldgen")),
"Biomes" => mod_categories.push(String::from("worldgen")),
"Ores and Resources" => mod_categories.push(String::from("worldgen")),
"Structures" => mod_categories.push(String::from("worldgen")),
"Dimensions" => mod_categories.push(String::from("worldgen")),
"Mobs" => mod_categories.push(String::from("worldgen")),
"Technology" => mod_categories.push(String::from("technology")),
"Processing" => mod_categories.push(String::from("technology")),
"Player Transport" => mod_categories.push(String::from("technology")),
"Energy, Fluid, and Item Transport" => { mod_categories.push(String::from("technology")) }
"Food" => mod_categories.push(String::from("food")),
"Farming" => mod_categories.push(String::from("food")),
"Energy" => mod_categories.push(String::from("technology")),
"Redstone" => mod_categories.push(String::from("technology")),
"Genetics" => mod_categories.push(String::from("technology")),
"Magic" => mod_categories.push(String::from("magic")),
"Storage" => mod_categories.push(String::from("storage")),
"API and Library" => mod_categories.push(String::from("library")),
"Adventure and RPG" => mod_categories.push(String::from("adventure")),
"Map and Information" => mod_categories.push(String::from("utility")),
"Cosmetic" => mod_categories.push(String::from("decoration")),
"Addons" => mod_categories.push(String::from("misc")),
"Thermal Expansion" => mod_categories.push(String::from("misc")),
"Tinker's Construct" => mod_categories.push(String::from("misc")),
"Industrial Craft" => mod_categories.push(String::from("misc")),
"Thaumcraft" => mod_categories.push(String::from("misc")),
"Buildcraft" => mod_categories.push(String::from("misc")),
"Forestry" => mod_categories.push(String::from("misc")),
"Blood Magic" => mod_categories.push(String::from("misc")),
"Lucky Blocks" => mod_categories.push(String::from("misc")),
"Applied Energistics 2" => mod_categories.push(String::from("misc")),
"CraftTweaker" => mod_categories.push(String::from("misc")),
"Miscellaneous" => mod_categories.push(String::from("misc")),
"Armor, Tools, and Weapons" => mod_categories.push(String::from("equipment")),
"Server Utility" => mod_categories.push(String::from("utility")),
"Fabric" => mod_categories.push(String::from("fabric")),
_ => {}
}
}
if mod_categories.contains(&"fabric".to_owned()) {
using_fabric = true;
}
mod_categories.sort();
mod_categories.dedup();
mod_categories.truncate(3);
if using_forge {
mod_categories.push(String::from("forge"));
}
if using_fabric {
mod_categories.push(String::from("fabric"));
}
let mut mod_attachments = curseforge_mod.attachments;
mod_attachments.retain(|x| x.is_default);
if mod_attachments.is_empty() {
mod_attachments.push(Attachment {
url: String::new(),
thumbnail_url: String::new(),
is_default: true,
})
}
let latest_version = if !mod_game_versions.is_empty() {
mod_game_versions[0].to_string()
} else {
"None".to_string()
};
let icon_url = mod_attachments[0].thumbnail_url.replace("/256/256/", "/64/64/");
docs_to_add.push(SearchMod {
mod_id: -curseforge_mod.id,
author: (&curseforge_mod.authors[0].name).to_string(),
title: curseforge_mod.name,
description: curseforge_mod.summary.chars().take(150).collect(),
keywords: mod_categories,
versions: mod_game_versions.clone(),
downloads: curseforge_mod.download_count as i32,
page_url: curseforge_mod.website_url,
icon_url,
author_url: (&curseforge_mod.authors[0].url).to_string(),
date_created: curseforge_mod.date_created.chars().take(10).collect(),
created: curseforge_mod.date_created.chars().filter(|c| c.is_ascii_digit()).collect::<String>().parse()?,
date_modified: curseforge_mod.date_modified.chars().take(10).collect(),
updated: curseforge_mod.date_modified.chars().filter(|c| c.is_ascii_digit()).collect::<String>().parse()?,
latest_version,
empty: String::from("{}{}{}"),
})
}
//TODO Reindex every hour for new mods.
Ok(docs_to_add)
}
fn default_rules() -> VecDeque<String> {
vec![
"typo".to_string(),
"words".to_string(),
"proximity".to_string(),
"attribute".to_string(),
"wordsPosition".to_string(),
"exactness".to_string(),
].into()
}
fn default_settings() -> Settings {
let displayed_attributes = vec![
"mod_id".to_string(),
"author".to_string(),
"title".to_string(),
"description".to_string(),
"keywords".to_string(),
"versions".to_string(),
"downloads".to_string(),
"page_url".to_string(),
"icon_url".to_string(),
"author_url".to_string(),
"date_created".to_string(),
"created".to_string(),
"date_modified".to_string(),
"updated".to_string(),
"latest_version".to_string(),
"empty".to_string(),
];
let searchable_attributes = vec![
"title".to_string(),
"description".to_string(),
"keywords".to_string(),
"versions".to_string(),
"author".to_string(),
"empty".to_string(),
];
Settings::new()
.with_displayed_attributes(displayed_attributes.clone())
.with_searchable_attributes(searchable_attributes.clone())
.with_accept_new_fields(true)
.with_stop_words(vec![])
.with_synonyms(HashMap::new())
}

View File

@ -0,0 +1,212 @@
use crate::search::{SearchError, SearchMod};
use log::info;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Attachment {
pub url: String,
pub thumbnail_url: String,
pub is_default: bool,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Category {
pub name: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Author {
pub name: String,
pub url: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct CurseVersion {
pub game_version: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct CurseForgeMod {
pub id: i32,
pub name: String,
pub authors: Vec<Author>,
pub attachments: Vec<Attachment>,
pub website_url: String,
pub summary: String,
pub download_count: f32,
pub categories: Vec<Category>,
pub game_version_latest_files: Vec<CurseVersion>,
pub date_created: String,
pub date_modified: String,
pub game_slug: String,
}
pub async fn index_curseforge(
start_index: i32,
end_index: i32,
) -> Result<Vec<SearchMod>, SearchError> {
info!("Indexing curseforge mods!");
let mut docs_to_add: Vec<SearchMod> = vec![];
let res = reqwest::Client::new()
.post("https://addons-ecs.forgesvc.net/api/v2/addon")
.header(reqwest::header::CONTENT_TYPE, "application/json")
.body(format!(
"{:?}",
(start_index..end_index).collect::<Vec<_>>()
))
.send()
.await?;
let text = &res.text().await?;
let curseforge_mods: Vec<CurseForgeMod> = serde_json::from_str(text)?;
let mut max_index = 0;
for curseforge_mod in curseforge_mods {
max_index = curseforge_mod.id;
if curseforge_mod.game_slug != "minecraft"
|| !curseforge_mod.website_url.contains("/mc-mods/")
{
continue;
}
let mut mod_game_versions = vec![];
let mut using_forge = false;
let mut using_fabric = false;
for version in curseforge_mod.game_version_latest_files {
let version_number: String = version
.game_version
.chars()
.skip(2)
.take(version.game_version.len())
.collect();
if version_number.parse::<f32>()? < 14.0 {
using_forge = true;
}
mod_game_versions.push(version.game_version);
}
let mut mod_categories = vec![];
for category in curseforge_mod.categories {
match &category.name[..] {
"World Gen" => mod_categories.push(String::from("worldgen")),
"Biomes" => mod_categories.push(String::from("worldgen")),
"Ores and Resources" => mod_categories.push(String::from("worldgen")),
"Structures" => mod_categories.push(String::from("worldgen")),
"Dimensions" => mod_categories.push(String::from("worldgen")),
"Mobs" => mod_categories.push(String::from("worldgen")),
"Technology" => mod_categories.push(String::from("technology")),
"Processing" => mod_categories.push(String::from("technology")),
"Player Transport" => mod_categories.push(String::from("technology")),
"Energy, Fluid, and Item Transport" => {
mod_categories.push(String::from("technology"))
}
"Food" => mod_categories.push(String::from("food")),
"Farming" => mod_categories.push(String::from("food")),
"Energy" => mod_categories.push(String::from("technology")),
"Redstone" => mod_categories.push(String::from("technology")),
"Genetics" => mod_categories.push(String::from("technology")),
"Magic" => mod_categories.push(String::from("magic")),
"Storage" => mod_categories.push(String::from("storage")),
"API and Library" => mod_categories.push(String::from("library")),
"Adventure and RPG" => mod_categories.push(String::from("adventure")),
"Map and Information" => mod_categories.push(String::from("utility")),
"Cosmetic" => mod_categories.push(String::from("decoration")),
"Addons" => mod_categories.push(String::from("misc")),
"Thermal Expansion" => mod_categories.push(String::from("misc")),
"Tinker's Construct" => mod_categories.push(String::from("misc")),
"Industrial Craft" => mod_categories.push(String::from("misc")),
"Thaumcraft" => mod_categories.push(String::from("misc")),
"Buildcraft" => mod_categories.push(String::from("misc")),
"Forestry" => mod_categories.push(String::from("misc")),
"Blood Magic" => mod_categories.push(String::from("misc")),
"Lucky Blocks" => mod_categories.push(String::from("misc")),
"Applied Energistics 2" => mod_categories.push(String::from("misc")),
"CraftTweaker" => mod_categories.push(String::from("misc")),
"Miscellaneous" => mod_categories.push(String::from("misc")),
"Armor, Tools, and Weapons" => mod_categories.push(String::from("equipment")),
"Server Utility" => mod_categories.push(String::from("utility")),
"Fabric" => mod_categories.push(String::from("fabric")),
_ => {}
}
}
if mod_categories.contains(&"fabric".to_owned()) {
using_fabric = true;
}
mod_categories.sort();
mod_categories.dedup();
mod_categories.truncate(3);
if using_forge {
mod_categories.push(String::from("forge"));
}
if using_fabric {
mod_categories.push(String::from("fabric"));
}
let mut mod_attachments = curseforge_mod.attachments;
mod_attachments.retain(|x| x.is_default);
if mod_attachments.is_empty() {
mod_attachments.push(Attachment {
url: String::new(),
thumbnail_url: String::new(),
is_default: true,
})
}
let latest_version = if !mod_game_versions.is_empty() {
mod_game_versions[0].to_string()
} else {
"None".to_string()
};
let icon_url = mod_attachments[0]
.thumbnail_url
.replace("/256/256/", "/64/64/");
docs_to_add.push(SearchMod {
mod_id: -curseforge_mod.id,
author: (&curseforge_mod.authors[0].name).to_string(),
title: curseforge_mod.name,
description: curseforge_mod.summary.chars().take(150).collect(),
keywords: mod_categories,
versions: mod_game_versions.clone(),
downloads: curseforge_mod.download_count as i32,
page_url: curseforge_mod.website_url,
icon_url,
author_url: (&curseforge_mod.authors[0].url).to_string(),
date_created: curseforge_mod.date_created.chars().take(10).collect(),
created: curseforge_mod
.date_created
.chars()
.filter(|c| c.is_ascii_digit())
.collect::<String>()
.parse()?,
date_modified: curseforge_mod.date_modified.chars().take(10).collect(),
updated: curseforge_mod
.date_modified
.chars()
.filter(|c| c.is_ascii_digit())
.collect::<String>()
.parse()?,
latest_version,
empty: String::from("{}{}{}"),
})
}
//TODO Reindex every hour for new mods.
Ok(docs_to_add)
}

View File

@ -0,0 +1,57 @@
use bson::doc;
use bson::Bson;
use futures::StreamExt;
use log::info;
use meilisearch_sdk::client::Client;
use crate::database::models::Item;
use crate::database::{Mod, Version};
use crate::search::{SearchError, SearchMod, SearchRequest};
pub async fn index_local(client: mongodb::Client) -> Result<Vec<SearchMod>, SearchError> {
info!("Indexing local mods!");
let mut docs_to_add: Vec<SearchMod> = vec![];
let db = client.database("modrinth");
let mods = db.collection("mods");
let versions = db.collection("versions");
let mut results = mods.find(None, None).await?;
while let Some(unparsed_result) = results.next().await {
let result: Mod = *Mod::from_doc(unparsed_result?)?;
let mut mod_versions = versions.find(doc! { "mod_id": result.id}, None).await?;
let mut mod_game_versions = vec![];
while let Some(unparsed_version) = mod_versions.next().await {
let mut version: Version = *Version::from_doc(unparsed_version?)?;
mod_game_versions.append(&mut version.game_versions);
}
docs_to_add.push(SearchMod {
mod_id: result.id,
author: result.author,
title: result.title,
description: result.description,
keywords: result.categories,
versions: mod_game_versions,
downloads: result.downloads,
page_url: "".to_string(),
icon_url: result.icon_path,
author_url: "".to_string(),
date_created: "".to_string(),
created: 0,
date_modified: "".to_string(),
updated: 0,
latest_version: "".to_string(),
empty: String::from("{}{}{}"),
});
}
Ok(docs_to_add)
}

135
src/search/indexing/mod.rs Normal file
View File

@ -0,0 +1,135 @@
/// This module is used for the indexing from any source.
pub mod curseforge_import;
pub mod local_import;
use crate::database::DatabaseError;
use crate::search::indexing::curseforge_import::index_curseforge;
use crate::search::indexing::local_import::index_local;
use crate::search::{SearchError, SearchMod};
use meilisearch_sdk::client::Client;
use meilisearch_sdk::settings::Settings;
use std::collections::{HashMap, VecDeque};
pub async fn index_mods(db: mongodb::Client) -> Result<(), SearchError> {
// Check if the index exists
let address = &*dotenv::var("MEILISEARCH_ADDR")?;
let client = Client::new(address, "");
let mut docs_to_add: Vec<SearchMod> = vec![];
docs_to_add.append(&mut index_local(db.clone()).await?);
if dotenv::var("INDEX_CURSEFORGE")
.expect("`INDEX_CURSEFORGE` is missing in the .env file.")
.parse()
.unwrap()
{
docs_to_add.append(&mut index_curseforge(1, 400000).await?);
}
//Write Indexes
//Relevance Index
let mut relevance_index = client.get_or_create("relevance_mods").unwrap();
let mut relevance_rules = default_rules();
relevance_rules.push_back("desc(downloads)".to_string());
relevance_index
.set_settings(&default_settings().with_ranking_rules(relevance_rules.into()))
.unwrap();
relevance_index
.add_documents(docs_to_add.clone(), Some("mod_id"))
.unwrap();
//Downloads Index
let mut downloads_index = client.get_or_create("downloads_mods").unwrap();
let mut downloads_rules = default_rules();
downloads_rules.push_front("desc(downloads)".to_string());
downloads_index
.set_settings(&default_settings().with_ranking_rules(downloads_rules.into()))
.unwrap();
downloads_index
.add_documents(docs_to_add.clone(), Some("mod_id"))
.unwrap();
//Updated Index
let mut updated_index = client.get_or_create("updated_mods").unwrap();
let mut updated_rules = default_rules();
updated_rules.push_front("desc(updated)".to_string());
updated_index
.set_settings(&default_settings().with_ranking_rules(updated_rules.into()))
.unwrap();
updated_index
.add_documents(docs_to_add.clone(), Some("mod_id"))
.unwrap();
//Created Index
let mut newest_index = client.get_or_create("newest_mods").unwrap();
let mut newest_rules = default_rules();
newest_rules.push_back("desc(created)".to_string());
newest_index
.set_settings(&default_settings().with_ranking_rules(newest_rules.into()))
.unwrap();
newest_index
.add_documents(docs_to_add.clone(), Some("mod_id"))
.unwrap();
Ok(())
}
//region Utils
fn default_rules() -> VecDeque<String> {
vec![
"typo".to_string(),
"words".to_string(),
"proximity".to_string(),
"attribute".to_string(),
"wordsPosition".to_string(),
"exactness".to_string(),
]
.into()
}
fn default_settings() -> Settings {
let displayed_attributes = vec![
"mod_id".to_string(),
"author".to_string(),
"title".to_string(),
"description".to_string(),
"keywords".to_string(),
"versions".to_string(),
"downloads".to_string(),
"page_url".to_string(),
"icon_url".to_string(),
"author_url".to_string(),
"date_created".to_string(),
"created".to_string(),
"date_modified".to_string(),
"updated".to_string(),
"latest_version".to_string(),
"empty".to_string(),
];
let searchable_attributes = vec![
"title".to_string(),
"description".to_string(),
"keywords".to_string(),
"versions".to_string(),
"author".to_string(),
"empty".to_string(),
];
Settings::new()
.with_displayed_attributes(displayed_attributes.clone())
.with_searchable_attributes(searchable_attributes.clone())
.with_accept_new_fields(true)
.with_stop_words(vec![])
.with_synonyms(HashMap::new())
}
//endregion

105
src/search/mod.rs Normal file
View File

@ -0,0 +1,105 @@
use crate::database::DatabaseError;
use crate::models::mods::SearchRequest;
use meilisearch_sdk::client::Client;
use meilisearch_sdk::document::Document;
use meilisearch_sdk::search::Query;
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub mod indexing;
#[derive(Error, Debug)]
pub enum SearchError {
#[error("Error while connection to the MeiliSearch database")]
IndexDBError(),
#[error("Error while connecting to the local server")]
LocalDatabaseError(#[from] mongodb::error::Error),
#[error("Error while accessing the data from remote")]
RemoteWebsiteError(#[from] reqwest::Error),
#[error("Error while serializing or deserializing JSON")]
SerDeError(#[from] serde_json::Error),
#[error("Error while parsing float")]
FloatParsingError(#[from] std::num::ParseFloatError),
#[error("Error while parsing float")]
IntParsingError(#[from] std::num::ParseIntError),
#[error("Error while parsing BSON")]
DatabaseError(#[from] DatabaseError),
#[error("Environment Error")]
EnvError(#[from] dotenv::Error),
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SearchMod {
pub mod_id: i32,
pub author: String,
pub title: String,
pub description: String,
pub keywords: Vec<String>,
pub versions: Vec<String>,
pub downloads: i32,
pub page_url: String,
pub icon_url: String,
pub author_url: String,
pub date_created: String,
pub created: i64,
pub date_modified: String,
pub updated: i64,
pub latest_version: String,
pub empty: String,
}
impl Document for SearchMod {
type UIDType = i32;
fn get_uid(&self) -> &Self::UIDType {
&self.mod_id
}
}
pub fn search_for_mod(info: &SearchRequest) -> Result<Vec<SearchMod>, SearchError> {
let address = &*dotenv::var("MEILISEARCH_ADDR")?;
let client = Client::new(address, "");
let search_query: &str;
let mut filters = String::new();
let mut offset = 0;
let mut index = "relevance";
match info.query.as_ref() {
Some(q) => search_query = q,
None => search_query = "{}{}{}",
}
if let Some(f) = info.filters.as_ref() {
filters = f.clone();
}
if let Some(v) = info.version.as_ref() {
if filters.is_empty() {
filters = v.clone();
} else {
filters = format!("({}) AND ({})", filters, v);
}
}
if let Some(o) = info.offset.as_ref() {
offset = o.parse().unwrap();
}
if let Some(s) = info.index.as_ref() {
index = s;
}
let mut query = Query::new(search_query).with_limit(10).with_offset(offset);
if !filters.is_empty() {
query = query.with_filters(&filters);
}
Ok(client
.get_index(format!("{}_mods", index).as_ref())
.unwrap()
.search::<SearchMod>(&query)
.unwrap()
.hits)
}

View File

@ -1,108 +0,0 @@
.creation-main {
margin: 10px auto;
width: 75%;
display: flex;
flex-direction: column;
}
progress::-webkit-progress-value { background: #0b75d8; }
progress::-moz-progress-bar { background: #0b75d8; }
.creation-progress-bar {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: none;
height: 20px;
background: white;
color: #0b75d8;
margin: 10px 0 0 0;
}
.creation-parts-header {
display: flex;
flex-direction: row;
color: #999;
}
.creation-parts-header a {
text-align: center;
width: 20%;
}
.creation-parts-header-active {
color: #0b75d8 !important;
font-weight: bold;
}
.creation-parts {
margin-top: 30px;
}
.creation-part {
padding: 5px;
}
.base-info label {
margin-top: 10px;
display: flex;
flex-direction: column;
}
.info-display {
display: flex;
flex-direction: row;
}
.info-display-inputs {
margin: 10px 20px;
width: 100%;
display: flex;
flex-direction: column;
}
.info-body {
margin-top: 20px;
}
.info-body textarea {
width: 100%;
height: 500px;
resize: vertical;
}
.button-container {
display: flex;
flex-direction: row;
justify-content: flex-end;
margin-top: 10px;
}
.next-button {
font-weight: bold;
color: white;
background-color: #69E781;
border-radius: 5px;
padding: 10px;
}
.draft-button {
margin-right: 10px;
font-weight: bold;
color: wheat;
background-color: #e1a15a;
border-radius: 5px;
padding: 10px;
}
.discard-button {
margin-right: 10px;
font-weight: bold;
color: white;
background-color: red;
border-radius: 5px;
padding: 10px;
}

View File

@ -1,182 +0,0 @@
@import url('https://fonts.googleapis.com/css?family=Montserrat:400,600&display=swap');
:root, [data-theme="light"] {
--background: #f3f2f0;
--highlight: #0b75d8;
--border: #a9a9a9;
--mod-bar: #fefefe;
--content-background: white;
--nav-background: #dfdfdf;
--content-text: black;
--header-text: black;
--white-text: white;
--muted: gray;
--forge-color: #1e2d44;
--tech-color: #d01111;
--adventure-color: #c8a800;
--magic-color: #7532b8;
--utility-color: #e3690f;
--decoration-color: #14a593;
--world-color: #32a31f;
--library-color: #1363b8;
--cursed-color: #933151;
--misc-color: #323232;
--storage-color: #a77741;
--food-color: #9f1823;
--equipment-color: #654700;
}
[data-theme="dark"] {
--background: #1b1b1b;
--highlight: #0b75d8;
--border: #1d1d1d;
--mod-bar: #222222;
--content-background: rgb(34, 34, 34);
--nav-background: #252525;
--content-text: rgb(241, 241, 241);
--header-text: rgb(241, 241, 241);
--white-text: white;
--muted: gray;
--forge-color: white;
--tech-color: #bf3f3f;
--adventure-color: #764827;
--magic-color: #663299;
--utility-color: #bf623f;
--decoration-color: #458ec1;
--world-color: #e6e62c;
--library-color: #cc9a3c;
--cursed-color: #d17695;
--misc-color: #3f9fbf;
--storage-color: #cea06c;
--food-color: #5975c8;
--equipment-color: #000000;
}
@media (prefers-color-scheme: dark) {
[data-theme="light"] {
}
:root, [data-theme="dark"] {
}
}
* {
transition: color 0.4s, background-color 0.4s, border-color 0.4s, fill 0.4s !important;
}
body {
margin: 0;
font-family: 'Montserrat', sans-serif;
background-color: var(--background);
color: var(--content-text);
}
h1, h2, h3, h4, h5, h6 {
color: var(--header-text);
}
.main-flex {
display: flex;
flex-direction: row;
}
.muted {
color: var(--muted);
}
.temp-circle-logo {
height: 50px;
width: 50px;
background-color: var(--content-background);
border-radius: 50%;
display: inline-block;
margin-left: 20%;
}
.site-header {
z-index: 2;
position: sticky;
background-color: var(--highlight);
top: 0;
width: 100%;
height: 75px;
display: flex;
align-items: center;
}
.site-header h2 {
color: var(--white-text);
font-weight: bolder;
padding: 0 20px 0 10px;
}
.links-container {
margin: 0 auto;
}
.links-container a {
color: var(--white-text);
padding: 0 30px;
text-decoration: none;
}
.rounded-border {
border-radius: 10px;
border: 1px;
}
.gray-border {
border: 1px solid var(--border);
}
.green {
color: #69E781;
}
.info-popup {
z-index: 10;
position: absolute;
width: 500px;
background-color: var(--content-background);
color: var(--content-text);
border-radius: 5px;
border: 1px solid var(--content-text);
padding: 20px;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
.discord-button {
text-decoration: none;
border-radius: 5px;
padding: 5px;
font-weight: bold;
color: white;
background-color: var(--library-color);
margin-left: 50px;
margin-right: 5px;
}
.github-button {
text-decoration: none;
border-radius: 5px;
padding: 5px;
font-weight: bold;
color: white;
background-color: var(--magic-color);
margin-right: 5px;
}
.exit-button {
border-radius: 5px;
padding: 5px;
font-weight: bold;
color: white;
background-color: red;
}

View File

@ -1,323 +0,0 @@
.main-content {
margin: 30px 20px 0 auto;
width: 45%;
display: flex;
flex-direction: column;
}
.mod-navigation {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 20px;
}
.mod-navigation p {
transform:scale(1,2);
}
.navigation-pointer {
color: gray;
background-color: var(--nav-background);
padding: 10px;
border-radius: 5px;
text-decoration: none;
margin-right: 10px;
font-weight: bold;
}
.navigation-text {
color: var(--highlight);
background-color: #c9def2;
padding: 10px;
border-radius: 5px;
text-decoration: none;
margin: 0 10px;
font-weight: bold;
}
.navigation-follow {
display: flex;
flex-direction: row;
align-items: center;
color: var(--white-text);
background-color: var(--highlight);
text-decoration: none;
font-weight: bold;
padding: 10px;
margin-left: auto;
border-radius: 5px;
}
.navigation-follow img {
height: 15px;
margin-right: 10px;
}
.mod-header {
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
height: 100px;
background-color: var(--content-background);
margin: 0 0 20px 0;
}
.mod-icon {
width: 70px;
height: 70px;
margin: 15px 10px 15px 25px;
}
.mod-title {
display: flex;
flex-direction: column;
margin: 15px 0;
}
.mod-title-text {
margin: 0;
padding: 0;
}
.mod-title h2 {
font-size: 24px;
}
.mod-title p {
font-size: 18px;
}
.mod-bar {
display: flex;
flex-direction: row;
}
.mod-bar-href {
margin: 5px 10px 0 0;
padding: 5px 10px;
color: gray;
background-color: var(--mod-bar);
border-radius: 5px 5px 0 0;
border: 1px solid var(--border);
border-bottom: none !important;
text-decoration: none;
cursor: pointer;
}
.mod-bar-active {
color: var(--highlight) !important;
font-weight: bold;
background-color: var(--content-background) !important;
}
.mod-hide {
display: none !important;
}
.mod-show {
display: block;
}
.sidebar {
display: flex;
flex-direction: column;
align-items: center;
margin: 30px auto 0 0;
width: 15%;
}
.search-bar {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--content-text);
background-color: var(--content-background);
border-color: var(--border);
width: 100%;
margin-top: 5px;
margin-bottom: 25px;
padding: 10px 0;
}
.mod-sidebar {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: auto !important;
background-color: var(--content-background);
}
.sidebar-entry {
margin: 30px auto;
text-align: center;
display: flex;
flex-direction: column;
}
.sidebar-info {
display: flex;
flex-direction: row;
align-items: center;
margin: 0 auto;
}
.mod-info-entry {
display: flex;
flex-direction: row;
margin: 5px;
align-items: center;
}
.mod-info-entry img {
margin: 0 5px;
height: 15px;
}
.mod-info-entry p {
margin: 0 auto;
}
.sidebar-img {
width: 20px !important;
height: 20px !important;
padding: 5px;
}
.donation-info img {
height: 50px;
object-fit: cover;
width: 200px;
}
.categories {
display: flex;
flex-direction: row;
}
.categories img {
width: 40px;
margin: 0 10px;
}
.contributor-card {
display: flex;
flex-direction: row;
height: 50px;
width: 200px;
margin: 5px 0;
}
.contributor-card img {
width: 50px;
height: 50px;
margin-right: 10px;
}
.contributor-card-text {
display: flex;
flex-direction: column;
margin: auto;
}
.contributor-card-text a {
text-decoration: none;
}
.sidebar-line {
height: 1px;
width: 80%;
background-color: var(--border);
margin: 0 auto;
}
.download {
color: var(--white-text);
padding: 10px 5px;
margin-bottom: 5px;
width: 200px;
font-size: 14px;
font-weight: bold;
border-radius: 5px;
}
.download-primary {
background-color: var(--highlight);
}
.download-normal {
background-color: #949494;
}
.mod-main {
padding: 5px;
margin-top: 0px;
width: 100%;
background-color: var(--content-background);
border-radius: 0 5px 5px 5px;
border: 1px solid var(--border);
font-size: 16px;
line-height: 20px;
}
.mod-description {
margin: 0 auto;
padding: 5px;
}
.mod-description img {
max-width: 1000px;
}
.files-search {
margin-top: 0px;
margin-bottom: 25px;
display: flex;
flex-direction: row;
}
.files-search-bar {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
height: 30px;
width: 90%;
padding: 10px 0;
}
.files-versions {
height: 33px;
width: 10%;
margin-left: auto;
}
.api {
margin-top: 0;
width: 100%;
background-color: var(--content-background);
border-radius: 0 5px 5px 5px;
border: 1px solid var(--border);
font-size: 16px;
line-height: 20px;
}
.api-container {
padding: 10px;
}
.api-code-block {
margin-top: 4px !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
border-radius: 0 5px 5px 5px;
}
.extra-top {
margin-top: 5px !important;
}

View File

@ -1,349 +0,0 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 2px; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

View File

@ -1,386 +0,0 @@
.clear-button {
margin: 30px auto 0 40px;
height: 33px;
width: 175px;
color: var(--content-text);
background-color: var(--content-background);
border-radius: 5px;
border: 1px solid var(--border);
}
.versions {
display: flex;
flex-direction: column;
width: 25%;
}
.version-type {
margin-top: 20px;
margin-left: 40px;
margin-right: auto;
}
.version-scroll {
height: 400px;
overflow-y: scroll;
}
.version-type-label {
width: 165px;
height: 25px;
margin-bottom: 0;
padding: 2px 5px;
cursor: pointer;
font-weight: bold;
color: white;
background-color: black;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.version {
height: 25px;
padding: 2px 5px;
cursor: pointer;
width: 152px;
margin: 0;
font-weight: bold;
color: var(--content-text);
background-color: var(--content-background);
border-bottom: 1px solid var(--border);
border-top: 1px solid var(--border);
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.left-flex {
display: flex;
flex-direction: column;
width: 25%;
}
.filters {
margin-top: 30px;
margin-right: 25px;
margin-left: auto;
}
.filters select {
height: 33px;
width: 175px;
text-align: center;
border-radius: 5px;
padding: 0 10px;
color: var(--content-text);
background-color: var(--content-background);
background-image: none;
border: 1px solid var(--border);
}
.categories {
margin-top: 30px;
padding: 5px;
margin-right: 20px;
margin-left: auto;
}
.categories-label {
color: white;
background-color: black;
padding-left: 10px;
}
.category-badge {
display: flex;
flex-direction: row;
align-items: center;
height: 25px;
padding: 2px 5px;
cursor: pointer;
width: 165px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.category-badge img, .category-badge svg {
height: 23px;
width: 23px;
}
.category-badge p {
margin: 0 auto;
font-weight: bolder;
text-transform: capitalize;
}
.category-ghost {
margin-left: 10px;
}
.search-main {
display: flex;
flex-direction: column;
width: 50%;
}
.search-bar {
position: -webkit-sticky !important;
position: sticky !important;
color: var(--content-text);
background-color: var(--content-background);
border-color: var(--border);
height: 2em;
margin: 30px auto 15px auto;
top: 80px;
width: calc(100% - 20px);
display: block;
}
.mod-info {
padding-top: 5px !important;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
}
.mod-info img, .mod-info svg {
height: 12px;
width: 12px;
padding: 0;
}
.mod-info span {
font-size: 12px;
padding-right: 15px;
white-space: nowrap;
}
.mod-info > span > img, .mod-info > span > svg {
padding-right: 5px;
vertical-align: top;
}
.loader-icons > * {
vertical-align: top;
white-space: nowrap;
display: inline-block;
}
.loader-icons img, .loader-icons svg {
padding-right: 5px;
}
.results {
width: 100%;
margin: 0 auto;
}
.search-error {
text-align: center;
word-break: break-word;
}
.result {
display: flex;
min-height: 100px;
margin: 15px 5px;
padding: 5px;
width: calc(100% - 20px);
flex-direction: row;
align-items: center;
background-color: var(--content-background);
}
.result-image {
object-fit: scale-down;
padding: 0 10px 0 5px;
min-width: 75px;
}
.badge-image {
object-fit: scale-down;
padding: 0 10px 0 5px;
}
.result-info {
display: flex;
flex-direction: column;
}
.result-info > * {
padding: 0 5px 0 0;
margin: 0;
}
.result-title {
text-decoration: none;
}
.result-title * {
display: inline;
padding-right: 5px;
}
.result-name > * {
margin: 0;
}
.result-author-container {
white-space: nowrap;
display: inline-block;
}
@media screen and (max-width: 1340px) {
.result-badge.result-badge {
width: initial;
}
.result-badge > p {
display: none;
}
}
.result-name {
text-decoration: none;
color: var(--highlight);
}
.result-author {
text-decoration: none;
color: #2f92d8;
}
.result-badges {
margin: 0 1em 20px auto;
align-self: center;
height: 75px;
display: flex;
flex-direction: column;
}
.result-badge {
display: flex;
flex-direction: row;
align-items: center;
height: 25px;
margin: 2px 0;
padding: 2px 5px;
width: 155px;
}
.result-badge img, .result-badge svg {
height: 23px;
width: 23px;
}
.result-badge p {
margin: 0 auto;
font-weight: bolder;
text-transform: capitalize;
}
.download-badge {
background-color: limegreen;
color: white;
}
.forge-badge {
color: #e1a15a;
background-color: #1e2d44;
}
.fabric-badge {
color: #585849;
background-color: #fffdd0;
}
.tech-badge {
color: white;
background-color: var(--tech-color);
}
.adventure-badge {
color: white;
background-color: var(--adventure-color);
}
.magic-badge {
color: white;
background-color: var(--magic-color);
}
.utility-badge {
color: white;
background-color: var(--utility-color);
}
.decoration-badge {
color: white;
background-color: var(--decoration-color);
}
.world-badge {
color: white;
background-color: var(--world-color);
}
.library-badge {
color: white;
background-color: var(--library-color);
}
.cursed-badge {
color: white;
background-color: var(--cursed-color);
}
.misc-badge {
color: white;
background-color: var(--misc-color);
}
.storage-badge {
color: white;
background-color: var(--storage-color);
}
.food-badge {
color: white;
background-color: var(--food-color);
}
.equipment-badge {
color: white;
background-color: var(--equipment-color);
}
svg.forge {
height: 12px;
width: auto;
fill: var(--forge-color);
}
.back-to-top {
position: fixed;
top: 80%;
/* left column = 25%, width ~= 90px, left column padding = 20px */
left: calc(25% - 90px - 20px);
background-color: var(--highlight);
text-align: center;
padding: 20px;
display: none;
}
.back-to-top img {
width: 50px;
height: 50px;
}

View File

@ -1,84 +0,0 @@
/*
Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #002b36;
color: #839496;
}
.hljs-comment,
.hljs-quote {
color: #586e75;
}
/* Solarized Green */
.hljs-keyword,
.hljs-selector-tag,
.hljs-addition {
color: #859900;
}
/* Solarized Cyan */
.hljs-number,
.hljs-string,
.hljs-meta .hljs-meta-string,
.hljs-literal,
.hljs-doctag,
.hljs-regexp {
color: #2aa198;
}
/* Solarized Blue */
.hljs-title,
.hljs-section,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #268bd2;
}
/* Solarized Yellow */
.hljs-attribute,
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-class .hljs-title,
.hljs-type {
color: #b58900;
}
/* Solarized Orange */
.hljs-symbol,
.hljs-bullet,
.hljs-subst,
.hljs-meta,
.hljs-meta .hljs-keyword,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-link {
color: #cb4b16;
}
/* Solarized Red */
.hljs-built_in,
.hljs-deletion {
color: #dc322f;
}
.hljs-formula {
background: #073642;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path fill="#e8d7b5" d="M15 18V6H9a6 6 0 100 12z"/><path fill="#ffecc7" d="M55 9c-5.3 0-10.6.8-15.6 2.4l-12.8 4A59.3 59.3 0 019 18a6 6 0 01-6-6v38a6 6 0 006 6c6 0 11.9-.9 17.6-2.7l12.8-4c3.4-1 7-1.7 10.6-2V21h5a6 6 0 100-12z"/><path fill="#88b337" d="M21 37c0-2-6-1.8-9.8-1.4-2 .2-3.6 1.5-4.4 3.3l-.2.5a5.2 5.2 0 002.6 6.7A103 103 0 0018 50c3 1 8-3 8-6s-5-4-5-7z"/><ellipse cx="36" cy="42" fill="#8c421c" rx="4" ry="2"/><path fill="#4398d1" d="M31.5 30c1.1 0 2-.4 2.7-1.1 1 .7 2.4 1.1 3.8 1.1 3.3 0 6-2.2 6-5s-2.7-5-6-5c-3 0-5.4 1.7-5.9 4a4 4 0 00-.6 0c-2 0-3.5 1.3-3.5 3s1.6 3 3.5 3z"/><g fill="#8c421c"><path d="M13.8 28.8l1.9.2.3-2a18 18 0 00-2-.2zM21 31l1.5 1 1.2-1.6-1.8-1.2zM9.7 27l.3 2a16 16 0 012-.2l-.2-2-2.1.2zM5.7 28l2-.5.5 2-2 .5zM24 33.2l1.8 1.2 1-1.7-1.5-1zM17.5 29.4l1.8.7.8-1.8-2-.8zM39.7 34.2l2-.4.4 2-2 .3zM43.7 33.4l2-.4.3 2-2 .4zM31.8 36.5l2 .3.2-2a16 16 0 01-1.9-.2zM27.7 35.4l2 .7.6-2-1.8-.6zM35.9 34.8l.1 2 2.1-.3-.4-2-1.8.3z"/></g><path fill="#fdb62f" d="M46 17.4L44.6 16l-2.3 2.3L40 16l-1.4 1.4 2.3 2.3-2.3 2.3 1.4 1.4 2.3-2.3 2.3 2.3L46 22l-2.3-2.3z"/><path fill="#e8d7b5" d="M55 21h-5v38c6 0 11-5 11-11V15a6 6 0 01-6 6z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><g data-name="File system"><path fill="#004fac" d="M61 32H3l7.6-27.5a2 2 0 012-1.5h38.9a2 2 0 012 1.5z"/><path fill="#2488ff" d="M61 32v25a4 4 0 01-4 4H7a4 4 0 01-4-4V32z"/><path fill="#006df0" d="M56 32v22a4 4 0 01-4 4H3.1A4 4 0 007 61h50a4 4 0 004-4V32z"/><path fill="#5eac24" d="M8.3 28h47.4l-1.9-7H10.2z"/><path fill="#d80027" d="M50 7H14l-1.9 7H52z"/><path fill="#ffcd00" d="M12.1 14l-2 7h43.7l-2-7z"/><path fill="#003f8a" d="M24.5 42.6a2 2 0 002 1.4h11a2 2 0 002-1.4l1-3.3a1 1 0 00-.9-1.3H24.4a1 1 0 00-1 1.3z"/></g></svg>

Before

Width:  |  Height:  |  Size: 588 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path fill="#4d2817" d="M20 14a7 7 0 017-7h9c0-2.2-2.6-4-7-4h-8a6 6 0 00-6 6v11l5-3z"/><path fill="#606060" d="M14 29.2V20h-2a4 4 0 00-4 4v4a4 4 0 004 4h2.7a6 6 0 01-.7-2.8zM41 28v-4a4 4 0 00-4-4h-1v8z"/><path fill="#4d2817" d="M31 10V7h-4a7 7 0 00-7 7v3h4a7 7 0 007-7z"/><path fill="#66351e" d="M31 10a7 7 0 01-7 7h6a7 7 0 007-7V7h-6z"/><path fill="#4d2817" d="M30 17h6a7 7 0 007-7V7h-6v3a7 7 0 01-7 7z"/><path fill="#66351e" d="M19 3h-2a6 6 0 00-6 6v11h4V9a6 6 0 016-6z"/><path fill="#878787" d="M11 29v-4a4 4 0 013-3.9V20h-2a4 4 0 00-4 4v4a4 4 0 004 4h.4a4 4 0 01-1.4-3zM37 20h-1v2a4 4 0 014 4v2h1v-4a4 4 0 00-4-4z"/><path fill="#d0382a" d="M41 43.4c2.8 1 5 2.4 5 3.6v14H4V47c0-3.3 16-7 16-7h10z"/><path fill="#b33024" d="M41 46.4L30 43H20S5.9 46.3 4.2 49.4L4 47c0-3.3 16-7 16-7h10l11 3.4c2.8 1 5 2.4 5 3.6l-.2 2.4c-.5-1-2.5-2.1-4.8-3z"/><path fill="#fce0b9" d="M19 17h17v12.2a6 6 0 01-2.2 4.6l-4.7 2.6a5 5 0 01-2.4.6h-3.4a5 5 0 01-2.4-.6l-4.7-2.6a6 6 0 01-2.2-4.6V21z"/><path fill="#fce0b9" d="M20.9 36.4a5 5 0 002.4.6h3.4a5 5 0 002.4-.6l.9-.5V42a7 7 0 01-10 0v-6.1z"/><path fill="#f5cba1" d="M20 35.9l.9.5a5 5 0 002.4.6h3.4a5 5 0 002.4-.6l.9-.5V42l-.5.4-9.5-6.1z"/><path fill="#f5cba1" d="M27 25a1 1 0 00-1 1v11h.7a5 5 0 002.4-.6l4.7-2.6a6 6 0 002.2-4.6V25z"/><g fill="#383838"><path d="M29 28v22h14V33a2 2 0 114 0v17h14V28z"/><path d="M45 31a2 2 0 00-2 2v24h4V33a2 2 0 00-2-2zM36 57v4h18v-4H43z"/></g><path fill="#3d2012" d="M24 15h-4v2h4a7 7 0 007-7V8a7 7 0 01-7 7z"/><path fill="#4d2817" d="M30 15h-1.1a7 7 0 01-4.9 2h6a7 7 0 007-7V8a7 7 0 01-7 7z"/><path fill="#3d2012" d="M39 14.3a7 7 0 01-3 .7h-1.1a7 7 0 01-4.9 2h6a7 7 0 007-7V8a7 7 0 01-4 6.3z"/><path fill="#fce0b9" d="M10 57l10-2h6a3 3 0 013 3v3H10z"/><path fill="#262626" d="M41 30.5V50h2V33a2 2 0 114 0v17h2V30.5c0-1.4-1.8-2.5-4-2.5s-4 1.1-4 2.5zM36 59h18v2H36z"/><path d="M20 25.8a1.8 1.8 0 110-3.6 1.8 1.8 0 010 3.6zm0-2c-.1 0-.3 0-.3.2 0 .3.6.3.6 0l-.3-.3zM30 25.8a1.8 1.8 0 110-3.6 1.8 1.8 0 010 3.6zm0-2c-.1 0-.3 0-.3.2 0 .3.6.3.6 0l-.3-.3z"/><path d="M61 27H42v-3a5 5 0 00-2-4v-3a8 8 0 004-7V7c0-.6-.4-1-1-1h-6.1c-.6-2.1-3.1-4-7.9-4H17a7 7 0 00-7 7v10.4A5 5 0 007 24v4a5 5 0 004 4.9v8.6C6.8 43 3 44.9 3 47v14c0 .6.4 1 1 1h50c.6 0 1-.4 1-1v-4c0-.6-.4-1-1-1h-6v-5h13c.6 0 1-.4 1-1V28c0-.6-.4-1-1-1zm-24 0v-6a3 3 0 013 3v3zM21 37.5a6 6 0 002.3.5h3.4l1.3-.1v4.4a6 6 0 01-7-.7zM29 27a1 1 0 00-1 1v7.8a4 4 0 01-1.3.2h-3.4a4 4 0 01-2-.5L16.7 33a5 5 0 01-1.7-3.8V21c.2 0 .4 0 .5-.2l4.8-2.8H35v9zm7-19v2a6 6 0 01-6 6h-.7a8 8 0 002.7-6V8zm-6 2a6 6 0 01-6 6h-3v-2a6 6 0 016-6h3zm8 9.1a5 5 0 00-1-.1v-1l1-.3zm4-9.1a6 6 0 01-6 6h-.7a8 8 0 002.7-6V8h4zM17 6a5 5 0 014-2h8c3 0 5 .9 5.7 2H27a8 8 0 00-8 8v2.4l-3 1.8V9a5 5 0 011-3zm-5 3a5 5 0 014-4.9A7 7 0 0014 9v10h-2zM9 28v-4a3 3 0 013-3h1v8.2c0 .6 0 1.2.2 1.8H12a3 3 0 01-3-3zm4 5h1.1a7 7 0 001.6 1.7l3.3 1.8v2.7l-6 1.6zM5 47c0-.8 2.4-2 6-3.3v12l-1.2.3.4 2 .8-.2V60H5zm23 13H13v-2.6l7.1-1.4H26a2 2 0 012 2zm7-3v3h-5v-2a4 4 0 00-4-4h-6-.2L13 55.4V43l6-1.7v.7c0 .3.1.5.3.7a8 8 0 008.7 1.8V50c0 .6.4 1 1 1h13v5h-6a1 1 0 00-1 1zm18 3H37v-2h16zm-9-4V33a1 1 0 012 0v23zm16-7H48V33a3 3 0 00-6 0v16H30V29h30z"/></svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><circle cx="256" cy="256" r="256" fill="#fe8205"/><path fill="#fa5d0f" d="M512 256C512 115 397 0 256 0v512c141 0 256-115 256-256z"/><path fill="#f0f7ff" d="M256 61a195 195 0 100 390 195 195 0 000-390z"/><path fill="#dfe7f4" d="M451 256c0-108-87-195-195-195v391c108 0 195-88 195-196z"/><path fill="#575f64" d="M256 121c-8 0-15 7-15 15v150a15 15 0 1030 0V136c0-8-7-15-15-15z"/><path fill="#474f54" d="M271 286V136c0-8-7-15-15-15v180c8 0 15-7 15-15z"/><path fill="#575f64" d="M346 241H226a15 15 0 100 30h120a15 15 0 100-30z"/><path fill="#474f54" d="M361 256c0-8-7-15-15-15h-90v30h90c8 0 15-7 15-15z"/></svg>

Before

Width:  |  Height:  |  Size: 667 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#fae19e" d="M47 452l296 20c5 0 10-4 11-9l28-425c0-5-4-10-9-10L77 8c-5-1-10 4-10 9L38 442c0 5 4 10 9 10z"/><path fill="#fff9e9" d="M18 504h226l80-79V69c0-6-5-10-10-10H17c-5 0-10 4-10 10v425c0 6 5 10 10 10z"/><path fill="#fff4d6" d="M314 59h-40c5 0 10 4 10 10v356l-1 40 41-40V69c0-6-5-10-10-10z"/><path fill="#ffeec2" d="M244 504v-70c0-6 4-10 10-10h70z"/><g><path fill="#fed23a" d="M469 249h-34v-51c0-9 8-17 17-17s17 8 17 17v51z"/><path fill="#54b1ff" d="M452 504a55 55 0 01-16-39v-74l1-1h30l1 1v74c0 15-6 29-16 39z"/><path fill="#fdf385" d="M452 469c-14 0-26-11-26-26V230c0-7 5-12 12-12l28-1c7 0 12 6 12 13v213c0 15-12 26-26 26z"/><path fill="#faee6e" d="M466 217l-24 1c6 0 11 5 11 12v213c0 10-6 19-14 23 4 2 8 3 13 3 14 0 26-11 26-26V230c0-7-5-13-12-13z"/><path fill="#54b1ff" d="M491 248h-71c-8 0-14 6-14 14 0 7 6 13 14 13l58-1v78c0 7 6 13 13 13 8 0 14-6 14-13v-91c0-7-6-13-14-13z"/><path fill="#3da7ff" d="M491 248h-38v26h25v78c0 7 6 13 13 13 8 0 13-6 13-13v-91c1-7-5-13-13-13z"/></g><g fill="#060606"><path d="M373 20L78 0C68 0 60 7 59 17l-2 34H17C8 51 0 59 0 69v425c0 10 8 18 17 18h227c2 0 4-1 5-3l34-33h1l58 4c10 0 18-7 19-17l28-424c1-10-6-18-16-19zM251 486v-52c0-1 1-3 3-3h52zm95-24c0 2-1 3-3 3l-46-4 32-31 2-5V69c0-10-8-18-17-18h-78c-10 0-10 15 0 15h78c1 0 2 1 2 3v347h-62c-10 0-18 8-18 18v63H18c-2 0-3-1-3-3V69c0-2 1-3 3-3h178c9 0 9-15 0-15H72l2-33c0-2 1-3 3-3l295 20c2 0 2 1 2 3z"/><path d="M268 237H63a8 8 0 000 15h205a7 7 0 100-15zM268 289H63a8 8 0 000 15h205a7 7 0 100-15zM56 192c0 4 3 8 7 8h205a7 7 0 100-15H63c-4 0-7 3-7 7zM92 140c0 4 3 7 7 7h133a8 8 0 000-15H99c-4 0-7 4-7 8zM195 439a36391 36391 0 01-54 0c-9 0-14-2-16-11-1-7-12-6-14 0-6 17-14 10-19-1s-6-23-8-35c-2-8-15-6-15 2 0 11-1 22-4 32l-11 31c-4 9 11 13 14 4l11-27c5 12 15 26 31 18l7-6c8 9 20 8 31 8h47c9 0 9-15 0-15zM506 246c-4-3-9-5-15-6h-5v-10c0-7-4-14-10-17v-15c0-31-48-31-48 0v15c-6 4-10 10-10 17v11c-25 2-25 40 0 41v101c0 9 15 10 15 0V282h38v161c0 24-38 24-38-1v-13c1-10-14-11-15-1v13c0 11 4 20 10 27 1 15 8 30 19 42 3 3 7 2 10-1 12-11 18-26 19-42 5-5 9-10 9-27l1-68c12 3 26-7 26-20v-91c0-5-2-11-6-15zm-73-5v-11c0-2 2-4 4-5h30a5 5 0 014 5v11zm19-52c5 0 9 4 9 9v12h-18v-12c0-5 4-9 9-9zm0 304c-4-5-6-11-7-17a33 33 0 0014 0c-1 6-3 12-7 17zm45-141c0 7-11 7-11 0v-78c0-4-4-7-8-7h-58c-8 0-7-11 0-11l71-1c4 1 6 3 6 6v91z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#80c56e" d="M409 46c2 6 27 79-24 166-32 53-79 56-84 57-2-4-29-44-8-101C329 74 403 48 409 46z"/><path fill="#66ad66" d="M409 46L301 269c5-1 52-4 84-57 51-87 26-160 24-166z"/><path fill="#fff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="15" d="M298 275l3-6v-1l-3 7z"/><path fill="#80c56e" d="M103 46c-2 6-27 79 24 166 32 53 79 56 84 57 2-4 29-44 8-101A203 203 0 00103 46z"/><path fill="#66ad66" d="M219 168A203 203 0 00103 46c64 121 98 199 108 222 4-5 29-44 8-100z"/><path fill="#80c56e" d="M256 0c-8 7-96 97-82 261 8 99 75 138 82 141 7-3 74-42 82-141C352 97 264 7 256 0z"/><path fill="#66ad66" d="M256 0v402c7-3 74-42 82-141C352 97 264 7 256 0z"/><path fill="#80c56e" d="M446 250c17-57 11-111 11-111s-32 15-113 67c-63 40-82 112-88 131h74c53 0 101-35 116-87z"/><path fill="#66ad66" d="M457 139s-83 164-201 198h74c53 0 101-35 116-87 17-57 11-111 11-111z"/><path fill="#80c56e" d="M66 250c-17-57-11-111-11-111s32 15 113 67c63 40 82 112 88 131h-74c-53 0-101-35-116-87z"/><path fill="#66ad66" d="M256 337c-6-19-25-91-88-131-81-52-113-67-113-67s83 164 201 198z"/><path fill="#fec37d" d="M309 512H203c-29 0-53-20-58-48l-23-123h268l-23 123c-5 28-29 48-58 48z"/><path fill="#f9ae5d" d="M338 341l-23 123c-5 28-29 48-57 48h51c29 0 53-20 58-48l23-123h-52z"/><path fill="#f2a559" d="M395 369H117c-11 0-20-10-20-21s9-20 20-20h278c11 0 20 9 20 20s-9 21-20 21z"/><path fill="#ea8f3d" d="M395 328h-33v41h33c11 0 20-10 20-21s-9-20-20-20z"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -20 464 464"><path fill="#ff6243" d="M340 0c-45 0-86 24-108 63-22-39-63-63-108-63C56 0 0 64 0 132c0 172 232 292 232 292s232-120 232-292C464 64 408 0 340 0zm0 0"/><path fill="#ff5023" d="M32 132C32 69 80 10 141 1l-17-1C56 0 0 64 0 132c0 172 232 292 232 292l16-9C196 384 32 276 32 132zm0 0"/></svg>

Before

Width:  |  Height:  |  Size: 347 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#E3E9ED" d="M400 216a24 24 0 01-17-7L256 82 129 209a24 24 0 01-34-34L239 31a24 24 0 0134 0l144 144a24 24 0 01-17 41zM273 481l144-144a24 24 0 00-34-34L256 430 129 303a24 24 0 00-34 34l144 144a24 24 0 0034 0z" class="active-path" data-old_color="#000000" data-original="#000000"/></svg>

Before

Width:  |  Height:  |  Size: 358 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs/><path fill="#69E781" d="M256 363c-9 0-16-7-16-16V16a16 16 0 0132 0v331c0 9-7 16-16 16zm0 0" class="active-path" data-old_color="#000000" data-original="#000000"/><path fill="#69E781" d="M256 363c-4 0-8-2-11-5l-86-85a16 16 0 0123-23l74 74 74-74a16 16 0 0123 23l-86 85c-3 3-7 5-11 5zm0 0" class="active-path" data-old_color="#000000" data-original="#000000"/><path fill="#69E781" d="M453 512H59c-33 0-59-26-59-59v-96a16 16 0 0132 0v96c0 15 12 27 27 27h394c15 0 27-12 27-27v-96a16 16 0 0132 0v96c0 33-26 59-59 59zm0 0" class="active-path" data-old_color="#000000" data-original="#000000"/></svg>

Before

Width:  |  Height:  |  Size: 661 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#fea832" d="M482 316v105H30V316c0-73 36-139 91-180l15 45 15-64a226 226 0 01210 0l15 64 15-45c55 41 91 107 91 180z"/><path fill="#fe9923" d="M482 316v105H256V91c38 0 74 10 105 26l15 64 15-45c55 41 91 107 91 180z"/><path fill="#fedb41" d="M331 106v150c0 8-7 15-15 15H196c-8 0-15-7-15-15V106c0-25 20-45 45-45h60c25 0 45 20 45 45z"/><path fill="#fcbf29" d="M376 241c8 0 15-7 15-15v-90c-9-7-19-13-30-19v109c0 8 7 15 15 15z"/><g fill="#fedb41"><path d="M136 241c8 0 15-7 15-15V117c-11 6-21 12-30 19v90c0 8 7 15 15 15zM512 421c0 17-13 30-30 30H30c-16 0-30-13-30-30s14-30 30-30h452c17 0 30 14 30 30z"/></g><g fill="#fcbf29"><path d="M316 271h-60V61h30c25 0 45 20 45 45v150c0 8-7 15-15 15zM512 421c0 17-13 30-30 30H256v-60h226c17 0 30 14 30 30z"/></g></svg>

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -20 464 464"><path fill="#fff" d="M340 0c-45 0-86 24-108 63-22-39-63-63-108-63C56 0 0 64 0 132c0 172 232 292 232 292s232-120 232-292C464 64 408 0 340 0zm0 0" data-old_color="#ff6243" data-original="#FF6243"/><path fill="#fff" d="M32 132C32 69 80 10 141 1l-17-1C56 0 0 64 0 132c0 172 232 292 232 292l16-9C196 384 32 276 32 132zm0 0" class="active-path" data-old_color="#ff5023" data-original="#FF5023"/></svg>

Before

Width:  |  Height:  |  Size: 459 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 480"><path fill="#ffdfba" d="M394 425v39c0 4-4 8-8 8H94c-4 0-8-4-8-8v-39c0-41 33-75 74-75 23 0 42-18 42-41v-7a99 99 0 01-61-92v-3c-14 0-25-11-25-25V94c0-29 14-56 38-72l12-8c5-3 11-1 12 4l4 14c2 4 7 6 11 5l59-26c4-1 9 1 11 5l5 13c1 4 5 6 9 5l49-13c5-2 10 2 10 7v12c0 3 2 6 5 7l36 15c5 1 7 7 4 11-10 19-16 41-16 64v44c0 14-12 26-26 26v3c0 41-25 77-61 92v7c0 23 19 41 42 41 41 0 74 34 74 75z"/><path fill="#ffaa64" d="M394 425v39c0 4-4 8-8 8H94c-4 0-8-4-8-8v-39c0-41 33-75 74-75 6 0 12-1 17-3a69 69 0 00126 0c5 2 11 3 17 3 41 0 74 34 74 75z"/><path fill="#ffe773" d="M336 40c0 3 2 6 5 7l36 15c5 1 7 7 4 11-10 19-16 41-16 64v44c0 14-12 26-26 26v-62c0-26-21-48-48-48H189c-27 0-48 22-48 48v62c-14 0-25-11-25-25V94c0-29 14-56 38-72l12-8c5-3 11-1 12 4l4 14c2 4 7 6 11 5l59-26c4-1 9 1 11 5l5 13c1 4 5 6 9 5l49-13c5-2 10 2 10 7v12z"/><path fill="#ffebd2" d="M339 210a99 99 0 01-198 0v-65c0-26 21-48 48-48h102c27 0 48 22 48 48z"/><path fill="#ffd6a6" d="M279 318a99 99 0 01-78 0l1-16c24 10 52 10 76 0l1 16z"/><path fill="#fff3e4" d="M218 274c16 10 3 35-15 28a99 99 0 01-62-92v-65c0-10 3-19 8-27 7-10 22-5 22 7v65c0 37 19 67 47 84z"/><path fill="#ffbd7b" d="M181 355c6 9 1 21-10 23-24 7-56 24-56 72v22H94c-4 0-8-4-8-8v-39c0-41 33-75 74-75 6 0 12-1 17-3l4 8z"/><path fill="#faa157" d="M299 355c-6 9-1 21 10 23 24 7 56 24 56 72v22h21c4 0 8-4 8-8v-39c0-41-33-75-74-75-6 0-12-1-17-3l-4 8z"/><path fill="#ffec8f" d="M193 37c0-1 1 0 0 0l-9 6a87 87 0 00-38 72v9c-3 6-5 14-5 21v62c-14 0-25-11-25-25V94c0-29 14-56 38-72l12-8c5-3 11-1 12 4l4 14c2 4 7 6 11 5z"/><path d="M402 425v47a8 8 0 01-16 0v-47c0-37-30-67-67-67-17 0-33-9-42-24a8 8 0 1114-8c6 10 17 16 28 16 46 0 83 37 83 83zm-112-59c3 4 3 9-1 12a77 77 0 01-116-21l-12 1c-37 0-67 30-67 67v47a8 8 0 01-16 0v-47c0-46 37-83 83-83 18 0 33-15 33-33v-2c-35-17-59-52-61-93-14-3-25-16-25-32V94c0-31 16-61 42-79l21-14c4-3 10-1 12 5l7 23 67-28c4-2 9 0 11 4l7 21 59-16c5-1 10 3 10 8v22l45 18c5 1 6 7 4 11-13 21-20 44-20 68v45a8 8 0 01-16 0v-45c0-24 6-47 17-68l-41-17c-3-1-5-4-5-7V28l-56 16c-4 1-8-1-10-5l-7-20-67 28c-4 2-9 0-11-5l-6-21-12 8a79 79 0 00-35 65v88c0 7 4 12 9 15v-52c0-31 25-56 56-56h102c31 0 56 25 56 56v66c-1 71-69 122-137 102-1 16-10 29-22 37 19 32 62 40 91 16 3-3 9-3 11 0zm-50-65c50 0 91-41 91-91v-65c0-22-18-40-40-40H189c-22 0-40 18-40 40v65c0 50 41 91 91 91z"/></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 504 504"><path fill="#7fb241" d="M253 120c-72 7-126-47-119-119 72-7 126 47 119 119z"/><path fill="#8e6d53" d="M256 171c-6-1-11-7-12-14A117 117 0 01348 28a16 16 0 014 32 85 85 0 00-76 94 16 16 0 01-20 17z"/><path fill="#e14b4b" d="M374 120c-17-4-35-3-53 2-45 15-93 15-138 0-18-5-36-6-53-2-69 19-103 119-75 224s107 175 176 157a78 78 0 0142 0c69 18 148-52 176-157s-6-205-75-224z"/><path fill="#d03f3f" d="M449 344c-28 105-107 175-176 157h-1c-13-4-27-4-41 0-26 7-53 1-79-14a426 426 0 00259-346c43 38 60 119 38 203z"/></svg>

Before

Width:  |  Height:  |  Size: 572 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none" viewBox="0 0 90 46"><defs><path id="a" fill="#fff" d="M85.8 49.1l-4.5-5.5q-1.65-.1-3.55-.55-3.8-.95-4.85-2.65Q68.75 34.25 74 27q5.45-7.65 17.55-10.3l-37.8-1.9H100v-3.7H47.75v14q0 .65-1.9-11.7h-4.1v13l-1.9-12.3h-27.9q12.85 10.8 19.9 14.3 2.45 1.2 6.05 1.65 2.1.25 6.35.35 2.1.1 3.1.35 1.65.4 2.7 1.45 1.75 1.7 2 4 .3 2.4-1.2 4.3-1.2 1.65-4.35 2.6l-2.95.6L39 49.1v6.4h10.25l.3-6.3 8.95-6.3q-2.85 2.4-6.25 7.7-.95 1.5-1.7 3.5 1.7-1.45 4.9-2.3 3.3-.9 7.3-.9 3.9 0 7.2.9 3.25.85 4.95 2.3-.6-1.75-1.7-3.5-3.4-5.2-6.2-7.7l8.9 6.3.3 6.3h9.6v-6.4z"/></defs><use transform="translate(-10.95 -10.3)" xlink:href="#a"/></svg>

Before

Width:  |  Height:  |  Size: 722 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none" viewBox="0 0 90 46"><defs><path id="a" fill="#1e2d44" d="M85.8 49.1l-4.5-5.5q-1.65-.1-3.55-.55-3.8-.95-4.85-2.65Q68.75 34.25 74 27q5.45-7.65 17.55-10.3l-37.8-1.9H100v-3.7H47.75v14q0 .65-1.9-11.7h-4.1v13l-1.9-12.3h-27.9q12.85 10.8 19.9 14.3 2.45 1.2 6.05 1.65 2.1.25 6.35.35 2.1.1 3.1.35 1.65.4 2.7 1.45 1.75 1.7 2 4 .3 2.4-1.2 4.3-1.2 1.65-4.35 2.6l-2.95.6L39 49.1v6.4h10.25l.3-6.3 8.95-6.3q-2.85 2.4-6.25 7.7-.95 1.5-1.7 3.5 1.7-1.45 4.9-2.3 3.3-.9 7.3-.9 3.9 0 7.2.9 3.25.85 4.95 2.3-.6-1.75-1.7-3.5-3.4-5.2-6.2-7.7l8.9 6.3.3 6.3h9.6v-6.4z"/></defs><use transform="translate(-10.95 -10.3)" xlink:href="#a"/></svg>

Before

Width:  |  Height:  |  Size: 725 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#2196f3" d="M13.9 3.6H3A2.6 2.6 0 00.6 6.2v11.6c0 1.4 1.1 2.6 2.5 2.6H14c1.4 0 2.5-1.2 2.5-2.6V6.2c0-1.4-1.1-2.6-2.5-2.6z"/><path fill="#1976d2" d="M11.9 2.1h-1a2.5 2.5 0 00-4.8 0h-1c-.3 0-.6.3-.6.7v1.8c0 .9.7 1.6 1.5 1.6h5c.8 0 1.6-.7 1.6-1.6V2.8c0-.4-.4-.7-.7-.7z"/><path fill="#4caf50" d="M17.5 23a5.5 5.5 0 110-11 5.5 5.5 0 010 11z"/><path d="M17.5 24a6.5 6.5 0 110-13 6.5 6.5 0 010 13zm0-11.5a5 5 0 100 10 5 5 0 000-10z"/><path d="M17.5 21a.8.8 0 01-.8-.8v-3.4a.8.8 0 011.6 0v3.4c0 .5-.4.8-.8.8z"/><circle cx="17.5" cy="14.8" r=".8"/><path d="M9.2 21H2.7A2.8 2.8 0 010 18.2V5.8C0 4.2 1.2 3 2.7 3h2a.8.8 0 010 1.5h-2c-.6 0-1.2.6-1.2 1.3v12.4c0 .7.6 1.3 1.2 1.3h6.5a.8.8 0 010 1.5zM16.3 9.6a.8.8 0 01-.8-.8v-3c0-.7-.6-1.3-1.3-1.3h-1.8a.8.8 0 010-1.5h1.8C15.8 3 17 4.2 17 5.8v3c0 .5-.3.8-.8.8z"/><path d="M11.3 6.5H5.7c-1 0-1.7-.8-1.7-1.8v-2c0-.4.3-.7.8-.7h1a2.8 2.8 0 015.3 0h1.2c.4 0 .7.3.7.8v2c0 1-.8 1.7-1.8 1.7zm-5.8-3v1.3s.1.2.3.2h5.5s.2-.1.2-.3V3.5h-1a.8.8 0 01-.8-.8 1.3 1.3 0 00-2.4 0c0 .5-.4.8-.8.8zM13.3 9.5H3.7a.8.8 0 010-1.5h9.6a.8.8 0 010 1.5zM11 12.5H3.6a.8.8 0 010-1.5H11a.8.8 0 010 1.5zM9.2 15.5H3.7a.8.8 0 010-1.5h5.5a.8.8 0 010 1.5z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 58 58"><defs/><g fill="none" fill-rule="nonzero"><path fill="#35495e" d="M5.7 52.2L.2 20.7l-.1-1c-.1-3.5 2.5-6.6 6-7.2l10.7-1.8-.3 41.5z"/><path fill="#2c3e50" d="M47 50.8a2 2 0 01-1.7 1.5L13.8 58a7 7 0 01-8.2-6.6c0-3.4 2.3-6.4 5.6-7.1l8.9 2.4-8 1.4a3 3 0 00-2.3 4 3 3 0 003.5 2l24-4.3z"/><path fill="#f9eab0" d="M20 46.6L12.2 48a3 3 0 00-2.3 4 3 3 0 003.5 2l24-4.3z"/><path fill="#e64c3c" d="M12.8 33.2l5.6-31.5A2 2 0 0120.7 0L52 5.5a7.2 7.2 0 015.9 8.2l-5.6 31.5z"/><path fill="#3f5c6c" d="M45.4 10.5h-.1l-22.7-4a1 1 0 01.4-2l22.6 4a1 1 0 01-.2 2zM40.6 14.7h-.1L25.7 12a1 1 0 01.3-2l14.8 2.6a1 1 0 01-.2 2z"/><rect width="23" height="12" x="19.8" y="17.2" fill="#ecf0f1" rx="1" transform="rotate(10 31.3 23.2)"/><path fill="#c03a2b" d="M58 12.8l-.1.9-5.6 31.5-7.7-2.3 4.5-25.4 1-6 1.1-6h.8c3.5.6 6 3.7 6 7.3z"/><path fill="#802f34" d="M46.4 37l-31.3-5.4a2 2 0 00-.7 4L46 40.9a3 3 0 012.2 4.1 3 3 0 01-3.4 1.8l-31.4-5.5a2 2 0 10-.7 4l31.5 5.5a7 7 0 008.2-6.6c.1-3.6-2.4-6.7-6-7.2z"/><path fill="#f9eab0" d="M48.2 45.1a3 3 0 01-3.4 1.8l-31.4-5.5 1-6L46 41a3 3 0 012.2 4.1z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#f9d366" d="M224 231l47-81h-94z"/><path fill="#d83" d="M224 231l-17-81h-30z"/><g fill="#96c"><path d="M359 155c-4 0-8-3-8-8v-20a8 8 0 1116 0v20c0 5-4 8-8 8zM359 210c-4 0-8-3-8-8v-20a8 8 0 1116 0v20c0 5-4 8-8 8zM397 173h-21a8 8 0 110-16h21a8 8 0 110 16zM342 173h-21a8 8 0 110-16h21a8 8 0 110 16z"/></g><path fill="#f9d366" d="M355 499H118a134 134 0 0083-72l70-4 5 11c11 21 34 51 79 65z"/><path fill="#d83" d="M237 425l-12 2c-3 20-11 56-27 72h-80c51-16 73-52 83-72l36-2z"/><path fill="#ddac33" d="M248 424l-11 1 11-2v1z"/><path fill="#f9d366" d="M162 280c10-35 34-59 62-59s52 25 62 61l-64 41-60-43z"/><path fill="#d83" d="M224 281l-62-1c10-35 34-59 62-59-10 0-18 29-22 64l22-4z"/><path fill="#f9d366" d="M512 234s-26 3-58 35-58 158-238 158c-92 0-119-50-124-100-3-25 17-47 43-47h23c106 0 194 18 258-46h96z"/><g fill="#d83"><path d="M276 434a319 319 0 01-82 5l7-12 30-20 40 16 5 11z"/><path d="M266 387c-92 0-119-51-124-101v-6h-7c-26 0-46 22-43 47 5 50 32 100 124 100 93 0 145-33 177-70-31 18-71 30-127 30z"/><path d="M67 422a8 8 0 110-15c6 0 10-3 11-8 4-10-3-35-30-55C6 313-5 270 2 241c5-19 18-31 35-34 16-3 30 1 41 10 20 17 30 53 30 110a8 8 0 11-16 0c0-51-8-84-24-98-7-6-17-8-29-7-15 3-20 16-22 23-8 33 15 68 40 87 14 10 25 23 32 37 6 13 8 25 4 35-4 12-13 18-26 18z"/></g><g fill="#cf8bfc"><path d="M161 65a8 8 0 01-5-14l5-4c25-17 49-34 87-34 31 0 51 11 64 21a8 8 0 01-9 13c-13-9-29-19-55-19-33 0-54 15-78 32a2487 2487 0 01-9 5zM437 205h-3c-4-2-6-7-4-11 11-22 11-49 1-67-8-16-23-26-44-29-30-4-49-21-64-35a8 8 0 0110-11c15 13 31 27 56 31 33 4 49 22 56 36 12 23 12 55-1 82-1 3-4 4-7 4zM494 155c-5 0-8-3-8-8 0-68-52-93-85-93a8 8 0 110-16c23 0 47 9 65 25 16 14 36 40 36 84 0 5-4 8-8 8z"/></g><path fill="#96c" d="M123 93l16-4c8-1 8-12 0-14l-16-3c-16-4-29-16-32-33l-4-16c-1-8-12-8-14 0l-3 16c-4 17-16 29-32 33l-17 3c-8 2-8 13 0 14l17 4c16 3 28 16 32 32l3 16c2 8 13 8 14 0l4-16c3-16 16-29 32-32z"/><path fill="#ffdb82" d="M341 308c0 9-23 27-52 27s-52-18-52-27 24-6 52-6c29 0 52-3 52 6z"/></svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#e53935" d="M491 129v254c0 13-7 24-19 30l-202 96a33 33 0 01-28 0L40 413c-12-6-19-17-19-30V129a33 33 0 0119-30L242 3c9-4 19-4 28 0l202 96a32 32 0 0119 30z"/><path fill="#d32f2f" d="M486 111c-4-5-8-9-14-12L270 3c-9-4-19-4-28 0l-1 1 200 95a32 32 0 0119 30v254c0 13-7 24-19 30l-200 95 1 1a33 33 0 0028 0l202-96c12-6 19-17 19-30V129c0-7-2-13-5-18z"/><path fill="#f44336" d="M256 220v292c-5 0-10-1-14-3L40 413c-12-6-19-17-19-30V129c0-7 2-13 5-18z"/><path fill="#d32f2f" d="M491 129v254c0 12-7 24-18 29l-1 1-202 96c-4 2-9 3-14 3V220l230-109c3 5 5 11 5 18z"/><path fill="#c62828" d="M486 111l-26 12v260c0 12-7 24-18 29l-1 1-185 88v11c5 0 10-1 14-3l202-96 1-1c11-5 18-17 18-29V129c0-7-2-13-5-18z"/><g fill="#f1f1f1"><ellipse cx="389.6" cy="306.5" rx="26.7" ry="19.7" transform="rotate(-82 390 306)"/><ellipse cx="190.5" cy="263.3" rx="19.6" ry="26.7" transform="rotate(-3 189 261)"/><ellipse cx="78.3" cy="360.2" rx="19.6" ry="26.7" transform="rotate(-3 78 357)"/><ellipse cx="161.1" cy="104.2" rx="26.7" ry="19.6" transform="rotate(-3 160 103)"/><ellipse cx="253.7" cy="58.5" rx="26.7" ry="19.6" transform="rotate(-3 251 58)"/><ellipse cx="350.6" cy="107.5" rx="26.7" ry="19.6" transform="rotate(-3 347 107)"/><ellipse cx="260.2" cy="150" rx="26.7" ry="19.6" transform="rotate(-3 258 149)"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#E3E9ED" d="M310 190a10 10 0 100 20 10 10 0 000-20z" class="active-path" data-old_color="#000" data-original="#000"/><path fill="#E3E9ED" d="M500 444L367 310a200 200 0 10-57 57l37 37 97 96a40 40 0 0056 0 40 40 0 000-56zm-194-98a180 180 0 1140-40c-11 15-25 29-40 40zm21 9l28-28 28 28c-8 10-18 20-28 28l-28-28zm159 131a20 20 0 01-28 0l-89-89c10-8 20-18 28-28l89 89a20 20 0 010 28z" class="active-path" data-old_color="#000" data-original="#000"/><path fill="#E3E9ED" d="M200 40a160 160 0 100 320 160 160 0 000-320zm0 300a140 140 0 110-280 140 140 0 010 280z" class="active-path" data-old_color="#000" data-original="#000"/><path fill="#E3E9ED" d="M312 157a120 120 0 00-112-77 10 10 0 000 20c41 0 79 26 93 64a10 10 0 1019-7z" class="active-path" data-old_color="#000" data-original="#000"/></svg>

Before

Width:  |  Height:  |  Size: 867 B

View File

@ -1,19 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="forge-alt" viewBox="0 0 90 46"><path transform="translate(-10.95 -10.3)" fill="#fff" d="M85.8 49.1l-4.5-5.5q-1.65-.1-3.55-.55-3.8-.95-4.85-2.65Q68.75 34.25 74 27q5.45-7.65 17.55-10.3l-37.8-1.9H100v-3.7H47.75v14q0 .65-1.9-11.7h-4.1v13l-1.9-12.3h-27.9q12.85 10.8 19.9 14.3 2.45 1.2 6.05 1.65 2.1.25 6.35.35 2.1.1 3.1.35 1.65.4 2.7 1.45 1.75 1.7 2 4 .3 2.4-1.2 4.3-1.2 1.65-4.35 2.6l-2.95.6L39 49.1v6.4h10.25l.3-6.3 8.95-6.3q-2.85 2.4-6.25 7.7-.95 1.5-1.7 3.5 1.7-1.45 4.9-2.3 3.3-.9 7.3-.9 3.9 0 7.2.9 3.25.85 4.95 2.3-.6-1.75-1.7-3.5-3.4-5.2-6.2-7.7l8.9 6.3.3 6.3h9.6v-6.4z"/></symbol>
<symbol id="tech" viewBox="0 0 512 512"><path fill="#FFF" d="M505.5 106.1a16 16 0 00-26.6-6.5l-67.6 67.6-51.7-14.8-14.8-51.7L412.4 33a16 16 0 00-6.5-26.6 149.5 149.5 0 00-183.8 193L18.7 402.8a63.5 63.5 0 000 90.4 63.5 63.5 0 0090.4 0L312.5 290a149.5 149.5 0 00193-183.8zm0 0" class="active-path" data-old_color="#00bcd4" data-original="#00BCD4"/></symbol>
<symbol id="adventure" viewBox="0 0 64 64"><path fill="#e8d7b5" d="M15 18V6H9a6 6 0 100 12z"/><path fill="#ffecc7" d="M55 9c-5.3 0-10.6.8-15.6 2.4l-12.8 4A59.3 59.3 0 019 18a6 6 0 01-6-6v38a6 6 0 006 6c6 0 11.9-.9 17.6-2.7l12.8-4c3.4-1 7-1.7 10.6-2V21h5a6 6 0 100-12z"/><path fill="#88b337" d="M21 37c0-2-6-1.8-9.8-1.4-2 .2-3.6 1.5-4.4 3.3l-.2.5a5.2 5.2 0 002.6 6.7A103 103 0 0018 50c3 1 8-3 8-6s-5-4-5-7z"/><ellipse cx="36" cy="42" fill="#8c421c" rx="4" ry="2"/><path fill="#4398d1" d="M31.5 30c1.1 0 2-.4 2.7-1.1 1 .7 2.4 1.1 3.8 1.1 3.3 0 6-2.2 6-5s-2.7-5-6-5c-3 0-5.4 1.7-5.9 4a4 4 0 00-.6 0c-2 0-3.5 1.3-3.5 3s1.6 3 3.5 3z"/><g fill="#8c421c"><path d="M13.8 28.8l1.9.2.3-2a18 18 0 00-2-.2zM21 31l1.5 1 1.2-1.6-1.8-1.2zM9.7 27l.3 2a16 16 0 012-.2l-.2-2-2.1.2zM5.7 28l2-.5.5 2-2 .5zM24 33.2l1.8 1.2 1-1.7-1.5-1zM17.5 29.4l1.8.7.8-1.8-2-.8zM39.7 34.2l2-.4.4 2-2 .3zM43.7 33.4l2-.4.3 2-2 .4zM31.8 36.5l2 .3.2-2a16 16 0 01-1.9-.2zM27.7 35.4l2 .7.6-2-1.8-.6zM35.9 34.8l.1 2 2.1-.3-.4-2-1.8.3z"/></g><path fill="#fdb62f" d="M46 17.4L44.6 16l-2.3 2.3L40 16l-1.4 1.4 2.3 2.3-2.3 2.3 1.4 1.4 2.3-2.3 2.3 2.3L46 22l-2.3-2.3z"/><path fill="#e8d7b5" d="M55 21h-5v38c6 0 11-5 11-11V15a6 6 0 01-6 6z"/></symbol>
<symbol id="magic" viewBox="0 0 512 512"><path fill="#f9d366" d="M224 231l47-81h-94z"/><path fill="#d83" d="M224 231l-17-81h-30z"/><g fill="#96c"><path d="M359 155c-4 0-8-3-8-8v-20a8 8 0 1116 0v20c0 5-4 8-8 8zM359 210c-4 0-8-3-8-8v-20a8 8 0 1116 0v20c0 5-4 8-8 8zM397 173h-21a8 8 0 110-16h21a8 8 0 110 16zM342 173h-21a8 8 0 110-16h21a8 8 0 110 16z"/></g><path fill="#f9d366" d="M355 499H118a134 134 0 0083-72l70-4 5 11c11 21 34 51 79 65z"/><path fill="#d83" d="M237 425l-12 2c-3 20-11 56-27 72h-80c51-16 73-52 83-72l36-2z"/><path fill="#ddac33" d="M248 424l-11 1 11-2v1z"/><path fill="#f9d366" d="M162 280c10-35 34-59 62-59s52 25 62 61l-64 41-60-43z"/><path fill="#d83" d="M224 281l-62-1c10-35 34-59 62-59-10 0-18 29-22 64l22-4z"/><path fill="#f9d366" d="M512 234s-26 3-58 35-58 158-238 158c-92 0-119-50-124-100-3-25 17-47 43-47h23c106 0 194 18 258-46h96z"/><g fill="#d83"><path d="M276 434a319 319 0 01-82 5l7-12 30-20 40 16 5 11z"/><path d="M266 387c-92 0-119-51-124-101v-6h-7c-26 0-46 22-43 47 5 50 32 100 124 100 93 0 145-33 177-70-31 18-71 30-127 30z"/><path d="M67 422a8 8 0 110-15c6 0 10-3 11-8 4-10-3-35-30-55C6 313-5 270 2 241c5-19 18-31 35-34 16-3 30 1 41 10 20 17 30 53 30 110a8 8 0 11-16 0c0-51-8-84-24-98-7-6-17-8-29-7-15 3-20 16-22 23-8 33 15 68 40 87 14 10 25 23 32 37 6 13 8 25 4 35-4 12-13 18-26 18z"/></g><g fill="#cf8bfc"><path d="M161 65a8 8 0 01-5-14l5-4c25-17 49-34 87-34 31 0 51 11 64 21a8 8 0 01-9 13c-13-9-29-19-55-19-33 0-54 15-78 32a2487 2487 0 01-9 5zM437 205h-3c-4-2-6-7-4-11 11-22 11-49 1-67-8-16-23-26-44-29-30-4-49-21-64-35a8 8 0 0110-11c15 13 31 27 56 31 33 4 49 22 56 36 12 23 12 55-1 82-1 3-4 4-7 4zM494 155c-5 0-8-3-8-8 0-68-52-93-85-93a8 8 0 110-16c23 0 47 9 65 25 16 14 36 40 36 84 0 5-4 8-8 8z"/></g><path fill="#96c" d="M123 93l16-4c8-1 8-12 0-14l-16-3c-16-4-29-16-32-33l-4-16c-1-8-12-8-14 0l-3 16c-4 17-16 29-32 33l-17 3c-8 2-8 13 0 14l17 4c16 3 28 16 32 32l3 16c2 8 13 8 14 0l4-16c3-16 16-29 32-32z"/><path fill="#ffdb82" d="M341 308c0 9-23 27-52 27s-52-18-52-27 24-6 52-6c29 0 52-3 52 6z"/></symbol>
<symbol id="util" viewBox="0 0 498 498"><path fill="#e9a52d" d="M301 36c-2-9-10-15-19-15h-66c-9 0-17 6-19 15l-21 71-2 40-19 32-17 60-1 39-20 34-36 124 170 10 166-10-36-124-20-37-1-36-17-60-21-36v-36z"/><g fill="#e69824"><path d="M301 36c-2-9-10-15-19-15h-30c9 0 17 6 19 15l116 400 15 10 15-10-36-124-20-37-1-36-17-60-20-34-1-38z"/><path d="M495 477H3c-2 0-3-1-3-3v-27c0-6 5-11 11-11h476c6 0 11 5 11 11v27c0 2-1 3-3 3z"/></g><path fill="#e18720" d="M487 436h-30c6 0 11 5 11 11v27c0 2-1 3-3 3h30c2 0 3-1 3-3v-27c0-6-5-11-11-11z"/><path fill="#f7f7f7" d="M155 179h188l-21-72H176zM381 312l-21-73H138l-21 73z"/><path fill="#e8e8e8" d="M322 107h-30l21 72h30zM360 239h-30l21 73h30z"/></symbol>
<symbol id="decoration" viewBox="0 0 512 512"><path fill="#80c56e" d="M409 46c2 6 27 79-24 166-32 53-79 56-84 57-2-4-29-44-8-101C329 74 403 48 409 46z"/><path fill="#66ad66" d="M409 46L301 269c5-1 52-4 84-57 51-87 26-160 24-166z"/><path fill="#fff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="15" d="M298 275l3-6v-1l-3 7z"/><path fill="#80c56e" d="M103 46c-2 6-27 79 24 166 32 53 79 56 84 57 2-4 29-44 8-101A203 203 0 00103 46z"/><path fill="#66ad66" d="M219 168A203 203 0 00103 46c64 121 98 199 108 222 4-5 29-44 8-100z"/><path fill="#80c56e" d="M256 0c-8 7-96 97-82 261 8 99 75 138 82 141 7-3 74-42 82-141C352 97 264 7 256 0z"/><path fill="#66ad66" d="M256 0v402c7-3 74-42 82-141C352 97 264 7 256 0z"/><path fill="#80c56e" d="M446 250c17-57 11-111 11-111s-32 15-113 67c-63 40-82 112-88 131h74c53 0 101-35 116-87z"/><path fill="#66ad66" d="M457 139s-83 164-201 198h74c53 0 101-35 116-87 17-57 11-111 11-111z"/><path fill="#80c56e" d="M66 250c-17-57-11-111-11-111s32 15 113 67c63 40 82 112 88 131h-74c-53 0-101-35-116-87z"/><path fill="#66ad66" d="M256 337c-6-19-25-91-88-131-81-52-113-67-113-67s83 164 201 198z"/><path fill="#fec37d" d="M309 512H203c-29 0-53-20-58-48l-23-123h268l-23 123c-5 28-29 48-58 48z"/><path fill="#f9ae5d" d="M338 341l-23 123c-5 28-29 48-57 48h51c29 0 53-20 58-48l23-123h-52z"/><path fill="#f2a559" d="M395 369H117c-11 0-20-10-20-21s9-20 20-20h278c11 0 20 9 20 20s-9 21-20 21z"/><path fill="#ea8f3d" d="M395 328h-33v41h33c11 0 20-10 20-21s-9-20-20-20z"/></symbol>
<symbol id="library" viewBox="0 0 58 58"><defs/><g fill="none" fill-rule="nonzero"><path fill="#35495e" d="M5.7 52.2L.2 20.7l-.1-1c-.1-3.5 2.5-6.6 6-7.2l10.7-1.8-.3 41.5z"/><path fill="#2c3e50" d="M47 50.8a2 2 0 01-1.7 1.5L13.8 58a7 7 0 01-8.2-6.6c0-3.4 2.3-6.4 5.6-7.1l8.9 2.4-8 1.4a3 3 0 00-2.3 4 3 3 0 003.5 2l24-4.3z"/><path fill="#f9eab0" d="M20 46.6L12.2 48a3 3 0 00-2.3 4 3 3 0 003.5 2l24-4.3z"/><path fill="#e64c3c" d="M12.8 33.2l5.6-31.5A2 2 0 0120.7 0L52 5.5a7.2 7.2 0 015.9 8.2l-5.6 31.5z"/><path fill="#3f5c6c" d="M45.4 10.5h-.1l-22.7-4a1 1 0 01.4-2l22.6 4a1 1 0 01-.2 2zM40.6 14.7h-.1L25.7 12a1 1 0 01.3-2l14.8 2.6a1 1 0 01-.2 2z"/><rect width="23" height="12" x="19.8" y="17.2" fill="#ecf0f1" rx="1" transform="rotate(10 31.3 23.2)"/><path fill="#c03a2b" d="M58 12.8l-.1.9-5.6 31.5-7.7-2.3 4.5-25.4 1-6 1.1-6h.8c3.5.6 6 3.7 6 7.3z"/><path fill="#802f34" d="M46.4 37l-31.3-5.4a2 2 0 00-.7 4L46 40.9a3 3 0 012.2 4.1 3 3 0 01-3.4 1.8l-31.4-5.5a2 2 0 10-.7 4l31.5 5.5a7 7 0 008.2-6.6c.1-3.6-2.4-6.7-6-7.2z"/><path fill="#f9eab0" d="M48.2 45.1a3 3 0 01-3.4 1.8l-31.4-5.5 1-6L46 41a3 3 0 012.2 4.1z"/></g></symbol>
<symbol id="world" viewBox="0 0 512 512"><path fill="#31a7fb" d="M370 392c4 7 2 16-4 21l-13 12c-5 4-11 6-17 4l-25-7-3 1-18 22v1l21 58A183 183 0 0180 278l24 28h2l67-6 3-3-1-45c0-6 3-12 8-15l40-27c4-2 9-3 14-2s9 4 11 8l11 18a18 18 0 01-8 26l-12 6-2 2v12l2 2 23 11h2l47-20 1-1 19-27c3-5 10-8 16-7l71 6c11 22 18 46 20 71l-84 15-1 1-15 15a3 3 0 000 4l15 12 5 6z"/><path fill="#1c96f9" d="M306 490l5 14c-24 7-49 10-74 7 24-2 47-10 69-21zm132-175l-37 6c-1-28-9-55-23-80l40 3c11 22 18 46 20 71z"/><path fill="#27e19d" d="M127 200a183 183 0 01295 52l-75-7c-4 0-8 2-10 5l-18 26-5 4-47 20c-3 2-6 2-9 0l-23-11c-3-2-5-5-5-9l-1-12c0-4 3-8 7-9l12-6c6-2 8-9 5-15l-11-18c-3-5-10-6-15-3l-40 26c-3 2-4 5-4 9v45c0 5-4 10-9 10l-67 7c-4 0-7-1-9-3l-20-23c8-32 24-63 49-88zm205 141l16-16 5-3 84-15a182 182 0 01-133 199l-21-58c-1-3-1-6 1-8l19-22c2-3 6-4 10-3l25 7c3 1 7 0 10-3l13-11c3-4 4-9 2-13l-12-23-3-4-15-12c-5-4-5-11-1-15zm-190 23l17-7c3-2 8-1 11 1l12 10 7 2h38c4 0 8 3 9 7l6 16v7l-16 36c-2 5-8 8-13 6l-48-16c-4-1-7-5-7-9l-1-18c0-5-3-9-7-10l-6-1c-5-2-8-5-8-10v-4c0-4 2-8 6-10z"/><path fill="#23f1a8" d="M258 102l-2-3c-2-36 13-71 43-88s68-13 97 7c2 1 2 2 2 4 3 36-12 70-42 88a91 91 0 01-98-8zm-4 0l2-3c2-36-13-71-43-88a91 91 0 00-97 7l-2 4c-3 36 12 70 42 88 30 17 68 13 98-8z"/><g fill="#26d192"><path d="M347 200c-30-31-70-48-110-52a182 182 0 01185 104l-40-3c-8-18-20-34-35-49zm38 258c-23 24-51 40-81 48l-5-13a182 182 0 00101-179l37-7c7 54-10 110-52 151zm-77-258l-5-2c-10-9-27-15-47-15s-37 6-47 15a8 8 0 11-11-11c13-12 34-19 58-19s45 7 58 19a8 8 0 01-6 13zM256 99V87c28 15 60 16 87 1s42-44 43-76l10 6c2 1 2 2 2 4 3 36-12 70-42 88s-68 13-98-8l-2-3z"/><path d="M388 76a86 86 0 01-32 34l-10 5c-28 11-61 6-88-13l-2-3V87c17 9 36 13 55 11a82 82 0 0056-31c12-16 18-35 19-55l10 6 2 4c2 19-2 38-10 54zM114 22c0-2 0-3 2-4 29-20 67-24 97-7s45 52 43 88l-2 3c-5 4-10 7-16 9 1-34-14-66-43-83a88 88 0 00-82-1l1-5zm285 6l-1-6-2-4-5-3-51 29 4-44-15 1-5 52-23 14 5-60a81 81 0 00-16 10l-6 59-28 16-28-16-6-59a81 81 0 00-16-10l5 60-23-14-5-52-15-1 4 44-51-29-5 3-2 4-1 6 51 29-40 19c3 5 5 9 9 13l48-22 23 13-54 25a81 81 0 0016 10l54-25 28 16v67a8 8 0 0016 0v-67l28-16 54 25a80 80 0 0016-10l-54-25 23-13 48 22c4-4 6-8 9-13l-40-19z"/></g><path fill="#1ec186" d="M362 105a81 81 0 01-16 10l-35-17c8-1 16-3 23-6zm26-29c-3 5-5 9-9 13l-23-11 11-11zM121 15l10 6-18 6 1-5c0-2 0-3 2-4l5-3zm117 85l10 6 6-4 2-3v-7l-21-12c1 6 3 13 3 20zm23-11l-5 3v7l2 3 6 4 16-10c-6-1-13-4-19-7zm138-61l-17 10 4-20 5-3 5 3 2 4 1 6zM226 60c-4-8-10-16-17-22l-3-31a81 81 0 0116 10zm-40-36l-16-5-2-19 15 1z"/></symbol>
<symbol id="storage" viewBox="0 0 480 480"><defs/><path fill="#ffaa64" d="M472 61v41c0 18-14 32-32 32h-2v285c0 18-14 32-32 32H74c-18 0-32-14-32-32V134h-2c-18 0-32-14-32-32V61c0-18 14-32 32-32h400c18 0 32 14 32 32z"/><path fill="#ffbd7b" d="M472 61v41c0 18-14 32-32 32H40c-18 0-32-14-32-32V61c0-18 14-32 32-32h400c18 0 32 14 32 32z"/><path fill="#fa9a4b" d="M320 217v10c0 13-11 24-24 24H184c-13 0-24-11-24-24v-10c0-13 11-24 24-24h112c13 0 24 11 24 24z"/><path fill="#ffd3a6" d="M440 69H80c-18 0-32 14-32 32v1c0 26-39 27-40 2V61c0-18 14-32 32-32h400c28 0 26 40 0 40z"/><path fill="#faa157" d="M42 134h396v35H42z"/><path d="M480 61v41c0 22-18 40-40 40h-15a8 8 0 010-16h15c13 0 24-11 24-24V61c0-13-11-24-24-24H40c-13 0-24 11-24 24v41c0 13 11 24 24 24h333a8 8 0 010 16H50v277c0 13 11 24 24 24h332c13 0 24-11 24-24V177a8 8 0 0116 0v242c0 22-18 40-40 40H74c-22 0-40-18-40-40V142c-19-3-34-20-34-40V61c0-22 18-40 40-40h400c22 0 40 18 40 40zM184 259c-18 0-32-14-32-32v-10c0-18 14-32 32-32h112c18 0 32 14 32 32v10c0 18-14 32-32 32zm0-16h112c9 0 16-7 16-16v-10c0-9-7-16-16-16H184c-9 0-16 7-16 16v10c0 9 7 16 16 16zm-24 102h-56a8 8 0 000 16h56a8 8 0 000-16zm0 40h-56a8 8 0 000 16h56a8 8 0 000-16z"/></symbol>
<symbol id="food" viewBox="0 0 504 504"><path fill="#7fb241" d="M253 120c-72 7-126-47-119-119 72-7 126 47 119 119z"/><path fill="#8e6d53" d="M256 171c-6-1-11-7-12-14A117 117 0 01348 28a16 16 0 014 32 85 85 0 00-76 94 16 16 0 01-20 17z"/><path fill="#e14b4b" d="M374 120c-17-4-35-3-53 2-45 15-93 15-138 0-18-5-36-6-53-2-69 19-103 119-75 224s107 175 176 157a78 78 0 0142 0c69 18 148-52 176-157s-6-205-75-224z"/><path fill="#d03f3f" d="M449 344c-28 105-107 175-176 157h-1c-13-4-27-4-41 0-26 7-53 1-79-14a426 426 0 00259-346c43 38 60 119 38 203z"/></symbol>
<symbol id="equipment" viewBox="0 0 512 512"><path fill="#fea832" d="M482 316v105H30V316c0-73 36-139 91-180l15 45 15-64a226 226 0 01210 0l15 64 15-45c55 41 91 107 91 180z"/><path fill="#fe9923" d="M482 316v105H256V91c38 0 74 10 105 26l15 64 15-45c55 41 91 107 91 180z"/><path fill="#fedb41" d="M331 106v150c0 8-7 15-15 15H196c-8 0-15-7-15-15V106c0-25 20-45 45-45h60c25 0 45 20 45 45z"/><path fill="#fcbf29" d="M376 241c8 0 15-7 15-15v-90c-9-7-19-13-30-19v109c0 8 7 15 15 15z"/><g fill="#fedb41"><path d="M136 241c8 0 15-7 15-15V117c-11 6-21 12-30 19v90c0 8 7 15 15 15zM512 421c0 17-13 30-30 30H30c-16 0-30-13-30-30s14-30 30-30h452c17 0 30 14 30 30z"/></g><g fill="#fcbf29"><path d="M316 271h-60V61h30c25 0 45 20 45 45v150c0 8-7 15-15 15zM512 421c0 17-13 30-30 30H256v-60h226c17 0 30 14 30 30z"/></g></symbol>
<symbol id="misc" viewBox="0 0 512 512"><path fill="#e53935" d="M491 129v254c0 13-7 24-19 30l-202 96a33 33 0 01-28 0L40 413c-12-6-19-17-19-30V129a33 33 0 0119-30L242 3c9-4 19-4 28 0l202 96a32 32 0 0119 30z"/><path fill="#d32f2f" d="M486 111c-4-5-8-9-14-12L270 3c-9-4-19-4-28 0l-1 1 200 95a32 32 0 0119 30v254c0 13-7 24-19 30l-200 95 1 1a33 33 0 0028 0l202-96c12-6 19-17 19-30V129c0-7-2-13-5-18z"/><path fill="#f44336" d="M256 220v292c-5 0-10-1-14-3L40 413c-12-6-19-17-19-30V129c0-7 2-13 5-18z"/><path fill="#d32f2f" d="M491 129v254c0 12-7 24-18 29l-1 1-202 96c-4 2-9 3-14 3V220l230-109c3 5 5 11 5 18z"/><path fill="#c62828" d="M486 111l-26 12v260c0 12-7 24-18 29l-1 1-185 88v11c5 0 10-1 14-3l202-96 1-1c11-5 18-17 18-29V129c0-7-2-13-5-18z"/><g fill="#f1f1f1"><ellipse cx="389.6" cy="306.5" rx="26.7" ry="19.7" transform="rotate(-82 390 306)"/><ellipse cx="190.5" cy="263.3" rx="19.6" ry="26.7" transform="rotate(-3 189 261)"/><ellipse cx="78.3" cy="360.2" rx="19.6" ry="26.7" transform="rotate(-3 78 357)"/><ellipse cx="161.1" cy="104.2" rx="26.7" ry="19.6" transform="rotate(-3 160 103)"/><ellipse cx="253.7" cy="58.5" rx="26.7" ry="19.6" transform="rotate(-3 251 58)"/><ellipse cx="350.6" cy="107.5" rx="26.7" ry="19.6" transform="rotate(-3 347 107)"/><ellipse cx="260.2" cy="150" rx="26.7" ry="19.6" transform="rotate(-3 258 149)"/></g></symbol>
<symbol id="version" viewBox="0 0 408 408"><path fill="#ed664c" d="M56 56c3-4 8-6 14-6l131-4c9 0 17 3 23 9l165 166c13 12 13 32 0 44L265 389a31 31 0 01-44 0L55 224c-6-6-9-14-9-23l4-131c0-6 2-11 6-14zm181 284l103-103-89-89-103 103 89 89zm-66-205a35 35 0 10-71 0 35 35 0 0071 0z"/><path fill="#fdc75b" d="M340 237L237 340l-89-89 103-103z"/><path d="M231 48c-8-8-19-12-30-12L70 40c-5 0-9 1-13 3L17 3A10 10 0 103 17l40 40c-2 4-3 8-3 13l-4 131c0 11 4 22 12 30l166 165a41 41 0 0058 0l124-124c16-16 16-42 0-58L231 48zm151 210L258 382c-8 9-22 9-30 0L63 217c-5-4-7-10-7-16l4-127 37 37a45 45 0 1014-14L74 59l128-3c6 0 11 2 15 6l165 166c9 8 9 22 0 30zM110 135a25 25 0 1151 0 25 25 0 01-51 0z"/><path d="M258 141c-4-4-11-4-14 0L141 243c-4 4-4 11 0 15l89 88c2 2 4 3 7 3s5-1 7-3l103-102c2-2 3-5 3-7l-3-7-89-89zm-21 184l-75-74 89-89 75 75-89 88z"/></symbol>
<symbol id="created" viewBox="0 0 512 512"><circle cx="256" cy="256" r="256" fill="#fe8205"/><path fill="#fa5d0f" d="M512 256C512 115 397 0 256 0v512c141 0 256-115 256-256z"/><path fill="#f0f7ff" d="M256 61a195 195 0 100 390 195 195 0 000-390z"/><path fill="#dfe7f4" d="M451 256c0-108-87-195-195-195v391c108 0 195-88 195-196z"/><path fill="#575f64" d="M256 121c-8 0-15 7-15 15v150a15 15 0 1030 0V136c0-8-7-15-15-15z"/><path fill="#474f54" d="M271 286V136c0-8-7-15-15-15v180c8 0 15-7 15-15z"/><path fill="#575f64" d="M346 241H226a15 15 0 100 30h120a15 15 0 100-30z"/><path fill="#474f54" d="M361 256c0-8-7-15-15-15h-90v30h90c8 0 15-7 15-15z"/></symbol>
<symbol id="download" viewBox="0 0 512 512"><defs/><path fill="#69E781" d="M256 363c-9 0-16-7-16-16V16a16 16 0 0132 0v331c0 9-7 16-16 16zm0 0" class="active-path" data-old_color="#000000" data-original="#000000"/><path fill="#69E781" d="M256 363c-4 0-8-2-11-5l-86-85a16 16 0 0123-23l74 74 74-74a16 16 0 0123 23l-86 85c-3 3-7 5-11 5zm0 0" class="active-path" data-old_color="#000000" data-original="#000000"/><path fill="#69E781" d="M453 512H59c-33 0-59-26-59-59v-96a16 16 0 0132 0v96c0 15 12 27 27 27h394c15 0 27-12 27-27v-96a16 16 0 0132 0v96c0 33-26 59-59 59zm0 0" class="active-path" data-old_color="#000000" data-original="#000000"/></symbol>
<symbol id="updated" viewBox="0 0 468.1 468.1"><defs/><path fill="#dc8744" d="M28 363L9.4 424 .6 452.5c-2.9 9.2 5.8 18 15 15l28.6-8.7 60.9-18.7-77-77z"/><path fill="#3a556a" d="M44.2 458.8l-28.5 8.8c-9.3 2.8-18-5.9-15.1-15.1L9.3 424l34.9 34.8z"/><path fill="#fcd462" d="M387.5 80.6l-321 321L28.2 363 349 42z"/><path fill="#f6c358" d="M426 119.2l-321 321-38.5-38.6 321-321z"/><path fill="#e56353" d="M426 119.1l-77-77 38.4-38.4a12.5 12.5 0 0117.7 0L464.5 63a12.5 12.5 0 010 17.7L426 119z"/><g fill="#ebf0f3"><path d="M406.2 138.9l-12.9 12.9-77-77 13-12.9zM380.6 164.6l-12.9 12.9-77-77 12.9-12.9z"/></g></symbol>
</svg>

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -10 512 511"><defs/><path fill="#ffc107" d="M500 189c-4-10-12-17-23-18l-141-13-56-131a26 26 0 00-48 0l-56 131-141 13a26 26 0 00-15 45l107 94-32 139a26 26 0 0039 28l122-73 122 73a26 26 0 0039-28l-32-139 107-94c8-7 11-18 8-27zm0 0"/><path d="M115 491a27 27 0 01-27-33l33-145L9 215a27 27 0 0116-48l148-13 58-137a27 27 0 0150 0l58 137 148 13a27 27 0 0116 48l-112 98 33 145a27 27 0 01-41 29l-127-76-127 76c-5 3-10 4-14 4zm141-113c5 0 10 2 14 4l120 72-31-137c-2-10 1-20 9-26l105-93-139-13c-10 0-19-7-23-16L256 40l-55 129c-4 9-13 15-23 16L39 198l105 93c8 6 11 16 9 26l-31 137 120-72c4-2 9-4 14-4zm-85-222zm170 0zm0 0"/></svg>

Before

Width:  |  Height:  |  Size: 669 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 480"><defs/><path fill="#ffaa64" d="M472 61v41c0 18-14 32-32 32h-2v285c0 18-14 32-32 32H74c-18 0-32-14-32-32V134h-2c-18 0-32-14-32-32V61c0-18 14-32 32-32h400c18 0 32 14 32 32z"/><path fill="#ffbd7b" d="M472 61v41c0 18-14 32-32 32H40c-18 0-32-14-32-32V61c0-18 14-32 32-32h400c18 0 32 14 32 32z"/><path fill="#fa9a4b" d="M320 217v10c0 13-11 24-24 24H184c-13 0-24-11-24-24v-10c0-13 11-24 24-24h112c13 0 24 11 24 24z"/><path fill="#ffd3a6" d="M440 69H80c-18 0-32 14-32 32v1c0 26-39 27-40 2V61c0-18 14-32 32-32h400c28 0 26 40 0 40z"/><path fill="#faa157" d="M42 134h396v35H42z"/><path d="M480 61v41c0 22-18 40-40 40h-15a8 8 0 010-16h15c13 0 24-11 24-24V61c0-13-11-24-24-24H40c-13 0-24 11-24 24v41c0 13 11 24 24 24h333a8 8 0 010 16H50v277c0 13 11 24 24 24h332c13 0 24-11 24-24V177a8 8 0 0116 0v242c0 22-18 40-40 40H74c-22 0-40-18-40-40V142c-19-3-34-20-34-40V61c0-22 18-40 40-40h400c22 0 40 18 40 40zM184 259c-18 0-32-14-32-32v-10c0-18 14-32 32-32h112c18 0 32 14 32 32v10c0 18-14 32-32 32zm0-16h112c9 0 16-7 16-16v-10c0-9-7-16-16-16H184c-9 0-16 7-16 16v10c0 9 7 16 16 16zm-24 102h-56a8 8 0 000 16h56a8 8 0 000-16zm0 40h-56a8 8 0 000 16h56a8 8 0 000-16z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs/><path fill="#FFF" d="M505.5 106.1a16 16 0 00-26.6-6.5l-67.6 67.6-51.7-14.8-14.8-51.7L412.4 33a16 16 0 00-6.5-26.6 149.5 149.5 0 00-183.8 193L18.7 402.8a63.5 63.5 0 000 90.4 63.5 63.5 0 0090.4 0L312.5 290a149.5 149.5 0 00193-183.8zm0 0" class="active-path" data-old_color="#00bcd4" data-original="#00BCD4"/></svg>

Before

Width:  |  Height:  |  Size: 381 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -10 512 511"><defs/><path d="M115 491a27 27 0 01-27-33l33-145L9 215a27 27 0 0116-48l148-13 58-137a27 27 0 0150 0l58 137 148 13a27 27 0 0116 48l-112 98 33 145a27 27 0 01-41 29l-127-76-127 76c-5 3-10 4-14 4zm141-113c5 0 10 2 14 4l120 72-31-137c-2-10 1-20 9-26l105-93-139-13c-10 0-19-7-23-16L256 40l-55 129c-4 9-13 15-23 16L39 198l105 93c8 6 11 16 9 26l-31 137 120-72c4-2 9-4 14-4zm-85-222zm170 0zm0 0"/></svg>

Before

Width:  |  Height:  |  Size: 458 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 491 491" fill="#fff"><path d="M18 274L245 47l227 227a11 11 0 0015-15L253 24c-4-4-11-4-15 0L3 259a11 11 0 0015 15z"/><path d="M253 216c-4-4-11-4-15 0L3 451a11 11 0 0015 15l227-227 227 227a11 11 0 0015-15L253 216z"/><path d="M480 277c-3 0-6-1-8-3L245 47 18 274a11 11 0 01-15-15L238 24c4-4 11-4 15 0l234 235a11 11 0 01-7 18z"/><path d="M480 469c-3 0-6-1-8-3L245 239 18 466a11 11 0 01-15-15l235-235c4-4 11-4 15 0l234 235a11 11 0 01-7 18z"/></svg>

Before

Width:  |  Height:  |  Size: 495 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 468.1 468.1"><defs/><path fill="#dc8744" d="M28 363L9.4 424 .6 452.5c-2.9 9.2 5.8 18 15 15l28.6-8.7 60.9-18.7-77-77z"/><path fill="#3a556a" d="M44.2 458.8l-28.5 8.8c-9.3 2.8-18-5.9-15.1-15.1L9.3 424l34.9 34.8z"/><path fill="#fcd462" d="M387.5 80.6l-321 321L28.2 363 349 42z"/><path fill="#f6c358" d="M426 119.2l-321 321-38.5-38.6 321-321z"/><path fill="#e56353" d="M426 119.1l-77-77 38.4-38.4a12.5 12.5 0 0117.7 0L464.5 63a12.5 12.5 0 010 17.7L426 119z"/><g fill="#ebf0f3"><path d="M406.2 138.9l-12.9 12.9-77-77 13-12.9zM380.6 164.6l-12.9 12.9-77-77 12.9-12.9z"/></g></svg>

Before

Width:  |  Height:  |  Size: 626 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 498 498"><path fill="#e9a52d" d="M301 36c-2-9-10-15-19-15h-66c-9 0-17 6-19 15l-21 71-2 40-19 32-17 60-1 39-20 34-36 124 170 10 166-10-36-124-20-37-1-36-17-60-21-36v-36z"/><g fill="#e69824"><path d="M301 36c-2-9-10-15-19-15h-30c9 0 17 6 19 15l116 400 15 10 15-10-36-124-20-37-1-36-17-60-20-34-1-38z"/><path d="M495 477H3c-2 0-3-1-3-3v-27c0-6 5-11 11-11h476c6 0 11 5 11 11v27c0 2-1 3-3 3z"/></g><path fill="#e18720" d="M487 436h-30c6 0 11 5 11 11v27c0 2-1 3-3 3h30c2 0 3-1 3-3v-27c0-6-5-11-11-11z"/><path fill="#f7f7f7" d="M155 179h188l-21-72H176zM381 312l-21-73H138l-21 73z"/><path fill="#e8e8e8" d="M322 107h-30l21 72h30zM360 239h-30l21 73h30z"/></svg>

Before

Width:  |  Height:  |  Size: 705 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 408 408"><path fill="#ed664c" d="M56 56c3-4 8-6 14-6l131-4c9 0 17 3 23 9l165 166c13 12 13 32 0 44L265 389a31 31 0 01-44 0L55 224c-6-6-9-14-9-23l4-131c0-6 2-11 6-14zm181 284l103-103-89-89-103 103 89 89zm-66-205a35 35 0 10-71 0 35 35 0 0071 0z"/><path fill="#fdc75b" d="M340 237L237 340l-89-89 103-103z"/><path d="M231 48c-8-8-19-12-30-12L70 40c-5 0-9 1-13 3L17 3A10 10 0 103 17l40 40c-2 4-3 8-3 13l-4 131c0 11 4 22 12 30l166 165a41 41 0 0058 0l124-124c16-16 16-42 0-58L231 48zm151 210L258 382c-8 9-22 9-30 0L63 217c-5-4-7-10-7-16l4-127 37 37a45 45 0 1014-14L74 59l128-3c6 0 11 2 15 6l165 166c9 8 9 22 0 30zM110 135a25 25 0 1151 0 25 25 0 01-51 0z"/><path d="M258 141c-4-4-11-4-14 0L141 243c-4 4-4 11 0 15l89 88c2 2 4 3 7 3s5-1 7-3l103-102c2-2 3-5 3-7l-3-7-89-89zm-21 184l-75-74 89-89 75 75-89 88z"/></svg>

Before

Width:  |  Height:  |  Size: 857 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#31a7fb" d="M370 392c4 7 2 16-4 21l-13 12c-5 4-11 6-17 4l-25-7-3 1-18 22v1l21 58A183 183 0 0180 278l24 28h2l67-6 3-3-1-45c0-6 3-12 8-15l40-27c4-2 9-3 14-2s9 4 11 8l11 18a18 18 0 01-8 26l-12 6-2 2v12l2 2 23 11h2l47-20 1-1 19-27c3-5 10-8 16-7l71 6c11 22 18 46 20 71l-84 15-1 1-15 15a3 3 0 000 4l15 12 5 6z"/><path fill="#1c96f9" d="M306 490l5 14c-24 7-49 10-74 7 24-2 47-10 69-21zm132-175l-37 6c-1-28-9-55-23-80l40 3c11 22 18 46 20 71z"/><path fill="#27e19d" d="M127 200a183 183 0 01295 52l-75-7c-4 0-8 2-10 5l-18 26-5 4-47 20c-3 2-6 2-9 0l-23-11c-3-2-5-5-5-9l-1-12c0-4 3-8 7-9l12-6c6-2 8-9 5-15l-11-18c-3-5-10-6-15-3l-40 26c-3 2-4 5-4 9v45c0 5-4 10-9 10l-67 7c-4 0-7-1-9-3l-20-23c8-32 24-63 49-88zm205 141l16-16 5-3 84-15a182 182 0 01-133 199l-21-58c-1-3-1-6 1-8l19-22c2-3 6-4 10-3l25 7c3 1 7 0 10-3l13-11c3-4 4-9 2-13l-12-23-3-4-15-12c-5-4-5-11-1-15zm-190 23l17-7c3-2 8-1 11 1l12 10 7 2h38c4 0 8 3 9 7l6 16v7l-16 36c-2 5-8 8-13 6l-48-16c-4-1-7-5-7-9l-1-18c0-5-3-9-7-10l-6-1c-5-2-8-5-8-10v-4c0-4 2-8 6-10z"/><path fill="#23f1a8" d="M258 102l-2-3c-2-36 13-71 43-88s68-13 97 7c2 1 2 2 2 4 3 36-12 70-42 88a91 91 0 01-98-8zm-4 0l2-3c2-36-13-71-43-88a91 91 0 00-97 7l-2 4c-3 36 12 70 42 88 30 17 68 13 98-8z"/><g fill="#26d192"><path d="M347 200c-30-31-70-48-110-52a182 182 0 01185 104l-40-3c-8-18-20-34-35-49zm38 258c-23 24-51 40-81 48l-5-13a182 182 0 00101-179l37-7c7 54-10 110-52 151zm-77-258l-5-2c-10-9-27-15-47-15s-37 6-47 15a8 8 0 11-11-11c13-12 34-19 58-19s45 7 58 19a8 8 0 01-6 13zM256 99V87c28 15 60 16 87 1s42-44 43-76l10 6c2 1 2 2 2 4 3 36-12 70-42 88s-68 13-98-8l-2-3z"/><path d="M388 76a86 86 0 01-32 34l-10 5c-28 11-61 6-88-13l-2-3V87c17 9 36 13 55 11a82 82 0 0056-31c12-16 18-35 19-55l10 6 2 4c2 19-2 38-10 54zM114 22c0-2 0-3 2-4 29-20 67-24 97-7s45 52 43 88l-2 3c-5 4-10 7-16 9 1-34-14-66-43-83a88 88 0 00-82-1l1-5zm285 6l-1-6-2-4-5-3-51 29 4-44-15 1-5 52-23 14 5-60a81 81 0 00-16 10l-6 59-28 16-28-16-6-59a81 81 0 00-16-10l5 60-23-14-5-52-15-1 4 44-51-29-5 3-2 4-1 6 51 29-40 19c3 5 5 9 9 13l48-22 23 13-54 25a81 81 0 0016 10l54-25 28 16v67a8 8 0 0016 0v-67l28-16 54 25a80 80 0 0016-10l-54-25 23-13 48 22c4-4 6-8 9-13l-40-19z"/></g><path fill="#1ec186" d="M362 105a81 81 0 01-16 10l-35-17c8-1 16-3 23-6zm26-29c-3 5-5 9-9 13l-23-11 11-11zM121 15l10 6-18 6 1-5c0-2 0-3 2-4l5-3zm117 85l10 6 6-4 2-3v-7l-21-12c1 6 3 13 3 20zm23-11l-5 3v7l2 3 6 4 16-10c-6-1-13-4-19-7zm138-61l-17 10 4-20 5-3 5 3 2 4 1 6zM226 60c-4-8-10-16-17-22l-3-31a81 81 0 0116 10zm-40-36l-16-5-2-19 15 1z"/></svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,16 +0,0 @@
window.onload = function () {
if (localStorage.getItem("data-theme")) {
document.documentElement.setAttribute("data-theme", localStorage.getItem("data-theme"));
}
}
function switchThemes() {
let switchTheme = localStorage.getItem("data-theme") === "light" ? "dark" : "light";
localStorage.setItem("data-theme", switchTheme);
document.documentElement.setAttribute("data-theme", switchTheme);
}
function closePopup(e) {
e.parentElement.outerHTML = "";
}

View File

@ -1,56 +0,0 @@
//TODO Reduce repeated code
let currentlySelected = document.getElementById("description-bar");
let currentlySelectedDiv = document.getElementById("description");
function toggleSection(element) {
currentlySelected.classList.remove("mod-bar-active");
currentlySelected = element;
currentlySelected.classList.add("mod-bar-active");
currentlySelectedDiv.classList.remove("mod-show");
currentlySelectedDiv.classList.add("mod-hide");
currentlySelectedDiv = document.getElementById(element.id.replace("-bar", ""));
currentlySelectedDiv.classList.remove("mod-hide");
currentlySelectedDiv.classList.add("mod-show");
}
let currentlyBuildSelected = document.getElementById("gradle-code-bar");
let currentlyBuildSelectedDiv = document.getElementById("gradle-code");
function toggleBuildSection(element) {
currentlyBuildSelected.classList.remove("mod-bar-active");
currentlyBuildSelected = element;
currentlyBuildSelected.classList.add("mod-bar-active");
currentlyBuildSelectedDiv.classList.remove("mod-show");
currentlyBuildSelectedDiv.classList.add("mod-hide");
currentlyBuildSelectedDiv = document.getElementById(element.id.replace("-bar", ""));
currentlyBuildSelectedDiv.classList.remove("mod-hide");
currentlyBuildSelectedDiv.classList.add("mod-show");
}
let currentlyApiSelected = document.getElementById("curl-code-bar");
let currentlyApiSelectedDiv = document.getElementById("curl-code");
function toggleApiSection(element) {
currentlyApiSelected.classList.remove("mod-bar-active");
currentlyApiSelected = element;
currentlyApiSelected.classList.add("mod-bar-active");
currentlyApiSelectedDiv.classList.remove("mod-show");
currentlyApiSelectedDiv.classList.add("mod-hide");
currentlyApiSelectedDiv = document.getElementById(element.id.replace("-bar", ""));
currentlyApiSelectedDiv.classList.remove("mod-hide");
currentlyApiSelectedDiv.classList.add("mod-show");
}
for (let block of document.getElementsByClassName("api-code-block")) {
hljs.highlightBlock(block);
}

View File

@ -1,299 +0,0 @@
let input = document.getElementById("search-input");
let category_inputs = {
"technology": false,
"adventure": false,
"magic": false,
"utility": false,
"decoration": false,
"library": false,
"worldgen": false,
"cursed": false,
"storage": false,
"food": false,
"equipment": false,
"misc": false,
"forge": false,
"fabric": false,
}
let version_inputs = {};
let selectedType = "relevance";
let resultContainer = document.getElementById("results");
window.onload = function () {
//Add category ghosts
let categories = document.getElementsByClassName("category-badge");
for (let category of categories) {
let ghost = document.createElement('div');
ghost.className = "category-ghost";
ghost.id = category.id + "-ghost";
category.appendChild(ghost);
}
//Set Initial Values based on URL
const urlParams = new URLSearchParams(window.location.search);
if(urlParams.has("q"))
document.getElementById("search-input").value = decodeURIComponent(urlParams.get("q"));
if(urlParams.has("f")) {
let value = decodeURIComponent(urlParams.get("f"));
for (let key in category_inputs) {
if (category_inputs.hasOwnProperty(key)) {
if(value.includes(key)) {
activateCategory(document.getElementById(key))
}
}
}
}
if(urlParams.has("s")) {
let value = decodeURIComponent(urlParams.get("s"));
selectedType = value;
document.getElementById("filters").value = value;
}
let urlVersions = [];
if(urlParams.has("v")) {
let versionsString = urlParams.get("v");
versionsString = versionsString.replace(/ /g, '');
versionsString = versionsString.replace(/versions=/g, '');
urlVersions = versionsString.split("OR")
}
// Set Version categories from Mojang Launcher Meta
let releases = document.getElementById("releases");
let snapshots = document.getElementById("snapshots");
let archaic = document.getElementById("archaic");
let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
let versions = JSON.parse(xmlHttp.responseText);
for (let version of versions.versions) {
let versionElement = document.createElement('p');
versionElement.className = "version";
versionElement.innerHTML = version.id;
versionElement.id = version.id;
versionElement.setAttribute("onclick", "activateVersion(this)");
version_inputs[version.id] = false;
if(version.type === "release")
releases.appendChild(versionElement)
else if (version.type === "snapshot")
snapshots.appendChild(versionElement)
else if (version.type === "old_alpha" || version.type === "old_beta")
archaic.appendChild(versionElement)
else
versionElement.outerHTML = "";
if(urlVersions.includes(version.id)) {
activateVersion(versionElement);
}
}
}
}
xmlHttp.open("GET", "https://launchermeta.mojang.com/mc/game/version_manifest.json", true);
xmlHttp.send(null);
}
function clearFilters() {
for (let key in category_inputs) {
if (category_inputs.hasOwnProperty(key)) {
if(category_inputs[key]) {
let element = document.getElementById(key);
element.style.width = "165px";
element.style.boxShadow = "0 0";
document.getElementById(key + "-ghost").className = "category-ghost";
category_inputs[key] = false;
}
}
}
for (let key in version_inputs) {
if (version_inputs.hasOwnProperty(key)) {
if(version_inputs[key]) {
let element = document.getElementById(key);
element.style.width = "152px";
element.style.boxShadow = "0 0";
version_inputs[key] = false;
}
}
}
handleSearch(0);
}
function toggleVisibility(e) {
let element = e.parentElement.lastElementChild;
if (element.style.display === "none") {
element.style.display = "block";
e.innerHTML = e.innerHTML.replace("+", "-")
}
else {
element.style.display = "none"
e.innerHTML = e.innerHTML.replace("-", "+")
}
}
function activateCategory(element) {
category_inputs[element.id] = !category_inputs[element.id]
if (category_inputs[element.id]) {
element.style.width = "155px";
element.style.boxShadow = "10px 0 " + element.style.color;
document.getElementById(element.id + "-ghost").className = "";
} else {
element.style.width = "165px";
element.style.boxShadow = "0 0";
document.getElementById(element.id + "-ghost").className = "category-ghost";
}
handleSearch(0);
}
function activateVersion(element) {
version_inputs[element.id] = !version_inputs[element.id]
if (version_inputs[element.id]) {
element.style.width = "142px";
element.style.boxShadow = "10px 0" + element.style.color;
} else {
element.style.width = "152px";
element.style.boxShadow = "0 0";
}
handleSearch(0);
}
function changeSortType(element) {
selectedType = element.options[element.selectedIndex].value;
handleSearch(0);
}
let body = document.documentElement;
let backToTop = document.getElementById("backToTop");
let currentlyLoadingExtra = false;
let currentOffset = 0;
function loadExtra() {
if (body.scrollTop > 400) {
backToTop.style.display = "block";
} else {
backToTop.style.display = "none";
}
if(!currentlyLoadingExtra) {
let scrollOffset = (body.scrollTop) / (body.scrollHeight - body.clientHeight);
if(scrollOffset > 0.9) {
currentOffset += 10;
handleSearch(currentOffset);
currentlyLoadingExtra = true;
}
}
}
function handleSearch(index) {
let queryString = "search";
if(input.value.length > 0) {
queryString += "?q=" + encodeURIComponent(input.value).replace(/%20/g,'+');
}
let filterString = "";
let versionString = "";
for (let key in category_inputs) {
if (category_inputs.hasOwnProperty(key)) {
if(category_inputs[key])
filterString += key + " AND keywords=";
}
}
let filterTakeOffLength = " AND keywords=".length;
if(filterString.length > filterTakeOffLength) {
filterString = filterString.substring(0, filterString.length - filterTakeOffLength)
queryString += "&f=" + encodeURIComponent( "keywords=" + filterString).replace(/%20/g,'+');
}
for (let key in version_inputs)
if (version_inputs.hasOwnProperty(key))
if(version_inputs[key])
versionString += key + " OR versions=";
let versionTakeOffLength = " OR versions=".length;
if(versionString.length > versionTakeOffLength) {
versionString = versionString.substring(0, versionString.length - versionTakeOffLength)
queryString += "&v=" + encodeURIComponent( "versions=" + versionString).replace(/%20/g,'+');
}
if(selectedType)
queryString += "&s=" + encodeURIComponent(selectedType).replace(/%20/g,'+');
if(!queryString.includes("?"))
queryString = queryString.replace("&", "?")
if(index === 0) {
let viewString = queryString;
viewString = viewString.replace("?q={}{}{}", "");
viewString = viewString.replace("&s=relevance", "");
if(!viewString.includes("?"))
viewString = viewString.replace("&", "?")
window.history.pushState('Search', 'Search', viewString);
}
else
queryString += "&o=" + index;
let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
if(index === 0) {
resultContainer.innerHTML = xmlHttp.responseText;
currentOffset = 0;
currentlyLoadingExtra = false;
}
else {
resultContainer.innerHTML += xmlHttp.responseText;
currentlyLoadingExtra = false;
}
}
}
xmlHttp.open("POST", queryString, true);
xmlHttp.send(null);
}

View File

@ -1,12 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Main Page</title>
</head>
<body>
<h1>Staging</h1>
<p>This is the guavy staging server!</p>
</body>
</html>

View File

@ -1,90 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/static/css/normalize.css" rel="stylesheet" type="text/css">
<link href="/static/css/main.css" rel="stylesheet" type="text/css">
<link href="/static/css/create-mod.css" rel="stylesheet" type="text/css">
<title>Create Mod</title>
</head>
<body>
<header class="site-header">
<div class="temp-circle-logo"></div>
<h2>Staging</h2>
<div class="links-container">
<a href="home">home</a>
<a href="mods">mods</a>
<a href="modpacks">modpacks</a>
<a href="about">about</a>
</div>
</header>
<div class="creation-main">
<progress max="5" value="1" class="creation-progress-bar"></progress>
<div class="creation-parts-header">
<a class="creation-parts-header-active" id="info-header">Info</a>
<a id="files-header">Files</a>
<a id="monetization-header">Monetization</a>
<a id="interaction-header">Interaction</a>
<a id="review-header">Review</a>
</div>
<div class="creation-parts">
<div class="creation-part base-info" id="info">
<div class="info-display">
<img src="..." class="mod-icon" width="250" height="250">
<div class="info-display-inputs">
<label>
Name:
<input type="text">
</label>
<label>
Description:
<input type="text">
</label>
<label>
Icon:
<input type="file">
</label>
</div>
</div>
<div class="info-body">
<label>
Body:
<textarea></textarea>
</label>
</div>
<div class="button-container">
<a class="discard-button">Discard</a>
<a class="draft-button">Save as Draft</a>
<a class="next-button">Next</a>
</div>
</div>
<div class="creation-part base-files" id="files">
</div>
<div class="creation-part base-monetization" id="monetization">
</div>
<div class="creation-part base-interaction" id="interaction">
</div>
<div class="creation-part base-integrations" id="integrations">
</div>
<div class="creation-part base-review" id="review">
</div>
</div>
</div>
</body>
</html>

View File

@ -1,240 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/static/css/normalize.css" rel="stylesheet" type="text/css">
<link href="/static/css/main.css" rel="stylesheet" type="text/css">
<link href="/static/css/mod.css" rel="stylesheet" type="text/css">
<link href="/static/css/solarized-dark.css" rel="stylesheet" type="text/css">
<title>Search</title>
</head>
<body>
<header class="site-header">
<div class="temp-circle-logo"></div>
<h2>Staging</h2>
<div class="links-container">
<a href="home">home</a>
<a href="mods">mods</a>
<a href="modpacks">modpacks</a>
<a href="about">about</a>
</div>
</header>
<div class="main-flex">
<div class="main-content">
<div class="mod-navigation">
<a class="navigation-pointer" href="mods">Mods</a>
<p>></p>
<a class="navigation-text" href="">Mod Name</a>
<a class="navigation-follow" href="">
<img src="/static/images/icon/follow.svg" alt="follow">
Follow
</a>
</div>
<div class="mod-header rounded-border gray-border">
<img class="mod-icon" src="...">
<div class="mod-title">
<h2 class="mod-title-text">Mod Name</h2>
<p class="mod-title-text">Blah blah blah bla hblahb lahb lahblah blahbl ahbla h blah blahblahb ahblahbl ahbla hblah </p>
</div>
</div>
<div class="mod-bar">
<a class="mod-bar-active mod-bar-href" onclick="toggleSection(this)" id="description-bar">Description</a>
<a class="mod-bar-href" onclick="toggleSection(this)" id="files-bar">Files</a>
<a class="mod-bar-href" onclick="toggleSection(this)" id="api-bar">API</a>
<a class="mod-bar-href" href="https://github.com/Geometrically/fabricate">Source</a>
<a class="mod-bar-href" href="https://github.com/Geometrically/fabricate/wiki">Wiki</a>
<a class="mod-bar-href" href="https://github.com/Geometrically/fabricate/issues">Issues</a>
</div>
<div class="mod-main mod-show" id="description">
<div class="mod-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed dignissim, lorem eget maximus cursus, quam est pellentesque leo, quis vulputate ante tellus et lacus. Vestibulum hendrerit finibus gravida. Nulla vitae faucibus massa. Nunc posuere ornare urna ut ultricies. Morbi a velit vestibulum, pulvinar massa nec, rhoncus tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu ante augue. Morbi nunc libero, ultrices vitae est nec, elementum blandit mauris. Aliquam venenatis faucibus massa in lobortis. Nunc tincidunt lectus in ultrices ultricies. Ut consectetur orci at ligula fringilla dapibus. Praesent porta, neque ut bibendum luctus, diam nibh auctor diam, eu condimentum enim nisi id erat. Nullam fringilla aliquam nulla sed lobortis. Sed ex neque, ultricies nec suscipit nec, aliquet ac mi. Aenean ut ultrices augue. Mauris ut sapien non arcu congue dapibus. Ut ornare ante odio, a rhoncus enim dignissim in. Vestibulum aliquet maximus nisi. Etiam fermentum velit quam, vitae molestie leo consequat malesuada. Vivamus felis nulla, egestas vitae efficitur in, vehicula eu ante. Nunc semper eu nibh sit amet iaculis. Proin eu finibus sapien, a luctus ante. Ut in congue massa. Cras malesuada magna est, id fringilla arcu tempor et. Proin fringilla orci ut tincidunt dictum. Nunc sodales ac urna sit amet fringilla. Donec eget dictum neque. Maecenas maximus libero sem, et lobortis diam imperdiet a. In ultrices quis massa id rutrum. Proin sit amet ex quis diam dapibus interdum vel a turpis. Cras elit ligula, bibendum id lacus id, feugiat mattis arcu. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras elit libero, porttitor eu blandit quis, elementum eget massa. Duis ac quam in neque feugiat egestas. Quisque blandit libero nisl, non convallis neque vestibulum quis. Donec vitae malesuada erat, sed faucibus diam. Duis fringilla eros elit, a pulvinar lacus malesuada feugiat. Integer ac hendrerit arcu. Phasellus quis eros faucibus metus blandit volutpat. Curabitur auctor iaculis leo sit amet tincidunt. Nam odio urna, rutrum non sodales sit amet, euismod at justo. Quisque pharetra ipsum sed sollicitudin pulvinar. Aenean eget cursus tellus, et convallis nisi. Maecenas malesuada lobortis condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nulla convallis orci magna, quis gravida purus aliquet sit amet. Pellentesque fringilla at nulla sit amet mollis. Cras euismod lorem non justo rhoncus, ut euismod urna egestas. Etiam luctus id lacus ut eleifend. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Cras eget lectus at lacus hendrerit gravida non vitae ipsum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed finibus tincidunt porta. Phasellus fringilla pulvinar pharetra. Praesent tristique mauris metus, vitae pellentesque est vestibulum id. Phasellus vitae nisi in nibh vehicula varius id hendrerit erat. Mauris tempus lorem eu nulla viverra facilisis. Phasellus posuere dui nunc, sit amet consectetur lacus scelerisque maximus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed dignissim, lorem eget maximus cursus, quam est pellentesque leo, quis vulputate ante tellus et lacus. Vestibulum hendrerit finibus gravida. Nulla vitae faucibus massa. Nunc posuere ornare urna ut ultricies. Morbi a velit vestibulum, pulvinar massa nec, rhoncus tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu ante augue. Morbi nunc libero, ultrices vitae est nec, elementum blandit mauris. Aliquam venenatis faucibus massa in lobortis. Nunc tincidunt lectus in ultrices ultricies. Ut consectetur orci at ligula fringilla dapibus. Praesent porta, neque ut bibendum luctus, diam nibh auctor diam, eu condimentum enim nisi id erat. Nullam fringilla aliquam nulla sed lobortis. Sed ex neque, ultricies nec suscipit nec, aliquet ac mi. Aenean ut ultrices augue. Mauris ut sapien non arcu congue dapibus. Ut ornare ante odio, a rhoncus enim dignissim in. Vestibulum aliquet maximus nisi. Etiam fermentum velit quam, vitae molestie leo consequat malesuada. Vivamus felis nulla, egestas vitae efficitur in, vehicula eu ante. Nunc semper eu nibh sit amet iaculis. Proin eu finibus sapien, a luctus ante. Ut in congue massa. Cras malesuada magna est, id fringilla arcu tempor et. Proin fringilla orci ut tincidunt dictum. Nunc sodales ac urna sit amet fringilla. Donec eget dictum neque. Maecenas maximus libero sem, et lobortis diam imperdiet a. In ultrices quis massa id rutrum. Proin sit amet ex quis diam dapibus interdum vel a turpis. Cras elit ligula, bibendum id lacus id, feugiat mattis arcu. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras elit libero, porttitor eu blandit quis, elementum eget massa. Duis ac quam in neque feugiat egestas. Quisque blandit libero nisl, non convallis neque vestibulum quis. Donec vitae malesuada erat, sed faucibus diam. Duis fringilla eros elit, a pulvinar lacus malesuada feugiat. Integer ac hendrerit arcu. Phasellus quis eros faucibus metus blandit volutpat. Curabitur auctor iaculis leo sit amet tincidunt. Nam odio urna, rutrum non sodales sit amet, euismod at justo. Quisque pharetra ipsum sed sollicitudin pulvinar. Aenean eget cursus tellus, et convallis nisi. Maecenas malesuada lobortis condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nulla convallis orci magna, quis gravida purus aliquet sit amet. Pellentesque fringilla at nulla sit amet mollis. Cras euismod lorem non justo rhoncus, ut euismod urna egestas. Etiam luctus id lacus ut eleifend. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Cras eget lectus at lacus hendrerit gravida non vitae ipsum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed finibus tincidunt porta. Phasellus fringilla pulvinar pharetra. Praesent tristique mauris metus, vitae pellentesque est vestibulum id. Phasellus vitae nisi in nibh vehicula varius id hendrerit erat. Mauris tempus lorem eu nulla viverra facilisis. Phasellus posuere dui nunc, sit amet consectetur lacus scelerisque maximus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed dignissim, lorem eget maximus cursus, quam est pellentesque leo, quis vulputate ante tellus et lacus. Vestibulum hendrerit finibus gravida. Nulla vitae faucibus massa. Nunc posuere ornare urna ut ultricies. Morbi a velit vestibulum, pulvinar massa nec, rhoncus tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu ante augue. Morbi nunc libero, ultrices vitae est nec, elementum blandit mauris. Aliquam venenatis faucibus massa in lobortis. Nunc tincidunt lectus in ultrices ultricies. Ut consectetur orci at ligula fringilla dapibus. Praesent porta, neque ut bibendum luctus, diam nibh auctor diam, eu condimentum enim nisi id erat. Nullam fringilla aliquam nulla sed lobortis. Sed ex neque, ultricies nec suscipit nec, aliquet ac mi. Aenean ut ultrices augue. Mauris ut sapien non arcu congue dapibus. Ut ornare ante odio, a rhoncus enim dignissim in. Vestibulum aliquet maximus nisi. Etiam fermentum velit quam, vitae molestie leo consequat malesuada. Vivamus felis nulla, egestas vitae efficitur in, vehicula eu ante. Nunc semper eu nibh sit amet iaculis. Proin eu finibus sapien, a luctus ante. Ut in congue massa. Cras malesuada magna est, id fringilla arcu tempor et. Proin fringilla orci ut tincidunt dictum. Nunc sodales ac urna sit amet fringilla. Donec eget dictum neque. Maecenas maximus libero sem, et lobortis diam imperdiet a. In ultrices quis massa id rutrum. Proin sit amet ex quis diam dapibus interdum vel a turpis. Cras elit ligula, bibendum id lacus id, feugiat mattis arcu. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras elit libero, porttitor eu blandit quis, elementum eget massa. Duis ac quam in neque feugiat egestas. Quisque blandit libero nisl, non convallis neque vestibulum quis. Donec vitae malesuada erat, sed faucibus diam. Duis fringilla eros elit, a pulvinar lacus malesuada feugiat. Integer ac hendrerit arcu. Phasellus quis eros faucibus metus blandit volutpat. Curabitur auctor iaculis leo sit amet tincidunt. Nam odio urna, rutrum non sodales sit amet, euismod at justo. Quisque pharetra ipsum sed sollicitudin pulvinar. Aenean eget cursus tellus, et convallis nisi. Maecenas malesuada lobortis condimentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nulla convallis orci magna, quis gravida purus aliquet sit amet. Pellentesque fringilla at nulla sit amet mollis. Cras euismod lorem non justo rhoncus, ut euismod urna egestas. Etiam luctus id lacus ut eleifend. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Cras eget lectus at lacus hendrerit gravida non vitae ipsum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed finibus tincidunt porta. Phasellus fringilla pulvinar pharetra. Praesent tristique mauris metus, vitae pellentesque est vestibulum id. Phasellus vitae nisi in nibh vehicula varius id hendrerit erat. Mauris tempus lorem eu nulla viverra facilisis. Phasellus posuere dui nunc, sit amet consectetur lacus scelerisque maximus.
</div>
<div class="mod-reviews">
<div class="review">
<div class="stars">
<img class="star" src="/static/images/icon/">
</div>
</div>
</div>
</div>
<div class="files mod-hide" id="files">
<div class="files-search">
<input class="files-search-bar" type="text" id="files-search" placeholder="Search for files..." oninput="handleFilesSearch()">
<select name="versions" class="files-versions" id="files-versions">
<option value="1.15.2">1.15.2</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</div>
</div>
<div class="api mod-hide" id="api">
<div class="api-container">
<div class="api-code-ref">
<h2>Maven</h2>
<p>This project has an API accessible from maven. You can add it to your project using the artifact below.</p>
<div class="api-code-blocks">
<div class="code-block-navigation">
<a class="mod-bar-href mod-bar-active" onclick="toggleBuildSection(this)" id="gradle-code-bar">Gradle</a>
<a class="mod-bar-href" onclick="toggleBuildSection(this)" id="maven-code-bar">Maven</a>
</div>
<pre class="api-code-block gradle mod-show" id="gradle-code">
repositories {
maven {
url "https://cdn.sitename.com/maven"
}
}
dependencies {
modApi "anime.sucks:balls:1.0"
}
</pre>
<pre class="api-code-block mod-hide" id="maven-code">
&lt;dependency&gt;
&lt;groupId&gt;anime.sucks&lt;/groupId&gt;
&lt;artifactId&gt;balls&lt;/artifactId&gt;
&lt;version&gt;1.0&lt;/version&gt;
&lt;/dependency&gt;
</pre>
</div>
</div>
<div class="api-code-ref">
<h2>Website API</h2>
<p>All projects and project files can be pulled using our REST API. You can pull this project's information using the code snippets below.</p>
<div class="api-code-blocks">
<div class="code-block-navigation">
<a class="mod-bar-href mod-bar-active" onclick="toggleApiSection(this)" id="curl-code-bar">cURL</a>
<a class="mod-bar-href" onclick="toggleApiSection(this)" id="js-code-bar">JS</a>
</div>
<pre class="api-code-block extra-top mod-show shell" id="curl-code">
$ curl -XGET -H "Content-type: application/json" 'http://api.sitename.com/mod/testmod'
</pre>
<pre class="api-code-block extra-top mod-hide javascript" id="js-code">
let httpClient = TooLazyToMakeWorkingCode();
httpClient.request('http://api.sitename.com/mod/testmod');
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sidebar">
<input class="search-bar" type="text" id="search-input" placeholder="Search for mods..." oninput="handleSearch()">
<div class="mod-sidebar rounded-border gray-border">
<div class="mod-info sidebar-entry">
<div class="sidebar-info">
<img src="/static/images/icon/information.svg" class="sidebar-img" alt="Donate">
<h3>Information</h3>
</div>
<div class="mod-info-entry">
<img src="/static/images/icon/download.svg" alt="Downloads" >
<p>1,292,112</p>
</div>
<div class="mod-info-entry">
<img src="/static/images/icon/followers.svg" alt="Followers" >
<p>2391</p>
</div>
<div class="mod-info-entry">
<img src="/static/images/icon/created.svg" alt="Created" >
<p>1/2/2020</p>
</div>
<div class="mod-info-entry">
<img src="/static/images/icon/updated.svg" alt="Updated" >
<p>5/4/2020</p>
</div>
</div>
<div class="sidebar-line"></div>
<div class="sidebar-entry">
<div class="sidebar-info">
<img src="/static/images/icon/curated.svg" class="sidebar-img" alt="Curated">
<h3>Downloads</h3>
</div>
<a class="download-primary download">v2.1.14 for Minecraft 1.15.2</a>
<a class="download-normal download">v2.0.8 for Minecraft 1.14.4</a>
</div>
<div class="sidebar-line"></div>
<div class="categories-info sidebar-entry">
<div class="sidebar-info">
<img src="/static/images/icon/category.svg" class="sidebar-img" alt="Donate">
<h3>Categories</h3>
</div>
<div class="categories">
<img alt="adventure" src="/static/images/icon/adventure.svg"/>
<img alt="magic" src="/static/images/icon/magic.svg"/>
<img alt="library" src="/static/images/icon/library.svg" class="result-image"/>
</div>
</div>
<div class="sidebar-line"></div>
<div class="member-info sidebar-entry">
<div class="sidebar-info">
<img src="/static/images/icon/contributor.svg" class="sidebar-img" alt="Donate">
<h3>Contributors</h3>
</div>
<div class="contributor-card rounded-border gray-border">
<img src="/static/images/icon/cursed.png" alt="">
<div class="contributor-card-text">
<a href="">Username</a>
<small>Role</small>
</div>
</div>
</div>
<div class="sidebar-line"></div>
<div class="donation-info sidebar-entry">
<div class="sidebar-info">
<img src="/static/images/icon/donate.svg" class="sidebar-img" alt="Donate">
<h3>Donate</h3>
</div>
<a href="" class="donation-link">
<img src="/static/images/donation/patreon.png">
</a>
<a href="" class="donation-link">
<img src="/static/images/donation/bmc-coffee.gif">
</a>
<a href="" class="donation-link">
<img src="/static/images/donation/paypal.jpg">
</a>
</div>
</div>
</div>
</div>
<script src="/static/js/main.js"></script>
<script src="/static/js/highlight.pack.js"></script>
<script src="/static/js/mod.js"></script>
</body>
</html>

View File

@ -1,128 +0,0 @@
{{#each results}}
<div class="result gray-border rounded-border">
<img src="{{this.icon_url}}" width="75px" height="75px" class="result-image"/>
<div class="result-info">
<div class="result-title">
<a class="result-name" href="{{this.page_url}}"><h2>{{this.title}}</h2></a><!--
--><span class="muted result-author-container">by <a class="result-author" href="{{this.author_url}}">{{this.author}}</a></span>
</div>
<p>{{this.description}}</p>
<div class="mod-info">
<span class="mod-downloads" title="Downloads">
<svg><use xlink:href="/static/images/icon/spritesheet.svg#download"/></svg><!--
-->{{format this.downloads}}
</span>
<span class="mod-created" title="Created">
<svg><use xlink:href="/static/images/icon/spritesheet.svg#created"/></svg><!--
-->{{this.date_created}}
</span>
<span class="mod-updated" title="Last Updated">
<svg><use xlink:href="/static/images/icon/spritesheet.svg#updated"/></svg><!--
-->{{this.date_modified}}
</span>
<span class="mod-version" title="Version">
<svg><use xlink:href="/static/images/icon/spritesheet.svg#version"/></svg><!--
-->{{this.latest_version}}
</span>
<div class="loader-icons">
{{#contains this.keywords "forge"}}
<div class="loader-forge" title="Forge">
<svg class="forge" viewbox="0 0 120 66.7"><use href="#forge" xlink:href="#forge"/></svg>
</div>
{{/contains}}
{{#contains this.keywords "fabric"}}
<div class="loader-fabric" title="Fabric">
<img alt="fabric" src="/static/images/icon/fabric.png"/>
</div>
{{/contains}}
</div>
</div>
</div>
<div class="result-badges">
{{#contains this.keywords "technology"}}
<div class="tech-badge result-badge" title="Tech">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#tech"/></svg>
<p>TECH</p>
</div>
{{/contains}}
{{#contains this.keywords "adventure"}}
<div class="adventure-badge result-badge" title="Adventure">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#adventure"/></svg>
<p>ADVENTURE</p>
</div>
{{/contains}}
{{#contains this.keywords "magic"}}
<div class="magic-badge result-badge" title="Magic">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#magic"/></svg>
<p>MAGIC</p>
</div>
{{/contains}}
{{#contains this.keywords "utility"}}
<div class="utility-badge result-badge" title="Utility">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#util"/></svg>
<p>UTILITY</p>
</div>
{{/contains}}
{{#contains this.keywords "decoration"}}
<div class="decoration-badge result-badge" title="Decoration">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#decoration"/></svg>
<p>DECORATION</p>
</div>
{{/contains}}
{{#contains this.keywords "library"}}
<div class="library-badge result-badge" title="Library">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#library"/></svg>
<p>LIBRARY</p>
</div>
{{/contains}}
{{#contains this.keywords "worldgen"}}
<div class="world-badge result-badge" title="Worldgen">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#world"/></svg>
<p>WORLDGEN</p>
</div>
{{/contains}}
{{#contains this.keywords "cursed"}}
<div class="cursed-badge result-badge" title="Cursed">
<img alt="cursed" src="/static/images/icon/cursed.png" class="badge-image"/>
<p>CURSED</p>
</div>
{{/contains}}
{{#contains this.keywords "storage"}}
<div class="storage-badge result-badge" title="Storage">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#storage"/></svg>
<p>STORAGE</p>
</div>
{{/contains}}
{{#contains this.keywords "food"}}
<div class="food-badge result-badge" title="Food">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#food"/></svg>
<p>FOOD</p>
</div>
{{/contains}}
{{#contains this.keywords "equipment"}}
<div class="equipment-badge result-badge" title="Equipment">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#equipment"/></svg>
<p>EQUIPMENT</p>
</div>
{{/contains}}
{{#contains this.keywords "misc"}}
<div class="misc-badge result-badge" title="Misc">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#misc"/></svg>
<p>MISC</p>
</div>
{{/contains}}
</div>
</div>
{{else}}
<div class="search-error">
{{#if ../query.q}}
<h2>No results found for query <code>"{{../query.q}}"</code></h2>
{{else}}
<h2>No results found</h2>
{{/if}}
</div>
{{/each}}

View File

@ -1,176 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="/static/js/main.js"></script>
<link href="/static/css/main.css" rel="stylesheet" type="text/css">
<link href="/static/css/search.css" rel="stylesheet" type="text/css">
<link href="/static/css/normalize.css" rel="stylesheet" type="text/css">
<link rel="dns-prefetch" href="//media.forgecdn.net">
<title>Search</title>
</head>
<body onscroll="loadExtra()">
<header class="site-header">
<div class="temp-circle-logo"></div>
<h2>Staging</h2>
<div class="links-container">
<a href="home">home</a>
<a href="mods">mods</a>
<a href="modpacks">modpacks</a>
<a href="about">about</a>
<input type="checkbox" onchange="switchThemes()">
</div>
</header>
<svg display="none">
<symbol viewBox="0 0 120 66.7" id="forge">
<path d="M91.6,16.7l-37.8-1.9l46.2,0v-3.7H47.8l0,7.8v6.2c0,0.1-1.5-9.1-1.9-11.7h-4.1v6.8v6.2
c0,0.1-1.8-10.9-1.9-12.3c-10.4,0-27.9,0-27.9,0c1.9,1.6,12.4,10.6,19.9,14.3c3.7,1.8,8.3,1.9,12.4,2c2.1,0.1,4.2,0.2,5.8,1.8
c2.3,2.2,2.8,5.7,0.8,8.3c-1.9,2.6-7.3,3.2-7.3,3.2L39,49.1v6.4h10.3l0.3-6.3l8.9-6.3c-0.9,0.8-3.1,2.8-6.2,7.7
c-0.7,1.1-1.3,2.3-1.7,3.5c2.2-1.9,6.8-3.2,12.2-3.2c5.3,0,9.9,1.3,12.1,3.2c-0.4-1.2-1-2.4-1.7-3.5c-3.2-4.9-5.3-6.9-6.2-7.7
l8.9,6.3l0.3,6.3h9.6v-6.4l-4.5-5.5c0,0-6.7-0.4-8.4-3.2C67.7,32.6,74.8,20.4,91.6,16.7z"/>
</symbol>
</svg>
<a href="#" class="back-to-top" id="backToTop">
<img src="/static/images/icon/up.svg" alt="up">
</a>
<div class="info-popup">
<h3>Welcome to Fabricate Staging!</h3>
<p>Fabricate is a work-in progress mod distribution platform that has full backwards compatibility with curseforge! Please keep in mind that we are in early beta so not everything works.</p>
<small>made possible by our contributors</small>
<a class="discord-button" href="https://discord.gg/JRMJpRX">Discord</a>
<a class="github-button" href="https://github.com/Geometrically/fabricate">GitHub</a>
<a onclick="closePopup(this)" class="exit-button">Close</a>
</div>
<div class="main-flex">
<div class="left-flex">
<div class="filters">
<select id="filters" onchange="changeSortType(this)">
<option value="relevance" selected="selected">Relevance</option>
<option value="downloads">Total Downloads</option>
<option value="updated">Last Updated</option>
<option value="newest">Newest</option>
</select>
</div>
<div class="categories">
<a class="categories-label category-badge category-active">
<p>Categories</p>
</a>
<a class="tech-badge category-badge category-active" id="technology" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#tech"/></svg>
<p>TECH</p>
</a>
<a class="adventure-badge category-badge" id="adventure" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#adventure"/></svg>
<p>ADVENTURE</p>
</a>
<a class="magic-badge category-badge" id="magic" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#magic"/></svg>
<p>MAGIC</p>
</a>
<a class="utility-badge category-badge" id="utility" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#util"/></svg>
<p>UTILITY</p>
</a>
<a class="decoration-badge category-badge" id="decoration" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#decoration"/></svg>
<p>DECORATION</p>
</a>
<a class="library-badge category-badge" id="library" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#library"/></svg>
<p>LIBRARY</p>
</a>
<a class="world-badge category-badge" id="worldgen" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#world"/></svg>
<p>WORLDGEN</p>
</a>
<a class="cursed-badge category-badge" id="cursed" onclick="activateCategory(this)">
<img alt="cursed" src="/static/images/icon/cursed.png" class="badge-image"/>
<p>CURSED</p>
</a>
<a class="storage-badge category-badge" id="storage" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#storage"/></svg>
<p>STORAGE</p>
</a>
<a class="food-badge category-badge" id="food" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#food"/></svg>
<p>FOOD</p>
</a>
<a class="equipment-badge category-badge" id="equipment" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#equipment"/></svg>
<p>EQUIPMENT</p>
</a>
<a class="misc-badge category-badge" id="misc" onclick="activateCategory(this)">
<svg class="badge-image"><use xlink:href="/static/images/icon/spritesheet.svg#misc"/></svg>
<p>MISC</p>
</a>
</div>
<div class="categories">
<a class="categories-label category-badge category-active">
<p>Loaders</p>
</a>
<a class="forge-badge category-badge" id="forge-icon" onclick="activateCategory(this)">
<svg class="forge" viewBox="0 0 90 46"><use xlink:href="/static/images/icon/spritesheet.svg#forge-alt" /></svg>
<p>FORGE</p>
</a>
<a class="fabric-badge category-badge" id="fabric-icon" onclick="activateCategory(this)">
<img alt="fabric" src="/static/images/icon/fabric.png" class="badge-image"/>
<p>FABRIC</p>
</a>
</div>
</div>
<div class="search-main">
<div class="search-div">
<input class="search-bar" type="text" id="search-input" placeholder="Search for mods..." oninput="handleSearch(0)">
</div>
<div id="results" class="results">
{{> search-results}}
</div>
</div>
<div class="versions">
<button type="button" class="clear-button" onclick="clearFilters()">Clear Filters</button>
<div class="version-type">
<p class="version-type-label" onclick="toggleVisibility(this)">[+] Releases</p>
<div class="version-scroll" id="releases" style="display: none">
</div>
</div> <script src="/static/js/main.js"></script>
<div class="version-type">
<p class="version-type-label" onclick="toggleVisibility(this)">[+] Snapshots</p>
<div class="version-scroll" id="snapshots" style="display: none">
</div>
</div>
<div class="version-type">
<p class="version-type-label" onclick="toggleVisibility(this)">[+] Archaic</p>
<div class="version-scroll" id="archaic" style="display: none">
</div>
</div>
</div>
</div>
<script src="/static/js/search.js"></script>
</body>
</html>