Migration to Django

This commit is contained in:
Mechseroms 2025-12-13 10:23:28 -06:00
parent 1d0a2b5fdf
commit 82487a417c
50 changed files with 37693 additions and 806 deletions

View File

@ -0,0 +1,22 @@
---
applyTo: '**'
---
# User Memory for Lessons & Guidance
- **Primary rule:** Guide the user to code and learn on their own; never just do, always explain and teach.
- **Learning path:** User migrated from Flask (minimal web server) to Django (full-featured framework) and prefers learning by doing.
- **Technical background:**
- Familiarity with virtualenv and has adapted fish shell activation (uses `source venv/bin/activate.fish`).
- Installed Django (ver. 6.0) in a venv and started a new project (`lisiumsite`) in-place.
- Created a Django app called `main`.
- Explored and understood Django project vs app structure; compared to Flask blueprints.
- Built and routed the first Django view, corrected import mixups (urls/path).
- Created (and fixed discovery of) a Django template, learning that apps must be listed in `INSTALLED_APPS` for templates/models/admin to work.
- Debugged template location and settings issues, solidifying how Django finds resources.
- **Learning style:**
- Wants to understand errors and adapt, not just copy fixes.
- Prefers step-wise, hands-on lessons with context and why explanations.
- **Next desired topics:**
- Dynamic data in templates, Django ORM/models, Django admin, or migration of existing features.
- Wants lesson continuity: future guidance should reference this journey so far, reviewing key learnings and next best steps for deeper Django mastery.

View File

@ -1,24 +1,28 @@
# AGENTS.md: Agent Guidelines # AGENTS.md: Guidelines for Agent Coders (2025)
## Build, Lint, Test ## Build/Lint/Test
- Run entrypoint: `python main.py` - Main entry: `python main.py`
- No project-wide test/lint commands found; recommend: - No test suite found; to run a single test (if using pytest):
- Run one test: `pytest test_file.py::test_func` (if pytest added) - `pytest test_file.py::test_func`
- Lint: `flake8 .` or `pylint main.py` (if installed) - Lint (if installed): `flake8 .` or `pylint main.py`
- Requirements: add `requirements.txt` if using dependencies - Add to `requirements.txt` if you introduce dependencies.
- No environment or shell scripts present. - No shell/env scripts found by default.
## Code Style ## Python Code Style
- Follow [PEP8](https://pep8.org/): 4 spaces per indent, <=79 chars/line - Follow [PEP8](https://pep8.org/) (4 spaces, ≤79 chars/line)
- Use explicit imports, not wildcard imports - Import order: stdlib, third-party, project/local
- Place stdlib, 3rd party, and local imports in separate groups - Never use wildcard imports; always explicit
- Use type annotations for all public functions/parameters - Naming: snake_case for vars/functions, PascalCase for classes, UPPER_SNAKE_CASE for constants
- Snake_case for functions/vars; PascalCase for classes; UPPER_SNAKE for constants - Add type annotations and docstrings to all public APIs/classes
- Write docstrings for all public functions/classes - Handle errors with try/except; log or re-raise as needed
- Handle errors with try/except and log exception details - One statement per line; trim trailing whitespace
- One statement per line; no trailing whitespace - Avoid global state. Organize code into functions/classes.
- Avoid global state; prefer function/class encapsulation - Use `if __name__ == '__main__'` to guard scripts.
- Place entry code in `if __name__ == '__main__'` block
- No Cursor or Copilot rules/configs detected
_Update this document if configs or standards are added later._ - No Cursor/.Copilot rules found (Dec 2025)
(Update as project conventions evolve)
## Custom Rules
- Ensure that you guide me to code myself and not write code that I should learn to do myself.

View File

@ -1,278 +0,0 @@
# D&D 5e Character Attributes
This document outlines all the core and expanded character attributes that should be tracked for D&D 5e gameplay. Attributes are grouped by category, reflecting dependencies and standard D&D 5e game structure.
---
## Base Attributes (Not Derived; static unless leveled up/class change)
- @name: Character name (save)
- @level: Character level (save)
- @race: Chosen race (grants features/traits) (save)
- @subrace: Optional, for races with subtypes (save)
- @class: Chosen class (save)
- @subclass: Optional archetype/subclass (save)
- @background: Character background (e.g., Soldier, Sage) (save)
- @alignment: Law/Chaos & Good/Evil axis (save)
- @size: (e.g., Medium, Small) (save)
- @age: Character's age (save)
- @gender: Gender identity (save)
- @height: Physical height (save)
- @weight: Physical weight (save)
- @deity: (optional) (save)
---
## Core Abilities (Derived, Priority 1—calculate first)
### Base Scores
- @strength::base (save)
- @dexterity::base (save)
- @constitution::base (save)
- @intelligence::base (save)
- @wisdom::base (save)
- @charisma::base (save)
- @armor::base (save if you allow a base AC override, else derived)
### Effective Scores (after modifiers, racial/class bonuses, etc.)
- @strength (derived)
- @dexterity (derived)
- @constitution (derived)
- @intelligence (derived)
- @wisdom (derived)
- @charisma (derived)
- @armor (derived; unless house rule for persistent AC overrides)
### Modifiers
- @strength::modifier (derived)
- @dexterity::modifier (derived)
- @constitution::modifier (derived)
- @intelligence::modifier (derived)
- @wisdom::modifier (derived)
- @charisma::modifier (derived)
### General
- @proficiency: Proficiency bonus (derived from level)
- @inspiration: Boolean (True/False) (save)
- @experience: XP points (save)
---
## Proficiencies & Languages
- @proficiencies::armor (save)
- @proficiencies::weapons (save)
- @proficiencies::tools (save)
- @languages (save)
---
## Saving Throws (Priority 2)
- @strength_save (derived)
- @dexterity_save (derived)
- @constitution_save (derived)
- @intelligence_save (derived)
- @wisdom_save (derived)
- @charisma_save (derived)
---
## HP, Initiative, Related (Priority 2)
- @hp (current) (save, often derived on session start)
- @hp_max (derived)
- @hp_temp (save)
- @hit_die (e.g., d8, d10; and total available) (save)
- @initiative (includes initiative modifier) (derived)
- @armor (effective AC) (derived)
### Death Saves
- @deathsaves::successes (save; reset between combats/long rests)
- @deathsaves::failures (save; reset between combats/long rests)
---
## Resistances & Immunities (Priority 2)
- @fire_resistance (derived from features, else save if affected in play)
- @poison_resistance (derived)
- @psychic_resistance (derived)
- @cold_resistance (derived)
- @thunder_resistance (derived)
- @acid_resistance (derived)
- @force_resistance (derived)
- @radiant_resistance (derived)
- @necrotic_resistance (derived)
- @bludgeoning_resistance (derived)
- @piercing_resistance (derived)
- @slashing_resistance (derived)
- ... (more as needed) (derived)
- @immunities (list) (save if gained or lost in play; else derived)
- @vulnerabilities (list) (save if gained or lost in play; else derived)
---
## Senses & Mobility (Priority 2)
- @speed::base (save)
- @speed::type (save)
- @darkvision (derived, unless modified at runtime; else save)
- @blindsight (derived)
- @tremorsense (derived)
- @truesight (derived)
- @passive_perception (derived)
---
## Skills (Priority 2)
#### Strength
- @athletics (derived)
#### Dexterity
- @acrobatics (derived)
- @sleight_of_hand (derived)
- @stealth (derived)
#### Intelligence
- @arcana (derived)
- @history (derived)
- @investigation (derived)
- @nature (derived)
- @religion (derived)
#### Wisdom
- @animal_handling (derived)
- @insight (derived)
- @medicine (derived)
- @perception (derived)
- @survival (derived)
#### Charisma
- @deception (derived)
- @intimidation (derived)
- @performance (derived)
- @persuasion (derived)
---
## Passives / Post-Derived Attributes (Priority 3)
- @athletics#passive (derived)
- @acrobatics#passive (derived)
- @sleight_of_hand#passive (derived)
- @stealth#passive (derived)
- @arcana#passive (derived)
- @history#passive (derived)
- @investigation#passive (derived)
- @nature#passive (derived)
- @religion#passive (derived)
- @animal_handling#passive (derived)
- @insight#passive (derived)
- @medicine#passive (derived)
- @perception#passive (derived)
- @survival#passive (derived)
- @deception#passive (derived)
- @intimidation#passive (derived)
- @performance#passive (derived)
- @persuasion#passive (derived)
- @passive_perception (derived)
- @passive_investigation (derived)
- @passive_insight (derived)
---
## Spellcasting (if applicable)
- @spellcasting_ability (e.g., Intelligence) (save)
- @spell_save_dc (derived)
- @spell_attack_bonus (derived)
- @known_spells (list) (save)
- @prepared_spells (if required) (save)
- @spell_slots (level-indexed: e.g., 1st:2, 2nd:1) (save; because depleted/used in play)
- @cantrips (list) (save)
- @spellcasting_class (save)
---
## Condition Tracking
- @exhaustion_level (save)
- @conditions_active (list; e.g., blinded, charmed, frightened, etc.) (save)
---
## Currency & Inventory
- @cp (copper) (save)
- @sp (silver) (save)
- @ep (electrum) (save)
- @gp (gold) (save)
- @pp (platinum) (save)
- @equipment (list or structured) (save)
---
## Features & Traits
- @features (class, race, background features—list) (save; usually as UUIDs/IDs, never as a derived calculation)
- @traits (racial, personality, ideals, bonds, flaws) (save, if you want to store narrative/roleplay traits)
- @personality_traits (save)
- @ideals (save)
- @bonds (save)
- @flaws (save)
---
## Others & Miscellaneous
- @notes (free text) (save)
- @custom_attributes (dict or list) (save)
---
## Recommended Attribute Application & Calculation Order in D&D 5e
When building or advancing a character, the order in which features (including class, race, background, feats, etc.) are applied is critically important for mathematically correct results. Heres the optimal order to apply these steps in any automated or manual pipeline:
### 1. Base Values
- Start with all attributes at their neutral defaults (from template.json or your starting schema).
- Set character-level information (`name`, `race`, `class`, `background`, etc.) and ability base scores (from point array/rolled stats).
### 2. Apply Racial and Background Features
- Apply all racial and background features and their effects (most commonly ability score increases (ASIs), senses, languages, and a few resistances or proficiencies).
- All static bonuses to scores or proficiencies from race/subrace and background get merged in.
### 3. Apply Class and Subclass Features
- Apply features from main class and subclass (including ASIs offered at certain levels via class progression, class proficiencies, and hit die type, etc).
- Ensure proficiency bonus and proficiency-lists are now set, as they affect saving throws, skills, and attacks.
### 4. Apply Feats and Optional Features
- Add in features/feats selected by the player (such as additional ASIs, new proficiencies, special rules, etc.).
- Apply any miscellaneous or homebrew features/effects here.
### 5. Calculate Derived and Secondary Stats
- Now that all bonuses are applied:
- Calculate modifiers for abilities (e.g., `modifier = floor((score - 10) / 2)`).
- Recompute max HP, initiative, AC, proficiency bonus, and other directly derived stats.
- Compute saving throws using the base stat modifier and proficiency if relevant.
### 6. Calculate Skills
- Compute each skill (e.g., `athletics`, `perception`) using the appropriate stat modifier(s) and proficiency bonus if applicable.
- Passive skills (e.g., `passive_perception`) are computed from active skills and modifiers — so must come after.
### 7. Final Derived/Dependent Values
- Any features or effects with logic that depends on already-calculated derived values (like “your proficiency bonus equals your Wisdom modifier,” or “your AC is 10 + Dexterity modifier + Constitution modifier”) must be applied now.
- Set final values for resistances, senses, special movement, etc.
### 8. Equipment, Spellcasting, and Other
- Add any changes or bonuses from starting equipment or attunements (if applicable).
- Spell slots, spells known, etc. should be finalized after class and subclass effects are complete.
### Order Summary Table
| Step | Key Calculation |
|----------------------------|-------------------------------------------|
| 1. Base values | Initial population, base stats set |
| 2. Race/Backgrounds | ASIs, languages, simple traits |
| 3. Class & Subclass | Class features, proficiencies, hit dice |
| 4. Feats & Optionals | Feat/modifiers, optional rules |
| 5. Derived attributes | Modifiers, HP, AC, saving throws |
| 6. Skills | Skill values, passives |
| 7. Final dependencies | Effects dependent on other derived stats |
| 8. Equipment/Spells | Inventory, spellcasting |
### Why This Order Works
- All stat boosts and proficiencies are resolved *before* using them in formulas for derived or secondary stats.
- Features that depend on other features (such as subclass features referencing class values, or feats modifying what skills are available) always work as intended.
- No recalculation is needed—just process each group in order.
---
This schema is suitable for comprehensive D&D 5e character management. Expand or contract as needed for house rules, modules, or additional systems.

View File

@ -1,149 +0,0 @@
all database files and backend code/api will be accessed in these files
The idea is that the api is set up in such a way that you can have only the backend run on the server or
the webapp can also be ran.
most cases both will be ran
### Character Attrinutes (dnd5e)
## Base Attributes
base attributes area attr that are not derived at run time. In most if not all cases
these will remain the same through the runtime process
- @name
- @level
- @race (package of feats)
- @class (package of feats)
## Derived Attributes
- @strength::base
- @dexterity::base
- @constitution::base
- @wisdom::base
- @intelligence::base
- @charisma::base
- @armor::base
(Priority 1, needs to calculate these before all other attribtues)
- @strength
- @dexterity
- @constitution
- @wisdom
- @intelligence
- @charisma
- @strength::modifier
- @dexterity::modifier
- @constitution::modifier
- @wisdom::modifier
- @intelligence::modifier
- @charisma::modifier
- @proficiency
(Priority 2, child derived attributes)
- @strength_save
- @dexterity_save
- @constitution_save
- @wisdom_save
- @intelligence_save
- @charisma_save
- @hp
- @hp_max
- @hp_temp
- @hit_die
- @initative
- @armor
- @fire_resistance
- @poison_resistance
- @psychic_resistance
- @cold_resistance
- @thunder_resistance
- @acid_resistance
- @force_resistance
- @radiant_resistance
- @necortic_resistance
- @bludgeoning_resistance
- @piercing_resistance
- @slashing_resistance
str skills
- @athletics
dex skills
- @acrobatics
- @sleight_of_hand
- @stealth
intelligence Skills
- @arcana
- @history
- @investigation
- @nature
- @religion
wisdom skills
- @animal_handling
- @insight
- @medicine
- @perception
- @survival
charisma skills
- @deception
- @intimidation
- @performance
- @persuasion
post derived attributes (Priority 3, grandchild derivatives)
str skills
- @athletics#passive
dex skills
- @acrobatics#passive
- @sleight_of_hand#passive
- @stealth#passive
intelligence Skills
- @arcana#passive
- @history#passive
- @investigation#passive
- @nature#passive
- @religion#passive
wisdom skills
- @animal_handling#passive
- @insight#passive
- @medicine#passive
- @perception#passive
- @survival#passive
charisma skills
- @deception#passive
- @intimidation#passive
- @performance#passive
- @persuasion#passive
### Databases
USERS: this database will store profile info associated with users
- user_uuid: Unique user ID (UUID)
- username: Username/display name
- password: Password (should be securely stored)
- type: User type (for future SSO integration)
- profile picture: Profile image (e.g. file path or URL)
- flags: Settings/status flags (for basic settings; future use)
CHARACTERS: this table will store basic character data but also link the characters to the user_id

View File

@ -1,201 +0,0 @@
from dataclasses import dataclass, field
from typing import List, Dict, Any, Union
@dataclass
class Effect:
attribute: str # name of attribute to change
operation: str # 'add', 'subtract', 'set', 'append'
value: Any # value to apply
def apply(self, character: 'Character'):
# Handle numeric attributes
if self.operation == 'add':
setattr(character, self.attribute, getattr(character, self.attribute) + self.value)
elif self.operation == 'subtract':
setattr(character, self.attribute, getattr(character, self.attribute) - self.value)
elif self.operation == 'set':
setattr(character, self.attribute, self.value)
elif self.operation == 'append':
current = getattr(character, self.attribute)
if isinstance(current, list):
if isinstance(self.value, list):
current.extend(self.value)
else:
current.append(self.value)
setattr(character, self.attribute, current)
else:
raise ValueError(f"Attribute '{self.attribute}' is not a list.")
else:
raise ValueError(f"Unknown operation: {self.operation}")
@dataclass
class Feature:
name: str
description: str
effects: List[Effect] = field(default_factory=list)
def apply(self, character: 'Character'):
for effect in self.effects:
effect.apply(character)
@dataclass
class Character:
name: str = ""
level: int = 0
race: str = ""
subrace: str = ""
class_: str = ""
subclass: str = ""
background: str = ""
alignment: str = ""
size: str = ""
age: int = 0
gender: str = ""
height: str = ""
weight: int = 0
deity: str = ""
strength_base: int = 0
dexterity_base: int = 0
constitution_base: int = 0
intelligence_base: int = 0
wisdom_base: int = 0
charisma_base: int = 0
armor_base: int = 0
strength: int = 0
dexterity: int = 0
constitution: int = 0
intelligence: int = 0
wisdom: int = 0
charisma: int = 0
armor: int = 0
strength_modifier: int = 0
dexterity_modifier: int = 0
constitution_modifier: int = 0
intelligence_modifier: int = 0
wisdom_modifier: int = 0
charisma_modifier: int = 0
proficiency: int = 0
inspiration: bool = False
experience: int = 0
proficiencies_armor: List[str] = field(default_factory=list)
proficiencies_weapons: List[str] = field(default_factory=list)
proficiencies_tools: List[str] = field(default_factory=list)
languages: List[str] = field(default_factory=list)
strength_save: int = 0
dexterity_save: int = 0
constitution_save: int = 0
intelligence_save: int = 0
wisdom_save: int = 0
charisma_save: int = 0
hp: int = 0
hp_max: int = 0
hp_temp: int = 0
hit_die: str = ""
initiative: int = 0
deathsaves_successes: int = 0
deathsaves_failures: int = 0
fire_resistance: bool = False
poison_resistance: bool = False
psychic_resistance: bool = False
cold_resistance: bool = False
thunder_resistance: bool = False
acid_resistance: bool = False
force_resistance: bool = False
radiant_resistance: bool = False
necrotic_resistance: bool = False
bludgeoning_resistance: bool = False
piercing_resistance: bool = False
slashing_resistance: bool = False
immunities: List[str] = field(default_factory=list)
vulnerabilities: List[str] = field(default_factory=list)
speed_base: int = 0
speed_type: List[str] = field(default_factory=list)
darkvision: int = 0
blindsight: int = 0
tremorsense: int = 0
truesight: int = 0
passive_perception: int = 0
athletics: int = 0
acrobatics: int = 0
sleight_of_hand: int = 0
stealth: int = 0
arcana: int = 0
history: int = 0
investigation: int = 0
nature: int = 0
religion: int = 0
animal_handling: int = 0
insight: int = 0
medicine: int = 0
perception: int = 0
survival: int = 0
deception: int = 0
intimidation: int = 0
performance: int = 0
persuasion: int = 0
athletics_passive: int = 0
acrobatics_passive: int = 0
sleight_of_hand_passive: int = 0
stealth_passive: int = 0
arcana_passive: int = 0
history_passive: int = 0
investigation_passive: int = 0
nature_passive: int = 0
religion_passive: int = 0
animal_handling_passive: int = 0
insight_passive: int = 0
medicine_passive: int = 0
perception_passive: int = 0
survival_passive: int = 0
deception_passive: int = 0
intimidation_passive: int = 0
performance_passive: int = 0
persuasion_passive: int = 0
passive_perception: int = 0
passive_investigation: int = 0
passive_insight: int = 0
spellcasting_ability: str = ""
spell_save_dc: int = 0
spell_attack_bonus: int = 0
known_spells: List[str] = field(default_factory=list)
prepared_spells: List[str] = field(default_factory=list)
spell_slots: Dict[str, Any] = field(default_factory=dict)
cantrips: List[str] = field(default_factory=list)
spellcasting_class: str = ""
exhaustion_level: int = 0
conditions_active: List[str] = field(default_factory=list)
cp: int = 0
sp: int = 0
ep: int = 0
gp: int = 0
pp: int = 0
equipment: List[str] = field(default_factory=list)
features: List[str] = field(default_factory=list)
traits: List[str] = field(default_factory=list)
personality_traits: List[str] = field(default_factory=list)
ideals: List[str] = field(default_factory=list)
bonds: List[str] = field(default_factory=list)
flaws: List[str] = field(default_factory=list)
notes: str = ""
custom_attributes: Dict[str, Any] = field(default_factory=dict)
def apply_features(character: Character, features: List[Feature]):
for feature in features:
feature.apply(character)

View File

@ -1,157 +0,0 @@
{
"name": "",
"level": 0,
"race": "",
"subrace": "",
"class": "",
"subclass": "",
"background": "",
"alignment": "",
"size": "",
"age": 0,
"gender": "",
"height": "",
"weight": 0,
"deity": "",
"strength_base": 0,
"dexterity_base": 0,
"constitution_base": 0,
"intelligence_base": 0,
"wisdom_base": 0,
"charisma_base": 0,
"armor_base": 0,
"strength": 0,
"dexterity": 0,
"constitution": 0,
"intelligence": 0,
"wisdom": 0,
"charisma": 0,
"armor": 0,
"strength_modifier": 0,
"dexterity_modifier": 0,
"constitution_modifier": 0,
"intelligence_modifier": 0,
"wisdom_modifier": 0,
"charisma_modifier": 0,
"proficiency": 0,
"inspiration": false,
"experience": 0,
"proficiencies_armor": [],
"proficiencies_weapons": [],
"proficiencies_tools": [],
"languages": [],
"strength_save": 0,
"dexterity_save": 0,
"constitution_save": 0,
"intelligence_save": 0,
"wisdom_save": 0,
"charisma_save": 0,
"hp": 0,
"hp_max": 0,
"hp_temp": 0,
"hit_die": "",
"initiative": 0,
"deathsaves_successes": 0,
"deathsaves_failures": 0,
"fire_resistance": false,
"poison_resistance": false,
"psychic_resistance": false,
"cold_resistance": false,
"thunder_resistance": false,
"acid_resistance": false,
"force_resistance": false,
"radiant_resistance": false,
"necrotic_resistance": false,
"bludgeoning_resistance": false,
"piercing_resistance": false,
"slashing_resistance": false,
"immunities": [],
"vulnerabilities": [],
"speed_base": 0,
"speed_type": [],
"darkvision": 0,
"blindsight": 0,
"tremorsense": 0,
"truesight": 0,
"passive_perception": 0,
"athletics": 0,
"acrobatics": 0,
"sleight_of_hand": 0,
"stealth": 0,
"arcana": 0,
"history": 0,
"investigation": 0,
"nature": 0,
"religion": 0,
"animal_handling": 0,
"insight": 0,
"medicine": 0,
"perception": 0,
"survival": 0,
"deception": 0,
"intimidation": 0,
"performance": 0,
"persuasion": 0,
"athletics_passive": 0,
"acrobatics_passive": 0,
"sleight_of_hand_passive": 0,
"stealth_passive": 0,
"arcana_passive": 0,
"history_passive": 0,
"investigation_passive": 0,
"nature_passive": 0,
"religion_passive": 0,
"animal_handling_passive": 0,
"insight_passive": 0,
"medicine_passive": 0,
"perception_passive": 0,
"survival_passive": 0,
"deception_passive": 0,
"intimidation_passive": 0,
"performance_passive": 0,
"persuasion_passive": 0,
"passive_perception": 0,
"passive_investigation": 0,
"passive_insight": 0,
"spellcasting_ability": "",
"spell_save_dc": 0,
"spell_attack_bonus": 0,
"known_spells": [],
"prepared_spells": [],
"spell_slots": {},
"cantrips": [],
"spellcasting_class": "",
"exhaustion_level": 0,
"conditions_active": [],
"cp": 0,
"sp": 0,
"ep": 0,
"gp": 0,
"pp": 0,
"equipment": [],
"features": [],
"traits": [],
"personality_traits": [],
"ideals": [],
"bonds": [],
"flaws": [],
"notes": "",
"custom_attributes": {}
}

View File

0
lisiumsite/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

16
lisiumsite/asgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
ASGI config for lisiumsite project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lisiumsite.settings')
application = get_asgi_application()

118
lisiumsite/settings.py Normal file
View File

@ -0,0 +1,118 @@
"""
Django settings for lisiumsite project.
Generated by 'django-admin startproject' using Django 6.0.
For more information on this file, see
https://docs.djangoproject.com/en/6.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/6.0/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-c@*)_9zq1%@%nv+q18ji6k^ixf(^!7@**di7_r-s5q33m@&w)q'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'main',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'lisiumsite.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'lisiumsite.wsgi.application'
# Database
# https://docs.djangoproject.com/en/6.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/6.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/6.0/howto/static-files/
STATIC_URL = 'static/'

23
lisiumsite/urls.py Normal file
View File

@ -0,0 +1,23 @@
"""
URL configuration for lisiumsite project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/6.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('main.urls')),
]

16
lisiumsite/wsgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
WSGI config for lisiumsite project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lisiumsite.settings')
application = get_wsgi_application()

0
main/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
main/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
main/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class MainConfig(AppConfig):
name = 'main'

View File

Binary file not shown.

3
main/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Lisium Django Demo</title>
</head>
<body>
<h1>Welcome to Django</h1>
<p>
This is being rendered from a django template.
</p>
</body>
</html>

3
main/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

6
main/urls.py Normal file
View File

@ -0,0 +1,6 @@
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='Home')
]

6
main/views.py Normal file
View File

@ -0,0 +1,6 @@
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def home(request):
return render(request, 'main/home.html')

22
manage.py Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lisiumsite.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
Flask
requests
Markdown

13333
static/css/uikit-rtl.css Normal file

File diff suppressed because it is too large Load Diff

1
static/css/uikit-rtl.min.css vendored Normal file

File diff suppressed because one or more lines are too long

13333
static/css/uikit.css Normal file

File diff suppressed because it is too large Load Diff

1
static/css/uikit.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,35 @@
document.addEventListener('DOMContentLoaded', async function () {
console.log(`Here there be dragons!! and ${feature_uuid}`)
})
async function saveFeature() {
var feature_name = document.getElementById("featureName").value;
var feature_description = document.getElementById("featureDescription").value;
const response = await fetch(`/f/${feature_uuid}/save`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
key: feature_uuid,
update: {
feature_name: feature_name,
feature_description: feature_description
}
})
});
data = await response.json();
if (data.error){
UIkit.notification({
message: data.message,
status: "danger",
pos: 'bottom-right',
timeout: 5000
});
} else if (!data.error) {
window.location.href = `/f/${feature_uuid}`;
}
};

32
static/js/loginHandler.js Normal file
View File

@ -0,0 +1,32 @@
document.addEventListener('DOMContentLoaded', async function() {
console.log("here i am")
});
async function authenticateLogin() {
var username = document.getElementById('login_username').value;
var password = document.getElementById('login_password').value;
const response = await fetch('/login/authenticate', {
method: 'POST',
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_username: username,
user_password: password
}),
});
data = await response.json()
console.log(data)
if (data.error){
UIkit.notification({
message: data.message,
status: "danger",
pos: 'bottom-right',
timeout: 5000
});
} else if (!data.error) {
window.location.href = '/';
}
}

View File

@ -0,0 +1,44 @@
document.addEventListener('DOMContentLoaded', async function () {
console.log(`Here there be dragons!! and ${package_object.package_uuid}`);
let doc_md = document.getElementById("md_document");
console.log(doc_md)
var doc_tables = doc_md.getElementsByTagName('table');
for (var i = 0; i < doc_tables.length; i++){
doc_tables[i].setAttribute("class", "uk-table uk-table-striped uk-table-small");
};
})
async function savePackage() {
var package_name = document.getElementById("packageName").value;
var package_description = document.getElementById("packageDescription").value;
var package_type = document.getElementById('packageType').value;
const response = await fetch(`/p/${package_object.package_uuid}/save`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
key: package_object.package_uuid,
update: {
package_name: package_name,
package_description: package_description,
package_type: package_type
}
})
});
data = await response.json();
if (data.error){
UIkit.notification({
message: data.message,
status: "danger",
pos: 'bottom-right',
timeout: 5000
});
} else if (!data.error) {
window.location.href = `/p/${package_object.package_uuid}`;
}
};

184
static/js/uikit-icons.js Normal file
View File

@ -0,0 +1,184 @@
/*! UIkit 3.24.2 | https://www.getuikit.com | (c) 2014 - 2025 YOOtheme | MIT License */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define('uikiticons', factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.UIkitIcons = factory());
})(this, (function () { 'use strict';
function plugin(UIkit) {
if (plugin.installed) {
return;
}
UIkit.icon.add({
"500px": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M9.624,11.866c-0.141,0.132,0.479,0.658,0.662,0.418c0.051-0.046,0.607-0.61,0.662-0.664c0,0,0.738,0.719,0.814,0.719 c0.1,0,0.207-0.055,0.322-0.17c0.27-0.269,0.135-0.416,0.066-0.495l-0.631-0.616l0.658-0.668c0.146-0.156,0.021-0.314-0.1-0.449 c-0.182-0.18-0.359-0.226-0.471-0.125l-0.656,0.654l-0.654-0.654c-0.033-0.034-0.08-0.045-0.124-0.045 c-0.079,0-0.191,0.068-0.307,0.181c-0.202,0.202-0.247,0.351-0.133,0.462l0.665,0.665L9.624,11.866z"/><path d="M11.066,2.884c-1.061,0-2.185,0.248-3.011,0.604c-0.087,0.034-0.141,0.106-0.15,0.205C7.893,3.784,7.919,3.909,7.982,4.066 c0.05,0.136,0.187,0.474,0.452,0.372c0.844-0.326,1.779-0.507,2.633-0.507c0.963,0,1.9,0.191,2.781,0.564 c0.695,0.292,1.357,0.719,2.078,1.34c0.051,0.044,0.105,0.068,0.164,0.068c0.143,0,0.273-0.137,0.389-0.271 c0.191-0.214,0.324-0.395,0.135-0.575c-0.686-0.654-1.436-1.138-2.363-1.533C13.24,3.097,12.168,2.884,11.066,2.884z"/><path d="M16.43,15.747c-0.092-0.028-0.242,0.05-0.309,0.119l0,0c-0.652,0.652-1.42,1.169-2.268,1.521 c-0.877,0.371-1.814,0.551-2.779,0.551c-0.961,0-1.896-0.189-2.775-0.564c-0.848-0.36-1.612-0.879-2.268-1.53 c-0.682-0.688-1.196-1.455-1.529-2.268c-0.325-0.799-0.471-1.643-0.471-1.643c-0.045-0.24-0.258-0.249-0.567-0.203 c-0.128,0.021-0.519,0.079-0.483,0.36v0.01c0.105,0.644,0.289,1.284,0.545,1.895c0.417,0.969,1.002,1.849,1.756,2.604 c0.757,0.754,1.636,1.34,2.604,1.757C8.901,18.785,9.97,19,11.088,19c1.104,0,2.186-0.215,3.188-0.645 c1.838-0.896,2.604-1.757,2.604-1.757c0.182-0.204,0.227-0.317-0.1-0.643C16.779,15.956,16.525,15.774,16.43,15.747z"/><path d="M5.633,13.287c0.293,0.71,0.723,1.341,1.262,1.882c0.54,0.54,1.172,0.971,1.882,1.264c0.731,0.303,1.509,0.461,2.298,0.461 c0.801,0,1.578-0.158,2.297-0.461c0.711-0.293,1.344-0.724,1.883-1.264c0.543-0.541,0.971-1.172,1.264-1.882 c0.314-0.721,0.463-1.5,0.463-2.298c0-0.79-0.148-1.569-0.463-2.289c-0.293-0.699-0.721-1.329-1.264-1.881 c-0.539-0.541-1.172-0.959-1.867-1.263c-0.721-0.303-1.5-0.461-2.299-0.461c-0.802,0-1.613,0.159-2.322,0.461 c-0.577,0.25-1.544,0.867-2.119,1.454v0.012V2.108h8.16C15.1,2.104,15.1,1.69,15.1,1.552C15.1,1.417,15.1,1,14.809,1H5.915 C5.676,1,5.527,1.192,5.527,1.384v6.84c0,0.214,0.273,0.372,0.529,0.428c0.5,0.105,0.614-0.056,0.737-0.224l0,0 c0.18-0.273,0.776-0.884,0.787-0.894c0.901-0.905,2.117-1.408,3.416-1.408c1.285,0,2.5,0.501,3.412,1.408 c0.914,0.914,1.408,2.122,1.408,3.405c0,1.288-0.508,2.496-1.408,3.405c-0.9,0.896-2.152,1.406-3.438,1.406 c-0.877,0-1.711-0.229-2.433-0.671v-4.158c0-0.553,0.237-1.151,0.643-1.614c0.462-0.519,1.094-0.799,1.782-0.799 c0.664,0,1.293,0.253,1.758,0.715c0.459,0.459,0.709,1.071,0.709,1.723c0,1.385-1.094,2.468-2.488,2.468 c-0.273,0-0.769-0.121-0.781-0.125c-0.281-0.087-0.405,0.306-0.438,0.436c-0.159,0.496,0.079,0.585,0.123,0.607 c0.452,0.137,0.743,0.157,1.129,0.157c1.973,0,3.572-1.6,3.572-3.57c0-1.964-1.6-3.552-3.572-3.552c-0.97,0-1.872,0.36-2.546,1.038 c-0.656,0.631-1.027,1.487-1.027,2.322v3.438v-0.011c-0.372-0.42-0.732-1.041-0.981-1.682c-0.102-0.248-0.315-0.202-0.607-0.113 c-0.135,0.035-0.519,0.157-0.44,0.439C5.372,12.799,5.577,13.164,5.633,13.287z"/></svg>',
"album": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="10" height="1" x="5" y="2"/><rect width="14" height="1" x="3" y="4"/><rect width="17" height="11" fill="none" stroke="#000" x="1.5" y="6.5"/></svg>',
"android": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m14.88,6.77l1.66-2.87c.09-.16.04-.37-.12-.46-.16-.09-.37-.04-.46.12l-1.68,2.91c-1.28-.59-2.73-.91-4.28-.91s-3,.33-4.28.91l-1.68-2.91c-.09-.16-.3-.22-.46-.12-.16.09-.22.3-.12.46l1.66,2.87C2.26,8.32.32,11.22,0,14.61h20c-.32-3.39-2.26-6.29-5.12-7.84h0Zm-9.47,5.03c-.46,0-.84-.38-.84-.84s.38-.84.84-.84.84.38.84.84c0,.46-.37.84-.84.84Zm9.18,0c-.46,0-.84-.38-.84-.84s.38-.84.84-.84.84.38.84.84c0,.46-.37.84-.84.84Z"/></svg>',
"android-robot": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m17.61,7.96v4.64c-.06,1.48-2.17,1.48-2.23,0v-4.64c.06-1.48,2.17-1.48,2.23,0Z"/><path d="m4.62,7.96v4.64c-.06,1.48-2.17,1.48-2.23,0v-4.64c.06-1.48,2.17-1.48,2.23,0Z"/><path d="m12.78,2.85c-.11-.07-.23-.13-.34-.19.13-.23.65-1.17.79-1.42.07-.12-.05-.27-.18-.23-.04.01-.07.04-.09.08l-.79,1.43c-1.32-.6-2.98-.6-4.3,0-.13-.23-.65-1.18-.79-1.43-.04-.07-.14-.1-.21-.06-.08.04-.1.14-.06.21,0,0,.79,1.42.79,1.42-1.49.77-2.53,2.28-2.53,3.99-.02,0,9.93,0,9.93,0,.01-1.55-.87-2.98-2.19-3.8Zm-5.07,1.98c-.23,0-.41-.19-.41-.41.01-.27.21-.41.41-.41s.4.14.42.41c0,.22-.18.42-.41.41Zm4.58,0c-.23,0-.42-.19-.41-.41.01-.28.21-.41.41-.41s.4.14.41.41c0,.23-.19.41-.41.41Z"/><path d="m14.97,7.03v7.2c0,.66-.54,1.2-1.2,1.2h-.8v2.46c-.06,1.48-2.16,1.48-2.23,0,0,0,0-2.46,0-2.46h-1.48v2.46c0,.61-.5,1.11-1.11,1.11s-1.11-.5-1.11-1.11v-2.46h-.8c-.66,0-1.2-.54-1.2-1.2,0,0,0-7.2,0-7.2h9.93Z"/></svg>',
"apple": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m17.23,6.93c-.1.08-1.95,1.12-1.95,3.43,0,2.67,2.35,3.62,2.42,3.64-.01.06-.37,1.29-1.24,2.55-.77,1.11-1.58,2.22-2.8,2.22s-1.54-.71-2.95-.71-1.87.73-2.99.73-1.9-1.03-2.8-2.29c-1.04-1.48-1.88-3.78-1.88-5.96,0-3.5,2.28-5.36,4.51-5.36,1.19,0,2.18.78,2.93.78s1.82-.83,3.17-.83c.51,0,2.36.05,3.57,1.79h0Zm-4.21-3.27c.56-.66.96-1.59.96-2.51,0-.13-.01-.26-.03-.36-.91.03-1.99.61-2.65,1.36-.51.58-.99,1.5-.99,2.44,0,.14.02.28.03.33.06.01.15.02.24.02.82,0,1.85-.55,2.44-1.28h0Z"/></svg>',
"arrow-down": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="3.48" x2="10" y2="15.48"/><polyline fill="none" stroke="#000" points="6.16 12 10 15.84 13.84 12"/></svg>',
"arrow-down-arrow-up": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="7" y1="3.38" x2="7" y2="15.38"/><polyline fill="none" stroke="#000" points="10.18 12.75 7 15.93 3.83 12.76"/><line fill="none" stroke="#000" x1="13" y1="16.62" x2="13" y2="4.62"/><polyline fill="none" stroke="#000" points="9.82 7.25 13 4.07 16.17 7.24"/></svg>',
"arrow-left": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="16.53" y1="10" x2="4.53" y2="10"/><polyline fill="none" stroke="#000" points="8 6.16 4.18 10 8 13.84"/></svg>',
"arrow-right": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="3.47" y1="10" x2="15.47" y2="10"/><polyline fill="none" stroke="#000" points="11.98 13.84 15.82 10 11.98 6.16"/></svg>',
"arrow-up": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="16.53" x2="10" y2="4.53"/><polyline fill="none" stroke="#000" points="13.84 8 10 4.17 6.16 8"/></svg>',
"arrow-up-right": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="4.5" y1="15.53" x2="16.5" y2="3.53"/><polyline fill="none" stroke="#000" points="16.5 9 16.5 3.5 11 3.5"/></svg>',
"bag": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M7.5,7.5V4A2.48,2.48,0,0,1,10,1.5,2.54,2.54,0,0,1,12.5,4V7.5"/><polygon fill="none" stroke="#000" points="16.5 7.5 3.5 7.5 2.5 18.5 17.5 18.5 16.5 7.5"/></svg>',
"ban": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><line fill="none" stroke="#000" stroke-width="1.1" x1="4" y1="3.5" x2="16" y2="16.5"/></svg>',
"behance": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M9.5,10.6c-0.4-0.5-0.9-0.9-1.6-1.1c1.7-1,2.2-3.2,0.7-4.7C7.8,4,6.3,4,5.2,4C3.5,4,1.7,4,0,4v12c1.7,0,3.4,0,5.2,0 c1,0,2.1,0,3.1-0.5C10.2,14.6,10.5,12.3,9.5,10.6L9.5,10.6z M5.6,6.1c1.8,0,1.8,2.7-0.1,2.7c-1,0-2,0-2.9,0V6.1H5.6z M2.6,13.8v-3.1 c1.1,0,2.1,0,3.2,0c2.1,0,2.1,3.2,0.1,3.2L2.6,13.8z"/><path d="M19.9,10.9C19.7,9.2,18.7,7.6,17,7c-4.2-1.3-7.3,3.4-5.3,7.1c0.9,1.7,2.8,2.3,4.7,2.1c1.7-0.2,2.9-1.3,3.4-2.9h-2.2 c-0.4,1.3-2.4,1.5-3.5,0.6c-0.4-0.4-0.6-1.1-0.6-1.7H20C20,11.7,19.9,10.9,19.9,10.9z M13.5,10.6c0-1.6,2.3-2.7,3.5-1.4 c0.4,0.4,0.5,0.9,0.6,1.4H13.5L13.5,10.6z"/><rect width="5" height="1.4" x="13" y="4"/></svg>',
"bell": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M17,15.5 L3,15.5 C2.99,14.61 3.79,13.34 4.1,12.51 C4.58,11.3 4.72,10.35 5.19,7.01 C5.54,4.53 5.89,3.2 7.28,2.16 C8.13,1.56 9.37,1.5 9.81,1.5 L9.96,1.5 C9.96,1.5 11.62,1.41 12.67,2.17 C14.08,3.2 14.42,4.54 14.77,7.02 C15.26,10.35 15.4,11.31 15.87,12.52 C16.2,13.34 17.01,14.61 17,15.5 L17,15.5 Z"/><path fill="none" stroke="#000" d="M12.39,16 C12.39,17.37 11.35,18.43 9.91,18.43 C8.48,18.43 7.42,17.37 7.42,16"/></svg>',
"bluesky": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M9.993,9.149c-.772-1.495-2.865-4.288-4.813-5.662-1.866-1.317-2.58-1.09-3.043-.878-.54.246-.637,1.075-.637,1.563s.265,4.003.444,4.587c.579,1.939,2.628,2.595,4.519,2.382.096-.014.193-.029.294-.039-.096.014-.198.029-.294.039-2.768.41-5.233,1.418-2.001,5.011,3.55,3.675,4.866-.786,5.541-3.053.675,2.262,1.452,6.564,5.474,3.053,3.024-3.053.83-4.601-1.939-5.011-.096-.01-.198-.024-.294-.039.101.014.198.024.294.039,1.89.212,3.945-.444,4.519-2.382.174-.588.444-4.099.444-4.587s-.096-1.317-.637-1.563c-.468-.212-1.177-.439-3.043.878-1.963,1.379-4.056,4.167-4.827,5.662h0Z"/></svg>',
"bold": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M5,15.3 C5.66,15.3 5.9,15 5.9,14.53 L5.9,5.5 C5.9,4.92 5.56,4.7 5,4.7 L5,4 L8.95,4 C12.6,4 13.7,5.37 13.7,6.9 C13.7,7.87 13.14,9.17 10.86,9.59 L10.86,9.7 C13.25,9.86 14.29,11.28 14.3,12.54 C14.3,14.47 12.94,16 9,16 L5,16 L5,15.3 Z M9,9.3 C11.19,9.3 11.8,8.5 11.85,7 C11.85,5.65 11.3,4.8 9,4.8 L7.67,4.8 L7.67,9.3 L9,9.3 Z M9.185,15.22 C11.97,15 12.39,14 12.4,12.58 C12.4,11.15 11.39,10 9,10 L7.67,10 L7.67,15 L9.18,15 Z"/></svg>',
"bolt": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M4.74,20 L7.73,12 L3,12 L15.43,1 L12.32,9 L17.02,9 L4.74,20 L4.74,20 L4.74,20 Z M9.18,11 L7.1,16.39 L14.47,10 L10.86,10 L12.99,4.67 L5.61,11 L9.18,11 L9.18,11 L9.18,11 Z"/></svg>',
"bookmark": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="5.5 1.5 15.5 1.5 15.5 17.5 10.5 12.5 5.5 17.5"/></svg>',
"calendar": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M 2,3 2,17 18,17 18,3 2,3 Z M 17,16 3,16 3,8 17,8 17,16 Z M 17,7 3,7 3,4 17,4 17,7 Z"/><rect width="1" height="3" x="6" y="2"/><rect width="1" height="3" x="13" y="2"/></svg>',
"camera": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10.8" r="3.8"/><path fill="none" stroke="#000" d="M1,4.5 C0.7,4.5 0.5,4.7 0.5,5 L0.5,17 C0.5,17.3 0.7,17.5 1,17.5 L19,17.5 C19.3,17.5 19.5,17.3 19.5,17 L19.5,5 C19.5,4.7 19.3,4.5 19,4.5 L13.5,4.5 L13.5,2.9 C13.5,2.6 13.3,2.5 13,2.5 L7,2.5 C6.7,2.5 6.5,2.6 6.5,2.9 L6.5,4.5 L1,4.5 L1,4.5 Z"/></svg>',
"cart": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="7.3" cy="17.3" r="1.4"/><circle cx="13.3" cy="17.3" r="1.4"/><polyline fill="none" stroke="#000" points="0 2 3.2 4 5.3 12.5 16 12.5 18 6.5 8 6.5"/></svg>',
"check": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.1" points="4,10 8,15 17,4"/></svg>',
"chevron-double-left": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="10 14 6 10 10 6"/><polyline fill="none" stroke="#000" stroke-width="1.03" points="14 14 10 10 14 6"/></svg>',
"chevron-double-right": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="10 6 14 10 10 14"/><polyline fill="none" stroke="#000" stroke-width="1.03" points="6 6 10 10 6 14"/></svg>',
"chevron-down": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="16 7 10 13 4 7"/></svg>',
"chevron-left": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="13 16 7 10 13 4"/></svg>',
"chevron-right": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="7 4 13 10 7 16"/></svg>',
"chevron-up": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="4 13 10 7 16 13"/></svg>',
"clock": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><rect width="1" height="7" x="9" y="4"/><path fill="none" stroke="#000" stroke-width="1.1" d="M13.018,14.197 L9.445,10.625"/></svg>',
"close": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.06" d="M16,16 L4,4"/><path fill="none" stroke="#000" stroke-width="1.06" d="M16,4 L4,16"/></svg>',
"close-circle": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><line fill="none" stroke="#000" x1="13.18" y1="6.82" x2="6.82" y2="13.18"/><line fill="none" stroke="#000" x1="6.82" y1="6.82" x2="13.18" y2="13.18"/></svg>',
"cloud-download": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M6.5,13.28h-2.75c-1.79,0-3.25-1.44-3.25-3.22,0-1.63,1.22-2.98,2.8-3.19.08-2.89,2.45-5.2,5.38-5.2,2.51,0,4.63,1.71,5.21,4.02.5-.22,1.04-.34,1.61-.34,2.21,0,4,1.77,4,3.96s-1.79,3.96-4,3.96h-3"/><path fill="none" stroke="#000" d="M9.5,18.17v-10"/><polyline fill="none" stroke="#000" points="12.67 15.66 9.5 18.83 6.33 15.66"/></svg>',
"cloud-upload": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M6.5,13.77h-2.75c-1.79,0-3.25-1.44-3.25-3.22,0-1.63,1.22-2.98,2.81-3.19.07-2.89,2.44-5.2,5.37-5.2,2.51,0,4.63,1.71,5.21,4.02.5-.22,1.04-.34,1.61-.34,2.21,0,4,1.77,4,3.96s-1.79,3.96-4,3.96h-3"/><path fill="none" stroke="#000" d="M9.51,9.34v9"/><polyline fill="none" stroke="#000" points="6.34 11.85 9.51 8.68 12.68 11.85"/></svg>',
"code": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.01" points="13,4 19,10 13,16"/><polyline fill="none" stroke="#000" stroke-width="1.01" points="7,4 1,10 7,16"/></svg>',
"cog": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="9.997" cy="10" r="3.31"/><path fill="none" stroke="#000" d="M18.488,12.285 L16.205,16.237 C15.322,15.496 14.185,15.281 13.303,15.791 C12.428,16.289 12.047,17.373 12.246,18.5 L7.735,18.5 C7.938,17.374 7.553,16.299 6.684,15.791 C5.801,15.27 4.655,15.492 3.773,16.237 L1.5,12.285 C2.573,11.871 3.317,10.999 3.317,9.991 C3.305,8.98 2.573,8.121 1.5,7.716 L3.765,3.784 C4.645,4.516 5.794,4.738 6.687,4.232 C7.555,3.722 7.939,2.637 7.735,1.5 L12.263,1.5 C12.072,2.637 12.441,3.71 13.314,4.22 C14.206,4.73 15.343,4.516 16.225,3.794 L18.487,7.714 C17.404,8.117 16.661,8.988 16.67,10.009 C16.672,11.018 17.415,11.88 18.488,12.285 L18.488,12.285 Z"/></svg>',
"comment": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M6,18.71 L6,14 L1,14 L1,1 L19,1 L19,14 L10.71,14 L6,18.71 L6,18.71 Z M2,13 L7,13 L7,16.29 L10.29,13 L18,13 L18,2 L2,2 L2,13 L2,13 Z"/></svg>',
"commenting": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="1.5,1.5 18.5,1.5 18.5,13.5 10.5,13.5 6.5,17.5 6.5,13.5 1.5,13.5"/><circle cx="10" cy="8" r="1"/><circle cx="6" cy="8" r="1"/><circle cx="14" cy="8" r="1"/></svg>',
"comments": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="2 0.5 19.5 0.5 19.5 13"/><path d="M5,19.71 L5,15 L0,15 L0,2 L18,2 L18,15 L9.71,15 L5,19.71 L5,19.71 L5,19.71 Z M1,14 L6,14 L6,17.29 L9.29,14 L17,14 L17,3 L1,3 L1,14 L1,14 L1,14 Z"/></svg>',
"copy": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="12" height="16" fill="none" stroke="#000" x="3.5" y="2.5"/><polyline fill="none" stroke="#000" points="5 0.5 17.5 0.5 17.5 17"/></svg>',
"credit-card": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="17" height="12" fill="none" stroke="#000" x="1.5" y="4.5"/><rect width="18" height="3" x="1" y="7"/></svg>',
"crosshairs": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="10" cy="10" r="7.5"/><line fill="none" stroke="#000" x1="10" x2="10" y2="8"/><line fill="none" stroke="#000" x1="10" y1="12" x2="10" y2="20"/><line fill="none" stroke="#000" y1="10" x2="8" y2="10"/><line fill="none" stroke="#000" x1="12" y1="10" x2="20" y2="10"/></svg>',
"database": '<svg width="20" height="20" viewBox="0 0 20 20"><ellipse fill="none" stroke="#000" cx="10" cy="4.64" rx="7.5" ry="3.14"/><path fill="none" stroke="#000" d="M17.5,8.11 C17.5,9.85 14.14,11.25 10,11.25 C5.86,11.25 2.5,9.84 2.5,8.11"/><path fill="none" stroke="#000" d="M17.5,11.25 C17.5,12.99 14.14,14.39 10,14.39 C5.86,14.39 2.5,12.98 2.5,11.25"/><path fill="none" stroke="#000" d="M17.49,4.64 L17.5,14.36 C17.5,16.1 14.14,17.5 10,17.5 C5.86,17.5 2.5,16.09 2.5,14.36 L2.5,4.64"/></svg>',
"desktop": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="1" height="2" x="8" y="15"/><rect width="1" height="2" x="11" y="15"/><rect width="10" height="1" x="5" y="16"/><rect width="17" height="11" fill="none" stroke="#000" x="1.5" y="3.5"/></svg>',
"discord": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M16.074,4.361a14.243,14.243,0,0,0-3.61-1.134,10.61,10.61,0,0,0-.463.96,13.219,13.219,0,0,0-4,0,10.138,10.138,0,0,0-.468-.96A14.206,14.206,0,0,0,3.919,4.364,15.146,15.146,0,0,0,1.324,14.5a14.435,14.435,0,0,0,4.428,2.269A10.982,10.982,0,0,0,6.7,15.21a9.294,9.294,0,0,1-1.494-.727c.125-.093.248-.19.366-.289a10.212,10.212,0,0,0,8.854,0c.119.1.242.2.366.289a9.274,9.274,0,0,1-1.5.728,10.8,10.8,0,0,0,.948,1.562,14.419,14.419,0,0,0,4.431-2.27A15.128,15.128,0,0,0,16.074,4.361Zm-8.981,8.1a1.7,1.7,0,0,1-1.573-1.79A1.689,1.689,0,0,1,7.093,8.881a1.679,1.679,0,0,1,1.573,1.791A1.687,1.687,0,0,1,7.093,12.462Zm5.814,0a1.7,1.7,0,0,1-1.573-1.79,1.689,1.689,0,0,1,1.573-1.791,1.679,1.679,0,0,1,1.573,1.791A1.688,1.688,0,0,1,12.907,12.462Z"/></svg>',
"download": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="2.09" x2="10" y2="14.09"/><polyline fill="none" stroke="#000" points="6.16 10.62 10 14.46 13.84 10.62"/><line stroke="#000" x1="3.5" y1="17.5" x2="16.5" y2="17.5"/></svg>',
"dribbble": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.4" d="M1.3,8.9c0,0,5,0.1,8.6-1c1.4-0.4,2.6-0.9,4-1.9 c1.4-1.1,2.5-2.5,2.5-2.5"/><path fill="none" stroke="#000" stroke-width="1.4" d="M3.9,16.6c0,0,1.7-2.8,3.5-4.2 c1.8-1.3,4-2,5.7-2.2C16,10,19,10.6,19,10.6"/><path fill="none" stroke="#000" stroke-width="1.4" d="M6.9,1.6c0,0,3.3,4.6,4.2,6.8 c0.4,0.9,1.3,3.1,1.9,5.2c0.6,2,0.9,4.4,0.9,4.4"/><circle fill="none" stroke="#000" stroke-width="1.4" cx="10" cy="10" r="9"/></svg>',
"etsy": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M8,4.26C8,4.07,8,4,8.31,4h4.46c.79,0,1.22.67,1.53,1.91l.25,1h.76c.14-2.82.26-4,.26-4S13.65,3,12.52,3H6.81L3.75,2.92v.84l1,.2c.73.11.9.27,1,1,0,0,.06,2,.06,5.17s-.06,5.14-.06,5.14c0,.59-.23.81-1,.94l-1,.2v.84l3.06-.1h5.11c1.15,0,3.82.1,3.82.1,0-.7.45-3.88.51-4.22h-.73l-.76,1.69a2.25,2.25,0,0,1-2.45,1.47H9.4c-1,0-1.44-.4-1.44-1.24V10.44s2.16,0,2.86.06c.55,0,.85.19,1.06,1l.23,1H13L12.9,9.94,13,7.41h-.85l-.28,1.13c-.16.74-.28.84-1,1-1,.1-2.89.09-2.89.09Z"/></svg>',
"expand": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M2.48,17.52l6.52-6.52"/><polyline fill="none" stroke="#000" points="6.97 17.52 2.48 17.52 2.48 13.03"/><path fill="none" stroke="#000" stroke-width="1.1" d="M17.52,2.48l-6.52,6.52"/><polyline fill="none" stroke="#000" points="13.03 2.48 17.52 2.48 17.52 6.97"/></svg>',
"eye": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="10" cy="10" r="3.45"/><path fill="none" stroke="#000" d="m19.5,10c-2.4,3.66-5.26,7-9.5,7h0,0,0c-4.24,0-7.1-3.34-9.49-7C2.89,6.34,5.75,3,9.99,3h0,0,0c4.25,0,7.11,3.34,9.5,7Z"/></svg>',
"eye-slash": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="m7.56,7.56c.62-.62,1.49-1.01,2.44-1.01,1.91,0,3.45,1.54,3.45,3.45,0,.95-.39,1.82-1.01,2.44"/><path fill="none" stroke="#000" d="m19.5,10c-2.4,3.66-5.26,7-9.5,7h0,0,0c-4.24,0-7.1-3.34-9.49-7C2.89,6.34,5.75,3,9.99,3h0,0,0c4.25,0,7.11,3.34,9.5,7Z"/><line fill="none" stroke="#000" x1="2.5" y1="2.5" x2="17.5" y2="17.5"/></svg>',
"facebook": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M11,10h2.6l0.4-3H11V5.3c0-0.9,0.2-1.5,1.5-1.5H14V1.1c-0.3,0-1-0.1-2.1-0.1C9.6,1,8,2.4,8,5v2H5.5v3H8v8h3V10z"/></svg>',
"file": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="17" fill="none" stroke="#000" x="3.5" y="1.5"/></svg>',
"file-edit": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M18.65,1.68 C18.41,1.45 18.109,1.33 17.81,1.33 C17.499,1.33 17.209,1.45 16.98,1.68 L8.92,9.76 L8,12.33 L10.55,11.41 L18.651,3.34 C19.12,2.87 19.12,2.15 18.65,1.68 L18.65,1.68 L18.65,1.68 Z"/><polyline fill="none" stroke="#000" points="16.5 8.482 16.5 18.5 3.5 18.5 3.5 1.5 14.211 1.5"/></svg>',
"file-pdf": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="17" fill="none" stroke="#000" x="3.5" y="1.5"/><path d="M14.65 11.67c-.48.3-1.37-.19-1.79-.37a4.65 4.65 0 0 1 1.49.06c.35.1.36.28.3.31zm-6.3.06l.43-.79a14.7 14.7 0 0 0 .75-1.64 5.48 5.48 0 0 0 1.25 1.55l.2.15a16.36 16.36 0 0 0-2.63.73zM9.5 5.32c.2 0 .32.5.32.97a1.99 1.99 0 0 1-.23 1.04 5.05 5.05 0 0 1-.17-1.3s0-.71.08-.71zm-3.9 9a4.35 4.35 0 0 1 1.21-1.46l.24-.22a4.35 4.35 0 0 1-1.46 1.68zm9.23-3.3a2.05 2.05 0 0 0-1.32-.3 11.07 11.07 0 0 0-1.58.11 4.09 4.09 0 0 1-.74-.5 5.39 5.39 0 0 1-1.32-2.06 10.37 10.37 0 0 0 .28-2.62 1.83 1.83 0 0 0-.07-.25.57.57 0 0 0-.52-.4H9.4a.59.59 0 0 0-.6.38 6.95 6.95 0 0 0 .37 3.14c-.26.63-1 2.12-1 2.12-.3.58-.57 1.08-.82 1.5l-.8.44A3.11 3.11 0 0 0 5 14.16a.39.39 0 0 0 .15.42l.24.13c1.15.56 2.28-1.74 2.66-2.42a23.1 23.1 0 0 1 3.59-.85 4.56 4.56 0 0 0 2.91.8.5.5 0 0 0 .3-.21 1.1 1.1 0 0 0 .12-.75.84.84 0 0 0-.14-.25z"/></svg>',
"file-text": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="17" fill="none" stroke="#000" x="3.5" y="1.5"/><line fill="none" stroke="#000" x1="6" y1="12.5" x2="12" y2="12.5"/><line fill="none" stroke="#000" x1="6" y1="8.5" x2="14" y2="8.5"/><line fill="none" stroke="#000" x1="6" y1="6.5" x2="14" y2="6.5"/><line fill="none" stroke="#000" x1="6" y1="10.5" x2="14" y2="10.5"/></svg>',
"flickr": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="5.5" cy="9.5" r="3.5"/><circle cx="14.5" cy="9.5" r="3.5"/></svg>',
"folder": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="9.5 5.5 8.5 3.5 1.5 3.5 1.5 16.5 18.5 16.5 18.5 5.5"/></svg>',
"forward": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M2.47,13.11 C4.02,10.02 6.27,7.85 9.04,6.61 C9.48,6.41 10.27,6.13 11,5.91 L11,2 L18.89,9 L11,16 L11,12.13 C9.25,12.47 7.58,13.19 6.02,14.25 C3.03,16.28 1.63,18.54 1.63,18.54 C1.63,18.54 1.38,15.28 2.47,13.11 L2.47,13.11 Z M5.3,13.53 C6.92,12.4 9.04,11.4 12,10.92 L12,13.63 L17.36,9 L12,4.25 L12,6.8 C11.71,6.86 10.86,7.02 9.67,7.49 C6.79,8.65 4.58,10.96 3.49,13.08 C3.18,13.7 2.68,14.87 2.49,16 C3.28,15.05 4.4,14.15 5.3,13.53 L5.3,13.53 Z"/></svg>',
"foursquare": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M15.23,2 C15.96,2 16.4,2.41 16.5,2.86 C16.57,3.15 16.56,3.44 16.51,3.73 C16.46,4.04 14.86,11.72 14.75,12.03 C14.56,12.56 14.16,12.82 13.61,12.83 C13.03,12.84 11.09,12.51 10.69,13 C10.38,13.38 7.79,16.39 6.81,17.53 C6.61,17.76 6.4,17.96 6.08,17.99 C5.68,18.04 5.29,17.87 5.17,17.45 C5.12,17.28 5.1,17.09 5.1,16.91 C5.1,12.4 4.86,7.81 5.11,3.31 C5.17,2.5 5.81,2.12 6.53,2 L15.23,2 L15.23,2 Z M9.76,11.42 C9.94,11.19 10.17,11.1 10.45,11.1 L12.86,11.1 C13.12,11.1 13.31,10.94 13.36,10.69 C13.37,10.64 13.62,9.41 13.74,8.83 C13.81,8.52 13.53,8.28 13.27,8.28 C12.35,8.29 11.42,8.28 10.5,8.28 C9.84,8.28 9.83,7.69 9.82,7.21 C9.8,6.85 10.13,6.55 10.5,6.55 C11.59,6.56 12.67,6.55 13.76,6.55 C14.03,6.55 14.23,6.4 14.28,6.14 C14.34,5.87 14.67,4.29 14.67,4.29 C14.67,4.29 14.82,3.74 14.19,3.74 L7.34,3.74 C7,3.75 6.84,4.02 6.84,4.33 C6.84,7.58 6.85,14.95 6.85,14.99 C6.87,15 8.89,12.51 9.76,11.42 L9.76,11.42 Z"/></svg>',
"future": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline points="19 2 18 2 18 6 14 6 14 7 19 7 19 2"/><path fill="none" stroke="#000" stroke-width="1.1" d="M18,6.548 C16.709,3.29 13.354,1 9.6,1 C4.6,1 0.6,5 0.6,10 C0.6,15 4.6,19 9.6,19 C14.6,19 18.6,15 18.6,10"/><rect width="1" height="7" x="9" y="4"/><path fill="none" stroke="#000" stroke-width="1.1" d="M13.018,14.197 L9.445,10.625"/></svg>',
"git-branch": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="m13.5,8c0,2.41-1.57,2.87-3.44,3.25-1.47.29-3.56.81-3.56,3.75V5"/><circle fill="none" stroke="#000" cx="6.5" cy="3" r="1.79"/><circle fill="none" stroke="#000" cx="13.5" cy="6" r="1.79"/><circle fill="none" stroke="#000" cx="6.5" cy="17" r="1.79"/></svg>',
"git-fork": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="6" cy="3" r="1.79"/><circle fill="none" stroke="#000" cx="14" cy="3" r="1.79"/><circle fill="none" stroke="#000" cx="10" cy="17" r="1.79"/><path fill="none" stroke="#000" d="m6,4.78v1.99c0,2.63,4,3.66,4,6.75,0,1.55.01,1.24.01,1.24,0-.18,0,.31,0-1.24,0-3.09,3.99-4.12,3.99-6.75v-1.99"/></svg>',
"github": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M10,1 C5.03,1 1,5.03 1,10 C1,13.98 3.58,17.35 7.16,18.54 C7.61,18.62 7.77,18.34 7.77,18.11 C7.77,17.9 7.76,17.33 7.76,16.58 C5.26,17.12 4.73,15.37 4.73,15.37 C4.32,14.33 3.73,14.05 3.73,14.05 C2.91,13.5 3.79,13.5 3.79,13.5 C4.69,13.56 5.17,14.43 5.17,14.43 C5.97,15.8 7.28,15.41 7.79,15.18 C7.87,14.6 8.1,14.2 8.36,13.98 C6.36,13.75 4.26,12.98 4.26,9.53 C4.26,8.55 4.61,7.74 5.19,7.11 C5.1,6.88 4.79,5.97 5.28,4.73 C5.28,4.73 6.04,4.49 7.75,5.65 C8.47,5.45 9.24,5.35 10,5.35 C10.76,5.35 11.53,5.45 12.25,5.65 C13.97,4.48 14.72,4.73 14.72,4.73 C15.21,5.97 14.9,6.88 14.81,7.11 C15.39,7.74 15.73,8.54 15.73,9.53 C15.73,12.99 13.63,13.75 11.62,13.97 C11.94,14.25 12.23,14.8 12.23,15.64 C12.23,16.84 12.22,17.81 12.22,18.11 C12.22,18.35 12.38,18.63 12.84,18.54 C16.42,17.35 19,13.98 19,10 C19,5.03 14.97,1 10,1 L10,1 Z"/></svg>',
"github-alt": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M10,0.5 C4.75,0.5 0.5,4.76 0.5,10.01 C0.5,15.26 4.75,19.51 10,19.51 C15.24,19.51 19.5,15.26 19.5,10.01 C19.5,4.76 15.25,0.5 10,0.5 L10,0.5 Z M12.81,17.69 C12.81,17.69 12.81,17.7 12.79,17.69 C12.47,17.75 12.35,17.59 12.35,17.36 L12.35,16.17 C12.35,15.45 12.09,14.92 11.58,14.56 C12.2,14.51 12.77,14.39 13.26,14.21 C13.87,13.98 14.36,13.69 14.74,13.29 C15.42,12.59 15.76,11.55 15.76,10.17 C15.76,9.25 15.45,8.46 14.83,7.8 C15.1,7.08 15.07,6.29 14.75,5.44 L14.51,5.42 C14.34,5.4 14.06,5.46 13.67,5.61 C13.25,5.78 12.79,6.03 12.31,6.35 C11.55,6.16 10.81,6.05 10.09,6.05 C9.36,6.05 8.61,6.15 7.88,6.35 C7.28,5.96 6.75,5.68 6.26,5.54 C6.07,5.47 5.9,5.44 5.78,5.44 L5.42,5.44 C5.06,6.29 5.04,7.08 5.32,7.8 C4.7,8.46 4.4,9.25 4.4,10.17 C4.4,11.94 4.96,13.16 6.08,13.84 C6.53,14.13 7.05,14.32 7.69,14.43 C8.03,14.5 8.32,14.54 8.55,14.55 C8.07,14.89 7.82,15.42 7.82,16.16 L7.82,17.51 C7.8,17.69 7.7,17.8 7.51,17.8 C4.21,16.74 1.82,13.65 1.82,10.01 C1.82,5.5 5.49,1.83 10,1.83 C14.5,1.83 18.17,5.5 18.17,10.01 C18.18,13.53 15.94,16.54 12.81,17.69 L12.81,17.69 Z"/></svg>',
"gitter": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="1.531" height="11.471" x="3.5" y="1"/><rect width="1.529" height="15.294" x="7.324" y="4.059"/><rect width="1.527" height="15.294" x="11.148" y="4.059"/><rect width="1.529" height="8.412" x="14.971" y="4.059"/></svg>',
"google": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.86,9.09 C18.46,12.12 17.14,16.05 13.81,17.56 C9.45,19.53 4.13,17.68 2.47,12.87 C0.68,7.68 4.22,2.42 9.5,2.03 C11.57,1.88 13.42,2.37 15.05,3.65 C15.22,3.78 15.37,3.93 15.61,4.14 C14.9,4.81 14.23,5.45 13.5,6.14 C12.27,5.08 10.84,4.72 9.28,4.98 C8.12,5.17 7.16,5.76 6.37,6.63 C4.88,8.27 4.62,10.86 5.76,12.82 C6.95,14.87 9.17,15.8 11.57,15.25 C13.27,14.87 14.76,13.33 14.89,11.75 L10.51,11.75 L10.51,9.09 L17.86,9.09 L17.86,9.09 Z"/></svg>',
"grid": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="3" height="3" x="2" y="2"/><rect width="3" height="3" x="8" y="2"/><rect width="3" height="3" x="14" y="2"/><rect width="3" height="3" x="2" y="8"/><rect width="3" height="3" x="8" y="8"/><rect width="3" height="3" x="14" y="8"/><rect width="3" height="3" x="2" y="14"/><rect width="3" height="3" x="8" y="14"/><rect width="3" height="3" x="14" y="14"/></svg>',
"happy": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="13" cy="7" r="1"/><circle cx="7" cy="7" r="1"/><circle fill="none" stroke="#000" cx="10" cy="10" r="8.5"/><path fill="none" stroke="#000" d="M14.6,11.4 C13.9,13.3 12.1,14.5 10,14.5 C7.9,14.5 6.1,13.3 5.4,11.4"/></svg>',
"hashtag": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M15.431,8 L15.661,7 L12.911,7 L13.831,3 L12.901,3 L11.98,7 L9.29,7 L10.21,3 L9.281,3 L8.361,7 L5.23,7 L5,8 L8.13,8 L7.21,12 L4.23,12 L4,13 L6.98,13 L6.061,17 L6.991,17 L7.911,13 L10.601,13 L9.681,17 L10.611,17 L11.531,13 L14.431,13 L14.661,12 L11.76,12 L12.681,8 L15.431,8 Z M10.831,12 L8.141,12 L9.061,8 L11.75,8 L10.831,12 Z"/></svg>',
"heart": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.03" d="M10,4 C10,4 8.1,2 5.74,2 C3.38,2 1,3.55 1,6.73 C1,8.84 2.67,10.44 2.67,10.44 L10,18 L17.33,10.44 C17.33,10.44 19,8.84 19,6.73 C19,3.55 16.62,2 14.26,2 C11.9,2 10,4 10,4 L10,4 Z"/></svg>',
"history": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="#000" points="1 2 2 2 2 6 6 6 6 7 1 7 1 2"/><path fill="none" stroke="#000" stroke-width="1.1" d="M2.1,6.548 C3.391,3.29 6.746,1 10.5,1 C15.5,1 19.5,5 19.5,10 C19.5,15 15.5,19 10.5,19 C5.5,19 1.5,15 1.5,10"/><rect width="1" height="7" x="9" y="4"/><path fill="none" stroke="#000" stroke-width="1.1" d="M13.018,14.197 L9.445,10.625"/></svg>',
"home": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="18.65 11.35 10 2.71 1.35 11.35 0.65 10.65 10 1.29 19.35 10.65"/><polygon points="15 4 18 4 18 7 17 7 17 5 15 5"/><polygon points="3 11 4 11 4 18 7 18 7 12 12 12 12 18 16 18 16 11 17 11 17 19 11 19 11 13 8 13 8 19 3 19"/></svg>',
"image": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="16.1" cy="6.1" r="1.1"/><rect width="19" height="15" fill="none" stroke="#000" x=".5" y="2.5"/><polyline fill="none" stroke="#000" stroke-width="1.01" points="4,13 8,9 13,14"/><polyline fill="none" stroke="#000" stroke-width="1.01" points="11,12 12.5,10.5 16,14"/></svg>',
"info": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/></svg>',
"instagram": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M13.55,1H6.46C3.45,1,1,3.44,1,6.44v7.12c0,3,2.45,5.44,5.46,5.44h7.08c3.02,0,5.46-2.44,5.46-5.44V6.44 C19.01,3.44,16.56,1,13.55,1z M17.5,14c0,1.93-1.57,3.5-3.5,3.5H6c-1.93,0-3.5-1.57-3.5-3.5V6c0-1.93,1.57-3.5,3.5-3.5h8 c1.93,0,3.5,1.57,3.5,3.5V14z"/><circle cx="14.87" cy="5.26" r="1.09"/><path d="M10.03,5.45c-2.55,0-4.63,2.06-4.63,4.6c0,2.55,2.07,4.61,4.63,4.61c2.56,0,4.63-2.061,4.63-4.61 C14.65,7.51,12.58,5.45,10.03,5.45L10.03,5.45L10.03,5.45z M10.08,13c-1.66,0-3-1.34-3-2.99c0-1.65,1.34-2.99,3-2.99s3,1.34,3,2.99 C13.08,11.66,11.74,13,10.08,13L10.08,13L10.08,13z"/></svg>',
"italic": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M12.63,5.48 L10.15,14.52 C10,15.08 10.37,15.25 11.92,15.3 L11.72,16 L6,16 L6.2,15.31 C7.78,15.26 8.19,15.09 8.34,14.53 L10.82,5.49 C10.97,4.92 10.63,4.76 9.09,4.71 L9.28,4 L15,4 L14.81,4.69 C13.23,4.75 12.78,4.91 12.63,5.48 L12.63,5.48 Z"/></svg>',
"joomla": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M7.8,13.4l1.7-1.7L5.9,8c-0.6-0.5-0.6-1.5,0-2c0.6-0.6,1.4-0.6,2,0l1.7-1.7c-1-1-2.3-1.3-3.6-1C5.8,2.2,4.8,1.4,3.7,1.4 c-1.3,0-2.3,1-2.3,2.3c0,1.1,0.8,2,1.8,2.3c-0.4,1.3-0.1,2.8,1,3.8L7.8,13.4L7.8,13.4z"/><path d="M10.2,4.3c1-1,2.5-1.4,3.8-1c0.2-1.1,1.1-2,2.3-2c1.3,0,2.3,1,2.3,2.3c0,1.2-0.9,2.2-2,2.3c0.4,1.3,0,2.8-1,3.8L13.9,8 c0.6-0.5,0.6-1.5,0-2c-0.5-0.6-1.5-0.6-2,0L8.2,9.7L6.5,8"/><path d="M14.1,16.8c-1.3,0.4-2.8,0.1-3.8-1l1.7-1.7c0.6,0.6,1.5,0.6,2,0c0.5-0.6,0.6-1.5,0-2l-3.7-3.7L12,6.7l3.7,3.7 c1,1,1.3,2.4,1,3.6c1.1,0.2,2,1.1,2,2.3c0,1.3-1,2.3-2.3,2.3C15.2,18.6,14.3,17.8,14.1,16.8"/><path d="M13.2,12.2l-3.7,3.7c-1,1-2.4,1.3-3.6,1c-0.2,1-1.2,1.8-2.2,1.8c-1.3,0-2.3-1-2.3-2.3c0-1.1,0.8-2,1.8-2.3 c-0.3-1.3,0-2.7,1-3.7l1.7,1.7c-0.6,0.6-0.6,1.5,0,2c0.6,0.6,1.4,0.6,2,0l3.7-3.7"/></svg>',
"laptop": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="20" height="1" y="16"/><rect width="15" height="10" fill="none" stroke="#000" x="2.5" y="4.5"/></svg>',
"lifesaver": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="10" cy="10" r="9"/><circle fill="none" stroke="#000" cx="10" cy="10" r="5"/><line fill="none" stroke="#000" stroke-width="1.1" x1="5.17" y1="2.39" x2="8.11" y2="5.33"/><line fill="none" stroke="#000" stroke-width="1.1" x1="5.33" y1="8.11" x2="2.39" y2="5.17"/><line fill="none" stroke="#000" stroke-width="1.1" x1="14.83" y1="17.61" x2="11.89" y2="14.67"/><line fill="none" stroke="#000" stroke-width="1.1" x1="14.67" y1="11.89" x2="17.61" y2="14.83"/><line fill="none" stroke="#000" stroke-width="1.1" x1="17.61" y1="5.17" x2="14.67" y2="8.11"/><line fill="none" stroke="#000" stroke-width="1.1" x1="11.89" y1="5.33" x2="14.83" y2="2.39"/><line fill="none" stroke="#000" stroke-width="1.1" x1="8.11" y1="14.67" x2="5.17" y2="17.61"/><line fill="none" stroke="#000" stroke-width="1.1" x1="2.39" y1="14.83" x2="5.33" y2="11.89"/></svg>',
"link": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M10.625,12.375 L7.525,15.475 C6.825,16.175 5.925,16.175 5.225,15.475 L4.525,14.775 C3.825,14.074 3.825,13.175 4.525,12.475 L7.625,9.375"/><path fill="none" stroke="#000" stroke-width="1.1" d="M9.325,7.375 L12.425,4.275 C13.125,3.575 14.025,3.575 14.724,4.275 L15.425,4.975 C16.125,5.675 16.125,6.575 15.425,7.275 L12.325,10.375"/><path fill="none" stroke="#000" stroke-width="1.1" d="M7.925,11.875 L11.925,7.975"/></svg>',
"link-external": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="15 10.5 15 17 3 17 3 5 9.5 5"/><line fill="none" stroke="#000" x1="8.22" y1="11.79" x2="17.01" y2="2.99"/><polyline fill="none" stroke="#000" points="12.5 3 17 3 17 7.5"/></svg>',
"linkedin": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M5.77,17.89 L5.77,7.17 L2.21,7.17 L2.21,17.89 L5.77,17.89 L5.77,17.89 Z M3.99,5.71 C5.23,5.71 6.01,4.89 6.01,3.86 C5.99,2.8 5.24,2 4.02,2 C2.8,2 2,2.8 2,3.85 C2,4.88 2.77,5.7 3.97,5.7 L3.99,5.7 L3.99,5.71 L3.99,5.71 Z"/><path d="M7.75,17.89 L11.31,17.89 L11.31,11.9 C11.31,11.58 11.33,11.26 11.43,11.03 C11.69,10.39 12.27,9.73 13.26,9.73 C14.55,9.73 15.06,10.71 15.06,12.15 L15.06,17.89 L18.62,17.89 L18.62,11.74 C18.62,8.45 16.86,6.92 14.52,6.92 C12.6,6.92 11.75,7.99 11.28,8.73 L11.3,8.73 L11.3,7.17 L7.75,7.17 C7.79,8.17 7.75,17.89 7.75,17.89 L7.75,17.89 L7.75,17.89 Z"/></svg>',
"list": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="12" height="1" x="6" y="4"/><rect width="12" height="1" x="6" y="9"/><rect width="12" height="1" x="6" y="14"/><rect width="2" height="1" x="2" y="4"/><rect width="2" height="1" x="2" y="9"/><rect width="2" height="1" x="2" y="14"/></svg>',
"location": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.01" d="M10,0.5 C6.41,0.5 3.5,3.39 3.5,6.98 C3.5,11.83 10,19 10,19 C10,19 16.5,11.83 16.5,6.98 C16.5,3.39 13.59,0.5 10,0.5 L10,0.5 Z"/><circle fill="none" stroke="#000" cx="10" cy="6.8" r="2.3"/></svg>',
"lock": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="10" fill="none" stroke="#000" x="3.5" y="8.5"/><path fill="none" stroke="#000" d="M6.5,8 L6.5,4.88 C6.5,3.01 8.07,1.5 10,1.5 C11.93,1.5 13.5,3.01 13.5,4.88 L13.5,8"/></svg>',
"mail": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="1.4,6.5 10,11 18.6,6.5"/><path d="M 1,4 1,16 19,16 19,4 1,4 Z M 18,15 2,15 2,5 18,5 18,15 Z"/></svg>',
"mastodon": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m18.5,6.87c0-3.95-2.59-5.11-2.59-5.11-1.31-.6-3.55-.85-5.88-.87h-.06c-2.33.02-4.57.27-5.88.87,0,0-2.59,1.16-2.59,5.11,0,.91-.02,1.99.01,3.14.09,3.87.71,7.68,4.28,8.62,1.65.44,3.06.53,4.2.47,2.07-.11,3.23-.74,3.23-.74l-.07-1.5s-1.48.47-3.14.41c-1.64-.06-3.38-.18-3.64-2.2-.02-.18-.04-.37-.04-.57,0,0,1.61.39,3.66.49,1.25.06,2.42-.07,3.61-.22,2.28-.27,4.27-1.68,4.52-2.97.39-2.02.36-4.94.36-4.94Zm-3.05,5.09h-1.9v-4.65c0-.98-.41-1.48-1.24-1.48-.91,0-1.37.59-1.37,1.76v2.54h-1.89v-2.54c0-1.17-.46-1.76-1.37-1.76-.82,0-1.24.5-1.24,1.48v4.65h-1.9v-4.79c0-.98.25-1.76.75-2.33.52-.58,1.19-.87,2.03-.87.97,0,1.71.37,2.19,1.12l.47.79.47-.79c.49-.75,1.22-1.12,2.19-1.12.84,0,1.51.29,2.03.87.5.58.75,1.35.75,2.33v4.79Z"/></svg>',
"menu": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="16" height="1" x="2" y="4"/><rect width="16" height="1" x="2" y="9"/><rect width="16" height="1" x="2" y="14"/></svg>',
"microphone": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="16.44" x2="10" y2="18.5"/><line fill="none" stroke="#000" x1="7" y1="18.5" x2="13" y2="18.5"/><path fill="none" stroke="#000" stroke-width="1.1" d="M13.5 4.89v5.87a3.5 3.5 0 0 1-7 0V4.89a3.5 3.5 0 0 1 7 0z"/><path fill="none" stroke="#000" stroke-width="1.1" d="M15.5 10.36V11a5.5 5.5 0 0 1-11 0v-.6"/></svg>',
"microsoft": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m2,2h7.58v7.58H2V2Zm8.42,0h7.58v7.58h-7.58V2ZM2,10.42h7.58v7.58H2v-7.58Zm8.42,0h7.58v7.58h-7.58"/></svg>',
"minus": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="18" height="1" x="1" y="9"/></svg>',
"minus-circle": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9.5" cy="9.5" r="9"/><line fill="none" stroke="#000" x1="5" y1="9.5" x2="14" y2="9.5"/></svg>',
"more": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="3" cy="10" r="2"/><circle cx="10" cy="10" r="2"/><circle cx="17" cy="10" r="2"/></svg>',
"more-vertical": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="3" r="2"/><circle cx="10" cy="10" r="2"/><circle cx="10" cy="17" r="2"/></svg>',
"move": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="4,5 1,5 1,9 2,9 2,6 4,6"/><polygon points="1,16 2,16 2,18 4,18 4,19 1,19"/><polygon points="14,16 14,19 11,19 11,18 13,18 13,16"/><rect width="13" height="13" fill="none" stroke="#000" x="5.5" y="1.5"/><rect width="1" height="3" x="1" y="11"/><rect width="3" height="1" x="6" y="18"/></svg>',
"nut": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="2.5,5.7 10,1.3 17.5,5.7 17.5,14.3 10,18.7 2.5,14.3"/><circle fill="none" stroke="#000" cx="10" cy="10" r="3.5"/></svg>',
"paint-bucket": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="m6.42,2.16l5.28,5.28"/><path d="m18.49,11.83s1.51,2.06,1.51,3.36c0,.92-.76,1.64-1.51,1.64h0c-.75,0-1.49-.72-1.49-1.64,0-1.3,1.49-3.36,1.49-3.36h0Z"/><line fill="none" stroke="#000" x1="1.26" y1="10.5" x2="16" y2="10.5"/><polygon fill="none" stroke="#000" stroke-width="1.1" points="10.2 1.55 17.6 8.93 8.08 18.45 .7 11.07 10.2 1.55"/></svg>',
"pencil": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M17.25,6.01 L7.12,16.1 L3.82,17.2 L5.02,13.9 L15.12,3.88 C15.71,3.29 16.66,3.29 17.25,3.88 C17.83,4.47 17.83,5.42 17.25,6.01 L17.25,6.01 Z"/><path fill="none" stroke="#000" d="M15.98,7.268 L13.851,5.148"/></svg>',
"phone": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M15.5,17 C15.5,17.8 14.8,18.5 14,18.5 L7,18.5 C6.2,18.5 5.5,17.8 5.5,17 L5.5,3 C5.5,2.2 6.2,1.5 7,1.5 L14,1.5 C14.8,1.5 15.5,2.2 15.5,3 L15.5,17 L15.5,17 L15.5,17 Z"/><circle cx="10.5" cy="16.5" r=".8"/></svg>',
"phone-landscape": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M17,5.5 C17.8,5.5 18.5,6.2 18.5,7 L18.5,14 C18.5,14.8 17.8,15.5 17,15.5 L3,15.5 C2.2,15.5 1.5,14.8 1.5,14 L1.5,7 C1.5,6.2 2.2,5.5 3,5.5 L17,5.5 L17,5.5 L17,5.5 Z"/><circle cx="3.8" cy="10.5" r=".8"/></svg>',
"pinterest": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M10.21,1 C5.5,1 3,4.16 3,7.61 C3,9.21 3.85,11.2 5.22,11.84 C5.43,11.94 5.54,11.89 5.58,11.69 C5.62,11.54 5.8,10.8 5.88,10.45 C5.91,10.34 5.89,10.24 5.8,10.14 C5.36,9.59 5,8.58 5,7.65 C5,5.24 6.82,2.91 9.93,2.91 C12.61,2.91 14.49,4.74 14.49,7.35 C14.49,10.3 13,12.35 11.06,12.35 C9.99,12.35 9.19,11.47 9.44,10.38 C9.75,9.08 10.35,7.68 10.35,6.75 C10.35,5.91 9.9,5.21 8.97,5.21 C7.87,5.21 6.99,6.34 6.99,7.86 C6.99,8.83 7.32,9.48 7.32,9.48 C7.32,9.48 6.24,14.06 6.04,14.91 C5.7,16.35 6.08,18.7 6.12,18.9 C6.14,19.01 6.26,19.05 6.33,18.95 C6.44,18.81 7.74,16.85 8.11,15.44 C8.24,14.93 8.79,12.84 8.79,12.84 C9.15,13.52 10.19,14.09 11.29,14.09 C14.58,14.09 16.96,11.06 16.96,7.3 C16.94,3.7 14,1 10.21,1"/></svg>',
"play": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="6.5,5 14.5,10 6.5,15"/></svg>',
"play-circle": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" stroke-width="1.1" points="8.5 7 13.5 10 8.5 13"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/></svg>',
"plus": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="1" height="17" x="9" y="1"/><rect width="17" height="1" x="1" y="9"/></svg>',
"plus-circle": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9.5" cy="9.5" r="9"/><line fill="none" stroke="#000" x1="9.5" y1="5" x2="9.5" y2="14"/><line fill="none" stroke="#000" x1="5" y1="9.5" x2="14" y2="9.5"/></svg>',
"print": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="4.5 13.5 1.5 13.5 1.5 6.5 18.5 6.5 18.5 13.5 15.5 13.5"/><polyline fill="none" stroke="#000" points="15.5 6.5 15.5 2.5 4.5 2.5 4.5 6.5"/><rect width="11" height="6" fill="none" stroke="#000" x="4.5" y="11.5"/><rect width="8" height="1" x="6" y="13"/><rect width="8" height="1" x="6" y="15"/></svg>',
"pull": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="11" x2="10" y2="2"/><polyline fill="none" stroke="#000" points="6.5 5.5 4 5.5 4 18.5 16 18.5 16 5.5 13.5 5.5"/><polyline fill="none" stroke="#000" points="13.18 8.2 10 11.38 6.83 8.21"/></svg>',
"push": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="11" x2="10" y2="1"/><polyline fill="none" stroke="#000" points="6.5 6.5 4 6.5 4 19.5 16 19.5 16 6.5 13.5 6.5"/><polyline fill="none" stroke="#000" points="6.82 3.88 10 .71 13.17 3.88"/></svg>',
"question": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><circle cx="9.99" cy="14.24" r="1.05"/><path fill="none" stroke="#000" stroke-width="1.2" d="m7.72,7.61c0-3.04,4.55-3.06,4.55-.07,0,.95-.91,1.43-1.49,2.03-.48.49-.72.98-.78,1.65-.01.13-.02.24-.02.35"/></svg>',
"quote-right": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.27,7.79 C17.27,9.45 16.97,10.43 15.99,12.02 C14.98,13.64 13,15.23 11.56,15.97 L11.1,15.08 C12.34,14.2 13.14,13.51 14.02,11.82 C14.27,11.34 14.41,10.92 14.49,10.54 C14.3,10.58 14.09,10.6 13.88,10.6 C12.06,10.6 10.59,9.12 10.59,7.3 C10.59,5.48 12.06,4 13.88,4 C15.39,4 16.67,5.02 17.05,6.42 C17.19,6.82 17.27,7.27 17.27,7.79 L17.27,7.79 Z"/><path d="M8.68,7.79 C8.68,9.45 8.38,10.43 7.4,12.02 C6.39,13.64 4.41,15.23 2.97,15.97 L2.51,15.08 C3.75,14.2 4.55,13.51 5.43,11.82 C5.68,11.34 5.82,10.92 5.9,10.54 C5.71,10.58 5.5,10.6 5.29,10.6 C3.47,10.6 2,9.12 2,7.3 C2,5.48 3.47,4 5.29,4 C6.8,4 8.08,5.02 8.46,6.42 C8.6,6.82 8.68,7.27 8.68,7.79 L8.68,7.79 Z"/></svg>',
"receiver": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.01" d="M6.189,13.611C8.134,15.525 11.097,18.239 13.867,18.257C16.47,18.275 18.2,16.241 18.2,16.241L14.509,12.551L11.539,13.639L6.189,8.29L7.313,5.355L3.76,1.8C3.76,1.8 1.732,3.537 1.7,6.092C1.667,8.809 4.347,11.738 6.189,13.611"/></svg>',
"reddit": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M19 9.05a2.56 2.56 0 0 0-2.56-2.56 2.59 2.59 0 0 0-1.88.82 10.63 10.63 0 0 0-4.14-1v-.08c.58-1.62 1.58-3.89 2.7-4.1.38-.08.77.12 1.19.57a1.15 1.15 0 0 0-.06.37 1.48 1.48 0 1 0 1.51-1.45 1.43 1.43 0 0 0-.76.19A2.29 2.29 0 0 0 12.91 1c-2.11.43-3.39 4.38-3.63 5.19 0 0 0 .11-.06.11a10.65 10.65 0 0 0-3.75 1A2.56 2.56 0 0 0 1 9.05a2.42 2.42 0 0 0 .72 1.76A5.18 5.18 0 0 0 1.24 13c0 3.66 3.92 6.64 8.73 6.64s8.74-3 8.74-6.64a5.23 5.23 0 0 0-.46-2.13A2.58 2.58 0 0 0 19 9.05zm-16.88 0a1.44 1.44 0 0 1 2.27-1.19 7.68 7.68 0 0 0-2.07 1.91 1.33 1.33 0 0 1-.2-.72zM10 18.4c-4.17 0-7.55-2.4-7.55-5.4S5.83 7.53 10 7.53 17.5 10 17.5 13s-3.38 5.4-7.5 5.4zm7.69-8.61a7.62 7.62 0 0 0-2.09-1.91 1.41 1.41 0 0 1 .84-.28 1.47 1.47 0 0 1 1.44 1.45 1.34 1.34 0 0 1-.21.72z"/><path d="M6.69 12.58a1.39 1.39 0 1 1 1.39-1.39 1.38 1.38 0 0 1-1.38 1.39z"/><path d="M14.26 11.2a1.39 1.39 0 1 1-1.39-1.39 1.39 1.39 0 0 1 1.39 1.39z"/><path d="M13.09 14.88a.54.54 0 0 1-.09.77 5.3 5.3 0 0 1-3.26 1.19 5.61 5.61 0 0 1-3.4-1.22.55.55 0 1 1 .73-.83 4.09 4.09 0 0 0 5.25 0 .56.56 0 0 1 .77.09z"/></svg>',
"refresh": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M17.08,11.15 C17.09,11.31 17.1,11.47 17.1,11.64 C17.1,15.53 13.94,18.69 10.05,18.69 C6.16,18.68 3,15.53 3,11.63 C3,7.74 6.16,4.58 10.05,4.58 C10.9,4.58 11.71,4.73 12.46,5"/><polyline fill="none" stroke="#000" points="9.9 2 12.79 4.89 9.79 7.9"/></svg>',
"reply": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.7,13.11 C16.12,10.02 13.84,7.85 11.02,6.61 C10.57,6.41 9.75,6.13 9,5.91 L9,2 L1,9 L9,16 L9,12.13 C10.78,12.47 12.5,13.19 14.09,14.25 C17.13,16.28 18.56,18.54 18.56,18.54 C18.56,18.54 18.81,15.28 17.7,13.11 L17.7,13.11 Z M14.82,13.53 C13.17,12.4 11.01,11.4 8,10.92 L8,13.63 L2.55,9 L8,4.25 L8,6.8 C8.3,6.86 9.16,7.02 10.37,7.49 C13.3,8.65 15.54,10.96 16.65,13.08 C16.97,13.7 17.48,14.86 17.68,16 C16.87,15.05 15.73,14.15 14.82,13.53 L14.82,13.53 Z"/></svg>',
"rss": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="3.12" cy="16.8" r="1.85"/><path fill="none" stroke="#000" stroke-width="1.1" d="M1.5,8.2 C1.78,8.18 2.06,8.16 2.35,8.16 C7.57,8.16 11.81,12.37 11.81,17.57 C11.81,17.89 11.79,18.19 11.76,18.5"/><path fill="none" stroke="#000" stroke-width="1.1" d="M1.5,2.52 C1.78,2.51 2.06,2.5 2.35,2.5 C10.72,2.5 17.5,9.24 17.5,17.57 C17.5,17.89 17.49,18.19 17.47,18.5"/></svg>',
"search": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9" cy="9" r="7"/><path fill="none" stroke="#000" stroke-width="1.1" d="M14,14 L18,18 L14,14 Z"/></svg>',
"server": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="1" height="2" x="3" y="3"/><rect width="1" height="2" x="5" y="3"/><rect width="1" height="2" x="7" y="3"/><rect width="1" height="1" x="16" y="3"/><rect width="1" height="1" x="16" y="10"/><circle fill="none" stroke="#000" cx="9.9" cy="17.4" r="1.4"/><rect width="1" height="2" x="3" y="10"/><rect width="1" height="2" x="5" y="10"/><rect width="1" height="2" x="9.5" y="14"/><rect width="6" height="1" x="3" y="17"/><rect width="6" height="1" x="11" y="17"/><rect width="17" height="5" fill="none" stroke="#000" x="1.5" y="1.5"/><rect width="17" height="5" fill="none" stroke="#000" x="1.5" y="8.5"/></svg>',
"settings": '<svg width="20" height="20" viewBox="0 0 20 20"><ellipse fill="none" stroke="#000" cx="6.11" cy="3.55" rx="2.11" ry="2.15"/><ellipse fill="none" stroke="#000" cx="6.11" cy="15.55" rx="2.11" ry="2.15"/><circle fill="none" stroke="#000" cx="13.15" cy="9.55" r="2.15"/><rect width="3" height="1" x="1" y="3"/><rect width="8" height="1" x="10" y="3"/><rect width="8" height="1" x="1" y="9"/><rect width="3" height="1" x="15" y="9"/><rect width="3" height="1" x="1" y="15"/><rect width="8" height="1" x="10" y="15"/></svg>',
"shrink": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M2,18l6-6"/><polyline fill="none" stroke="#000" points="4 11.5 8.49 11.5 8.49 15.99"/><path fill="none" stroke="#000" stroke-width="1.1" d="M18,2l-6,6"/><polyline fill="none" stroke="#000" points="15.99 8.49 11.5 8.49 11.5 4"/></svg>',
"sign-in": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="7 2 17 2 17 17 7 17 7 16 16 16 16 3 7 3 7 2"/><line stroke="#000" x1="3" y1="9.5" x2="12" y2="9.5"/><polyline fill="none" stroke="#000" points="9.2 6.33 12.37 9.5 9.2 12.67"/></svg>',
"sign-out": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="13 2 3 2 3 17 13 17 13 16 4 16 4 3 13 3 13 2"/><line stroke="#000" x1="7.96" y1="9.49" x2="16.96" y2="9.49"/><polyline fill="none" stroke="#000" points="14.17 6.31 17.35 9.48 14.17 12.66"/></svg>',
"signal": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m7.86,1.34l.2.81c-.79.19-1.54.51-2.24.93l-.43-.71c.77-.46,1.6-.81,2.47-1.02Zm4.28,0l-.2.81c.79.19,1.54.51,2.24.93l.43-.72c-.77-.46-1.6-.81-2.47-1.02h0ZM2.37,5.39c-.46.77-.81,1.6-1.02,2.47l.81.2c.19-.79.51-1.54.93-2.24l-.71-.43Zm-.45,4.61c0-.41.03-.81.09-1.21l-.83-.13c-.13.89-.13,1.79,0,2.67l.83-.13c-.06-.4-.09-.81-.09-1.21h0Zm12.69,7.63l-.43-.72c-.7.42-1.45.73-2.24.93l.2.81c.87-.21,1.7-.56,2.46-1.02h0Zm3.47-7.63c0,.41-.03.81-.09,1.21l.83.13c.13-.89.13-1.79,0-2.67l-.83.13c.06.4.09.81.09,1.21Zm.58,2.14l-.81-.2c-.19.79-.51,1.54-.93,2.24l.72.43c.46-.77.81-1.6,1.02-2.47h0Zm-7.44,5.85c-.8.12-1.62.12-2.42,0l-.13.83c.89.13,1.79.13,2.67,0l-.13-.83Zm5.29-3.2c-.48.65-1.06,1.23-1.71,1.71l.5.67c.72-.53,1.36-1.16,1.89-1.88l-.67-.5Zm-1.71-11.29c.65.48,1.23,1.06,1.71,1.71l.67-.5c-.53-.72-1.17-1.35-1.88-1.88l-.5.67Zm-11.29,1.71c.48-.65,1.06-1.23,1.71-1.71l-.5-.67c-.72.53-1.35,1.17-1.88,1.88l.67.5Zm14.14.18l-.72.43c.42.7.73,1.45.93,2.24l.81-.2c-.21-.87-.56-1.7-1.02-2.46h0Zm-8.84-3.38c.8-.12,1.62-.12,2.42,0l.13-.83c-.89-.13-1.79-.13-2.67,0l.13.83Zm-4.86,15.38l-1.73.4.4-1.73-.81-.19-.4,1.73c-.07.28.02.58.22.78s.5.29.78.22l1.73-.39-.19-.82Zm-1.96-2.26l.81.19.28-1.2c-.41-.68-.71-1.42-.9-2.19l-.81.2c.18.74.46,1.45.82,2.12l-.2.88Zm3.9,1.81l-1.19.28.19.81.88-.2c.67.36,1.38.64,2.12.82l.2-.81c-.77-.19-1.51-.5-2.19-.9h0ZM10,2.75c-2.63,0-5.06,1.43-6.34,3.74s-1.19,5.12.21,7.36l-.7,2.97,2.97-.7c2.61,1.64,5.96,1.46,8.37-.46s3.34-5.15,2.32-8.06c-1.02-2.91-3.77-4.85-6.85-4.85Z"/></svg>',
"social": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" stroke-width="1.1" x1="13.4" y1="14" x2="6.3" y2="10.7"/><line fill="none" stroke="#000" stroke-width="1.1" x1="13.5" y1="5.5" x2="6.5" y2="8.8"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="15.5" cy="4.6" r="2.3"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="15.5" cy="14.8" r="2.3"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="4.5" cy="9.8" r="2.3"/></svg>',
"sorting": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="7" y1="3.38" x2="7" y2="15.38"/><polyline fill="none" stroke="#000" points="10.18 12.75 7 15.93 3.83 12.76"/><line fill="none" stroke="#000" x1="13" y1="16.62" x2="13" y2="4.62"/><polyline fill="none" stroke="#000" points="9.82 7.25 13 4.07 16.17 7.24"/></svg>',
"soundcloud": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.2,9.4c-0.4,0-0.8,0.1-1.101,0.2c-0.199-2.5-2.399-4.5-5-4.5c-0.6,0-1.2,0.1-1.7,0.3C9.2,5.5,9.1,5.6,9.1,5.6V15h8 c1.601,0,2.801-1.2,2.801-2.8C20,10.7,18.7,9.4,17.2,9.4L17.2,9.4z"/><rect width="1.5" height="8.5" x="6" y="6.5"/><rect width="1.5" height="7" x="3" y="8"/><rect width="1.5" height="5" y="10"/></svg>',
"star": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" stroke-width="1.01" points="10 2 12.63 7.27 18.5 8.12 14.25 12.22 15.25 18 10 15.27 4.75 18 5.75 12.22 1.5 8.12 7.37 7.27"/></svg>',
"strikethrough": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M6,13.02 L6.65,13.02 C7.64,15.16 8.86,16.12 10.41,16.12 C12.22,16.12 12.92,14.93 12.92,13.89 C12.92,12.55 11.99,12.03 9.74,11.23 C8.05,10.64 6.23,10.11 6.23,7.83 C6.23,5.5 8.09,4.09 10.4,4.09 C11.44,4.09 12.13,4.31 12.72,4.54 L13.33,4 L13.81,4 L13.81,7.59 L13.16,7.59 C12.55,5.88 11.52,4.89 10.07,4.89 C8.84,4.89 7.89,5.69 7.89,7.03 C7.89,8.29 8.89,8.78 10.88,9.45 C12.57,10.03 14.38,10.6 14.38,12.91 C14.38,14.75 13.27,16.93 10.18,16.93 C9.18,16.93 8.17,16.69 7.46,16.39 L6.52,17 L6,17 L6,13.02 L6,13.02 Z"/><rect width="15" height="1" x="3" y="10"/></svg>',
"table": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="18" height="1" x="1" y="3"/><rect width="18" height="1" x="1" y="7"/><rect width="18" height="1" x="1" y="11"/><rect width="18" height="1" x="1" y="15"/></svg>',
"tablet": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M5,18.5 C4.2,18.5 3.5,17.8 3.5,17 L3.5,3 C3.5,2.2 4.2,1.5 5,1.5 L16,1.5 C16.8,1.5 17.5,2.2 17.5,3 L17.5,17 C17.5,17.8 16.8,18.5 16,18.5 L5,18.5 L5,18.5 L5,18.5 Z"/><circle cx="10.5" cy="16.3" r=".8"/></svg>',
"tablet-landscape": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M1.5,5 C1.5,4.2 2.2,3.5 3,3.5 L17,3.5 C17.8,3.5 18.5,4.2 18.5,5 L18.5,16 C18.5,16.8 17.8,17.5 17,17.5 L3,17.5 C2.2,17.5 1.5,16.8 1.5,16 L1.5,5 L1.5,5 L1.5,5 Z"/><circle cx="3.7" cy="10.5" r=".8"/></svg>',
"tag": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M17.5,3.71 L17.5,7.72 C17.5,7.96 17.4,8.2 17.21,8.39 L8.39,17.2 C7.99,17.6 7.33,17.6 6.93,17.2 L2.8,13.07 C2.4,12.67 2.4,12.01 2.8,11.61 L11.61,2.8 C11.81,2.6 12.08,2.5 12.34,2.5 L16.19,2.5 C16.52,2.5 16.86,2.63 17.11,2.88 C17.35,3.11 17.48,3.4 17.5,3.71 L17.5,3.71 Z"/><circle cx="14" cy="6" r="1"/></svg>',
"telegram": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m10,1.09C5.08,1.09,1.09,5.08,1.09,10s3.99,8.91,8.91,8.91,8.91-3.99,8.91-8.91S14.92,1.09,10,1.09Zm4.25,5.8c-.03.36-.23,1.62-.44,2.99-.31,1.93-.64,4.04-.64,4.04,0,0-.05.59-.49.7s-1.16-.36-1.29-.46c-.1-.08-1.93-1.24-2.6-1.8-.18-.15-.39-.46.03-.82.93-.85,2.04-1.91,2.7-2.58.31-.31.62-1.03-.67-.15-1.83,1.26-3.63,2.45-3.63,2.45,0,0-.41.26-1.19.03-.77-.23-1.67-.54-1.67-.54,0,0-.62-.39.44-.8h0s4.46-1.83,6-2.47c.59-.26,2.6-1.08,2.6-1.08,0,0,.93-.36.85.52Z"/></svg>',
"threads": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m14.47,9.29c-.08-.04-.16-.08-.25-.11-.14-2.66-1.6-4.18-4.04-4.2-.01,0-.02,0-.03,0-1.46,0-2.67.62-3.42,1.76l1.34.92c.56-.85,1.43-1.03,2.08-1.03,0,0,.01,0,.02,0,.8,0,1.41.24,1.8.69.29.33.48.79.57,1.37-.71-.12-1.48-.16-2.31-.11-2.32.13-3.81,1.49-3.71,3.37.05.95.53,1.77,1.34,2.31.69.45,1.57.67,2.49.62,1.21-.07,2.16-.53,2.83-1.38.5-.64.82-1.48.96-2.52.58.35,1.01.81,1.24,1.36.4.94.43,2.48-.83,3.74-1.1,1.1-2.43,1.58-4.43,1.59-2.22-.02-3.9-.73-4.99-2.12-1.02-1.3-1.55-3.18-1.57-5.58.02-2.4.55-4.28,1.57-5.58,1.09-1.39,2.77-2.1,4.99-2.12,2.24.02,3.95.73,5.08,2.13.56.68.98,1.54,1.25,2.55l1.57-.42c-.33-1.23-.86-2.3-1.58-3.18-1.45-1.79-3.58-2.7-6.32-2.72h-.01c-2.73.02-4.84.94-6.25,2.73-1.26,1.6-1.9,3.82-1.93,6.61h0s0,.01,0,.01c.02,2.79.67,5.01,1.93,6.61,1.41,1.8,3.51,2.71,6.25,2.73h.01c2.43-.02,4.14-.65,5.55-2.06,1.85-1.84,1.79-4.16,1.18-5.58-.44-1.02-1.27-1.84-2.41-2.39Zm-4.2,3.95c-1.02.06-2.07-.4-2.12-1.38-.04-.72.52-1.53,2.19-1.63.19-.01.38-.02.56-.02.61,0,1.17.06,1.69.17-.19,2.41-1.32,2.8-2.32,2.85Z"/></svg>',
"thumbnails": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="5" height="5" fill="none" stroke="#000" x="3.5" y="3.5"/><rect width="5" height="5" fill="none" stroke="#000" x="11.5" y="3.5"/><rect width="5" height="5" fill="none" stroke="#000" x="11.5" y="11.5"/><rect width="5" height="5" fill="none" stroke="#000" x="3.5" y="11.5"/></svg>',
"tiktok": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.24,6V8.82a6.79,6.79,0,0,1-4-1.28v5.81A5.26,5.26,0,1,1,8,8.1a4.36,4.36,0,0,1,.72.05v2.9A2.57,2.57,0,0,0,7.64,11a2.4,2.4,0,1,0,2.77,2.38V2h2.86a4,4,0,0,0,1.84,3.38A4,4,0,0,0,17.24,6Z"/></svg>',
"trash": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="6.5 3 6.5 1.5 13.5 1.5 13.5 3"/><polyline fill="none" stroke="#000" points="4.5 4 4.5 18.5 15.5 18.5 15.5 4"/><rect width="1" height="9" x="8" y="7"/><rect width="1" height="9" x="11" y="7"/><rect width="16" height="1" x="2" y="3"/></svg>',
"triangle-down": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="5 7 15 7 10 12"/></svg>',
"triangle-left": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="12 5 7 10 12 15"/></svg>',
"triangle-right": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="8 5 13 10 8 15"/></svg>',
"triangle-up": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="5 13 10 8 15 13"/></svg>',
"tripadvisor": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M19.021,7.866C19.256,6.862,20,5.854,20,5.854h-3.346C14.781,4.641,12.504,4,9.98,4C7.363,4,4.999,4.651,3.135,5.876H0 c0,0,0.738,0.987,0.976,1.988c-0.611,0.837-0.973,1.852-0.973,2.964c0,2.763,2.249,5.009,5.011,5.009 c1.576,0,2.976-0.737,3.901-1.879l1.063,1.599l1.075-1.615c0.475,0.611,1.1,1.111,1.838,1.451c1.213,0.547,2.574,0.612,3.825,0.15 c2.589-0.963,3.913-3.852,2.964-6.439c-0.175-0.463-0.4-0.876-0.675-1.238H19.021z M16.38,14.594 c-1.002,0.371-2.088,0.328-3.06-0.119c-0.688-0.317-1.252-0.817-1.657-1.438c-0.164-0.25-0.313-0.52-0.417-0.811 c-0.124-0.328-0.186-0.668-0.217-1.014c-0.063-0.689,0.037-1.396,0.339-2.043c0.448-0.971,1.251-1.71,2.25-2.079 c2.075-0.765,4.375,0.3,5.14,2.366c0.762,2.066-0.301,4.37-2.363,5.134L16.38,14.594L16.38,14.594z M8.322,13.066 c-0.72,1.059-1.935,1.76-3.309,1.76c-2.207,0-4.001-1.797-4.001-3.996c0-2.203,1.795-4.002,4.001-4.002 c2.204,0,3.999,1.8,3.999,4.002c0,0.137-0.024,0.261-0.04,0.396c-0.067,0.678-0.284,1.313-0.648,1.853v-0.013H8.322z M2.472,10.775 c0,1.367,1.112,2.479,2.476,2.479c1.363,0,2.472-1.11,2.472-2.479c0-1.359-1.11-2.468-2.472-2.468 C3.584,8.306,2.473,9.416,2.472,10.775L2.472,10.775z M12.514,10.775c0,1.367,1.104,2.479,2.471,2.479 c1.363,0,2.474-1.108,2.474-2.479c0-1.359-1.11-2.468-2.474-2.468c-1.364,0-2.477,1.109-2.477,2.468H12.514z M3.324,10.775 c0-0.893,0.726-1.618,1.614-1.618c0.889,0,1.625,0.727,1.625,1.618c0,0.898-0.725,1.627-1.625,1.627 c-0.901,0-1.625-0.729-1.625-1.627H3.324z M13.354,10.775c0-0.893,0.726-1.618,1.627-1.618c0.886,0,1.61,0.727,1.61,1.618 c0,0.898-0.726,1.627-1.626,1.627s-1.625-0.729-1.625-1.627H13.354z M9.977,4.875c1.798,0,3.425,0.324,4.849,0.968 c-0.535,0.015-1.061,0.108-1.586,0.3c-1.264,0.463-2.264,1.388-2.815,2.604c-0.262,0.551-0.398,1.133-0.448,1.72 C9.79,7.905,7.677,5.873,5.076,5.82C6.501,5.208,8.153,4.875,9.94,4.875H9.977z"/></svg>',
"tumblr": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M6.885,8.598c0,0,0,3.393,0,4.996c0,0.282,0,0.66,0.094,0.942c0.377,1.509,1.131,2.545,2.545,3.11 c1.319,0.472,2.356,0.472,3.676,0c0.565-0.188,1.132-0.659,1.132-0.659l-0.849-2.263c0,0-1.036,0.378-1.603,0.283 c-0.565-0.094-1.226-0.66-1.226-1.508c0-1.603,0-4.902,0-4.902h2.828V5.771h-2.828V2H8.205c0,0-0.094,0.66-0.188,0.942 C7.828,3.791,7.262,4.733,6.603,5.394C5.848,6.147,5,6.43,5,6.43v2.168H6.885z"/></svg>',
"tv": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="6" height="1" x="7" y="16"/><rect width="19" height="11" fill="none" stroke="#000" x=".5" y="3.5"/></svg>',
"twitch": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M5.23,1,2,4.23V15.85H5.88v3.23L9.1,15.85h2.59L17.5,10V1Zm11,8.4L13.62,12H11L8.78,14.24V12H5.88V2.29H16.21Z"/><rect width="1.29" height="3.88" x="12.98" y="4.55"/><rect width="1.29" height="3.88" x="9.43" y="4.55"/></svg>',
"twitter": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M19,4.74 C18.339,5.029 17.626,5.229 16.881,5.32 C17.644,4.86 18.227,4.139 18.503,3.28 C17.79,3.7 17.001,4.009 16.159,4.17 C15.485,3.45 14.526,3 13.464,3 C11.423,3 9.771,4.66 9.771,6.7 C9.771,6.99 9.804,7.269 9.868,7.539 C6.795,7.38 4.076,5.919 2.254,3.679 C1.936,4.219 1.754,4.86 1.754,5.539 C1.754,6.82 2.405,7.95 3.397,8.61 C2.79,8.589 2.22,8.429 1.723,8.149 L1.723,8.189 C1.723,9.978 2.997,11.478 4.686,11.82 C4.376,11.899 4.049,11.939 3.713,11.939 C3.475,11.939 3.245,11.919 3.018,11.88 C3.49,13.349 4.852,14.419 6.469,14.449 C5.205,15.429 3.612,16.019 1.882,16.019 C1.583,16.019 1.29,16.009 1,15.969 C2.635,17.019 4.576,17.629 6.662,17.629 C13.454,17.629 17.17,12 17.17,7.129 C17.17,6.969 17.166,6.809 17.157,6.649 C17.879,6.129 18.504,5.478 19,4.74"/></svg>',
"uikit": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="14.4,3.1 11.3,5.1 15,7.3 15,12.9 10,15.7 5,12.9 5,8.5 2,6.8 2,14.8 9.9,19.5 18,14.8 18,5.3"/><polygon points="9.8,4.2 6.7,2.4 9.8,0.4 12.9,2.3"/></svg>',
"unlock": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="10" fill="none" stroke="#000" x="3.5" y="8.5"/><path fill="none" stroke="#000" d="M6.5,8.5 L6.5,4.9 C6.5,3 8.1,1.5 10,1.5 C11.9,1.5 13.5,3 13.5,4.9"/></svg>',
"upload": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="15.17" x2="10" y2="3.17"/><polyline fill="none" stroke="#000" points="13.84 6.63 10 2.8 6.16 6.64"/><line fill="#fff" stroke="#000" x1="3.5" y1="17.5" x2="16.5" y2="17.5"/></svg>',
"user": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9.9" cy="6.4" r="4.4"/><path fill="none" stroke="#000" stroke-width="1.1" d="M1.5,19 C2.3,14.5 5.8,11.2 10,11.2 C14.2,11.2 17.7,14.6 18.5,19.2"/></svg>',
"users": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="7.7" cy="8.6" r="3.5"/><path fill="none" stroke="#000" stroke-width="1.1" d="M1,18.1 C1.7,14.6 4.4,12.1 7.6,12.1 C10.9,12.1 13.7,14.8 14.3,18.3"/><path fill="none" stroke="#000" stroke-width="1.1" d="M11.4,4 C12.8,2.4 15.4,2.8 16.3,4.7 C17.2,6.6 15.7,8.9 13.6,8.9 C16.5,8.9 18.8,11.3 19.2,14.1"/></svg>',
"video-camera": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="19.5 5.9 19.5 14.1 14.5 10.4 14.5 15.5 .5 15.5 .5 4.5 14.5 4.5 14.5 9.6 19.5 5.9"/></svg>',
"vimeo": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M2.065,7.59C1.84,7.367,1.654,7.082,1.468,6.838c-0.332-0.42-0.137-0.411,0.274-0.772c1.026-0.91,2.004-1.896,3.127-2.688 c1.017-0.713,2.365-1.173,3.286-0.039c0.849,1.045,0.869,2.629,1.084,3.891c0.215,1.309,0.421,2.648,0.88,3.901 c0.127,0.352,0.37,1.018,0.81,1.074c0.567,0.078,1.145-0.917,1.408-1.289c0.684-0.987,1.611-2.317,1.494-3.587 c-0.115-1.349-1.572-1.095-2.482-0.773c0.146-1.514,1.555-3.216,2.912-3.792c1.439-0.597,3.579-0.587,4.302,1.036 c0.772,1.759,0.078,3.802-0.763,5.396c-0.918,1.731-2.1,3.333-3.363,4.829c-1.114,1.329-2.432,2.787-4.093,3.422 c-1.897,0.723-3.021-0.686-3.667-2.318c-0.705-1.777-1.056-3.771-1.565-5.621C4.898,8.726,4.644,7.836,4.136,7.191 C3.473,6.358,2.72,7.141,2.065,7.59C1.977,7.502,2.115,7.551,2.065,7.59L2.065,7.59z"/></svg>',
"warning": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="14" r="1"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><path d="M10.97,7.72 C10.85,9.54 10.56,11.29 10.56,11.29 C10.51,11.87 10.27,12 9.99,12 C9.69,12 9.49,11.87 9.43,11.29 C9.43,11.29 9.16,9.54 9.03,7.72 C8.96,6.54 9.03,6 9.03,6 C9.03,5.45 9.46,5.02 9.99,5 C10.53,5.01 10.97,5.44 10.97,6 C10.97,6 11.04,6.54 10.97,7.72 L10.97,7.72 Z"/></svg>',
"whatsapp": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M16.7,3.3c-1.8-1.8-4.1-2.8-6.7-2.8c-5.2,0-9.4,4.2-9.4,9.4c0,1.7,0.4,3.3,1.3,4.7l-1.3,4.9l5-1.3c1.4,0.8,2.9,1.2,4.5,1.2 l0,0l0,0c5.2,0,9.4-4.2,9.4-9.4C19.5,7.4,18.5,5,16.7,3.3 M10.1,17.7L10.1,17.7c-1.4,0-2.8-0.4-4-1.1l-0.3-0.2l-3,0.8l0.8-2.9 l-0.2-0.3c-0.8-1.2-1.2-2.7-1.2-4.2c0-4.3,3.5-7.8,7.8-7.8c2.1,0,4.1,0.8,5.5,2.3c1.5,1.5,2.3,3.4,2.3,5.5 C17.9,14.2,14.4,17.7,10.1,17.7 M14.4,11.9c-0.2-0.1-1.4-0.7-1.6-0.8c-0.2-0.1-0.4-0.1-0.5,0.1c-0.2,0.2-0.6,0.8-0.8,0.9 c-0.1,0.2-0.3,0.2-0.5,0.1c-0.2-0.1-1-0.4-1.9-1.2c-0.7-0.6-1.2-1.4-1.3-1.6c-0.1-0.2,0-0.4,0.1-0.5C8,8.8,8.1,8.7,8.2,8.5 c0.1-0.1,0.2-0.2,0.2-0.4c0.1-0.2,0-0.3,0-0.4C8.4,7.6,7.9,6.5,7.7,6C7.5,5.5,7.3,5.6,7.2,5.6c-0.1,0-0.3,0-0.4,0 c-0.2,0-0.4,0.1-0.6,0.3c-0.2,0.2-0.8,0.8-0.8,2c0,1.2,0.8,2.3,1,2.4c0.1,0.2,1.7,2.5,4,3.5c0.6,0.2,1,0.4,1.3,0.5 c0.6,0.2,1.1,0.2,1.5,0.1c0.5-0.1,1.4-0.6,1.6-1.1c0.2-0.5,0.2-1,0.1-1.1C14.8,12.1,14.6,12,14.4,11.9"/></svg>',
"wordpress": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M10,0.5c-5.2,0-9.5,4.3-9.5,9.5s4.3,9.5,9.5,9.5c5.2,0,9.5-4.3,9.5-9.5S15.2,0.5,10,0.5L10,0.5L10,0.5z M15.6,3.9h-0.1 c-0.8,0-1.4,0.7-1.4,1.5c0,0.7,0.4,1.3,0.8,1.9c0.3,0.6,0.7,1.3,0.7,2.3c0,0.7-0.3,1.5-0.6,2.7L14.1,15l-3-8.9 c0.5,0,0.9-0.1,0.9-0.1C12.5,6,12.5,5.3,12,5.4c0,0-1.3,0.1-2.2,0.1C9,5.5,7.7,5.4,7.7,5.4C7.2,5.3,7.2,6,7.6,6c0,0,0.4,0.1,0.9,0.1 l1.3,3.5L8,15L5,6.1C5.5,6.1,5.9,6,5.9,6C6.4,6,6.3,5.3,5.9,5.4c0,0-1.3,0.1-2.2,0.1c-0.2,0-0.3,0-0.5,0c1.5-2.2,4-3.7,6.9-3.7 C12.2,1.7,14.1,2.6,15.6,3.9L15.6,3.9L15.6,3.9z M2.5,6.6l3.9,10.8c-2.7-1.3-4.6-4.2-4.6-7.4C1.8,8.8,2,7.6,2.5,6.6L2.5,6.6L2.5,6.6 z M10.2,10.7l2.5,6.9c0,0,0,0.1,0.1,0.1C11.9,18,11,18.2,10,18.2c-0.8,0-1.6-0.1-2.3-0.3L10.2,10.7L10.2,10.7L10.2,10.7z M14.2,17.1 l2.5-7.3c0.5-1.2,0.6-2.1,0.6-2.9c0-0.3,0-0.6-0.1-0.8c0.6,1.2,1,2.5,1,4C18.3,13,16.6,15.7,14.2,17.1L14.2,17.1L14.2,17.1z"/></svg>',
"world": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M1,10.5 L19,10.5"/><path fill="none" stroke="#000" d="M2.35,15.5 L17.65,15.5"/><path fill="none" stroke="#000" d="M2.35,5.5 L17.523,5.5"/><path fill="none" stroke="#000" d="M10,19.46 L9.98,19.46 C7.31,17.33 5.61,14.141 5.61,10.58 C5.61,7.02 7.33,3.83 10,1.7 C10.01,1.7 9.99,1.7 10,1.7 L10,1.7 C12.67,3.83 14.4,7.02 14.4,10.58 C14.4,14.141 12.67,17.33 10,19.46 L10,19.46 L10,19.46 L10,19.46 Z"/><circle fill="none" stroke="#000" cx="10" cy="10.5" r="9"/></svg>',
"x": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m15.08,2.1h2.68l-5.89,6.71,6.88,9.1h-5.4l-4.23-5.53-4.84,5.53H1.59l6.24-7.18L1.24,2.1h5.54l3.82,5.05,4.48-5.05Zm-.94,14.23h1.48L6,3.61h-1.6l9.73,12.71h0Z"/></svg>',
"xing": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M4.4,4.56 C4.24,4.56 4.11,4.61 4.05,4.72 C3.98,4.83 3.99,4.97 4.07,5.12 L5.82,8.16 L5.82,8.17 L3.06,13.04 C2.99,13.18 2.99,13.33 3.06,13.44 C3.12,13.55 3.24,13.62 3.4,13.62 L6,13.62 C6.39,13.62 6.57,13.36 6.71,13.12 C6.71,13.12 9.41,8.35 9.51,8.16 C9.49,8.14 7.72,5.04 7.72,5.04 C7.58,4.81 7.39,4.56 6.99,4.56 L4.4,4.56 L4.4,4.56 Z"/><path d="M15.3,1 C14.91,1 14.74,1.25 14.6,1.5 C14.6,1.5 9.01,11.42 8.82,11.74 C8.83,11.76 12.51,18.51 12.51,18.51 C12.64,18.74 12.84,19 13.23,19 L15.82,19 C15.98,19 16.1,18.94 16.16,18.83 C16.23,18.72 16.23,18.57 16.16,18.43 L12.5,11.74 L12.5,11.72 L18.25,1.56 C18.32,1.42 18.32,1.27 18.25,1.16 C18.21,1.06 18.08,1 17.93,1 L15.3,1 L15.3,1 Z"/></svg>',
"yelp": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.175,14.971c-0.112,0.77-1.686,2.767-2.406,3.054c-0.246,0.1-0.487,0.076-0.675-0.069 c-0.122-0.096-2.446-3.859-2.446-3.859c-0.194-0.293-0.157-0.682,0.083-0.978c0.234-0.284,0.581-0.393,0.881-0.276 c0.016,0.01,4.21,1.394,4.332,1.482c0.178,0.148,0.263,0.379,0.225,0.646L17.175,14.971L17.175,14.971z M11.464,10.789 c-0.203-0.307-0.199-0.666,0.009-0.916c0,0,2.625-3.574,2.745-3.657c0.203-0.135,0.452-0.141,0.69-0.025 c0.691,0.335,2.085,2.405,2.167,3.199v0.027c0.024,0.271-0.082,0.491-0.273,0.623c-0.132,0.083-4.43,1.155-4.43,1.155 c-0.322,0.096-0.68-0.06-0.882-0.381L11.464,10.789z M9.475,9.563C9.32,9.609,8.848,9.757,8.269,8.817c0,0-3.916-6.16-4.007-6.351 c-0.057-0.212,0.011-0.455,0.202-0.65C5.047,1.211,8.21,0.327,9.037,0.529c0.27,0.069,0.457,0.238,0.522,0.479 c0.047,0.266,0.433,5.982,0.488,7.264C10.098,9.368,9.629,9.517,9.475,9.563z M9.927,19.066c-0.083,0.225-0.273,0.373-0.54,0.421 c-0.762,0.13-3.15-0.751-3.647-1.342c-0.096-0.131-0.155-0.262-0.167-0.394c-0.011-0.095,0-0.189,0.036-0.272 c0.061-0.155,2.917-3.538,2.917-3.538c0.214-0.272,0.595-0.355,0.952-0.213c0.345,0.13,0.56,0.428,0.536,0.749 C10.014,14.479,9.977,18.923,9.927,19.066z M3.495,13.912c-0.235-0.009-0.444-0.148-0.568-0.382c-0.089-0.17-0.151-0.453-0.19-0.794 C2.63,11.701,2.761,10.144,3.07,9.648c0.145-0.226,0.357-0.345,0.592-0.336c0.154,0,4.255,1.667,4.255,1.667 c0.321,0.118,0.521,0.453,0.5,0.833c-0.023,0.37-0.236,0.655-0.551,0.738L3.495,13.912z"/></svg>',
"yootheme": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m16.15,5.48c-1.37,0-2.45.61-3.11,1.54-.66-.93-1.74-1.54-3.11-1.54-1.75,0-3.03,1-3.57,2.41v-2.22h-2.01v4.45c0,.85-.31,1.35-1.18,1.35s-1.18-.5-1.18-1.35v-4.45H0v4.86c0,.7.17,1.33.53,1.82.34.49.88.85,1.6,1v3.16h2.1v-3.16c1.28-.28,1.96-1.17,2.1-2.35.52,1.44,1.81,2.48,3.59,2.48,1.37,0,2.45-.61,3.11-1.54.66.93,1.74,1.54,3.11,1.54,2.37,0,3.85-1.82,3.85-4s-1.49-4-3.85-4Zm-6.22,5.99c-1.11,0-1.85-.72-1.85-1.99s.74-1.99,1.85-1.99,1.85.72,1.85,1.99-.74,1.99-1.85,1.99Zm6.22,0c-1.11,0-1.85-.72-1.85-1.99s.74-1.99,1.85-1.99,1.85.72,1.85,1.99-.74,1.99-1.85,1.99Z"/></svg>',
"youtube": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M15,4.1c1,0.1,2.3,0,3,0.8c0.8,0.8,0.9,2.1,0.9,3.1C19,9.2,19,10.9,19,12c-0.1,1.1,0,2.4-0.5,3.4c-0.5,1.1-1.4,1.5-2.5,1.6 c-1.2,0.1-8.6,0.1-11,0c-1.1-0.1-2.4-0.1-3.2-1c-0.7-0.8-0.7-2-0.8-3C1,11.8,1,10.1,1,8.9c0-1.1,0-2.4,0.5-3.4C2,4.5,3,4.3,4.1,4.2 C5.3,4.1,12.6,4,15,4.1z M8,7.5v6l5.5-3L8,7.5z"/></svg>'
});
}
if (typeof window !== "undefined" && window.UIkit) {
window.UIkit.use(plugin);
}
return plugin;
}));

1
static/js/uikit-icons.min.js vendored Normal file

File diff suppressed because one or more lines are too long

10077
static/js/uikit.js Normal file

File diff suppressed because it is too large Load Diff

1
static/js/uikit.min.js vendored Normal file

File diff suppressed because one or more lines are too long

52
templates/feature.html Normal file
View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="en" dir="ltr" id="main_html">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
<title id="title">Feature - {{feature['feature_name']}}</title>
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
<!-- Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<!-- Material Symbols - Outlined Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<!-- Material Symbols - Rounded Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
<!-- Material Symbols - Sharp Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}"/>
<script src="{{ url_for('static', filename='js/uikit.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/uikit-icons.min.js') }}"></script>
</head>
<body>
<div class="uk-container">
<div class="uk-section">
<div>
<h1>View/Edit Feature</h1>
<p class="uk-text-meta">Below you can view and edit <strong>{{feature['feature_name']}} as well as its elements.</strong></p>
</div>
<div class="uk-margin">
<label for="featureName">Feature Name</label>
<input id="featureName" class="uk-input" type="text" placeholder="" aria-label="Input" value="{{feature['feature_name']}}">
</div>
<div class="uk-margin">
<label for="featureDescription">Feature Description</label>
<textarea id="featureDescription" class="uk-textarea" rows="15"
uk-tooltip="It is possible to use html tags within descriptions that will be rendered in other parts of the system."
aria-label="Textarea" value="{{feature['feature_description']}}" autocomplete="off">{{feature['feature_description']}}</textarea>
</div>
<hr class="uk-divider-icon">
<div>
<button onclick="saveFeature()" class="uk-button uk-button-primary">Save Changes</button>
</div>
</div>
</div>
</body>
<script src="{{ url_for('static', filename='js/featureHandler.js') }}"></script>
<script>
const feature_uuid = {{feature|tojson}}.feature_uuid;
</script>
</html>

62
templates/login.html Normal file
View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en" dir="ltr" id="main_html">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
<title id="title">Login</title>
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
<!-- Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<!-- Material Symbols - Outlined Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<!-- Material Symbols - Rounded Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
<!-- Material Symbols - Sharp Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}"/>
<script src="{{ url_for('static', filename='js/uikit.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/uikit-icons.min.js') }}"></script>
</head>
<body>
<div class="uk-container">
<div class="uk-section">
<div class="uk-flex-center" uk-grid>
<div class="uk-card uk-card-default uk-card-body uk-width-1-2@m uk-flex-center">
<h1 class="uk-text-center">Lisium</h1>
<ul uk-tab>
<li><a href="#">Login</a></li>
</ul>
<div class="uk-switcher">
<div class="uk-grid-small" uk-grid>
<div class="uk-width-1-1">
<div class="uk-margin">
<label class="uk-form-label" for="login_username">Username</label>
<div class="uk-form-controls">
<input class="uk-input" id="login_username" type="text">
</div>
</div>
</div>
<div class="uk-width-1-1">
<div class="uk-margin">
<label class="uk-form-label" for="login_password">Password</label>
<div class="uk-form-controls">
<input onkeydown="" class="uk-input" id="login_password" type="password">
</div>
</div>
</div>
<div class="uk-width-1-1">
<a onclick="authenticateLogin()" class="uk-button uk-button-primary uk-align-center">Login</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="{{ url_for('static', filename='js/loginHandler.js') }}"></script>
</html>

72
templates/package.html Normal file
View File

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en" dir="ltr" id="main_html">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
<title id="title"></title>
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
<!-- Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<!-- Material Symbols - Outlined Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<!-- Material Symbols - Rounded Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
<!-- Material Symbols - Sharp Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}"/>
<script src="{{ url_for('static', filename='js/uikit.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/uikit-icons.min.js') }}"></script>
</head>
<body>
<div class="uk-container">
<div class="uk-section">
<div>
<h1>View/Edit Package</h1>
</div>
<div class="uk-margin">
<label for="packageName">Package Name</label>
<input id="packageName" class="uk-input" type="text" placeholder="" aria-label="Input" value="{{package_object['package_name']}}">
</div>
<div class="uk-margin">
<label class="uk-form-label" for="packageType">Package Type</label>
<div class="uk-form-controls">
<select class="uk-select" id="packageType">
{% for t_type in defined_types %}
<option value="{{t_type['value']}}">{{t_type['string']}}</option>
{% endfor %}
</select>
</div>
</div>
<div class="uk-margin">
<label for="packageDescription">Package Description</label>
<textarea id="packageDescription" class="uk-textarea" rows="15"
uk-tooltip="It is possible to use html tags within descriptions that will be rendered in other parts of the system."
aria-label="Textarea" autocomplete="off">{{package_object['package_description']}}</textarea>
</div>
<ul class="uk-subnav uk-subnav-pill" uk-switcher>
<li><a href="#">Document</a></li>
<li><a href="#">Features</a></li>
</ul>
<div class="uk-switcher uk-margin">
<div id="md_document">{{package_object['package_document']|safe}}</div>
<div>Hello again!</div>
</div>
<hr class="uk-divider-icon">
<div>
<button onclick="savePackage()" class="uk-button uk-button-primary">Save Changes</button>
</div>
</div>
</div>
<!--p>{{package_object}}</p -->
</body>
<script>
const package_object = {{package_object|tojson}}
console.log(package_object['package_uuid'])
document.getElementById('packageType').value = `${package_object.package_type}`;
</script>
<script src="{{ url_for('static', filename='js/packageHandler.js') }}"></script>
</html>

18
test.py Normal file
View File

@ -0,0 +1,18 @@
from backend.models.users import UsersModel
UsersModel.create_table()
payload = UsersModel.Payload(
user_username="Mechseroms",
user_email="jadowyne.ulve@outlook.com",
user_hashed_password="test"
)
#UsersModel.insert_tuple(payload=payload.payload_dictionary())
authenticated, user, message = UsersModel.authenticate_login('Mechseroms', 'test')
print(authenticated)
print(user)
print(message)

164
webserver.py Normal file
View File

@ -0,0 +1,164 @@
from flask import Flask, jsonify, request, render_template, session, redirect, url_for
from functools import wraps
import requests
import markdown
app = Flask(__name__)
app.secret_key = "53016ca1157efe86174936227721c701048926d4c31c4531201bcfcff4725277"
backend_config = {
'host': '127.0.0.1',
'port': '5001'
}
def login_required(func):
@wraps(func)
def wrapper(*args, **kwargs):
if 'user' not in session or session['user'] == None:
return redirect(url_for('login'))
return func(*args, **kwargs)
return wrapper
@app.route('/')
@login_required
def home():
return 'Hello, World!'
@app.route('/p/<uuid>', methods=['GET'])
@login_required
def package_main(uuid):
defined_types = [
{'value': '5e_class', 'string': '5e Class'},
{'value': '5e_race', 'string': '5e Race'},
{'value': '5e_background', 'string': '5e Background'},
{'value': '5e_subclass', 'string': '5e Subclass'},
]
if uuid == "new":
response = requests.post(url = f'http://{backend_config["host"]}:{backend_config["port"]}/packages/add')
if response.status_code == 200 and not response.json()['error']:
return redirect(f'/p/{response.json()['package']['package_uuid']}')
response = requests.get(url = f'http://{backend_config["host"]}:{backend_config["port"]}/packages/get/{uuid}')
if response.status_code == 200 and not response.json()['error']:
package = response.json()['package']
return render_template('package.html', package_object=package, defined_types=defined_types)
return redirect('/')
@app.route('/p/<uuid>/save', methods=['POST'])
def package_save(uuid):
if request.method != 'POST':
return jsonify(
error = True,
message = f"Incorrect Method attempted; {request.method}."
)
response = requests.post(
url = f'http://{backend_config["host"]}:{backend_config["port"]}/packages/update',
json = request.get_json()
)
if response.status_code == 200 and not response.json()['error']:
return jsonify(
error=False,
message=f"{uuid} updated successfully!"
)
return jsonify(
error=True,
message=f"Error while trying to update package {uuid}"
)
@app.route('/f/<uuid>', methods=['GET'])
@login_required
def feature_main(uuid):
if uuid == "new":
response = requests.post(url = f'http://{backend_config["host"]}:{backend_config["port"]}/features/add')
if response.status_code == 200 and not response.json()['error']:
return redirect(f'/f/{response.json()['feature']['feature_uuid']}')
response = requests.get(url = f'http://{backend_config["host"]}:{backend_config["port"]}/features/get/{uuid}')
if response.status_code == 200 and not response.json()['error']:
feature = response.json()['feature']
return render_template('feature.html', feature=feature)
return redirect('/')
@app.route('/f/<uuid>/save', methods=['POST'])
def feature_save(uuid):
if request.method != 'POST':
return jsonify(
error = True,
message = f"Incorrect Method attempted; {request.method}."
)
response = requests.post(
url = f'http://{backend_config["host"]}:{backend_config["port"]}/features/update',
json = request.get_json()
)
if response.status_code == 200 and not response.json()['error']:
return jsonify(
error=False,
message=f"{uuid} updated successfully!"
)
return jsonify(
error=True,
message=f"Error while trying to update feature {uuid}"
)
@app.route('/login', methods=['GET'])
def login():
return render_template('login.html')
@app.route('/logout', methods=['GET'])
def logout():
if request.method != "GET":
return jsonify(
error = True,
message = f"Incorrect Method attempted; {request.method}."
)
if session['user']:
del session['user']
return redirect('/login')
@app.route('/login/authenticate', methods=['POST'])
def basic_authenticate():
if request.method != 'POST':
return jsonify(
error = True,
message = f"Incorrect Method attempted; {request.method}."
)
response = requests.post(
url = f'http://{backend_config["host"]}:{backend_config["port"]}/users/authenticate',
json = request.get_json()
)
if response.status_code == 200 and not response.json()['error']:
session['user'] = response.json()['user']
return jsonify(
error = False,
message = f"Successfully Logged in."
)
return jsonify(
error = True,
message = f"Username or Password Incorrect!"
)
if __name__ == '__main__':
app.run(debug=True)